Skip to content

Commit 3bd58a8

Browse files
authored
Merge pull request #7745 from nik012003/main
Update wl-paste handling and return None for some errors in grabclipboard() on Linux
2 parents fe09f0d + d8f52f5 commit 3bd58a8

2 files changed

Lines changed: 35 additions & 15 deletions

File tree

Tests/test_imagegrab.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,15 @@ def test_grabclipboard_wl_clipboard(self, ext) -> None:
119119
subprocess.call(["wl-copy"], stdin=fp)
120120
im = ImageGrab.grabclipboard()
121121
assert_image_equal_tofile(im, image_path)
122+
123+
@pytest.mark.skipif(
124+
(
125+
sys.platform != "linux"
126+
or not all(shutil.which(cmd) for cmd in ("wl-paste", "wl-copy"))
127+
),
128+
reason="Linux with wl-clipboard only",
129+
)
130+
@pytest.mark.parametrize("arg", ("text", "--clear"))
131+
def test_grabclipboard_wl_clipboard_errors(self, arg):
132+
subprocess.call(["wl-copy", arg])
133+
assert ImageGrab.grabclipboard() is None

src/PIL/ImageGrab.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,29 +149,37 @@ def grabclipboard():
149149
session_type = None
150150

151151
if shutil.which("wl-paste") and session_type in ("wayland", None):
152-
output = subprocess.check_output(["wl-paste", "-l"]).decode()
153-
mimetypes = output.splitlines()
154-
if "image/png" in mimetypes:
155-
mimetype = "image/png"
156-
elif mimetypes:
157-
mimetype = mimetypes[0]
158-
else:
159-
mimetype = None
160-
161-
args = ["wl-paste"]
162-
if mimetype:
163-
args.extend(["-t", mimetype])
152+
args = ["wl-paste", "-t", "image"]
164153
elif shutil.which("xclip") and session_type in ("x11", None):
165154
args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"]
166155
else:
167156
msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux"
168157
raise NotImplementedError(msg)
169158

170159
p = subprocess.run(args, capture_output=True)
171-
err = p.stderr
172-
if err:
173-
msg = f"{args[0]} error: {err.strip().decode()}"
160+
if p.returncode != 0:
161+
err = p.stderr
162+
for silent_error in [
163+
# wl-paste, when the clipboard is empty
164+
b"Nothing is copied",
165+
# Ubuntu/Debian wl-paste, when the clipboard is empty
166+
b"No selection",
167+
# Ubuntu/Debian wl-paste, when an image isn't available
168+
b"No suitable type of content copied",
169+
# wl-paste or Ubuntu/Debian xclip, when an image isn't available
170+
b" not available",
171+
# xclip, when an image isn't available
172+
b"cannot convert ",
173+
# xclip, when the clipboard isn't initialized
174+
b"xclip: Error: There is no owner for the ",
175+
]:
176+
if silent_error in err:
177+
return None
178+
msg = f"{args[0]} error"
179+
if err:
180+
msg += f": {err.strip().decode()}"
174181
raise ChildProcessError(msg)
182+
175183
data = io.BytesIO(p.stdout)
176184
im = Image.open(data)
177185
im.load()

0 commit comments

Comments
 (0)