Skip to content

Commit

Permalink
Merge pull request #13671 from madbird1304/madbird1304/issue-13073-fi…
Browse files Browse the repository at this point in the history
…x-paste-magic

Fix paste magic on Wayland
  • Loading branch information
Carreau committed Aug 30, 2022
2 parents c2c6349 + f64d2b1 commit 0ae1099
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
8 changes: 5 additions & 3 deletions IPython/core/hooks.py
Expand Up @@ -155,15 +155,17 @@ def clipboard_get(self):
""" Get text from the clipboard.
"""
from ..lib.clipboard import (
osx_clipboard_get, tkinter_clipboard_get,
win32_clipboard_get
osx_clipboard_get,
tkinter_clipboard_get,
win32_clipboard_get,
wayland_clipboard_get,
)
if sys.platform == 'win32':
chain = [win32_clipboard_get, tkinter_clipboard_get]
elif sys.platform == 'darwin':
chain = [osx_clipboard_get, tkinter_clipboard_get]
else:
chain = [tkinter_clipboard_get]
chain = [wayland_clipboard_get, tkinter_clipboard_get]
dispatcher = CommandChainDispatcher()
for func in chain:
dispatcher.add(func)
Expand Down
34 changes: 33 additions & 1 deletion IPython/lib/clipboard.py
@@ -1,14 +1,16 @@
""" Utilities for accessing the platform's clipboard.
"""

import os
import subprocess

from IPython.core.error import TryNext
import IPython.utils.py3compat as py3compat


class ClipboardEmpty(ValueError):
pass


def win32_clipboard_get():
""" Get the current clipboard's text on Windows.
Expand All @@ -32,6 +34,7 @@ def win32_clipboard_get():
win32clipboard.CloseClipboard()
return text


def osx_clipboard_get() -> str:
""" Get the clipboard's text on OS X.
"""
Expand All @@ -43,6 +46,7 @@ def osx_clipboard_get() -> str:
text = py3compat.decode(bytes_)
return text


def tkinter_clipboard_get():
""" Get the clipboard's text using Tkinter.
Expand All @@ -67,3 +71,31 @@ def tkinter_clipboard_get():
return text


def wayland_clipboard_get():
"""Get the clipboard's text under Wayland using wl-paste command.
This requires Wayland and wl-clipboard installed and running.
"""
if os.environ.get("XDG_SESSION_TYPE") != "wayland":
raise TryNext("wayland is not detected")

try:
with subprocess.Popen(["wl-paste"], stdout=subprocess.PIPE) as p:
raw, err = p.communicate()
if p.wait():
raise TryNext(err)
except FileNotFoundError as e:
raise TryNext(
"Getting text from the clipboard under Wayland requires the wl-clipboard "
"extension: https://github.com/bugaevc/wl-clipboard"
) from e

if not raw:
raise ClipboardEmpty

try:
text = py3compat.decode(raw)
except UnicodeDecodeError as e:
raise ClipboardEmpty from e

return text

0 comments on commit 0ae1099

Please sign in to comment.