Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update wl-paste handling and return None for some errors in grabclipboard() on Linux #7745

Merged
merged 13 commits into from
Feb 5, 2024
32 changes: 17 additions & 15 deletions src/PIL/ImageGrab.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,29 +149,31 @@
session_type = None

if shutil.which("wl-paste") and session_type in ("wayland", None):
output = subprocess.check_output(["wl-paste", "-l"]).decode()
mimetypes = output.splitlines()
if "image/png" in mimetypes:
mimetype = "image/png"
elif mimetypes:
mimetype = mimetypes[0]
else:
mimetype = None

args = ["wl-paste"]
if mimetype:
args.extend(["-t", mimetype])
args = ["wl-paste", "-t", "image"]

Check warning on line 152 in src/PIL/ImageGrab.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageGrab.py#L152

Added line #L152 was not covered by tests
elif shutil.which("xclip") and session_type in ("x11", None):
args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"]
else:
msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux"
raise NotImplementedError(msg)

p = subprocess.run(args, capture_output=True)
err = p.stderr
if err:
msg = f"{args[0]} error: {err.strip().decode()}"
if p.returncode != 0:
allowed_errors = [

Check warning on line 161 in src/PIL/ImageGrab.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageGrab.py#L160-L161

Added lines #L160 - L161 were not covered by tests
# wl-paste, when the clipboard is empty
b"Nothing is copied",
# wl-paste/debian xclip, when an image isn't available
b"not available",
# xclip, when an image isn't available
b"cannot convert",
# xclip, when the clipboard isn't initialized
b"There is no owner",
]
err = p.stderr
if any(e in err for e in allowed_errors):
return None
msg = f"{args[0]} error: {err.strip().decode() if err else 'Unknown error'}"

Check warning on line 174 in src/PIL/ImageGrab.py

View check run for this annotation

Codecov / codecov/patch

src/PIL/ImageGrab.py#L171-L174

Added lines #L171 - L174 were not covered by tests
nik012003 marked this conversation as resolved.
Show resolved Hide resolved
raise ChildProcessError(msg)

data = io.BytesIO(p.stdout)
im = Image.open(data)
im.load()
Expand Down
Loading