From 2e87ee0960f8370921c9f32283e5ca6048b0edd3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 14 Mar 2018 09:34:56 +0100 Subject: Swap Control/Meta back on macOS Fixes #3697 (cherry picked from commit fd9e7bed7fd9842eac22ed304a094a92cc953577) (cherry picked from commit 84c7c37e8eb61f7e3dddbbfc6dbbcfd3f5afeffd) --- qutebrowser/keyinput/keyutils.py | 12 +++++++++ tests/unit/keyinput/test_basekeyparser.py | 9 ++++--- tests/unit/keyinput/test_keyutils.py | 42 ++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py index d0a17eca8..1f34fcae0 100644 --- a/qutebrowser/keyinput/keyutils.py +++ b/qutebrowser/keyinput/keyutils.py @@ -505,6 +505,18 @@ class KeySequence: not ev.text().isupper()): modifiers = Qt.KeyboardModifiers() + # On macOS, swap Ctrl and Meta back + # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-51293 + if utils.is_mac: + if modifiers & Qt.ControlModifier and modifiers & Qt.MetaModifier: + pass + elif modifiers & Qt.ControlModifier: + modifiers &= ~Qt.ControlModifier + modifiers |= Qt.MetaModifier + elif modifiers & Qt.MetaModifier: + modifiers &= ~Qt.MetaModifier + modifiers |= Qt.ControlModifier + keys = list(self._iter_keys()) keys.append(key | int(modifiers)) diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py index e4837783a..7915e2b75 100644 --- a/tests/unit/keyinput/test_basekeyparser.py +++ b/tests/unit/keyinput/test_basekeyparser.py @@ -25,6 +25,7 @@ from PyQt5.QtCore import Qt import pytest from qutebrowser.keyinput import basekeyparser, keyutils +from qutebrowser.utils import utils # Alias because we need this a lot in here. @@ -153,14 +154,16 @@ class TestHandle: keyparser._read_config('prompt') def test_valid_key(self, fake_keyevent, keyparser): - keyparser.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier)) - keyparser.handle(fake_keyevent(Qt.Key_X, Qt.ControlModifier)) + modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier + keyparser.handle(fake_keyevent(Qt.Key_A, modifier)) + keyparser.handle(fake_keyevent(Qt.Key_X, modifier)) keyparser.execute.assert_called_once_with('message-info ctrla', None) assert not keyparser._sequence def test_valid_key_count(self, fake_keyevent, keyparser): + modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier keyparser.handle(fake_keyevent(Qt.Key_5)) - keyparser.handle(fake_keyevent(Qt.Key_A, Qt.ControlModifier)) + keyparser.handle(fake_keyevent(Qt.Key_A, modifier)) keyparser.execute.assert_called_once_with('message-info ctrla', 5) @pytest.mark.parametrize('keys', [ diff --git a/tests/unit/keyinput/test_keyutils.py b/tests/unit/keyinput/test_keyutils.py index 92e9292ef..37519ca85 100644 --- a/tests/unit/keyinput/test_keyutils.py +++ b/tests/unit/keyinput/test_keyutils.py @@ -28,6 +28,7 @@ from PyQt5.QtWidgets import QWidget from tests.unit.keyinput import key_data from qutebrowser.keyinput import keyutils +from qutebrowser.utils import utils @pytest.fixture(params=key_data.KEYS, ids=lambda k: k.attribute) @@ -346,20 +347,28 @@ class TestKeySequence: @pytest.mark.parametrize('old, key, modifiers, text, expected', [ ('a', Qt.Key_B, Qt.NoModifier, 'b', 'ab'), ('a', Qt.Key_B, Qt.ShiftModifier, 'B', 'aB'), - ('a', Qt.Key_B, Qt.ControlModifier | Qt.ShiftModifier, 'B', - 'a'), + ('a', Qt.Key_B, Qt.AltModifier | Qt.ShiftModifier, 'B', + 'a'), # Modifier stripping with symbols ('', Qt.Key_Colon, Qt.NoModifier, ':', ':'), ('', Qt.Key_Colon, Qt.ShiftModifier, ':', ':'), - ('', Qt.Key_Colon, Qt.ControlModifier | Qt.ShiftModifier, ':', - ''), + ('', Qt.Key_Colon, Qt.AltModifier | Qt.ShiftModifier, ':', + ''), + + # Swapping Control/Meta on macOS + ('', Qt.Key_A, Qt.ControlModifier, '', + '' if utils.is_mac else ''), + ('', Qt.Key_A, Qt.ControlModifier | Qt.ShiftModifier, '', + '' if utils.is_mac else ''), + ('', Qt.Key_A, Qt.MetaModifier, '', + '' if utils.is_mac else ''), # Handling of Backtab ('', Qt.Key_Backtab, Qt.NoModifier, '', ''), ('', Qt.Key_Backtab, Qt.ShiftModifier, '', ''), - ('', Qt.Key_Backtab, Qt.ControlModifier | Qt.ShiftModifier, '', - ''), + ('', Qt.Key_Backtab, Qt.AltModifier | Qt.ShiftModifier, '', + ''), # Stripping of Qt.GroupSwitchModifier ('', Qt.Key_A, Qt.GroupSwitchModifier, 'a', 'a'), @@ -370,6 +379,27 @@ class TestKeySequence: new = seq.append_event(event) assert new == keyutils.KeySequence.parse(expected) + @pytest.mark.fake_os('mac') + @pytest.mark.parametrize('modifiers, expected', [ + (Qt.ControlModifier, + Qt.MetaModifier), + (Qt.MetaModifier, + Qt.ControlModifier), + (Qt.ControlModifier | Qt.MetaModifier, + Qt.ControlModifier | Qt.MetaModifier), + (Qt.ControlModifier | Qt.ShiftModifier, + Qt.MetaModifier | Qt.ShiftModifier), + (Qt.MetaModifier | Qt.ShiftModifier, + Qt.ControlModifier | Qt.ShiftModifier), + (Qt.ShiftModifier, Qt.ShiftModifier), + ]) + def test_fake_mac(self, fake_keyevent, modifiers, expected): + """Make sure Control/Meta are swapped with a simulated Mac.""" + seq = keyutils.KeySequence() + event = fake_keyevent(key=Qt.Key_A, modifiers=modifiers) + new = seq.append_event(event) + assert new[0] == keyutils.KeyInfo(Qt.Key_A, expected) + @pytest.mark.parametrize('key', [Qt.Key_unknown, 0x0]) def test_append_event_invalid(self, key): seq = keyutils.KeySequence() -- cgit v1.2.3-54-g00ecf