applet: Add a profile switching applet

This exposes the profile list, currently selected profile, and the ability to
set the selected profile via the AppletManager's D-Bus interface. This isn't
really the ideal place for it, but Gtk Actions aren't really suited for this,
either. Additionally, it creates the profile switcher applet as an external
applet to better exercise the Applet interface.

  - Manager passes in the preferences object to the AppletManager, so that these
    variables can be exposed over D-Bus.
  - Exposed the list of profiles, get/set of active profile via D-Bus.
  - Created the Profiles applet.
  - Exposed a onRegistered / onUnregistered hook for Applets to make use of.
  - Removed the onUpdateScreen hook from KeyPressed/KeyReleased, since the
    onKeyPressed/onKeyReleased hooks handle this nicely already.
  - Fixed the AppletManager's method authorization checks.
This commit is contained in:
June Tate-Gans 2021-05-09 11:50:09 -05:00
parent 4eb039bc27
commit 4ca08c5f05
4 changed files with 130 additions and 9 deletions

View File

@ -51,6 +51,8 @@ class Applet(dbus.service.Object):
self._manager.Register(self._name) self._manager.Register(self._name)
self._registered = True self._registered = True
GLib.idle_add(self.onRegistered)
GLib.timeout_add_seconds(1, self._ping) GLib.timeout_add_seconds(1, self._ping)
return False return False
@ -62,7 +64,10 @@ class Applet(dbus.service.Object):
except DBusException as err: except DBusException as err:
print('Lost connection with AppletManager: %s' % err) print('Lost connection with AppletManager: %s' % err)
self._registered = False self._registered = False
GLib.idle_add(self.onUnregistered)
GLib.timeout_add_seconds(1, self.register) GLib.timeout_add_seconds(1, self.register)
return False return False
return True return True
@ -91,6 +96,10 @@ class Applet(dbus.service.Object):
def screen(self): def screen(self):
return self._s return self._s
@property
def manager(self):
return self._manager
def onKeyPressed(self, timestamp, key): def onKeyPressed(self, timestamp, key):
pass pass
@ -103,7 +112,10 @@ class Applet(dbus.service.Object):
def onHidden(self): def onHidden(self):
pass pass
def onUpdateScreen(self): def onRegistered(self):
pass
def onUnregistered(self):
pass pass
def maybePresentScreen(self): def maybePresentScreen(self):
@ -139,7 +151,6 @@ class Applet(dbus.service.Object):
def KeyPressed(self, timestamp, key): def KeyPressed(self, timestamp, key):
self.onKeyPressed(timestamp, key) self.onKeyPressed(timestamp, key)
self._setButtonPressed(True, key) self._setButtonPressed(True, key)
self.onUpdateScreen()
self.screen.nextFrame() self.screen.nextFrame()
return ByteArray(self.displayDevice.frame) return ByteArray(self.displayDevice.frame)
@ -147,9 +158,8 @@ class Applet(dbus.service.Object):
in_signature='di', out_signature='ay', in_signature='di', out_signature='ay',
byte_arrays=True) byte_arrays=True)
def KeyReleased(self, timestamp, key): def KeyReleased(self, timestamp, key):
self.onKeyPressed(timestamp, key) self.onKeyReleased(timestamp, key)
self._setButtonPressed(False, key) self._setButtonPressed(False, key)
self.onUpdateScreen()
self.screen.nextFrame() self.screen.nextFrame()
return ByteArray(self.displayDevice.frame) return ByteArray(self.displayDevice.frame)

View File

@ -20,7 +20,7 @@ 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): def __init__(self, manager, 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,
@ -28,6 +28,7 @@ class AppletManager(dbus.service.Object, Subject):
Subject.__init__(self) Subject.__init__(self)
self._manager = manager self._manager = manager
self._prefs = prefs
# [name] -> (sender, proxy) # [name] -> (sender, proxy)
self._applets = {} self._applets = {}
@ -102,14 +103,48 @@ class AppletManager(dbus.service.Object, Subject):
in_signature='ay', sender_keyword='sender', in_signature='ay', sender_keyword='sender',
byte_arrays=True) byte_arrays=True)
def Present(self, screen, sender): def Present(self, screen, sender):
# if self._activeApplet.bus_name != sender: if self._activeApplet.bus_name != sender:
# return print('Sender %s is not the active applet.' % (sender))
return
GLib.idle_add(self._presentScreen, screen, sender) GLib.idle_add(self._presentScreen, screen, sender)
@dbus.service.method(dbus_interface=INTERFACE_NAME, @dbus.service.method(dbus_interface=INTERFACE_NAME,
out_signature='b', out_signature='b',
sender_keyword='sender') sender_keyword='sender')
def Ping(self, sender): def Ping(self, sender):
if sender not in [s[0] for s in self._applets]: if sender not in [s[0] for s in self._applets.values()]:
print('Sender %s is not in the registered list of applets.' % (sender))
return False return False
return True return True
@dbus.service.method(dbus_interface=INTERFACE_NAME,
out_signature='as',
sender_keyword='sender')
def GetProfiles(self, sender):
if sender not in [s[0] for s in self._applets.values()]:
print('Sender %s is not in the registered list of applets.' % (sender))
return []
return self._prefs.profileNames()
@dbus.service.method(dbus_interface=INTERFACE_NAME,
out_signature='s',
sender_keyword='sender')
def GetSelectedProfile(self, sender):
if sender not in [s[0] for s in self._applets.values()]:
print('Sender %s is not in the registered list of applets.' % (sender))
return ''
return self._prefs.selectedProfileName()
@dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='s', out_signature='b',
sender_keyword='sender')
def SetSelectedProfile(self, profileName, sender):
if self._activeApplet.bus_name != sender:
print('Sender %s is not the active applet' % (sender))
return False
if profileName not in self._prefs.profileNames():
print('Sender %s attempted to set nonexistant profile %s' %
(sender, profileName))
return False
GLib.idle_add(self._prefs.setSelectedProfile, profileName)

View File

@ -0,0 +1,76 @@
import gi
import time
import enum
from g13gui.applet.applet import Applet
from g13gui.applet.applet import Buttons
from g13gui.applet.applet import RunApplet
from g13gui.bitwidgets.listview import ListView
from g13gui.bitwidgets.button import Button
from g13gui.bitwidgets.glyph import Glyphs
gi.require_version('GLib', '2.0')
from gi.repository import GLib
class ProfilesApplet(Applet):
NAME = 'Profiles'
def __init__(self):
Applet.__init__(self, ProfilesApplet.NAME)
self._profiles = []
self._selectedProfile = None
self._lv = ListView(self._profiles)
self._lv.showAll()
self.screen.addChild(self._lv)
button = Button(Glyphs.DOWN_ARROW)
self.screen.buttonBar.setButton(1, button)
button = Button(Glyphs.UP_ARROW)
self.screen.buttonBar.setButton(2, button)
button = Button(Glyphs.CHECKMARK)
self.screen.buttonBar.setButton(3, button)
self.screen.buttonBar.showAll()
def _updateProfileStates(self):
profiles = [str(x) for x in self.manager.GetProfiles()]
self._profiles.clear()
self._profiles.extend(profiles)
self._selectedProfile = str(self.manager.GetSelectedProfile())
def _updateListView(self):
self._lv.markedIndex = self._profiles.index(self._selectedProfile)
self._lv.model = self._profiles
self._lv.update()
def _updateAndPresent(self):
self._updateProfileStates()
self._updateListView()
self.maybePresentScreen()
def onRegistered(self):
self._updateProfileStates()
def onShown(self, timestamp):
self._updateListView()
GLib.idle_add(self._updateAndPresent)
def _setActiveProfile(self):
selectedProfile = self._lv.selection()
self.manager.SetSelectedProfile(selectedProfile)
self._updateAndPresent()
def onKeyReleased(self, timestamp, key):
if key == Buttons.L2: # down
self._lv.nextSelection()
elif key == Buttons.L3: # up
self._lv.prevSelection()
elif key == Buttons.L4: # select
self._lv.markSelection()
GLib.idle_add(self._setActiveProfile)
if __name__ == '__main__':
RunApplet(ProfilesApplet)

View File

@ -72,7 +72,7 @@ class DeviceManager(threading.Thread, Observer):
self._commandQueue = queue.Queue() self._commandQueue = queue.Queue()
self._lastProfile = None self._lastProfile = None
self._appletManager = AppletManager(self) self._appletManager = AppletManager(self, prefs)
self._prefs.registerObserver(self, {'selectedProfile'}) self._prefs.registerObserver(self, {'selectedProfile'})
self._updateProfileRegistration() self._updateProfileRegistration()