Avoid leaving insert mode when page finished loading

This commit is contained in:
Florian Bruhin 2020-07-20 14:19:38 +02:00
parent 4ea9758150
commit 9bcf0b2369
4 changed files with 58 additions and 10 deletions

View File

@ -38,6 +38,9 @@ Changed
all three settings. To review/change previously granted permissions, use
`:config-diff` and e.g.
`:config-unset -u example.org content.media.video_capture`.
- When `input.insert_mode.leave_on_load` is enabled (the default), there are
now additional heuristics to avoid leaving insert mode if an editable element
is focused before the page finished loading.
Added
~~~~~

View File

@ -35,7 +35,7 @@ from qutebrowser.mainwindow import tabwidget, mainwindow
from qutebrowser.browser import signalfilter, browsertab, history
from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
urlutils, message, jinja)
from qutebrowser.misc import quitter
from qutebrowser.misc import quitter, objects
@attr.s
@ -215,7 +215,11 @@ class TabbedBrowser(QWidget):
self.widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
if qtutils.version_check('5.10', compiled=False):
self._leave_modes_on_load_finished = (
qtutils.version_check('5.10', compiled=False) and
objects.backend == usertypes.Backend.QtWebEngine)
if self._leave_modes_on_load_finished:
self.cur_load_finished.connect(self._leave_modes_on_load)
else:
self.cur_load_started.connect(self._leave_modes_on_load)
@ -716,21 +720,32 @@ class TabbedBrowser(QWidget):
@pyqtSlot()
def _leave_modes_on_load(self):
"""Leave insert/hint mode when loading started."""
try:
url = self.current_url()
if not url.isValid():
url = None
except qtutils.QtValueError:
tab = self.widget.currentWidget()
if tab is None:
return
url = tab.url()
if not url.isValid():
url = None
def _leave_mode_cb(elem):
"""Leave insert mode if the current element isn't editable."""
if elem is None or not elem.is_editable():
modeman.leave(self._win_id, usertypes.KeyMode.insert,
'new page loaded', maybe=True)
if config.instance.get('input.insert_mode.leave_on_load',
url=url):
modeman.leave(self._win_id, usertypes.KeyMode.insert,
'load started', maybe=True)
if self._leave_modes_on_load_finished:
tab.elements.find_focused(_leave_mode_cb)
else:
_leave_mode_cb(elem=None)
else:
log.modes.debug("Ignoring leave_on_load request due to setting.")
if config.cache['hints.leave_on_load']:
modeman.leave(self._win_id, usertypes.KeyMode.hint,
'load started', maybe=True)
'new page loaded', maybe=True)
else:
log.modes.debug("Ignoring leave_on_load request due to setting.")

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Input with delayed load</title>
</head>
<body>
<input id="qute-input" type="text" value=""/>
<img src="/delayed-image">
</body>
</html>

View File

@ -102,3 +102,22 @@ def test_auto_leave_insert_mode_reload(quteproc, leave_on_load):
else:
quteproc.wait_for(
message='Ignoring leave_on_load request due to setting.')
def test_auto_leave_insert_mode_delayed_load(quteproc):
"""Test insert mode leave behavior with a delayed load.
If we finish loading after the user focused an insert field, we should not
exit insert mode.
"""
quteproc.set_setting('input.insert_mode.leave_on_load', 'true')
quteproc.open_path('data/insert_mode_settings/html/delayed.html', wait=False)
quteproc.wait_for(message="Changing title for idx 0 to "
"'Input with delayed load'")
quteproc.send_cmd(':click-element --force-event id qute-input')
quteproc.wait_for(message='Entering mode KeyMode.insert (reason: *)')
quteproc.open_path('delayed-image-continue', new_bg_tab=True)
quteproc.ensure_not_logged(message='Leaving mode KeyMode.insert '
'(reason: load started)')