class DbusMenu: def __init__(self): self.keyb = GlobalKeybinder(self.on_keybind_activated) self.app = None self.session = dbus.SessionBus() self.window = WindowManager.new_window() self._init_window() self._listen_menu_activated() self._width_offset = 300 WindowManager.add_listener(self.on_window_switched) def _init_window(self): self.appmenu = DbusAppMenu(self.session, self.window) self.gtkmenu = DbusGtkMenu(self.session, self.window) self._update() def on_window_switched(self, window): self.window = window self._init_window() def _listen_menu_activated(self): proxy = self.session.get_object(MyService.BUS_NAME, MyService.BUS_PATH) signal = proxy.connect_to_signal("MenuActivated", self.on_menu_activated) def on_menu_activated(self, menu: str, x: int): if menu == '__fildem_move': self._move_menu(x) return if x != -1: self._width_offset = x self._start_app(menu) def on_keybind_activated(self, character: str): self.on_app_started() self._start_app(character) def _move_menu(self, x: int): if self.app is None: return self.app.move_window(x) def _start_app(self, menu_activated: str): if self.app is None: self.app = GlobalMenu(self, menu_activated, self._width_offset) self.app.connect('shutdown', self.on_app_shutdown) self.app.run() def on_app_started(self): self._echo_onoff(True) def on_app_shutdown(self, app): self._echo_onoff(False) self.app = None def _echo_onoff(self, on: bool): self.proxy = dbus.SessionBus().get_object(MyService.BUS_NAME, MyService.BUS_PATH) self.proxy.EchoMenuOnOff(on) def _handle_shortcuts(self, top_level_menus): self.keyb.remove_all_keybindings() for label in top_level_menus: idx = label.find('_') if idx == -1: continue c = label[idx + 1] self.keyb.add_keybinding(c) def _update_menus(self): self.gtkmenu.get_results() if not len(self.appmenu.items): self.appmenu.get_results() def _update(self): self._update_menus() top_level_menus = list(dict.fromkeys(map(lambda it: it.path[0] if len(it.path) > 0 else None, self.items))) top_level_menus = list(filter(lambda x: x is not None, top_level_menus)) self._handle_shortcuts(top_level_menus) self._send_msg(top_level_menus) def _send_msg(self, top_level_menus): if len(top_level_menus) == 0: top_level_menus = dbus.Array(signature="s") proxy = self.session.get_object(MyService.BUS_NAME, MyService.BUS_PATH) proxy.EchoSendTopLevelMenus(top_level_menus) @property def prompt(self): return self.window.get_app_name() @property def actions(self): actions = self.gtkmenu.actions if not len(actions): actions = self.appmenu.actions self.handle_empty(actions) return actions.keys() def accel(self): accel = self.gtkmenu.accels if not len(accel): accel = self.appmenu.accels return accel @property def items(self): items = self.appmenu.items if not len(items): items = self.gtkmenu.items return items def activate(self, selection): if selection in self.gtkmenu.actions: self.gtkmenu.activate(selection) elif selection in self.appmenu.actions: self.appmenu.activate(selection) def handle_empty(self, actions): if not len(actions): alert = 'No menu items available!' promt = '' try: promt = self.prompt except Exception as e: pass print('Gnome HUD: WARNING: (%s) %s' % (promt, alert))
def global_hud_menu(accel, dbus_menu): menu = GlobalMenu(dbus_menu) menu.run()