Merge pull request #7745 from nik012003/main

Update wl-paste handling and return None for some errors in grabclipboard() on Linux
This commit is contained in:
Andrew Murray 2024-02-05 11:49:31 +11:00 committed by GitHub
commit 3bd58a80a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 15 deletions

View File

@ -119,3 +119,15 @@ $ms = new-object System.IO.MemoryStream(, $bytes)
subprocess.call(["wl-copy"], stdin=fp) subprocess.call(["wl-copy"], stdin=fp)
im = ImageGrab.grabclipboard() im = ImageGrab.grabclipboard()
assert_image_equal_tofile(im, image_path) assert_image_equal_tofile(im, image_path)
@pytest.mark.skipif(
(
sys.platform != "linux"
or not all(shutil.which(cmd) for cmd in ("wl-paste", "wl-copy"))
),
reason="Linux with wl-clipboard only",
)
@pytest.mark.parametrize("arg", ("text", "--clear"))
def test_grabclipboard_wl_clipboard_errors(self, arg):
subprocess.call(["wl-copy", arg])
assert ImageGrab.grabclipboard() is None

View File

@ -149,18 +149,7 @@ def grabclipboard():
session_type = None session_type = None
if shutil.which("wl-paste") and session_type in ("wayland", None): if shutil.which("wl-paste") and session_type in ("wayland", None):
output = subprocess.check_output(["wl-paste", "-l"]).decode() args = ["wl-paste", "-t", "image"]
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])
elif shutil.which("xclip") and session_type in ("x11", None): elif shutil.which("xclip") and session_type in ("x11", None):
args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"] args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"]
else: else:
@ -168,10 +157,29 @@ def grabclipboard():
raise NotImplementedError(msg) raise NotImplementedError(msg)
p = subprocess.run(args, capture_output=True) p = subprocess.run(args, capture_output=True)
err = p.stderr if p.returncode != 0:
if err: err = p.stderr
msg = f"{args[0]} error: {err.strip().decode()}" for silent_error in [
# wl-paste, when the clipboard is empty
b"Nothing is copied",
# Ubuntu/Debian wl-paste, when the clipboard is empty
b"No selection",
# Ubuntu/Debian wl-paste, when an image isn't available
b"No suitable type of content copied",
# wl-paste or Ubuntu/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"xclip: Error: There is no owner for the ",
]:
if silent_error in err:
return None
msg = f"{args[0]} error"
if err:
msg += f": {err.strip().decode()}"
raise ChildProcessError(msg) raise ChildProcessError(msg)
data = io.BytesIO(p.stdout) data = io.BytesIO(p.stdout)
im = Image.open(data) im = Image.open(data)
im.load() im.load()