mirror of
https://github.com/jtgans/g13gui.git
synced 2025-06-20 08:23:50 -04:00
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:
parent
f485f2cbf0
commit
298cefe9c2
@ -16,11 +16,9 @@ gi.require_version('GLib', '2.0')
|
|||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
|
||||||
class Buttons(object):
|
BUTTONS = [
|
||||||
L1 = 1
|
'L1', 'L2', 'L3', 'L4'
|
||||||
L2 = 2
|
]
|
||||||
L3 = 3
|
|
||||||
L4 = 4
|
|
||||||
|
|
||||||
|
|
||||||
class Applet(dbus.service.Object):
|
class Applet(dbus.service.Object):
|
||||||
@ -140,7 +138,8 @@ class Applet(dbus.service.Object):
|
|||||||
self.onHidden()
|
self.onHidden()
|
||||||
|
|
||||||
def _setButtonPressed(self, state, button):
|
def _setButtonPressed(self, state, button):
|
||||||
buttonIdx = button - 1
|
if button in BUTTONS:
|
||||||
|
buttonIdx = BUTTONS.index(button)
|
||||||
button = self._s.buttonBar.button(buttonIdx)
|
button = self._s.buttonBar.button(buttonIdx)
|
||||||
if button:
|
if button:
|
||||||
button.pressed = state
|
button.pressed = state
|
||||||
|
@ -20,20 +20,21 @@ class AppletManager(dbus.service.Object, Subject):
|
|||||||
BUS_NAME = 'com.theonelab.g13.AppletManager'
|
BUS_NAME = 'com.theonelab.g13.AppletManager'
|
||||||
BUS_PATH = '/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._bus = dbus.SessionBus()
|
||||||
self._busName = dbus.service.BusName(AppletManager.BUS_NAME, self._bus)
|
self._busName = dbus.service.BusName(AppletManager.BUS_NAME, self._bus)
|
||||||
dbus.service.Object.__init__(self, self._bus,
|
dbus.service.Object.__init__(self, self._bus,
|
||||||
AppletManager.BUS_PATH)
|
AppletManager.BUS_PATH)
|
||||||
Subject.__init__(self)
|
Subject.__init__(self)
|
||||||
|
|
||||||
self._manager = manager
|
self._deviceManager = deviceManager
|
||||||
self._prefs = prefs
|
self._prefs = prefs
|
||||||
|
|
||||||
# [name] -> (sender, proxy)
|
# [name] -> (sender, proxy)
|
||||||
self._applets = {}
|
self._applets = {}
|
||||||
|
|
||||||
self._switcher = Switcher(self)
|
self._switcher = Switcher(self)
|
||||||
|
self._lastApplet = self._switcher
|
||||||
self._activeApplet = self._switcher
|
self._activeApplet = self._switcher
|
||||||
|
|
||||||
self._applets['Switcher'] = (self._switcher, self._switcher)
|
self._applets['Switcher'] = (self._switcher, self._switcher)
|
||||||
@ -50,13 +51,29 @@ class AppletManager(dbus.service.Object, Subject):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self._activeApplet.Unpresent()
|
self._activeApplet.Unpresent()
|
||||||
|
self._lastApplet = self._activeApplet
|
||||||
except dbus.exceptions.DBusException as err:
|
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._removeActiveApplet()
|
||||||
|
|
||||||
self.setProperty('activeApplet', appletProxy)
|
self.setProperty('activeApplet', appletProxy)
|
||||||
self.onPresent()
|
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):
|
def raiseSwitcher(self):
|
||||||
self._activeApplet = self._switcher
|
self._activeApplet = self._switcher
|
||||||
self.onPresent()
|
self.onPresent()
|
||||||
@ -66,7 +83,7 @@ class AppletManager(dbus.service.Object, Subject):
|
|||||||
return self._applets.keys()
|
return self._applets.keys()
|
||||||
|
|
||||||
def _updateLCD(self, frame):
|
def _updateLCD(self, frame):
|
||||||
self._manager.setLCDBuffer(frame)
|
self._deviceManager.setLCDBuffer(frame)
|
||||||
|
|
||||||
def _removeActiveApplet(self):
|
def _removeActiveApplet(self):
|
||||||
senders = {proxy: name for (name, (_, proxy)) in self._applets.items()}
|
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.addChange(ChangeType.REMOVE, 'applet', name)
|
||||||
self._activeApplet = self._switcher
|
self._activeApplet = self._switcher
|
||||||
|
self._lastApplet = self._switcher
|
||||||
self.activeApplet = 'Switcher'
|
self.activeApplet = 'Switcher'
|
||||||
|
|
||||||
def onPresent(self):
|
def onPresent(self):
|
||||||
@ -87,24 +105,24 @@ class AppletManager(dbus.service.Object, Subject):
|
|||||||
print('Failed to present applet: %s' % (err))
|
print('Failed to present applet: %s' % (err))
|
||||||
self._removeActiveApplet()
|
self._removeActiveApplet()
|
||||||
|
|
||||||
def onKeyPressed(self, key):
|
def onKeyPressed(self, keyname):
|
||||||
# Swap to the switcher
|
# Swap to the switcher
|
||||||
if key == G13Keys.BD:
|
if keyname == 'BD':
|
||||||
self.activeApplet = 'Switcher'
|
self.swapApplets()
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
frame = self._activeApplet.KeyPressed(time.time(),
|
frame = self._activeApplet.KeyPressed(time.time(),
|
||||||
key.value['bit'])
|
keyname)
|
||||||
self._updateLCD(frame)
|
self._updateLCD(frame)
|
||||||
except dbus.exceptions.DBusException as err:
|
except dbus.exceptions.DBusException as err:
|
||||||
print('Failed to send keyPressed for applet: %s' % (err))
|
print('Failed to send keyPressed for applet: %s' % (err))
|
||||||
self._removeActiveApplet()
|
self._removeActiveApplet()
|
||||||
|
|
||||||
def onKeyReleased(self, key):
|
def onKeyReleased(self, keyname):
|
||||||
try:
|
try:
|
||||||
frame = self._activeApplet.KeyReleased(time.time(),
|
frame = self._activeApplet.KeyReleased(time.time(),
|
||||||
key.value['bit'])
|
keyname)
|
||||||
self._updateLCD(frame)
|
self._updateLCD(frame)
|
||||||
except dbus.exceptions.DBusException as err:
|
except dbus.exceptions.DBusException as err:
|
||||||
print('Failed to send keyReleased for applet: %s' % (err))
|
print('Failed to send keyReleased for applet: %s' % (err))
|
||||||
|
@ -6,7 +6,7 @@ from builtins import property
|
|||||||
|
|
||||||
from g13gui.observer.observer import Observer
|
from g13gui.observer.observer import Observer
|
||||||
from g13gui.observer.subject import ChangeType
|
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.applet.loopbackdisplaydevice import LoopbackDisplayDevice
|
||||||
from g13gui.bitwidgets.display import Display
|
from g13gui.bitwidgets.display import Display
|
||||||
from g13gui.bitwidgets.screen import Screen
|
from g13gui.bitwidgets.screen import Screen
|
||||||
@ -62,7 +62,8 @@ class Switcher(Observer):
|
|||||||
self._s.buttonBar.showAll()
|
self._s.buttonBar.showAll()
|
||||||
|
|
||||||
def _setButtonPressed(self, state, button):
|
def _setButtonPressed(self, state, button):
|
||||||
buttonIdx = button - 1
|
if button in BUTTONS:
|
||||||
|
buttonIdx = BUTTONS.index(button)
|
||||||
button = self._s.buttonBar.button(buttonIdx)
|
button = self._s.buttonBar.button(buttonIdx)
|
||||||
if button:
|
if button:
|
||||||
button.pressed = state
|
button.pressed = state
|
||||||
@ -82,18 +83,18 @@ class Switcher(Observer):
|
|||||||
return self.Present(timestamp)
|
return self.Present(timestamp)
|
||||||
|
|
||||||
def _setActiveApplet(self):
|
def _setActiveApplet(self):
|
||||||
selectedName = self._lv.markedItem()
|
selectedName = self._lv.selection()
|
||||||
|
if selectedName:
|
||||||
self._appletManager.activeApplet = selectedName
|
self._appletManager.activeApplet = selectedName
|
||||||
|
|
||||||
def KeyReleased(self, timestamp, key):
|
def KeyReleased(self, timestamp, key):
|
||||||
self._setButtonPressed(False, key)
|
self._setButtonPressed(False, key)
|
||||||
|
|
||||||
if key == Buttons.L2: # down
|
if key == 'L2': # down
|
||||||
self._lv.nextSelection()
|
self._lv.nextSelection()
|
||||||
elif key == Buttons.L3: # up
|
elif key == 'L3': # up
|
||||||
self._lv.prevSelection()
|
self._lv.prevSelection()
|
||||||
elif key == Buttons.L4: # select
|
elif key == 'L4': # select
|
||||||
self._lv.markSelection()
|
|
||||||
GLib.idle_add(self._setActiveApplet)
|
GLib.idle_add(self._setActiveApplet)
|
||||||
|
|
||||||
return self.Present(timestamp)
|
return self.Present(timestamp)
|
||||||
|
@ -4,7 +4,7 @@ import enum
|
|||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from g13gui.applet.applet import Applet
|
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.applet.applet import RunApplet
|
||||||
from g13gui.bitwidgets.label import Label
|
from g13gui.bitwidgets.label import Label
|
||||||
from g13gui.bitwidgets.fonts import Fonts
|
from g13gui.bitwidgets.fonts import Fonts
|
||||||
@ -100,15 +100,19 @@ class ClockApplet(Applet):
|
|||||||
self.screen.buttonBar.setButton(0, button)
|
self.screen.buttonBar.setButton(0, button)
|
||||||
|
|
||||||
def onKeyReleased(self, timestamp, key):
|
def onKeyReleased(self, timestamp, key):
|
||||||
if key == Buttons.L1:
|
if key == 'L1':
|
||||||
self._onModeSwitch()
|
self._onModeSwitch()
|
||||||
elif key == Buttons.L2:
|
elif key == 'L2':
|
||||||
self._loadGraphToggle.toggle()
|
self._loadGraphToggle.toggle()
|
||||||
self._loadGraph.visible = self._loadGraphToggle.isOn
|
self._loadGraph.visible = self._loadGraphToggle.isOn
|
||||||
elif key == Buttons.L3:
|
elif key == 'L3':
|
||||||
self._ramGraphToggle.toggle()
|
self._ramGraphToggle.toggle()
|
||||||
self._ramGraph.visible = self._ramGraphToggle.isOn
|
self._ramGraph.visible = self._ramGraphToggle.isOn
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def main():
|
||||||
RunApplet(ClockApplet)
|
RunApplet(ClockApplet)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
@ -3,7 +3,7 @@ import time
|
|||||||
import enum
|
import enum
|
||||||
|
|
||||||
from g13gui.applet.applet import Applet
|
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.applet.applet import RunApplet
|
||||||
from g13gui.bitwidgets.listview import ListView
|
from g13gui.bitwidgets.listview import ListView
|
||||||
from g13gui.bitwidgets.button import Button
|
from g13gui.bitwidgets.button import Button
|
||||||
@ -63,14 +63,18 @@ class ProfilesApplet(Applet):
|
|||||||
self._updateAndPresent()
|
self._updateAndPresent()
|
||||||
|
|
||||||
def onKeyReleased(self, timestamp, key):
|
def onKeyReleased(self, timestamp, key):
|
||||||
if key == Buttons.L2: # down
|
if key == 'L2': # down
|
||||||
self._lv.nextSelection()
|
self._lv.nextSelection()
|
||||||
elif key == Buttons.L3: # up
|
elif key == 'L3': # up
|
||||||
self._lv.prevSelection()
|
self._lv.prevSelection()
|
||||||
elif key == Buttons.L4: # select
|
elif key == 'L4': # select
|
||||||
self._lv.markSelection()
|
self._lv.markSelection()
|
||||||
GLib.idle_add(self._setActiveProfile)
|
GLib.idle_add(self._setActiveProfile)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def main():
|
||||||
RunApplet(ProfilesApplet)
|
RunApplet(ProfilesApplet)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
@ -15,6 +15,7 @@ from evdev import ecodes as e
|
|||||||
|
|
||||||
from g13gui.observer.observer import Observer
|
from g13gui.observer.observer import Observer
|
||||||
from g13gui.model.bindings import StickMode
|
from g13gui.model.bindings import StickMode
|
||||||
|
from g13gui.g13.common import G13Keys
|
||||||
from g13gui.g13.common import G13NormalKeys
|
from g13gui.g13.common import G13NormalKeys
|
||||||
from g13gui.g13.common import G13AppletKeys
|
from g13gui.g13.common import G13AppletKeys
|
||||||
from g13gui.g13.common import G13SpecialKeys
|
from g13gui.g13.common import G13SpecialKeys
|
||||||
@ -71,6 +72,8 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
self._lastKeyState = {}
|
self._lastKeyState = {}
|
||||||
self._commandQueue = queue.Queue()
|
self._commandQueue = queue.Queue()
|
||||||
self._lastProfile = None
|
self._lastProfile = None
|
||||||
|
self._grabNextKey = False
|
||||||
|
self._leds = 0
|
||||||
|
|
||||||
self._appletManager = AppletManager(self, prefs)
|
self._appletManager = AppletManager(self, prefs)
|
||||||
|
|
||||||
@ -249,9 +252,7 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
count = self._readKeys(reportBuffer)
|
count = self._readKeys(reportBuffer)
|
||||||
|
|
||||||
if count == REPORT_SIZE:
|
if count == REPORT_SIZE:
|
||||||
self._synthesizeKeys(reportBuffer)
|
self._handleKeys(reportBuffer)
|
||||||
self._signalSpecialKeys(reportBuffer)
|
|
||||||
self._synthesizeStick(reportBuffer)
|
|
||||||
self._uinput.syn()
|
self._uinput.syn()
|
||||||
|
|
||||||
self._processCommands()
|
self._processCommands()
|
||||||
@ -265,6 +266,15 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
if self._device and self._state == DeviceManager.State.FOUND:
|
if self._device and self._state == DeviceManager.State.FOUND:
|
||||||
self._reset()
|
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):
|
def _synthesizeStick(self, report):
|
||||||
(joy_x, joy_y) = report[1:3]
|
(joy_x, joy_y) = report[1:3]
|
||||||
stickMode = self._prefs.selectedProfile().stickMode
|
stickMode = self._prefs.selectedProfile().stickMode
|
||||||
@ -282,9 +292,15 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
nowPressed = inX and inY
|
nowPressed = inX and inY
|
||||||
|
|
||||||
if not wasPressed and nowPressed:
|
if not wasPressed and nowPressed:
|
||||||
|
if self._grabNextKey:
|
||||||
|
self._appletManager.onKeyPressed(name)
|
||||||
|
else:
|
||||||
for code in binding:
|
for code in binding:
|
||||||
self._uinput.write(e.EV_KEY, code, 1)
|
self._uinput.write(e.EV_KEY, code, 1)
|
||||||
elif wasPressed and not nowPressed:
|
elif wasPressed and not nowPressed:
|
||||||
|
if self._grabNextKey:
|
||||||
|
self._appletManager.onKeyReleased(name)
|
||||||
|
else:
|
||||||
for code in binding:
|
for code in binding:
|
||||||
self._uinput.write(e.EV_KEY, code, 0)
|
self._uinput.write(e.EV_KEY, code, 0)
|
||||||
|
|
||||||
@ -304,9 +320,16 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
nowPressed = key.testReport(report)
|
nowPressed = key.testReport(report)
|
||||||
|
|
||||||
if not wasPressed and nowPressed:
|
if not wasPressed and nowPressed:
|
||||||
|
if self._grabNextKey:
|
||||||
|
self._appletManager.onKeyPressed(key.name)
|
||||||
|
else:
|
||||||
for code in binding:
|
for code in binding:
|
||||||
self._uinput.write(e.EV_KEY, code, 1)
|
self._uinput.write(e.EV_KEY, code, 1)
|
||||||
|
|
||||||
elif wasPressed and not nowPressed:
|
elif wasPressed and not nowPressed:
|
||||||
|
if self._grabNextKey:
|
||||||
|
self._appletManager.onKeyPressed(key.name)
|
||||||
|
else:
|
||||||
for code in binding:
|
for code in binding:
|
||||||
self._uinput.write(e.EV_KEY, code, 0)
|
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
|
# Emit special keypress if and only if it was released
|
||||||
if wasPressed and not nowPressed:
|
if wasPressed and not nowPressed:
|
||||||
self._appletManager.onKeyReleased(key)
|
self._appletManager.onKeyReleased(key.name)
|
||||||
elif not wasPressed and nowPressed:
|
elif not wasPressed and nowPressed:
|
||||||
self._appletManager.onKeyPressed(key)
|
self._appletManager.onKeyPressed(key.name)
|
||||||
|
|
||||||
self._lastKeyState[key] = nowPressed
|
self._lastKeyState[key] = nowPressed
|
||||||
|
|
||||||
@ -330,9 +353,12 @@ class DeviceManager(threading.Thread, Observer):
|
|||||||
nowPressed = key.testReport(report)
|
nowPressed = key.testReport(report)
|
||||||
|
|
||||||
# Emit special keypress if and only if it was released
|
# Emit special keypress if and only if it was released
|
||||||
if wasPressed and not nowPressed:
|
if not wasPressed and nowPressed:
|
||||||
# check for MR, allow for key record this way
|
if key == G13Keys.MR:
|
||||||
pass
|
self._appletManager.onKeyPressed(key.name)
|
||||||
|
elif wasPressed and not nowPressed:
|
||||||
|
if key == G13Keys.MR:
|
||||||
|
self._appletManager.onKeyReleased(key.name)
|
||||||
|
|
||||||
self._lastKeyState[key] = nowPressed
|
self._lastKeyState[key] = nowPressed
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from dbus.mainloop.glib import DBusGMainLoop
|
|||||||
from g13gui.app import Application
|
from g13gui.app import Application
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def main():
|
||||||
DBusGMainLoop(set_as_default=True)
|
DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
app = Application()
|
app = Application()
|
||||||
|
Loading…
Reference in New Issue
Block a user