diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 3d7b0f735..1a0734377 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -123,6 +123,8 @@ Fixed - Movements in caret mode now should work correctly on OS X and Windows. - Fixed upgrade from earlier config versions. - Fixed crash when killing a running userscript. +- Fixed characters being passed through when shifted with + `forward-unbound-keys` set to `auto`. v0.4.1 ------ diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py index 6906a8720..e2ae924e0 100644 --- a/qutebrowser/keyinput/modeman.py +++ b/qutebrowser/keyinput/modeman.py @@ -168,7 +168,9 @@ class ModeManager(QObject): "{}".format(curmode, utils.qualname(parser))) handled = parser.handle(event) - is_non_alnum = bool(event.modifiers()) or not event.text().strip() + is_non_alnum = ( + event.modifiers() not in (Qt.NoModifier, Qt.ShiftModifier) or + not event.text().strip()) focus_widget = QApplication.instance().focusWidget() is_tab = event.key() in (Qt.Key_Tab, Qt.Key_Backtab) diff --git a/tests/conftest.py b/tests/conftest.py index 407540fbe..d1cbfd426 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,6 +39,7 @@ from helpers.messagemock import message_mock from qutebrowser.config import config from qutebrowser.utils import objreg +from PyQt5.QtCore import QEvent from PyQt5.QtNetwork import QNetworkCookieJar import xvfbwrapper @@ -315,12 +316,13 @@ def fake_keyevent_factory(): from unittest import mock from PyQt5.QtGui import QKeyEvent - def fake_keyevent(key, modifiers=0, text=''): + def fake_keyevent(key, modifiers=0, text='', typ=QEvent.KeyPress): """Generate a new fake QKeyPressEvent.""" evtmock = mock.create_autospec(QKeyEvent, instance=True) evtmock.key.return_value = key evtmock.modifiers.return_value = modifiers evtmock.text.return_value = text + evtmock.type.return_value = typ return evtmock return fake_keyevent diff --git a/tests/unit/keyinput/test_modeman.py b/tests/unit/keyinput/test_modeman.py new file mode 100644 index 000000000..d0569f7de --- /dev/null +++ b/tests/unit/keyinput/test_modeman.py @@ -0,0 +1,58 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +import pytest + +from qutebrowser.keyinput import modeman as modeman_module +from qutebrowser.utils import usertypes + +from PyQt5.QtCore import Qt + + +class FakeKeyparser: + + """A fake BaseKeyParser which doesn't handle anything.""" + + def __init__(self): + self.passthrough = False + + def handle(self, evt): + return False + + +@pytest.fixture +def modeman(config_stub, qapp): + config_stub.data = {'input': {'forward-unbound-keys': 'auto'}} + mm = modeman_module.ModeManager(0) + mm.register(usertypes.KeyMode.normal, FakeKeyparser()) + return mm + + +@pytest.mark.parametrize('key, modifiers, text, filtered', [ + (Qt.Key_A, Qt.NoModifier, 'a', True), + (Qt.Key_Up, Qt.NoModifier, '', False), + # https://github.com/The-Compiler/qutebrowser/issues/1207 + (Qt.Key_A, Qt.ShiftModifier, 'A', True), + (Qt.Key_A, Qt.ShiftModifier | Qt.ControlModifier, 'x', False), +]) +def test_non_alphanumeric(key, modifiers, text, filtered, + fake_keyevent_factory, modeman): + """Make sure non-alphanumeric keys are passed through correctly.""" + evt = fake_keyevent_factory(key=key, modifiers=modifiers, text=text) + assert modeman.eventFilter(evt) == filtered