Skip to content

Commit

Permalink
Add missing multi-level ID support for menu items
Browse files Browse the repository at this point in the history
1297d88 requires this to be available but it is not as it is part of #1652. This backports the relevant changes.
  • Loading branch information
cschramm committed Oct 13, 2022
1 parent 06b4ce4 commit 1cb88bd
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 19 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.3.4

### Bugs fixed

* Errors when connected to a device with the DisconnectItems plugin enabled

## 2.3.3

### Changes
Expand Down
17 changes: 9 additions & 8 deletions blueman/main/indicators/StatusNotifierItem.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,17 @@ def _advertise_revision(self) -> bool:
def _get_layout(self, parent_id: int, _recursion_depth: int, _property_names: List[str]
) -> Tuple[int, Tuple[int, Dict[str, GLib.Variant], List[GLib.Variant]]]:
if parent_id == 0:
return self._revision, (0, {}, self._render_menu(self._items.items(), self._render_submenu))
return self._revision, (0, {}, self._render_menu(((item["id"] << 8, item) for item in self._items.values()),
self._render_submenu))
else:
item = self._items[parent_id]
item = self._items[parent_id >> 8]
if "submenu" in item and _recursion_depth != 0:
return self._revision, (parent_id, self._render_item(item), self._render_submenu(item, parent_id))
return self._revision, (parent_id, self._render_item(item), [])

def _render_submenu(self, item: "MenuItemDict", idx: int) -> List[GLib.Variant]:
if "submenu" in item:
return self._render_menu(enumerate(item["submenu"], idx * 100 + 1), lambda _item, _isx: [])
return self._render_menu(enumerate(item["submenu"], idx + 1), lambda _item, _isx: [])
else:
return []

Expand All @@ -67,9 +68,9 @@ def _render_menu(self, items: Iterable[Tuple[int, _T]], submenu_callback: Callab

def _iterate_items(self) -> Iterable[Tuple[int, "SubmenuItemDict"]]:
for item in self._items.values():
yield item["id"], item
yield item["id"] << 8, item
if "submenu" in item:
yield from enumerate(item["submenu"], item["id"] * 100 + 1)
yield from enumerate(item["submenu"], (item["id"] << 8) + 1)

def _render_item(self, item: Union["MenuItemDict", "SubmenuItemDict"]) -> Dict[str, GLib.Variant]:
if "text" in item and "icon_name" in item:
Expand All @@ -87,10 +88,10 @@ def _render_item(self, item: Union["MenuItemDict", "SubmenuItemDict"]) -> Dict[s

def _on_event(self, idx: int, event_id: str, _data: GLib.Variant, _timestamp: int) -> None:
if event_id == "clicked":
if idx < 100:
self._on_activate(idx)
if idx % (1 << 8) == 0:
self._on_activate(idx >> 8)
else:
self._on_activate(int(idx / 100), idx % 100 - 1)
self._on_activate(idx >> 8, idx % (1 << 8) - 1)


class StatusNotifierItemService(DbusService):
Expand Down
22 changes: 13 additions & 9 deletions blueman/plugins/applet/Menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class MenuItemDict(MenuItemDictBase, total=False):


class MenuItem:
def __init__(self, menu_plugin: "Menu", owner: AppletPlugin, priority: int, text: Optional[str], markup: bool,
icon_name: Optional[str], tooltip: Optional[str], callback: Optional[Callable[[], None]],
def __init__(self, menu_plugin: "Menu", owner: AppletPlugin, priority: Tuple[int, int], text: Optional[str],
markup: bool, icon_name: Optional[str], tooltip: Optional[str], callback: Optional[Callable[[], None]],
submenu_function: Optional[Callable[[], Iterable["SubmenuItemDict"]]], visible: bool, sensitive: bool):
self._menu_plugin = menu_plugin
self._owner = owner
Expand All @@ -48,7 +48,7 @@ def owner(self) -> AppletPlugin:
return self._owner

@property
def priority(self) -> int:
def priority(self) -> Tuple[int, int]:
return self._priority

@property
Expand All @@ -66,7 +66,7 @@ def _iter_base(self) -> Iterator[Tuple[str, Union[str, bool]]]:
yield key, value

def __iter__(self) -> Iterator[Tuple[str, Union[int, str, bool, List[Dict[str, Union[str, bool]]]]]]:
yield "id", self.priority
yield "id", (self._priority[0] << 8) + self._priority[1]
yield from self._iter_base()
submenu = self.submenu_items
if submenu:
Expand All @@ -79,7 +79,7 @@ def submenu_items(self) -> List["SubmenuItem"]:
submenu_items = self._submenu_function()
if not submenu_items:
return []
return [SubmenuItem(self._menu_plugin, self._owner, 0, item.get('text'), item.get('markup', False),
return [SubmenuItem(self._menu_plugin, self._owner, (0, 0), item.get('text'), item.get('markup', False),
item.get('icon_name'), item.get('tooltip'), item.get('callback'), None, True,
item.get('sensitive', True))
for item in submenu_items]
Expand Down Expand Up @@ -118,17 +118,21 @@ class Menu(AppletPlugin):
__unloadable__ = False

def on_load(self) -> None:
self.__menuitems: Dict[int, MenuItem] = {}
self.__menuitems: Dict[Tuple[int, int], MenuItem] = {}

self._add_dbus_signal("MenuChanged", "aa{sv}")
self._add_dbus_method("GetMenu", (), "aa{sv}", self._get_menu)
self._add_dbus_method("ActivateMenuItem", ("ai",), "", self._activate_menu_item)

def add(self, owner: AppletPlugin, priority: int, text: Optional[str] = None, markup: bool = False,
icon_name: Optional[str] = None, tooltip: Optional[str] = None,
def add(self, owner: AppletPlugin, priority: Union[int, Tuple[int, int]], text: Optional[str] = None,
markup: bool = False, icon_name: Optional[str] = None, tooltip: Optional[str] = None,
callback: Optional[Callable[[], None]] = None,
submenu_function: Optional[Callable[[], Iterable["SubmenuItemDict"]]] = None,
visible: bool = True, sensitive: bool = True) -> MenuItem:

if isinstance(priority, int):
priority = (priority, 0)

item = MenuItem(self, owner, priority, text, markup, icon_name, tooltip, callback, submenu_function, visible,
sensitive)
self.__menuitems[item.priority] = item
Expand Down Expand Up @@ -164,7 +168,7 @@ def _build_variant(self, value: Union[int, str, bool, Iterable[Mapping[str, Unio
return GLib.Variant("aa{sv}", self._prepare_menu(value))

def _activate_menu_item(self, indexes: Sequence[int]) -> None:
node = self.__menuitems[indexes[0]]
node = self.__menuitems[(indexes[0] >> 8, indexes[0] % (1 << 8))]
for index in list(indexes)[1:]:
node = node.submenu_items[index]
if node.callback:
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
AC_PREREQ(2.61)

AC_INIT([blueman], [2.3.3], [https://github.com/blueman-project/blueman/issues])
AC_INIT([blueman], [2.3.4], [https://github.com/blueman-project/blueman/issues])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_MACRO_DIRS([m4])
AM_INIT_AUTOMAKE([1.16.3 foreign dist-xz])
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(
'blueman', 'c',
version: '2.3.3',
version: '2.3.4',
license: 'GPL3',
meson_version: '>=0.50.0',
default_options: 'b_lundef=false'
Expand Down

0 comments on commit 1cb88bd

Please sign in to comment.