Use a stack for current modes
This commit is contained in:
parent
19d25b2282
commit
3d292fbc27
1
TODO
1
TODO
@ -4,7 +4,6 @@ keyparser foo
|
|||||||
- Get to insert mode when clicking flash plugins
|
- Get to insert mode when clicking flash plugins
|
||||||
- Handle keybind to get out of insert mode (e.g. esc)
|
- Handle keybind to get out of insert mode (e.g. esc)
|
||||||
- Pass keypresses to statusbar correctly
|
- Pass keypresses to statusbar correctly
|
||||||
- Use stack for modes and .leave()
|
|
||||||
- Switch to normal mode if new page loaded
|
- Switch to normal mode if new page loaded
|
||||||
- Add passthrough-keys option to pass through unmapped keys
|
- Add passthrough-keys option to pass through unmapped keys
|
||||||
- Add auto-insert-mode to switch to insert mode if editable element is focused
|
- Add auto-insert-mode to switch to insert mode if editable element is focused
|
||||||
|
@ -403,7 +403,7 @@ class HintManager(QObject):
|
|||||||
self._elems = {}
|
self._elems = {}
|
||||||
self._target = None
|
self._target = None
|
||||||
self._frame = None
|
self._frame = None
|
||||||
modemanager.enter("normal")
|
modemanager.leave("hint")
|
||||||
message.clear()
|
message.clear()
|
||||||
|
|
||||||
def handle_partial_key(self, keystr):
|
def handle_partial_key(self, keystr):
|
||||||
|
@ -47,6 +47,11 @@ def enter(mode):
|
|||||||
manager.enter(mode)
|
manager.enter(mode)
|
||||||
|
|
||||||
|
|
||||||
|
def leave(mode):
|
||||||
|
"""Leave the mode 'mode'."""
|
||||||
|
manager.leave(mode)
|
||||||
|
|
||||||
|
|
||||||
class ModeManager(QObject):
|
class ModeManager(QObject):
|
||||||
|
|
||||||
"""Manager for keyboard modes.
|
"""Manager for keyboard modes.
|
||||||
@ -54,7 +59,9 @@ class ModeManager(QObject):
|
|||||||
Attributes:
|
Attributes:
|
||||||
_handlers: A dictionary of modes and their handlers.
|
_handlers: A dictionary of modes and their handlers.
|
||||||
_passthrough: A list of modes in which to pass through events.
|
_passthrough: A list of modes in which to pass through events.
|
||||||
mode: The current mode.
|
_mode_stack: A list of the modes we're currently in, with the active
|
||||||
|
one on the right.
|
||||||
|
mode: The current mode (readonly property).
|
||||||
|
|
||||||
Signals:
|
Signals:
|
||||||
entered: Emitted when a mode is entered.
|
entered: Emitted when a mode is entered.
|
||||||
@ -70,7 +77,14 @@ class ModeManager(QObject):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._handlers = {}
|
self._handlers = {}
|
||||||
self._passthrough = []
|
self._passthrough = []
|
||||||
self.mode = None
|
self._mode_stack = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
"""Read-only property for the current mode."""
|
||||||
|
if not self._mode_stack:
|
||||||
|
return None
|
||||||
|
return self._mode_stack[-1]
|
||||||
|
|
||||||
def register(self, mode, handler, passthrough=False):
|
def register(self, mode, handler, passthrough=False):
|
||||||
"""Register a new mode.
|
"""Register a new mode.
|
||||||
@ -88,19 +102,34 @@ class ModeManager(QObject):
|
|||||||
def enter(self, mode):
|
def enter(self, mode):
|
||||||
"""Enter a new mode.
|
"""Enter a new mode.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mode; The name of the mode to enter.
|
||||||
|
|
||||||
Emit:
|
Emit:
|
||||||
leaved: With the old mode name.
|
|
||||||
entered: With the new mode name.
|
entered: With the new mode name.
|
||||||
"""
|
"""
|
||||||
oldmode = self.mode
|
logging.debug("Switching mode to {}".format(mode))
|
||||||
logging.debug("Switching mode: {} -> {}".format(oldmode, mode))
|
logging.debug("Mode stack: {}".format(self._mode_stack))
|
||||||
if mode not in self._handlers:
|
if mode not in self._handlers:
|
||||||
raise ValueError("No handler for mode {}".format(mode))
|
raise ValueError("No handler for mode {}".format(mode))
|
||||||
if oldmode is not None:
|
self._mode_stack.append(mode)
|
||||||
self.leaved.emit(oldmode)
|
|
||||||
self.mode = mode
|
|
||||||
self.entered.emit(mode)
|
self.entered.emit(mode)
|
||||||
|
|
||||||
|
def leave(self, mode):
|
||||||
|
"""Leave a mode.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mode; The name of the mode to leave.
|
||||||
|
|
||||||
|
Emit:
|
||||||
|
leaved: With the old mode name.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self._mode_stack.remove(mode)
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError("Mode {} not on mode stack!".format(mode))
|
||||||
|
self.leaved.emit(mode)
|
||||||
|
|
||||||
def eventFilter(self, obj, evt):
|
def eventFilter(self, obj, evt):
|
||||||
"""Filter all events based on the currently set mode.
|
"""Filter all events based on the currently set mode.
|
||||||
|
|
||||||
|
@ -272,7 +272,10 @@ class BrowserTab(QWebView):
|
|||||||
logging.debug("Clicked editable element!")
|
logging.debug("Clicked editable element!")
|
||||||
modemanager.enter("insert")
|
modemanager.enter("insert")
|
||||||
else:
|
else:
|
||||||
modemanager.enter("normal")
|
try:
|
||||||
|
modemanager.leave("insert")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
if self._force_open_target is not None:
|
if self._force_open_target is not None:
|
||||||
self._open_target = self._force_open_target
|
self._open_target = self._force_open_target
|
||||||
|
@ -363,7 +363,7 @@ class _Command(QLineEdit):
|
|||||||
clear_completion_selection: Always emitted.
|
clear_completion_selection: Always emitted.
|
||||||
hide_completion: Always emitted so the completion is hidden.
|
hide_completion: Always emitted so the completion is hidden.
|
||||||
"""
|
"""
|
||||||
modemanager.enter("normal")
|
modemanager.leave("command")
|
||||||
if e.reason() in [Qt.MouseFocusReason, Qt.TabFocusReason,
|
if e.reason() in [Qt.MouseFocusReason, Qt.TabFocusReason,
|
||||||
Qt.BacktabFocusReason, Qt.OtherFocusReason]:
|
Qt.BacktabFocusReason, Qt.OtherFocusReason]:
|
||||||
self.setText('')
|
self.setText('')
|
||||||
|
Loading…
Reference in New Issue
Block a user