Skip to content
Merged
34 changes: 19 additions & 15 deletions src/PIL/ImageGrab.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,29 +149,33 @@ def grabclipboard():
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"]
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 = [
# 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"
if err:
msg += f": {err.strip().decode()}"
raise ChildProcessError(msg)

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