Repository: python-pillow/Pillow

Issue:
ImageGrab.grabclipboard on Linux with both X11 and Wayland installed
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?
1. Using `grabclipboard` on X11 session with `wl-paste` utility installed regardless if `xclip` is installed
2. Using `grabclipboard` on Wayland session without `wl-paste` but `xclip` is installed

### What did you expect to happen?
1.  * If `xclip` is installed, `xclip` command should be used
    * If `xclip` is not installed, raise `NotImplementedError`
2. Raise `NotImplementedError`

### What actually happened?
1. `wl-paste` command is used instead of `xclip`
```pytb
>>> ImageGrab.grabclipboard()
Failed to connect to a Wayland server
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[path redacted]/python3.11/site-packages/PIL/ImageGrab.py", line 144, in grabclipboard
    output = subprocess.check_output(["wl-paste", "-l"]).decode()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/subprocess.py", line 466, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['wl-paste', '-l']' returned non-zero exit status 1.
```
3. `xclip` is used and failed as it cannot access Wayland clipboard
```pytb
>>> ImageGrab.grabclipboard()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[path redacted]/lib/python3.11/site-packages/PIL/ImageGrab.py", line 165, in grabclipboard
    raise ChildProcessError(msg)
ChildProcessError: xclip error: Error: target image/png not available
```

### What are your OS, Python and Pillow versions?

* OS: Debian 12
* Python: 3.11.2
* Pillow: 10.0.0

<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->

```python
from PIL import ImageGrab

ImageGrab.grabclipboard()
```



Discussion:

Resolving patch:
diff --git a/src/PIL/ImageGrab.py b/src/PIL/ImageGrab.py
--- a/src/PIL/ImageGrab.py
+++ b/src/PIL/ImageGrab.py
@@ -140,7 +140,14 @@ def grabclipboard():
                 return BmpImagePlugin.DibImageFile(data)
         return None
     else:
-        if shutil.which("wl-paste"):
+        if os.getenv("WAYLAND_DISPLAY"):
+            session_type = "wayland"
+        elif os.getenv("DISPLAY"):
+            session_type = "x11"
+        else:  # Session type check failed
+            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:
@@ -153,11 +160,12 @@ def grabclipboard():
             args = ["wl-paste"]
             if mimetype:
                 args.extend(["-t", mimetype])
-        elif shutil.which("xclip"):
+        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, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         err = p.stderr
         if err:


Test patch: