Skip to content

Commit

Permalink
fix(clipboard): adjust choice of clipboard handler
Browse files Browse the repository at this point in the history
- Use qt on Xorg (should fix #581)
- Use wlclipboard as default on Wayland
- Use xclip instead of wlclipboard on Wayland with Gnome 45
- Fix error message for missing xclip (also noticed in #581)
  • Loading branch information
dynobo committed Jan 4, 2024
1 parent 5c806ed commit 3a80c25
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 9 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
37 changes: 37 additions & 0 deletions normcap/clipboard/handlers/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import abc
import logging
import os
import re
import shutil
import subprocess
import sys

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions normcap/clipboard/handlers/wlclipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
5 changes: 2 additions & 3 deletions normcap/clipboard/handlers/xclip.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 25 additions & 5 deletions normcap/clipboard/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3a80c25

Please sign in to comment.