Skip to content

Commit cd640e5

Browse files
committed
Refactor grabclipboard() for x11 and wayland
Simpified logic and made it more robust against edge cases ( see the `allowed_errors` list ). Doing error checking this way, makes the behaviour of this function for x11 and wayland platforms more silimar to darwin and windows systems. fix typo src/PIL/ImageGrab.py Co-authored-by: Ondrej Baranovič <nulano@nulano.eu> fix typo src/PIL/ImageGrab.py Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> ImageGrab: \added debian edge case to comment
1 parent 1185fb8 commit cd640e5

File tree

1 file changed

+13
-15
lines changed

1 file changed

+13
-15
lines changed

src/PIL/ImageGrab.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,29 +149,27 @@ 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+
err = p.stderr.decode()
161+
if p.returncode != 0:
162+
allowed_errors = [
163+
"Nothing is copied", # wl-paste, when the clipboard is empty
164+
"not available", # wl-paste/debian xclip, when an image isn't available
165+
"cannot convert", # xclip, when an image isn't available
166+
"There is no owner", # xclip, when the clipboard isn't initialized
167+
]
168+
if any(e in err for e in allowed_errors):
169+
return None
170+
msg = f"{args[0]} error: {err.strip() if err else 'Unknown error'}"
174171
raise ChildProcessError(msg)
172+
175173
data = io.BytesIO(p.stdout)
176174
im = Image.open(data)
177175
im.load()

0 commit comments

Comments
 (0)