From 298cefe9c22e909ff4e6235b7119212e9aade87e Mon Sep 17 00:00:00 2001 From: June Tate-Gans Date: Sun, 23 May 2021 11:27:20 -0500 Subject: [PATCH] applets: Rework how keys are delivered This makes us use strings instead of numbers. This allows us to export more of the G13's key matrix to applets, so we can include things like MR, BD, and the rest of the keyboard matrix. Most of this work is done in prep for the real-time macro recording functionality that I'm attempting to hack in. --- g13gui/applet/applet.py | 17 ++++++----- g13gui/applet/manager.py | 38 ++++++++++++++++++------- g13gui/applet/switcher.py | 23 +++++++-------- g13gui/applets/clock.py | 14 +++++---- g13gui/applets/profiles.py | 14 +++++---- g13gui/g13/manager.py | 58 +++++++++++++++++++++++++++----------- g13gui/main.py | 2 +- 7 files changed, 109 insertions(+), 57 deletions(-) diff --git a/g13gui/applet/applet.py b/g13gui/applet/applet.py index da97a5a..ad045bd 100644 --- a/g13gui/applet/applet.py +++ b/g13gui/applet/applet.py @@ -16,11 +16,9 @@ gi.require_version('GLib', '2.0') from gi.repository import GLib -class Buttons(object): - L1 = 1 - L2 = 2 - L3 = 3 - L4 = 4 +BUTTONS = [ + 'L1', 'L2', 'L3', 'L4' +] class Applet(dbus.service.Object): @@ -140,10 +138,11 @@ class Applet(dbus.service.Object): self.onHidden() def _setButtonPressed(self, state, button): - buttonIdx = button - 1 - button = self._s.buttonBar.button(buttonIdx) - if button: - button.pressed = state + if button in BUTTONS: + buttonIdx = BUTTONS.index(button) + button = self._s.buttonBar.button(buttonIdx) + if button: + button.pressed = state @dbus.service.method(BUS_INTERFACE, in_signature='di', out_signature='ay', diff --git a/g13gui/applet/manager.py b/g13gui/applet/manager.py index b9250dc..21d825c 100644 --- a/g13gui/applet/manager.py +++ b/g13gui/applet/manager.py @@ -20,20 +20,21 @@ class AppletManager(dbus.service.Object, Subject): BUS_NAME = 'com.theonelab.g13.AppletManager' BUS_PATH = '/com/theonelab/g13/AppletManager' - def __init__(self, manager, prefs): + def __init__(self, deviceManager, prefs): self._bus = dbus.SessionBus() self._busName = dbus.service.BusName(AppletManager.BUS_NAME, self._bus) dbus.service.Object.__init__(self, self._bus, AppletManager.BUS_PATH) Subject.__init__(self) - self._manager = manager + self._deviceManager = deviceManager self._prefs = prefs # [name] -> (sender, proxy) self._applets = {} self._switcher = Switcher(self) + self._lastApplet = self._switcher self._activeApplet = self._switcher self._applets['Switcher'] = (self._switcher, self._switcher) @@ -50,13 +51,29 @@ class AppletManager(dbus.service.Object, Subject): try: self._activeApplet.Unpresent() + self._lastApplet = self._activeApplet except dbus.exceptions.DBusException as err: - print('Failed to unpresent %s: %s' % (appletName, err)) + print('Failed to unpresent active applet: %s' % (err)) self._removeActiveApplet() self.setProperty('activeApplet', appletProxy) self.onPresent() + def swapApplets(self): + try: + self._activeApplet.Unpresent() + except dbus.exceptions.DBusException as err: + print('Failed to unpresent active applet: %s' % (err)) + self._removeActiveApplet() + self._lastApplet = self._switcher + self.setProperty('activeApplet', self._switcher) + else: + lastApplet = self._lastApplet + self._lastApplet = self._activeApplet + self.setProperty('activeApplet', lastApplet) + finally: + self.onPresent() + def raiseSwitcher(self): self._activeApplet = self._switcher self.onPresent() @@ -66,7 +83,7 @@ class AppletManager(dbus.service.Object, Subject): return self._applets.keys() def _updateLCD(self, frame): - self._manager.setLCDBuffer(frame) + self._deviceManager.setLCDBuffer(frame) def _removeActiveApplet(self): senders = {proxy: name for (name, (_, proxy)) in self._applets.items()} @@ -76,6 +93,7 @@ class AppletManager(dbus.service.Object, Subject): self.addChange(ChangeType.REMOVE, 'applet', name) self._activeApplet = self._switcher + self._lastApplet = self._switcher self.activeApplet = 'Switcher' def onPresent(self): @@ -87,24 +105,24 @@ class AppletManager(dbus.service.Object, Subject): print('Failed to present applet: %s' % (err)) self._removeActiveApplet() - def onKeyPressed(self, key): + def onKeyPressed(self, keyname): # Swap to the switcher - if key == G13Keys.BD: - self.activeApplet = 'Switcher' + if keyname == 'BD': + self.swapApplets() return try: frame = self._activeApplet.KeyPressed(time.time(), - key.value['bit']) + keyname) self._updateLCD(frame) except dbus.exceptions.DBusException as err: print('Failed to send keyPressed for applet: %s' % (err)) self._removeActiveApplet() - def onKeyReleased(self, key): + def onKeyReleased(self, keyname): try: frame = self._activeApplet.KeyReleased(time.time(), - key.value['bit']) + keyname) self._updateLCD(frame) except dbus.exceptions.DBusException as err: print('Failed to send keyReleased for applet: %s' % (err)) diff --git a/g13gui/applet/switcher.py b/g13gui/applet/switcher.py index d4ce824..4269109 100644 --- a/g13gui/applet/switcher.py +++ b/g13gui/applet/switcher.py @@ -6,7 +6,7 @@ from builtins import property from g13gui.observer.observer import Observer from g13gui.observer.subject import ChangeType -from g13gui.applet.applet import Buttons +from g13gui.applet.applet import BUTTONS from g13gui.applet.loopbackdisplaydevice import LoopbackDisplayDevice from g13gui.bitwidgets.display import Display from g13gui.bitwidgets.screen import Screen @@ -62,10 +62,11 @@ class Switcher(Observer): self._s.buttonBar.showAll() def _setButtonPressed(self, state, button): - buttonIdx = button - 1 - button = self._s.buttonBar.button(buttonIdx) - if button: - button.pressed = state + if button in BUTTONS: + buttonIdx = BUTTONS.index(button) + button = self._s.buttonBar.button(buttonIdx) + if button: + button.pressed = state def Present(self, timestamp, **kwargs): self._s.show() @@ -82,18 +83,18 @@ class Switcher(Observer): return self.Present(timestamp) def _setActiveApplet(self): - selectedName = self._lv.markedItem() - self._appletManager.activeApplet = selectedName + selectedName = self._lv.selection() + if selectedName: + self._appletManager.activeApplet = selectedName def KeyReleased(self, timestamp, key): self._setButtonPressed(False, key) - if key == Buttons.L2: # down + if key == 'L2': # down self._lv.nextSelection() - elif key == Buttons.L3: # up + elif key == 'L3': # up self._lv.prevSelection() - elif key == Buttons.L4: # select - self._lv.markSelection() + elif key == 'L4': # select GLib.idle_add(self._setActiveApplet) return self.Present(timestamp) diff --git a/g13gui/applets/clock.py b/g13gui/applets/clock.py index 63dba9e..ba812c7 100644 --- a/g13gui/applets/clock.py +++ b/g13gui/applets/clock.py @@ -4,7 +4,7 @@ import enum import psutil from g13gui.applet.applet import Applet -from g13gui.applet.applet import Buttons +from g13gui.applet.applet import BUTTONS from g13gui.applet.applet import RunApplet from g13gui.bitwidgets.label import Label from g13gui.bitwidgets.fonts import Fonts @@ -100,15 +100,19 @@ class ClockApplet(Applet): self.screen.buttonBar.setButton(0, button) def onKeyReleased(self, timestamp, key): - if key == Buttons.L1: + if key == 'L1': self._onModeSwitch() - elif key == Buttons.L2: + elif key == 'L2': self._loadGraphToggle.toggle() self._loadGraph.visible = self._loadGraphToggle.isOn - elif key == Buttons.L3: + elif key == 'L3': self._ramGraphToggle.toggle() self._ramGraph.visible = self._ramGraphToggle.isOn -if __name__ == '__main__': +def main(): RunApplet(ClockApplet) + + +if __name__ == '__main__': + main() diff --git a/g13gui/applets/profiles.py b/g13gui/applets/profiles.py index cafda34..adeac33 100644 --- a/g13gui/applets/profiles.py +++ b/g13gui/applets/profiles.py @@ -3,7 +3,7 @@ import time import enum from g13gui.applet.applet import Applet -from g13gui.applet.applet import Buttons +from g13gui.applet.applet import BUTTONS from g13gui.applet.applet import RunApplet from g13gui.bitwidgets.listview import ListView from g13gui.bitwidgets.button import Button @@ -63,14 +63,18 @@ class ProfilesApplet(Applet): self._updateAndPresent() def onKeyReleased(self, timestamp, key): - if key == Buttons.L2: # down + if key == 'L2': # down self._lv.nextSelection() - elif key == Buttons.L3: # up + elif key == 'L3': # up self._lv.prevSelection() - elif key == Buttons.L4: # select + elif key == 'L4': # select self._lv.markSelection() GLib.idle_add(self._setActiveProfile) -if __name__ == '__main__': +def main(): RunApplet(ProfilesApplet) + + +if __name__ == '__main__': + main() diff --git a/g13gui/g13/manager.py b/g13gui/g13/manager.py index 0472152..9d6fd13 100644 --- a/g13gui/g13/manager.py +++ b/g13gui/g13/manager.py @@ -15,6 +15,7 @@ from evdev import ecodes as e from g13gui.observer.observer import Observer from g13gui.model.bindings import StickMode +from g13gui.g13.common import G13Keys from g13gui.g13.common import G13NormalKeys from g13gui.g13.common import G13AppletKeys from g13gui.g13.common import G13SpecialKeys @@ -71,6 +72,8 @@ class DeviceManager(threading.Thread, Observer): self._lastKeyState = {} self._commandQueue = queue.Queue() self._lastProfile = None + self._grabNextKey = False + self._leds = 0 self._appletManager = AppletManager(self, prefs) @@ -249,9 +252,7 @@ class DeviceManager(threading.Thread, Observer): count = self._readKeys(reportBuffer) if count == REPORT_SIZE: - self._synthesizeKeys(reportBuffer) - self._signalSpecialKeys(reportBuffer) - self._synthesizeStick(reportBuffer) + self._handleKeys(reportBuffer) self._uinput.syn() self._processCommands() @@ -265,6 +266,15 @@ class DeviceManager(threading.Thread, Observer): if self._device and self._state == DeviceManager.State.FOUND: self._reset() + def appletGrabNextKey(self): + self._grabNextKey = True + + def _handleKeys(self, reportBuffer): + self._synthesizeKeys(reportBuffer) + self._signalSpecialKeys(reportBuffer) + self._synthesizeStick(reportBuffer) + self._grabNextKey = False + def _synthesizeStick(self, report): (joy_x, joy_y) = report[1:3] stickMode = self._prefs.selectedProfile().stickMode @@ -282,11 +292,17 @@ class DeviceManager(threading.Thread, Observer): nowPressed = inX and inY if not wasPressed and nowPressed: - for code in binding: - self._uinput.write(e.EV_KEY, code, 1) + if self._grabNextKey: + self._appletManager.onKeyPressed(name) + else: + for code in binding: + self._uinput.write(e.EV_KEY, code, 1) elif wasPressed and not nowPressed: - for code in binding: - self._uinput.write(e.EV_KEY, code, 0) + if self._grabNextKey: + self._appletManager.onKeyReleased(name) + else: + for code in binding: + self._uinput.write(e.EV_KEY, code, 0) self._lastKeyState[name] = nowPressed @@ -304,11 +320,18 @@ class DeviceManager(threading.Thread, Observer): nowPressed = key.testReport(report) if not wasPressed and nowPressed: - for code in binding: - self._uinput.write(e.EV_KEY, code, 1) + if self._grabNextKey: + self._appletManager.onKeyPressed(key.name) + else: + for code in binding: + self._uinput.write(e.EV_KEY, code, 1) + elif wasPressed and not nowPressed: - for code in binding: - self._uinput.write(e.EV_KEY, code, 0) + if self._grabNextKey: + self._appletManager.onKeyPressed(key.name) + else: + for code in binding: + self._uinput.write(e.EV_KEY, code, 0) self._lastKeyState[key] = nowPressed @@ -319,9 +342,9 @@ class DeviceManager(threading.Thread, Observer): # Emit special keypress if and only if it was released if wasPressed and not nowPressed: - self._appletManager.onKeyReleased(key) + self._appletManager.onKeyReleased(key.name) elif not wasPressed and nowPressed: - self._appletManager.onKeyPressed(key) + self._appletManager.onKeyPressed(key.name) self._lastKeyState[key] = nowPressed @@ -330,9 +353,12 @@ class DeviceManager(threading.Thread, Observer): nowPressed = key.testReport(report) # Emit special keypress if and only if it was released - if wasPressed and not nowPressed: - # check for MR, allow for key record this way - pass + if not wasPressed and nowPressed: + if key == G13Keys.MR: + self._appletManager.onKeyPressed(key.name) + elif wasPressed and not nowPressed: + if key == G13Keys.MR: + self._appletManager.onKeyReleased(key.name) self._lastKeyState[key] = nowPressed diff --git a/g13gui/main.py b/g13gui/main.py index 8e94181..19d666a 100644 --- a/g13gui/main.py +++ b/g13gui/main.py @@ -7,7 +7,7 @@ from dbus.mainloop.glib import DBusGMainLoop from g13gui.app import Application -if __name__ == '__main__': +def main(): DBusGMainLoop(set_as_default=True) app = Application()