From a3d1a710179914d69baa6481717d28d31024e06a Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 10 Aug 2021 16:57:19 -0400 Subject: [PATCH] Unpack keyboard events into an explicit msg model --- piker/ui/_event.py | 45 ++++++++++++++++++++++++++++++++++------ piker/ui/_interaction.py | 3 ++- piker/ui/_search.py | 8 ++----- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/piker/ui/_event.py b/piker/ui/_event.py index 769d96cf..bf6bf766 100644 --- a/piker/ui/_event.py +++ b/piker/ui/_event.py @@ -25,6 +25,35 @@ from PyQt5 import QtCore from PyQt5.QtCore import QEvent from PyQt5.QtWidgets import QWidget import trio +from pydantic import BaseModel + + +# TODO: maybe consider some constrained ints down the road? +# https://pydantic-docs.helpmanual.io/usage/types/#constrained-types + +class KeyboardMsg(BaseModel): + '''Unpacked Qt keyboard event data. + + ''' + event: QEvent + etype: int + key: int + mods: int + txt: str + + class Config: + arbitrary_types_allowed = True + + def to_tuple(self) -> tuple: + return tuple(self.dict().values()) + + +# TODO: maybe add some methods to detect key combos? Or is that gonna be +# better with pattern matching? +# # ctl + alt as combo +# ctlalt = False +# if (QtCore.Qt.AltModifier | QtCore.Qt.ControlModifier) == mods: +# ctlalt = True class EventRelay(QtCore.QObject): @@ -67,22 +96,26 @@ class EventRelay(QtCore.QObject): if etype in {QEvent.KeyPress, QEvent.KeyRelease}: + msg = KeyboardMsg( + event=ev, + etype=ev.type(), + key=ev.key(), + mods=ev.modifiers(), + txt=ev.text(), + ) + # TODO: is there a global setting for this? if ev.isAutoRepeat() and self._filter_auto_repeats: ev.ignore() return True - key = ev.key() - mods = ev.modifiers() - txt = ev.text() - # NOTE: the event object instance coming out # the other side is mutated since Qt resumes event # processing **before** running a ``trio`` guest mode # tick, thus special handling or copying must be done. - # send elements to async handler - self._send_chan.send_nowait((ev, etype, key, mods, txt)) + # send keyboard msg to async handler + self._send_chan.send_nowait(msg) else: # send event to async handler diff --git a/piker/ui/_interaction.py b/piker/ui/_interaction.py index 7e80f197..aa03cdbf 100644 --- a/piker/ui/_interaction.py +++ b/piker/ui/_interaction.py @@ -64,7 +64,8 @@ async def handle_viewmode_inputs( 'cc': mode.cancel_all_orders, } - async for event, etype, key, mods, text in recv_chan: + async for kbmsg in recv_chan: + event, etype, key, mods, text = kbmsg.to_tuple() log.debug(f'key: {key}, mods: {mods}, text: {text}') now = time.time() period = now - last diff --git a/piker/ui/_search.py b/piker/ui/_search.py index c3c8520f..7e52074e 100644 --- a/piker/ui/_search.py +++ b/piker/ui/_search.py @@ -815,7 +815,8 @@ async def handle_keyboard_input( ) ) - async for event, etype, key, mods, txt in recv_chan: + async for kbmsg in recv_chan: + event, etype, key, mods, txt = kbmsg.to_tuple() log.debug(f'key: {key}, mods: {mods}, txt: {txt}') @@ -823,11 +824,6 @@ async def handle_keyboard_input( if mods == Qt.ControlModifier: ctl = True - # # ctl + alt as combo - # ctlalt = False - # if (QtCore.Qt.AltModifier | QtCore.Qt.ControlModifier) == mods: - # ctlalt = True - if key in (Qt.Key_Enter, Qt.Key_Return): search.chart_current_item(clear_to_cache=True)