Skip to content

Commit

Permalink
FEAT: WAYLAND support with wl-copy/wl-paste cmds
Browse files Browse the repository at this point in the history
  • Loading branch information
ankostis committed Aug 22, 2019
1 parent 7526310 commit 3f6b5da
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 10 deletions.
58 changes: 48 additions & 10 deletions src/pyperclip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
On Windows, no additional modules are needed.
On Mac, the pyobjc module is used, falling back to the pbcopy and pbpaste cli
commands. (These commands should come with OS X.).
On Linux, install xclip or xsel via package manager. For example, in Debian:
On Linux, install xclip, xsel, or wl-clipboard (for "wayland" sessions) via package manager.
For example, in Debian:
sudo apt-get install xclip
sudo apt-get install xsel
sudo apt-get install wl-clipboard
Otherwise on Linux, you will need the gtk or PyQt5/PyQt4 modules installed.
Expand All @@ -37,6 +39,7 @@
- pbpaste
- xclip
- xsel
- wl-copy/wl-paste
- klipper
- qdbus
A malicious user could rename or add programs with these names, tricking
Expand Down Expand Up @@ -247,6 +250,33 @@ def paste_xsel(primary=False):
return copy_xsel, paste_xsel


def init_wl_clipboard():
PRIMARY_SELECTION = "-p"

def copy_wl(text, primary=False):
text = _stringifyText(text) # Converts non-str values to str.
args = ["wl-copy"]
if primary:
args.append(PRIMARY_SELECTION)
if not text:
args.append('--clear')
subprocess.check_call(args, close_fds=True)
else:
pass
p = subprocess.Popen(args, stdin=subprocess.PIPE, close_fds=True)
p.communicate(input=text.encode(ENCODING))

def paste_wl(primary=False):
args = ["wl-paste", "-n"]
if primary:
args.append(PRIMARY_SELECTION)
p = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
stdout, _stderr = p.communicate()
return stdout.decode(ENCODING)

return copy_wl, paste_wl


def init_klipper_clipboard():
def copy_klipper(text):
text = _stringifyText(text) # Converts non-str values to str.
Expand Down Expand Up @@ -532,6 +562,11 @@ def determine_clipboard():
else:
return init_gtk_clipboard()

if (
os.environ["XDG_SESSION_TYPE"] == "wayland" and
_executable_exists("wl-copy")
):
return init_wl_clipboard()
if _executable_exists("xsel"):
return init_xsel_clipboard()
if _executable_exists("xclip"):
Expand Down Expand Up @@ -580,15 +615,18 @@ def set_clipboard(clipboard):
'''
global copy, paste

clipboard_types = {'pbcopy': init_osx_pbcopy_clipboard,
'pyobjc': init_osx_pyobjc_clipboard,
'gtk': init_gtk_clipboard,
'qt': init_qt_clipboard, # TODO - split this into 'qtpy', 'pyqt4', and 'pyqt5'
'xclip': init_xclip_clipboard,
'xsel': init_xsel_clipboard,
'klipper': init_klipper_clipboard,
'windows': init_windows_clipboard,
'no': init_no_clipboard}
clipboard_types = {
"pbcopy": init_osx_pbcopy_clipboard,
"pyobjc": init_osx_pyobjc_clipboard,
"gtk": init_gtk_clipboard,
"qt": init_qt_clipboard, # TODO - split this into 'qtpy', 'pyqt4', and 'pyqt5'
"xclip": init_xclip_clipboard,
"xsel": init_xsel_clipboard,
"wl-clipboard": init_wl_clipboard,
"klipper": init_klipper_clipboard,
"windows": init_windows_clipboard,
"no": init_no_clipboard,
}

if clipboard not in clipboard_types:
raise ValueError('Argument must be one of %s' % (', '.join([repr(_) for _ in clipboard_types.keys()])))
Expand Down
6 changes: 6 additions & 0 deletions tests/test_pyperclip.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
init_dev_clipboard_clipboard,
init_gtk_clipboard, init_qt_clipboard,
init_xclip_clipboard, init_xsel_clipboard,
init_wl_clipboard,
init_klipper_clipboard, init_no_clipboard)
from pyperclip import init_windows_clipboard
from pyperclip import init_wsl_clipboard
Expand Down Expand Up @@ -168,6 +169,11 @@ class TestXSel(_TestClipboard):
clipboard = init_xsel_clipboard()


class TestWlClipboard(_TestClipboard):
if _executable_exists("wl-copy"):
clipboard = init_wl_clipboard()


class TestKlipper(_TestClipboard):
if _executable_exists("klipper") and _executable_exists("qdbus"):
clipboard = init_klipper_clipboard()
Expand Down

0 comments on commit 3f6b5da

Please sign in to comment.