From ccac8540771120bdeb570ec5b7bbfc4e3e9a38dd Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 7 Dec 2022 21:33:09 +1100 Subject: [PATCH 1/3] If available, use wl-paste for grabclipboard() on Linux --- Tests/test_imagegrab.py | 10 +++++++--- src/PIL/ImageGrab.py | 12 +++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Tests/test_imagegrab.py b/Tests/test_imagegrab.py index 5e0eca28be1..1ad4de63f72 100644 --- a/Tests/test_imagegrab.py +++ b/Tests/test_imagegrab.py @@ -64,9 +64,13 @@ def test_grabclipboard(self): ) p.communicate() else: - with pytest.raises(NotImplementedError) as e: - ImageGrab.grabclipboard() - assert str(e.value) == "ImageGrab.grabclipboard() is macOS and Windows only" + if not shutil.which("wl-paste"): + with pytest.raises(NotImplementedError) as e: + ImageGrab.grabclipboard() + assert ( + str(e.value) + == "wl-paste is required for ImageGrab.grabclipboard() on Linux" + ) return ImageGrab.grabclipboard() diff --git a/src/PIL/ImageGrab.py b/src/PIL/ImageGrab.py index 38074cb1b0d..12ad9ad71fe 100644 --- a/src/PIL/ImageGrab.py +++ b/src/PIL/ImageGrab.py @@ -132,4 +132,14 @@ def grabclipboard(): return BmpImagePlugin.DibImageFile(data) return None else: - raise NotImplementedError("ImageGrab.grabclipboard() is macOS and Windows only") + if not shutil.which("wl-paste"): + raise NotImplementedError( + "wl-paste is required for ImageGrab.grabclipboard() on Linux" + ) + fh, filepath = tempfile.mkstemp() + subprocess.call(["wl-paste"], stdout=fh) + os.close(fh) + im = Image.open(filepath) + im.load() + os.unlink(filepath) + return im From 2ecf88eaa621266f63405ca7e1fdbdb7ed4d5c8d Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 7 Dec 2022 22:01:37 +1100 Subject: [PATCH 2/3] If available, use xclip for grabclipboard() on Linux --- Tests/test_imagegrab.py | 4 ++-- src/PIL/ImageGrab.py | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Tests/test_imagegrab.py b/Tests/test_imagegrab.py index 1ad4de63f72..01442dc69f0 100644 --- a/Tests/test_imagegrab.py +++ b/Tests/test_imagegrab.py @@ -68,8 +68,8 @@ def test_grabclipboard(self): with pytest.raises(NotImplementedError) as e: ImageGrab.grabclipboard() assert ( - str(e.value) - == "wl-paste is required for ImageGrab.grabclipboard() on Linux" + str(e.value) == "wl-paste or xclip is required" + " for ImageGrab.grabclipboard() on Linux" ) return diff --git a/src/PIL/ImageGrab.py b/src/PIL/ImageGrab.py index 12ad9ad71fe..8cf95680995 100644 --- a/src/PIL/ImageGrab.py +++ b/src/PIL/ImageGrab.py @@ -132,12 +132,16 @@ def grabclipboard(): return BmpImagePlugin.DibImageFile(data) return None else: - if not shutil.which("wl-paste"): + if shutil.which("wl-paste"): + args = ["wl-paste"] + elif shutil.which("xclip"): + args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"] + else: raise NotImplementedError( - "wl-paste is required for ImageGrab.grabclipboard() on Linux" + "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux" ) fh, filepath = tempfile.mkstemp() - subprocess.call(["wl-paste"], stdout=fh) + subprocess.call(args, stdout=fh) os.close(fh) im = Image.open(filepath) im.load() From 73a2c3049f905bba20748c82ce12e6ca971360f6 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 29 Dec 2022 10:27:03 +1100 Subject: [PATCH 3/3] Use pytest.raises match argument --- Tests/test_imagegrab.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Tests/test_imagegrab.py b/Tests/test_imagegrab.py index 01442dc69f0..317db4c0120 100644 --- a/Tests/test_imagegrab.py +++ b/Tests/test_imagegrab.py @@ -65,12 +65,12 @@ def test_grabclipboard(self): p.communicate() else: if not shutil.which("wl-paste"): - with pytest.raises(NotImplementedError) as e: + with pytest.raises( + NotImplementedError, + match="wl-paste or xclip is required for" + r" ImageGrab.grabclipboard\(\) on Linux", + ): ImageGrab.grabclipboard() - assert ( - str(e.value) == "wl-paste or xclip is required" - " for ImageGrab.grabclipboard() on Linux" - ) return ImageGrab.grabclipboard()