diff --git a/kitty/keys.py b/kitty/keys.py index 45af41638..77888f58a 100644 --- a/kitty/keys.py +++ b/kitty/keys.py @@ -3,7 +3,7 @@ # License: GPL v3 Copyright: 2016, Kovid Goyal -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QObject, QEvent CTRL_MASK = 0b10011111 @@ -20,3 +20,35 @@ def key_event_to_data(ev, mods): else: data.extend(t) return bytes(data) + + +class KeyFilter(QObject): + + def __init__(self, parent=None): + QObject.__init__(self, parent) + self.disabled = False + + @property + def disable_filtering(self): + return self + + def __enter__(self): + self.disabled = True + + def __exit__(self, *args): + self.disabled = False + + def eventFilter(self, watched, event): + if self.disabled: + return False + etype = event.type() + if etype == QEvent.KeyPress: + # We use a global event filter to prevent Qt from re-painting the + # entire terminal widget on a Tab key press + app = self.parent() + window, fw = app.activeWindow(), app.focusWidget() + if hasattr(window, 'boss') and fw is window.boss.term: + window.boss.term.keyPressEvent(event) + if event.isAccepted(): + return True + return False diff --git a/kitty/main.py b/kitty/main.py index 29ae4f93e..8da5c4fc6 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -17,6 +17,7 @@ from .config import load_config, validate_font from .constants import appname, str_version, config_dir from .boss import Boss from .utils import fork_child +from .keys import KeyFilter class MainWindow(QMainWindow): @@ -105,6 +106,8 @@ def main(): QApplication.setAttribute(Qt.AA_DisableHighDpiScaling, True) app = QApplication([appname]) + keyfilter = KeyFilter(app) + app.installEventFilter(keyfilter) app.setOrganizationName(args.cls) app.setApplicationName(args.name) try: @@ -122,4 +125,6 @@ def main(): pr.disable() else: ret = run_app() - return ret + app.installEventFilter(None) + del keyfilter + return ret diff --git a/kitty/term.py b/kitty/term.py index 76ca6c750..7c3f158e4 100644 --- a/kitty/term.py +++ b/kitty/term.py @@ -105,6 +105,7 @@ class TerminalWidget(QWidget): def update_screen(self, changes): self.cursor = changes['cursor'] or self.cursor + if changes['screen']: self.pending_update += self.rect() else: @@ -217,3 +218,5 @@ class TerminalWidget(QWidget): if data: self.send_data_to_child.emit(data) ev.accept() + return + return QWidget.keyPressEvent(self, ev)