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.
This commit is contained in:
June Tate-Gans 2021-05-23 11:27:20 -05:00
parent f485f2cbf0
commit 298cefe9c2
7 changed files with 109 additions and 57 deletions

View File

@ -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,7 +138,8 @@ class Applet(dbus.service.Object):
self.onHidden()
def _setButtonPressed(self, state, button):
buttonIdx = button - 1
if button in BUTTONS:
buttonIdx = BUTTONS.index(button)
button = self._s.buttonBar.button(buttonIdx)
if button:
button.pressed = state

View File

@ -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))

View File

@ -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,7 +62,8 @@ class Switcher(Observer):
self._s.buttonBar.showAll()
def _setButtonPressed(self, state, button):
buttonIdx = button - 1
if button in BUTTONS:
buttonIdx = BUTTONS.index(button)
button = self._s.buttonBar.button(buttonIdx)
if button:
button.pressed = state
@ -82,18 +83,18 @@ class Switcher(Observer):
return self.Present(timestamp)
def _setActiveApplet(self):
selectedName = self._lv.markedItem()
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)

View File

@ -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()

View File

@ -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()

View File

@ -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,9 +292,15 @@ class DeviceManager(threading.Thread, Observer):
nowPressed = inX and inY
if not wasPressed and nowPressed:
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:
if self._grabNextKey:
self._appletManager.onKeyReleased(name)
else:
for code in binding:
self._uinput.write(e.EV_KEY, code, 0)
@ -304,9 +320,16 @@ class DeviceManager(threading.Thread, Observer):
nowPressed = key.testReport(report)
if not wasPressed and nowPressed:
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:
if self._grabNextKey:
self._appletManager.onKeyPressed(key.name)
else:
for code in binding:
self._uinput.write(e.EV_KEY, code, 0)
@ -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

View File

@ -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()