From 1eda2b0ea47525eee1936117dee9fed5af8c19d6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 29 Mar 2017 17:17:48 +0200 Subject: [PATCH] Fallback to clipboard when primary selection is unsupported --- qutebrowser/browser/commands.py | 5 +---- qutebrowser/mainwindow/prompt.py | 6 +++--- qutebrowser/misc/miscwidgets.py | 9 +++++---- qutebrowser/utils/utils.py | 18 +++++++++++++++--- tests/unit/utils/test_utils.py | 9 +++++++++ 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 45c2a7b9f..12f58d610 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1542,10 +1542,7 @@ class CommandDispatcher: backend=usertypes.Backend.QtWebKit) def paste_primary(self): """Paste the primary selection at cursor position.""" - try: - self.insert_text(utils.get_clipboard(selection=True)) - except utils.SelectionUnsupportedError: - self.insert_text(utils.get_clipboard()) + self.insert_text(utils.get_clipboard(selection=True, fallback=True)) @cmdutils.register(instance='command-dispatcher', maxsplit=0, scope='window') diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py index f57e2cad6..69feab920 100644 --- a/qutebrowser/mainwindow/prompt.py +++ b/qutebrowser/mainwindow/prompt.py @@ -437,13 +437,13 @@ class LineEdit(QLineEdit): """Override keyPressEvent to paste primary selection on Shift + Ins.""" if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier: try: - text = utils.get_clipboard(selection=True) + text = utils.get_clipboard(selection=True, fallback=True) except utils.ClipboardError: # pragma: no cover - pass + e.ignore() else: e.accept() self.insert(text) - return + return super().keyPressEvent(e) def __repr__(self): diff --git a/qutebrowser/misc/miscwidgets.py b/qutebrowser/misc/miscwidgets.py index f696951ec..956d60d4a 100644 --- a/qutebrowser/misc/miscwidgets.py +++ b/qutebrowser/misc/miscwidgets.py @@ -46,11 +46,12 @@ class MinimalLineEditMixin: """Override keyPressEvent to paste primary selection on Shift + Ins.""" if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier: try: - text = utils.get_clipboard(selection=True) + text = utils.get_clipboard(selection=True, fallback=True) except utils.ClipboardError: - text = utils.get_clipboard() - e.accept() - self.insert(text) + e.ignore() + else: + e.accept() + self.insert(text) return super().keyPressEvent(e) diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py index 08ccaf3e8..c34df896e 100644 --- a/qutebrowser/utils/utils.py +++ b/qutebrowser/utils/utils.py @@ -767,11 +767,23 @@ def set_clipboard(data, selection=False): QApplication.clipboard().setText(data, mode=mode) -def get_clipboard(selection=False): - """Get data from the clipboard.""" +def get_clipboard(selection=False, fallback=False): + """Get data from the clipboard. + + Args: + selection: Use the primary selection. + fallback: Fall back to the clipboard if primary selection is + unavailable. + """ global fake_clipboard + if fallback and not selection: + raise ValueError("fallback given without selection!") + if selection and not supports_selection(): - raise SelectionUnsupportedError + if fallback: + selection = False + else: + raise SelectionUnsupportedError if fake_clipboard is not None: data = fake_clipboard diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py index c60b640d6..d42f7a971 100644 --- a/tests/unit/utils/test_utils.py +++ b/tests/unit/utils/test_utils.py @@ -836,6 +836,11 @@ class TestGetSetClipboard: with pytest.raises(utils.SelectionUnsupportedError): utils.get_clipboard(selection=True) + def test_get_unsupported_selection_fallback(self, clipboard_mock): + clipboard_mock.supportsSelection.return_value = False + clipboard_mock.text.return_value = 'text' + assert utils.get_clipboard(selection=True, fallback=True) == 'text' + @pytest.mark.parametrize('selection', [True, False]) def test_get_fake_clipboard(self, selection): utils.fake_clipboard = 'fake clipboard text' @@ -847,6 +852,10 @@ class TestGetSetClipboard: clipboard_mock.supportsSelection.return_value = selection assert utils.supports_selection() == selection + def test_fallback_without_selection(self): + with pytest.raises(ValueError): + utils.get_clipboard(fallback=True) + @pytest.mark.parametrize('keystr, expected', [ ('', True),