Refactor EventFilter.
This commit is contained in:
parent
f77ba5744b
commit
83dbe48469
@ -33,9 +33,9 @@ import faulthandler
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||||
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor
|
from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon, QCursor, QWindow
|
||||||
from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QTimer, QUrl,
|
from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QTimer, QUrl,
|
||||||
QObject, Qt, QSocketNotifier)
|
QObject, Qt, QSocketNotifier, QEvent)
|
||||||
try:
|
try:
|
||||||
import hunter
|
import hunter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -52,7 +52,6 @@ from qutebrowser.mainwindow import mainwindow
|
|||||||
from qutebrowser.misc import (crashdialog, readline, ipc, earlyinit,
|
from qutebrowser.misc import (crashdialog, readline, ipc, earlyinit,
|
||||||
savemanager, sessions)
|
savemanager, sessions)
|
||||||
from qutebrowser.misc import utilcmds # pylint: disable=unused-import
|
from qutebrowser.misc import utilcmds # pylint: disable=unused-import
|
||||||
from qutebrowser.keyinput import modeman
|
|
||||||
from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils,
|
from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils,
|
||||||
objreg, usertypes, standarddir)
|
objreg, usertypes, standarddir)
|
||||||
# We import utilcmds to run the cmdutils.register decorators.
|
# We import utilcmds to run the cmdutils.register decorators.
|
||||||
@ -143,7 +142,7 @@ class Application(QApplication):
|
|||||||
QTimer.singleShot(0, self._process_args)
|
QTimer.singleShot(0, self._process_args)
|
||||||
|
|
||||||
log.init.debug("Initializing eventfilter...")
|
log.init.debug("Initializing eventfilter...")
|
||||||
self._event_filter = modeman.EventFilter(self)
|
self._event_filter = EventFilter(self)
|
||||||
self.installEventFilter(self._event_filter)
|
self.installEventFilter(self._event_filter)
|
||||||
|
|
||||||
log.init.debug("Connecting signals...")
|
log.init.debug("Connecting signals...")
|
||||||
@ -977,3 +976,92 @@ class Application(QApplication):
|
|||||||
print("Now logging late shutdown.", file=sys.stderr)
|
print("Now logging late shutdown.", file=sys.stderr)
|
||||||
hunter.trace()
|
hunter.trace()
|
||||||
super().exit(status)
|
super().exit(status)
|
||||||
|
|
||||||
|
|
||||||
|
class EventFilter(QObject):
|
||||||
|
|
||||||
|
"""Global Qt event filter.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
_activated: Whether the EventFilter is currently active.
|
||||||
|
_handlers; A {QEvent.Type: callable} dict with the handlers for an
|
||||||
|
event.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self._activated = True
|
||||||
|
self._handlers = {
|
||||||
|
QEvent.MouseButtonDblClick: self._handle_mouse_event,
|
||||||
|
QEvent.MouseButtonPress: self._handle_mouse_event,
|
||||||
|
QEvent.MouseButtonRelease: self._handle_mouse_event,
|
||||||
|
QEvent.MouseMove: self._handle_mouse_event,
|
||||||
|
QEvent.KeyPress: self._handle_key_event,
|
||||||
|
QEvent.KeyRelease: self._handle_key_event,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _handle_key_event(self, event):
|
||||||
|
"""Handle a key press/release event.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
event: The QEvent which is about to be delivered.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
True if the event should be filtered, False if it's passed through.
|
||||||
|
"""
|
||||||
|
qapp = QApplication.instance()
|
||||||
|
if qapp.activeWindow() not in objreg.window_registry.values():
|
||||||
|
# Some other window (print dialog, etc.) is focused so we pass the
|
||||||
|
# event through.
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
man = objreg.get('mode-manager', scope='window', window='current')
|
||||||
|
return man.eventFilter(event)
|
||||||
|
except objreg.RegistryUnavailableError:
|
||||||
|
# No window available yet, or not a MainWindow
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _handle_mouse_event(self, _event):
|
||||||
|
"""Handle a mouse event.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
_event: The QEvent which is about to be delivered.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
True if the event should be filtered, False if it's passed through.
|
||||||
|
"""
|
||||||
|
if QApplication.instance().overrideCursor() is None:
|
||||||
|
# Mouse cursor shown -> don't filter event
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Mouse cursor hidden -> filter event
|
||||||
|
return True
|
||||||
|
|
||||||
|
def eventFilter(self, obj, event):
|
||||||
|
"""Handle an event.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj: The object which will get the event.
|
||||||
|
event: The QEvent which is about to be delivered.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
True if the event should be filtered, False if it's passed through.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if not self._activated:
|
||||||
|
return False
|
||||||
|
if not isinstance(obj, QWindow):
|
||||||
|
# We already handled this same event at some point earlier, so
|
||||||
|
# we're not interested in it anymore.
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
handler = self._handlers[event.type()]
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return handler(event)
|
||||||
|
except:
|
||||||
|
# If there is an exception in here and we leave the eventfilter
|
||||||
|
# activated, we'll get an infinite loop and a stack overflow.
|
||||||
|
self._activated = False
|
||||||
|
raise
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt5.QtGui import QWindow
|
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QEvent
|
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QEvent
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from PyQt5.QtWebKitWidgets import QWebView
|
from PyQt5.QtWebKitWidgets import QWebView
|
||||||
@ -120,56 +119,6 @@ def maybe_leave(win_id, mode, reason=None):
|
|||||||
log.modes.debug("{} (leave reason: {})".format(e, reason))
|
log.modes.debug("{} (leave reason: {})".format(e, reason))
|
||||||
|
|
||||||
|
|
||||||
class EventFilter(QObject):
|
|
||||||
|
|
||||||
"""Event filter which passes the event to the current ModeManager."""
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self._activated = True
|
|
||||||
|
|
||||||
def eventFilter(self, obj, event):
|
|
||||||
"""Forward events to the correct modeman."""
|
|
||||||
try:
|
|
||||||
qapp = QApplication.instance()
|
|
||||||
if not self._activated:
|
|
||||||
return False
|
|
||||||
if event.type() in [QEvent.MouseButtonDblClick,
|
|
||||||
QEvent.MouseButtonPress,
|
|
||||||
QEvent.MouseButtonRelease,
|
|
||||||
QEvent.MouseMove]:
|
|
||||||
if qapp.overrideCursor() is None:
|
|
||||||
# Mouse cursor shown -> don't filter event
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
# Mouse cursor hidden -> filter event
|
|
||||||
return True
|
|
||||||
elif event.type() not in [QEvent.KeyPress, QEvent.KeyRelease]:
|
|
||||||
# We're not interested in non-key-events so we pass them
|
|
||||||
# through.
|
|
||||||
return False
|
|
||||||
if not isinstance(obj, QWindow):
|
|
||||||
# We already handled this same event at some point earlier, so
|
|
||||||
# we're not interested in it anymore.
|
|
||||||
return False
|
|
||||||
if qapp.activeWindow() not in objreg.window_registry.values():
|
|
||||||
# Some other window (print dialog, etc.) is focused so we pass
|
|
||||||
# the event through.
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
modeman = objreg.get('mode-manager', scope='window',
|
|
||||||
window='current')
|
|
||||||
return modeman.eventFilter(event)
|
|
||||||
except objreg.RegistryUnavailableError:
|
|
||||||
# No window available yet, or not a MainWindow
|
|
||||||
return False
|
|
||||||
except:
|
|
||||||
# If there is an exception in here and we leave the eventfilter
|
|
||||||
# activated, we'll get an infinite loop and a stack overflow.
|
|
||||||
self._activated = False
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
class ModeManager(QObject):
|
class ModeManager(QObject):
|
||||||
|
|
||||||
"""Manager for keyboard modes.
|
"""Manager for keyboard modes.
|
||||||
|
Loading…
Reference in New Issue
Block a user