dbusmenu: implement all methods

This commit is contained in:
deltragon 2024-07-08 12:34:05 +02:00
parent ea2c747978
commit 1967d32d11
No known key found for this signature in database
GPG Key ID: 41F552553C6D94B5
1 changed files with 97 additions and 15 deletions

View File

@ -63,16 +63,35 @@ MENU_NODE_INFO = Gio.DBusNodeInfo.new_for_xml("""
<arg type="u" direction="out"/> <arg type="u" direction="out"/>
<arg type="(ia{sv}av)" direction="out"/> <arg type="(ia{sv}av)" direction="out"/>
</method> </method>
<method name="GetGroupProperties">
<arg type="ai" name="ids" direction="in"/>
<arg type="as" name="propertyNames" direction="in" />
<arg type="a(ia{sv})" name="properties" direction="out" />
</method>
<method name="GetProperty">
<arg type="i" name="id" direction="in"/>
<arg type="s" name="name" direction="in"/>
<arg type="v" name="value" direction="out"/>
</method>
<method name="Event"> <method name="Event">
<arg type="i" direction="in"/> <arg type="i" direction="in"/>
<arg type="s" direction="in"/> <arg type="s" direction="in"/>
<arg type="v" direction="in"/> <arg type="v" direction="in"/>
<arg type="u" direction="in"/> <arg type="u" direction="in"/>
</method> </method>
<method name="EventGroup">
<arg type="a(isvu)" name="events" direction="in" />
<arg type="ai" name="idErrors" direction="out" />
</method>
<method name="AboutToShow"> <method name="AboutToShow">
<arg type="i" direction="in"/> <arg type="i" direction="in"/>
<arg type="b" direction="out"/> <arg type="b" direction="out"/>
</method> </method>
<method name="AboutToShowGroup">
<arg type="ai" name="ids" direction="in" />
<arg type="ai" name="updatesNeeded" direction="out" />
<arg type="ai" name="idErrors" direction="out" />
</method>
<signal name="LayoutUpdated"> <signal name="LayoutUpdated">
<arg type="u"/> <arg type="u"/>
<arg type="i"/> <arg type="i"/>
@ -144,7 +163,7 @@ class DBusMenuService(DBusService):
revision = 0 revision = 0
items = [] items = []
idToCallback = {} idToItems = {}
def __init__(self, session_bus, context, items): def __init__(self, session_bus, context, items):
super().__init__( super().__init__(
@ -158,30 +177,34 @@ class DBusMenuService(DBusService):
def set_items(self, items): def set_items(self, items):
self.items = items self.items = items
self.idToCallback = self.getItemCallbacks(items, {}) self.idToItems = self.getItemsFlat(items, {})
self.revision += 1 self.revision += 1
self.LayoutUpdated(self.revision, 0) self.LayoutUpdated(self.revision, 0)
@staticmethod @staticmethod
def getItemCallbacks(items, idToCallback): def getItemsFlat(items, idToItems):
for item in items: for item in items:
if item.get('hidden', False) == True: if item.get('hidden', False) == True:
continue continue
if 'callback' in item:
idToCallback[item['id']] = item['callback']
if 'children' in item:
idToCallback = DBusMenuService.getItemCallbacks(item['children'], idToCallback)
return idToCallback idToItems[item['id']] = item
if 'children' in item:
idToItems = DBusMenuService.getItemsFlat(item['children'], idToItems)
return idToItems
@staticmethod @staticmethod
def itemToDbus(item, recursion_depth): def singleItemToDbus(item):
result = {} props = DBusMenuService.itemPropsToDbus(item)
if item.get('hidden', False) == True: return (item['id'], props)
return None
@staticmethod
def itemPropsToDbus(item):
result = {}
string_props = ['label', 'icon-name', 'type', 'children-display'] string_props = ['label', 'icon-name', 'type', 'children-display']
for key in string_props: for key in string_props:
@ -193,13 +216,22 @@ class DBusMenuService(DBusService):
if key in item: if key in item:
result[key] = GLib.Variant('b', item[key]) result[key] = GLib.Variant('b', item[key])
return result
@staticmethod
def itemToDbus(item, recursion_depth):
if item.get('hidden', False) == True:
return None
props = DBusMenuService.itemPropsToDbus(item)
children = [] children = []
if recursion_depth > 1 or recursion_depth == -1: if recursion_depth > 1 or recursion_depth == -1:
if "children" in item: if "children" in item:
children = [DBusMenuService.itemToDbus(item, recursion_depth - 1) for item in item['children']] children = [DBusMenuService.itemToDbus(item, recursion_depth - 1) for item in item['children']]
children = [i for i in children if i is not None] children = [i for i in children if i is not None]
return GLib.Variant("(ia{sv}av)", (item['id'], result, children)) return GLib.Variant("(ia{sv}av)", (item['id'], props, children))
def findItemsWithParent(self, parent_id, items): def findItemsWithParent(self, parent_id, items):
for item in items: for item in items:
@ -238,16 +270,66 @@ class DBusMenuService(DBusService):
return ret return ret
def GetGroupProperties(self, ids, property_names):
ret = []
for idx in ids:
if idx in self.idToItems:
props = DBusMenuService.singleItemToDbus(self.idToItems[idx])
if props is not None:
ret.append(props)
return (ret,)
def GetProperty(self, idx, name):
ret = None
if idx in self.idToItems:
props = DBusMenuService.singleItemToDbus(self.idToItems[idx])
if props is not None and name in props:
ret = props[name]
return ret
def Event(self, idx, event_id, data, timestamp): def Event(self, idx, event_id, data, timestamp):
if event_id != "clicked": if event_id != "clicked":
return return
if idx in self.idToCallback: if idx in self.idToItems:
self.idToCallback[idx]() item = self.idToItems[idx]
if 'callback' in item:
item['callback']()
def EventGroup(self, events):
not_found = []
for (idx, event_id, data, timestamp) in events:
if idx not in self.idToItems:
not_found.append(idx)
continue
if event_id != "clicked":
continue
item = self.idToItems[idx]
if 'callback' in item:
item['callback']()
return not_found
def AboutToShow(self, item_id): def AboutToShow(self, item_id):
return (False,) return (False,)
def AboutToShowGroup(self, ids):
not_found = []
for idx in ids:
if idx not in self.idToItems:
not_found.append(idx)
continue
return ([], not_found)
def LayoutUpdated(self, revision, parent): def LayoutUpdated(self, revision, parent):
self.emit_signal( self.emit_signal(
'LayoutUpdated', 'LayoutUpdated',