diff --git a/CHANGELOG b/CHANGELOG index b0c4f69c3..10ff19c0b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,9 +2,11 @@ # Changelog -## v0.5.3 (upcoming) +## v0.5.3 (2024-01-04) - All: Add CLI argument for selecting clipboard handler (mainly intended for debugging). +- Linux: Revert clipboard handling to use Qt on Xorg, wl-clipboard on Wayland, and xclip + only on AwesomeWM and Gnome 45. ([#581](https://github.com/dynobo/normcap/issues/581)) ## v0.5.2 (2023-12-12) diff --git a/normcap/clipboard/handlers/base.py b/normcap/clipboard/handlers/base.py index 7a51e35f9..ef46fdddd 100644 --- a/normcap/clipboard/handlers/base.py +++ b/normcap/clipboard/handlers/base.py @@ -1,6 +1,9 @@ import abc import logging import os +import re +import shutil +import subprocess import sys logger = logging.getLogger(__name__) @@ -50,6 +53,40 @@ def _os_has_awesome_wm() -> bool: return "awesome" in os.environ.get("XDG_CURRENT_DESKTOP", "").lower() + @staticmethod + def _get_gnome_version() -> str: + """Detect Gnome version of current session. + + Returns: + Version string or empty string if not detected. + """ + if sys.platform != "linux": + return "" + + if ( + not os.environ.get("GNOME_DESKTOP_SESSION_ID", "") + and "gnome" not in os.environ.get("XDG_CURRENT_DESKTOP", "").lower() + ): + return "" + + if not shutil.which("gnome-shell"): + return "" + + try: + output = subprocess.check_output( + ["gnome-shell", "--version"], # noqa: S607 + shell=False, # noqa: S603 + text=True, + ) + if result := re.search(r"\s+([\d.]+)", output.strip()): + gnome_version = result.groups()[0] + except Exception as e: + logger.warning("Exception when trying to get gnome version from cli %s", e) + return "" + else: + logger.debug("Detected Gnome Version: %s", gnome_version) + return gnome_version + @abc.abstractmethod def _is_compatible(self) -> bool: ... # pragma: no cover diff --git a/normcap/clipboard/handlers/wlclipboard.py b/normcap/clipboard/handlers/wlclipboard.py index cf9d962f3..ffae56927 100644 --- a/normcap/clipboard/handlers/wlclipboard.py +++ b/normcap/clipboard/handlers/wlclipboard.py @@ -37,6 +37,10 @@ def _is_compatible(self) -> bool: logger.debug("%s is not compatible with Awesome WM", self.name) return False + if self._get_gnome_version().startswith("45."): + logger.debug("%s is not compatible with Gnome 45", self.name) + return False + if not (wl_copy_bin := shutil.which("wl-copy")): logger.debug("%s is not compatible: wl-copy was not found", self.name) logger.warning( diff --git a/normcap/clipboard/handlers/xclip.py b/normcap/clipboard/handlers/xclip.py index be29941b4..c60510198 100644 --- a/normcap/clipboard/handlers/xclip.py +++ b/normcap/clipboard/handlers/xclip.py @@ -34,9 +34,8 @@ def _is_compatible(self) -> bool: if not (xclip_bin := shutil.which("xclip")): logger.debug("%s is not compatible: xclip was not found", self.name) logger.warning( - "Your Linux runs with Wayland. Please install the system " - "package 'xclip' to ensure that text can be copied to " - "the clipboard correctly" + "Please install the system package 'xclip' to ensure that text can be" + "copied to the clipboard correctly" ) return False diff --git a/normcap/clipboard/main.py b/normcap/clipboard/main.py index 4440f01dd..b03efa6a0 100644 --- a/normcap/clipboard/main.py +++ b/normcap/clipboard/main.py @@ -7,11 +7,31 @@ class ClipboardHandlers(Enum): - windll = windll.WindllHandler() # win32 - pbcopy = pbcopy.PbCopyHandler() # darwin - xclip = xclip.XclipCopyHandler() # linux, xorg and wayland - wlclipboard = wlclipboard.WlCopyHandler() # linux, wayland, broken in Gnome 45 atm - qt = qtclipboard.QtCopyHandler() # cross platform + """All supported clipboard handlers. + + The handlers are ordered by preference: copy() tries them from top to bottom + and uses the first one that is detected as compatible. + """ + + # For win32 + windll = windll.WindllHandler() + + # For darwin + pbcopy = pbcopy.PbCopyHandler() + + # Cross platform + # - Not working on linux with wayland + qt = qtclipboard.QtCopyHandler() + + # For linux with wayland + # - Not working with Awesome WM + # - Problems with Gnome 45: https://github.com/bugaevc/wl-clipboard/issues/168 + wlclipboard = wlclipboard.WlCopyHandler() + + # For linux with xorg and wayland + # - Seems not very robust on wayland + # - Works with Awesome WM + xclip = xclip.XclipCopyHandler() # TODO: Think about implementing a _real_ success check