Lock mode while prompting.
This commit is contained in:
parent
40acc5c6ff
commit
3dc7a1b735
@ -167,6 +167,14 @@ class HintManager(QObject):
|
||||
modeman.instance().left.connect(self.on_mode_left)
|
||||
modeman.instance().entered.connect(self.on_mode_entered)
|
||||
|
||||
def _cleanup(self):
|
||||
"""Clean up after hinting."""
|
||||
for elem in self._context.elems.values():
|
||||
if not elem.label.isNull():
|
||||
elem.label.removeFromDocument()
|
||||
self._context = None
|
||||
message.instance().set_text('')
|
||||
|
||||
def _hint_strings(self, elems):
|
||||
"""Calculate the hint strings for elems.
|
||||
|
||||
@ -507,7 +515,10 @@ class HintManager(QObject):
|
||||
self._context = ctx
|
||||
self._connect_frame_signals()
|
||||
self.hint_strings_updated.emit(strings)
|
||||
modeman.enter(KeyMode.hint, 'HintManager.start')
|
||||
try:
|
||||
modeman.enter(KeyMode.hint, 'HintManager.start')
|
||||
except modeman.ModeLockedError:
|
||||
self._cleanup()
|
||||
|
||||
def handle_partial_key(self, keystr):
|
||||
"""Handle a new partial keypress."""
|
||||
@ -630,8 +641,4 @@ class HintManager(QObject):
|
||||
# self._context might be None, because the current tab is not
|
||||
# hinting.
|
||||
return
|
||||
for elem in self._context.elems.values():
|
||||
if not elem.label.isNull():
|
||||
elem.label.removeFromDocument()
|
||||
self._context = None
|
||||
message.instance().set_text('')
|
||||
self._cleanup()
|
||||
|
@ -34,6 +34,11 @@ from qutebrowser.utils.usertypes import KeyMode
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
|
||||
|
||||
class ModeLockedError(Exception):
|
||||
|
||||
"""Exception raised when the mode is currently locked."""
|
||||
|
||||
|
||||
def instance():
|
||||
"""Get the global modeman instance."""
|
||||
return QApplication.instance().modeman
|
||||
@ -49,6 +54,14 @@ def leave(mode, reason=None):
|
||||
instance().leave(mode, reason)
|
||||
|
||||
|
||||
def maybe_enter(mode, reason=None):
|
||||
"""Convenience method to enter 'mode' without exceptions."""
|
||||
try:
|
||||
instance().enter(mode, reason)
|
||||
except ModeLockedError as e:
|
||||
pass
|
||||
|
||||
|
||||
def maybe_leave(mode, reason=None):
|
||||
"""Convenience method to leave 'mode' without exceptions."""
|
||||
try:
|
||||
@ -65,6 +78,9 @@ class ModeManager(QObject):
|
||||
mode: The current mode (readonly property).
|
||||
passthrough: A list of modes in which to pass through events.
|
||||
mainwindow: The mainwindow object
|
||||
locked: Whether current mode is locked. This means the current mode can
|
||||
still be left (then locked will be reset), but no new mode can
|
||||
be entered while the current mode is active.
|
||||
_handlers: A dictionary of modes and their handlers.
|
||||
_mode_stack: A list of the modes we're currently in, with the active
|
||||
one on the right.
|
||||
@ -86,6 +102,7 @@ class ModeManager(QObject):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.mainwindow = None
|
||||
self.locked = False
|
||||
self._handlers = {}
|
||||
self.passthrough = []
|
||||
self._mode_stack = []
|
||||
@ -200,6 +217,11 @@ class ModeManager(QObject):
|
||||
"""
|
||||
if not isinstance(mode, KeyMode):
|
||||
raise TypeError("Mode {} is no KeyMode member!".format(mode))
|
||||
if self.locked:
|
||||
logger.debug("Not entering mode {} because mode is locked to "
|
||||
"{}.".format(mode, self.mode))
|
||||
raise ModeLockedError("Mode is currently locked to {}".format(
|
||||
self.mode))
|
||||
logger.debug("Entering mode {}{}".format(
|
||||
mode, '' if reason is None else ' (reason: {})'.format(reason)))
|
||||
if mode not in self._handlers:
|
||||
@ -238,6 +260,7 @@ class ModeManager(QObject):
|
||||
self._mode_stack.remove(mode)
|
||||
except ValueError:
|
||||
raise ValueError("Mode {} not on mode stack!".format(mode))
|
||||
self.locked = False
|
||||
logger.debug("Leaving mode {}{}, new mode stack {}".format(
|
||||
mode, '' if reason is None else ' (reason: {})'.format(reason),
|
||||
self._mode_stack))
|
||||
|
@ -299,7 +299,7 @@ class Command(MinimalLineEdit):
|
||||
|
||||
def focusInEvent(self, e):
|
||||
"""Extend focusInEvent to enter command mode."""
|
||||
modeman.enter(KeyMode.command, 'cmd focus')
|
||||
modeman.maybe_enter(KeyMode.command, 'cmd focus')
|
||||
super().focusInEvent(e)
|
||||
|
||||
|
||||
|
@ -279,7 +279,13 @@ class Prompter:
|
||||
self.question = question
|
||||
mode = self._display_question()
|
||||
question.aborted.connect(lambda: modeman.maybe_leave(mode, 'aborted'))
|
||||
modeman.enter(mode, 'question asked')
|
||||
try:
|
||||
modeman.enter(mode, 'question asked')
|
||||
except modeman.ModeLockedError:
|
||||
if modeman.instance().mode != KeyMode.prompt:
|
||||
question.abort()
|
||||
return None
|
||||
modeman.instance().locked = True
|
||||
if blocking:
|
||||
loop = EventLoop()
|
||||
self._loops.append(loop)
|
||||
|
@ -233,7 +233,7 @@ class WebView(QWebView):
|
||||
elif ((hitresult.isContentEditable() and webelem.is_writable(elem)) or
|
||||
webelem.is_editable(elem)):
|
||||
log.mouse.debug("Clicked editable element!")
|
||||
modeman.enter(KeyMode.insert, 'click')
|
||||
modeman.maybe_enter(KeyMode.insert, 'click')
|
||||
else:
|
||||
log.mouse.debug("Clicked non-editable element!")
|
||||
if config.get('input', 'auto-leave-insert-mode'):
|
||||
@ -247,7 +247,7 @@ class WebView(QWebView):
|
||||
elem = webelem.focus_elem(self.page().currentFrame())
|
||||
if webelem.is_editable(elem):
|
||||
log.mouse.debug("Clicked editable element (delayed)!")
|
||||
modeman.enter(KeyMode.insert, 'click-delayed')
|
||||
modeman.maybe_enter(KeyMode.insert, 'click-delayed')
|
||||
else:
|
||||
log.mouse.debug("Clicked non-editable element (delayed)!")
|
||||
if config.get('input', 'auto-leave-insert-mode'):
|
||||
@ -402,7 +402,7 @@ class WebView(QWebView):
|
||||
if elem.isNull():
|
||||
log.webview.debug("Focused element is null!")
|
||||
elif webelem.is_editable(elem):
|
||||
modeman.enter(KeyMode.insert, 'load finished')
|
||||
modeman.maybe_enter(KeyMode.insert, 'load finished')
|
||||
|
||||
@pyqtSlot(str)
|
||||
def set_force_open_target(self, target):
|
||||
|
Loading…
Reference in New Issue
Block a user