Merge remote-tracking branch 'origin/pr/3590' into tab-mode
This commit is contained in:
commit
1335fccba1
@ -30,6 +30,9 @@ from qutebrowser.config import config
|
||||
from qutebrowser.commands import cmdexc, cmdutils
|
||||
from qutebrowser.utils import usertypes, log, objreg, utils
|
||||
|
||||
INPUT_MODES = [usertypes.KeyMode.insert, usertypes.KeyMode.passthrough]
|
||||
PROMPT_MODES = [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]
|
||||
|
||||
|
||||
@attr.s(frozen=True)
|
||||
class KeyEvent:
|
||||
@ -121,6 +124,7 @@ class ModeManager(QObject):
|
||||
Attributes:
|
||||
mode: The mode we're currently in.
|
||||
_win_id: The window ID of this ModeManager
|
||||
_prev_mode: Mode before a prompt popped up
|
||||
_parsers: A dictionary of modes and their keyparsers.
|
||||
_forward_unbound_keys: If we should forward unbound keys.
|
||||
_releaseevents_to_pass: A set of KeyEvents where the keyPressEvent was
|
||||
@ -144,6 +148,7 @@ class ModeManager(QObject):
|
||||
super().__init__(parent)
|
||||
self._win_id = win_id
|
||||
self._parsers = {}
|
||||
self._prev_mode = usertypes.KeyMode.normal
|
||||
self.mode = usertypes.KeyMode.normal
|
||||
self._releaseevents_to_pass = set()
|
||||
|
||||
@ -240,9 +245,8 @@ class ModeManager(QObject):
|
||||
mode, '' if reason is None else ' (reason: {})'.format(reason)))
|
||||
if mode not in self._parsers:
|
||||
raise ValueError("No keyparser for mode {}".format(mode))
|
||||
prompt_modes = (usertypes.KeyMode.prompt, usertypes.KeyMode.yesno)
|
||||
if self.mode == mode or (self.mode in prompt_modes and
|
||||
mode in prompt_modes):
|
||||
if self.mode == mode or (self.mode in PROMPT_MODES and
|
||||
mode in PROMPT_MODES):
|
||||
log.modes.debug("Ignoring request as we're in mode {} "
|
||||
"already.".format(self.mode))
|
||||
return
|
||||
@ -254,6 +258,11 @@ class ModeManager(QObject):
|
||||
return
|
||||
log.modes.debug("Overriding mode {}.".format(self.mode))
|
||||
self.left.emit(self.mode, mode, self._win_id)
|
||||
if (mode in PROMPT_MODES and self.mode in INPUT_MODES and
|
||||
config.val.tabs.mode_on_change == 'restore'):
|
||||
self._prev_mode = self.mode
|
||||
else:
|
||||
self._prev_mode = usertypes.KeyMode.normal
|
||||
self.mode = mode
|
||||
self.entered.emit(mode, self._win_id)
|
||||
|
||||
@ -301,6 +310,9 @@ class ModeManager(QObject):
|
||||
self.clear_keychain()
|
||||
self.mode = usertypes.KeyMode.normal
|
||||
self.left.emit(mode, self.mode, self._win_id)
|
||||
if mode in PROMPT_MODES:
|
||||
self.enter(self._prev_mode,
|
||||
reason='restore mode before {}'.format(mode.name))
|
||||
|
||||
@cmdutils.register(instance='mode-manager', name='leave-mode',
|
||||
not_modes=[usertypes.KeyMode.normal], scope='window')
|
||||
|
@ -492,6 +492,7 @@ class MainWindow(QWidget):
|
||||
self.tabbed_browser.cur_fullscreen_requested.connect(status.maybe_hide)
|
||||
|
||||
# command input / completion
|
||||
mode_manager.entered.connect(self.tabbed_browser.on_mode_entered)
|
||||
mode_manager.left.connect(self.tabbed_browser.on_mode_left)
|
||||
cmd.clear_completion_selection.connect(
|
||||
completion_obj.on_clear_completion_selection)
|
||||
|
@ -644,24 +644,32 @@ class TabbedBrowser(QWidget):
|
||||
if config.val.tabs.tabs_are_windows:
|
||||
self.widget.window().setWindowIcon(icon)
|
||||
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_entered(self, mode):
|
||||
"""Save input mode when tabs.mode_on_change = restore."""
|
||||
if (config.val.tabs.mode_on_change == 'restore' and
|
||||
mode in modeman.INPUT_MODES):
|
||||
tab = self.widget.currentWidget()
|
||||
if tab is not None:
|
||||
tab.data.input_mode = mode
|
||||
|
||||
@pyqtSlot(usertypes.KeyMode)
|
||||
def on_mode_left(self, mode):
|
||||
"""Give focus to current tab if command mode was left."""
|
||||
if mode in [usertypes.KeyMode.command, usertypes.KeyMode.prompt,
|
||||
usertypes.KeyMode.yesno]:
|
||||
widget = self.widget.currentWidget()
|
||||
log.modes.debug("Left status-input mode, focusing {!r}".format(
|
||||
widget))
|
||||
if widget is None:
|
||||
return
|
||||
if mode in [usertypes.KeyMode.command] + modeman.PROMPT_MODES:
|
||||
log.modes.debug("Left status-input mode, focusing {!r}".format(
|
||||
widget))
|
||||
widget.setFocus()
|
||||
if config.val.tabs.mode_on_change == 'restore':
|
||||
widget.data.input_mode = usertypes.KeyMode.normal
|
||||
|
||||
@pyqtSlot(int)
|
||||
def on_current_changed(self, idx):
|
||||
"""Set last-focused-tab and leave hinting mode when focus changed."""
|
||||
mode_on_change = config.val.tabs.mode_on_change
|
||||
modes_to_save = [usertypes.KeyMode.insert,
|
||||
usertypes.KeyMode.passthrough]
|
||||
if idx == -1 or self.shutting_down:
|
||||
# closing the last tab (before quitting) or shutting down
|
||||
return
|
||||
@ -670,26 +678,28 @@ class TabbedBrowser(QWidget):
|
||||
log.webview.debug("on_current_changed got called with invalid "
|
||||
"index {}".format(idx))
|
||||
return
|
||||
if self._now_focused is not None and mode_on_change == 'restore':
|
||||
current_mode = modeman.instance(self._win_id).mode
|
||||
if current_mode not in modes_to_save:
|
||||
current_mode = usertypes.KeyMode.normal
|
||||
self._now_focused.data.input_mode = current_mode
|
||||
|
||||
log.modes.debug("Current tab changed, focusing {!r}".format(tab))
|
||||
tab.setFocus()
|
||||
|
||||
modes_to_leave = [usertypes.KeyMode.hint, usertypes.KeyMode.caret]
|
||||
if mode_on_change != 'persist':
|
||||
modes_to_leave += modes_to_save
|
||||
|
||||
mm_instance = modeman.instance(self._win_id)
|
||||
current_mode = mm_instance.mode
|
||||
log.modes.debug("Mode before tab change: {} (mode_on_change = {})"
|
||||
.format(current_mode.name, mode_on_change))
|
||||
if mode_on_change == 'normal':
|
||||
modes_to_leave += modeman.INPUT_MODES
|
||||
for mode in modes_to_leave:
|
||||
modeman.leave(self._win_id, mode, 'tab changed', maybe=True)
|
||||
if mode_on_change == 'restore':
|
||||
modeman.enter(self._win_id, tab.data.input_mode,
|
||||
'restore input mode for tab')
|
||||
if (mode_on_change == 'restore' and
|
||||
current_mode not in modeman.PROMPT_MODES):
|
||||
modeman.enter(self._win_id, tab.data.input_mode, 'restore')
|
||||
if self._now_focused is not None:
|
||||
objreg.register('last-focused-tab', self._now_focused, update=True,
|
||||
scope='window', window=self._win_id)
|
||||
log.modes.debug("Mode after tab change: {} (mode_on_change = {})"
|
||||
.format(current_mode.name, mode_on_change))
|
||||
self._now_focused = tab
|
||||
self.current_tab_changed.emit(tab)
|
||||
QTimer.singleShot(0, self._update_window_title)
|
||||
|
@ -160,3 +160,45 @@ Feature: Keyboard input
|
||||
And I press the key "c"
|
||||
Then the message "foo 3" should be shown
|
||||
And the message "foo 3" should be shown
|
||||
|
||||
# test all tabs.mode_on_change modes
|
||||
|
||||
Scenario: mode on change normal
|
||||
Given I set tabs.mode_on_change to normal
|
||||
And I clean up open tabs
|
||||
When I open about:blank
|
||||
And I run :enter-mode insert
|
||||
And I open about:blank in a new tab
|
||||
Then "Entering mode KeyMode.insert (reason: command)" should be logged
|
||||
And "Leaving mode KeyMode.insert (reason: tab changed)" should be logged
|
||||
And "Mode before tab change: insert (mode_on_change = normal)" should be logged
|
||||
And "Mode after tab change: normal (mode_on_change = normal)" should be logged
|
||||
|
||||
Scenario: mode on change persist
|
||||
Given I set tabs.mode_on_change to persist
|
||||
And I clean up open tabs
|
||||
When I open about:blank
|
||||
And I run :enter-mode insert
|
||||
And I open about:blank in a new tab
|
||||
Then "Entering mode KeyMode.insert (reason: command)" should be logged
|
||||
And "Leaving mode KeyMode.insert (reason: tab changed)" should not be logged
|
||||
And "Mode before tab change: insert (mode_on_change = persist)" should be logged
|
||||
And "Mode after tab change: insert (mode_on_change = persist)" should be logged
|
||||
|
||||
Scenario: mode on change restore
|
||||
Given I set tabs.mode_on_change to restore
|
||||
And I clean up open tabs
|
||||
When I open about:blank
|
||||
And I run :enter-mode insert
|
||||
And I open about:blank in a new tab
|
||||
And I run :enter-mode passthrough
|
||||
And I run :tab-focus 1
|
||||
Then "Entering mode KeyMode.insert (reason: command)" should be logged
|
||||
And "Mode before tab change: insert (mode_on_change = restore)" should be logged
|
||||
And "Entering mode KeyMode.normal (reason: restore)" should be logged
|
||||
And "Mode after tab change: normal (mode_on_change = restore)" should be logged
|
||||
And "Entering mode KeyMode.passthrough (reason: command)" should be logged
|
||||
And "Mode before tab change: passthrough (mode_on_change = restore)" should be logged
|
||||
And "Entering mode KeyMode.insert (reason: restore)" should be logged
|
||||
And "Mode after tab change: insert (mode_on_change = restore)" should be logged
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user