diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index c44dfb9a6..279e7889e 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -242,7 +242,7 @@ |<>|Position of new tabs opened from another tab. |<>|Position of new tabs which aren't opened from another tab. |<>|Padding (in pixels) around text for tabs. -|<>|Stay in insert/passthrough mode when switching tabs. +|<>|Set input mode behavior when switching tab. |<>|Shrink pinned tabs down to their contents. |<>|Position of the tab bar. |<>|Which tab to select when the focused tab is removed. @@ -2825,13 +2825,19 @@ Default: - +pass:[right]+: +pass:[5]+ - +pass:[top]+: +pass:[0]+ -[[tabs.persist_mode_on_change]] -=== tabs.persist_mode_on_change -Stay in insert/passthrough mode when switching tabs. +[[tabs.mode_on_change]] +=== tabs.mode_on_change +When switching tabs, what input mode is applied. -Type: <> +Type: <> -Default: +pass:[false]+ +Valid values: + + * +persist+: Retain the current mode. + * +restore+: Restore previously saved mode. + * +normal+: Always revert to normal mode. + +Default: +pass:[normal]+ [[tabs.pinned.shrink]] === tabs.pinned.shrink diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 28a40dbfe..dca4e1449 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -98,6 +98,7 @@ class TabData: Only used for QtWebKit. pinned: Flag to pin the tab. fullscreen: Whether the tab has a video shown fullscreen currently. + input_mode: current input mode for the tab. """ keep_icon = attr.ib(False) @@ -105,6 +106,7 @@ class TabData: override_target = attr.ib(None) pinned = attr.ib(False) fullscreen = attr.ib(False) + input_mode = attr.ib(usertypes.KeyMode.normal) class AbstractAction: diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index e2daefe3b..5e47eb84e 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1251,10 +1251,15 @@ tabs.padding: type: Padding desc: Padding (in pixels) around text for tabs. -tabs.persist_mode_on_change: - default: false - type: Bool - desc: Stay in insert/passthrough mode when switching tabs. +tabs.mode_on_change: + default: normal + type: + name: String + valid_values: + - persist: "Retain the current mode." + - restore: "Restore previously saved mode." + - normal: "Always revert to normal mode." + desc: When switching tabs, what input mode is applied. tabs.position: default: top diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index 77b5190ce..2220de93d 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -175,10 +175,17 @@ class YamlConfig(QObject): new_name = configdata.MIGRATIONS.renamed[name] log.config.debug("Renaming {} to {}".format(name, new_name)) self._values[new_name] = self._values[name] - del self._values[name] + self.unset(name) elif name in configdata.MIGRATIONS.deleted: log.config.debug("Removing {}".format(name)) - del self._values[name] + self.unset(name) + persist = 'tabs.persist_mode_on_change' + if persist in self._values: + if self._values[persist]: + self._values['tabs.mode_on_change'] = 'persist' + else: + self._values['tabs.mode_on_change'] = 'normal' + self.unset(persist) def _validate(self): """Make sure all settings exist.""" diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 824abf25b..cd9f52b37 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -643,6 +643,9 @@ class TabbedBrowser(tabwidget.TabWidget): @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 @@ -651,17 +654,23 @@ class TabbedBrowser(tabwidget.TabWidget): 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 not config.val.tabs.persist_mode_on_change: - modes_to_leave += [usertypes.KeyMode.insert, - usertypes.KeyMode.passthrough] + if mode_on_change != 'persist': + modes_to_leave += modes_to_save 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 self._now_focused is not None: objreg.register('last-focused-tab', self._now_focused, update=True, scope='window', window=self._win_id) diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index 8659cf891..341fad689 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -152,7 +152,7 @@ class TestYaml: yaml._save() lines = autoconfig.read_text('utf-8').splitlines() - assert ' hello:' not in lines + assert ' hello: world' not in lines def test_renamed_key(self, monkeypatch, yaml, config_tmpdir): """A key marked as renamed should be renamed properly.""" @@ -166,8 +166,22 @@ class TestYaml: yaml._save() lines = autoconfig.read_text('utf-8').splitlines() - assert ' old:' not in lines - assert ' new:' not in lines + assert ' old: value' not in lines + assert ' tabs.show: value' in lines + + @pytest.mark.parametrize('persist', [True, False]) + def test_merge_persist(self, yaml, config_tmpdir, persist): + """Tests for migration of tabs.persist_mode_on_change.""" + autoconfig = config_tmpdir / 'autoconfig.yml' + autoconfig.write_text('global:\n tabs.persist_mode_on_change: {}'. + format(persist), encoding='utf-8') + yaml.load() + yaml._save() + + lines = autoconfig.read_text('utf-8').splitlines() + mode = 'persist' if persist else 'normal' + assert ' tabs.persist_mode_on_change:' not in lines + assert ' tabs.mode_on_change: {}'.format(mode) in lines def test_renamed_key_unknown_target(self, monkeypatch, yaml, config_tmpdir):