def show_menu(self, event): self.menu = Menu(gtk_menu=True) # Since some application menus doesn't seem to be # update, let's try to fetch just in case. self.dbusmenu.fetch_layout() self.menu.add_quicklist(self.dbusmenu.layout) self.sids = {} self.sids[0] = self.menu.connect("item-activated", self.on_menuitem_activated) #~ self.sids[1] = self.menu.connect("item-hovered", #~ self.__on_menuitem_hovered) #~ self.sids[2] = self.menu.connect("menu-resized", #~ self.__on_menu_resized) gtkmenu = self.menu.get_menu() self.sd_sid = gtkmenu.connect("selection-done", self.menu_closed) gtkmenu.popup(None, None, self.position_menu, event.button, event.time)
class AppIndicator(gtk.EventBox): def __init__(self, applet, icon_name, position, address, obj, icon_path, label, labelguide, accessibledesc, hint=None, title=None): self.applet_r = weakref.ref(applet) self.menu = None gtk.EventBox.__init__(self) self.set_visible_window(False) self.box = None self.icon = gtk.Image() self.icon_name = None self.icon_pixbufs = {} self.label = gtk.Label() self.repack() self.icon_themepath = icon_path self.on_icon_changed(icon_name, None) self.on_label_changed(label, labelguide) # Older versions of application-indicator-service doesn't give a title. self.title = title self.dbusmenu = DBusMenu(self, address, obj) self.show_all() self.connect("button-press-event", self.on_button_press_event) def repack(self): if self.box is not None: self.box.remove(self.icon) self.box.remove(self.label) self.remove(self.box) self.box.destroy() if self.applet_r().get_position() in ("left", "right"): self.box = gtk.VBox() self.label.set_angle(270) else: self.box = gtk.HBox() self.label.set_angle(0) self.box.pack_start(self.icon) self.box.pack_start(self.label) self.add(self.box) def on_button_press_event(self, widget, event): self.show_menu(event) def show_menu(self, event): self.menu = Menu(gtk_menu=True) # Since some application menus doesn't seem to be # update, let's try to fetch just in case. self.dbusmenu.fetch_layout() self.menu.add_quicklist(self.dbusmenu.layout) self.sids = {} self.sids[0] = self.menu.connect("item-activated", self.on_menuitem_activated) #~ self.sids[1] = self.menu.connect("item-hovered", #~ self.__on_menuitem_hovered) #~ self.sids[2] = self.menu.connect("menu-resized", #~ self.__on_menu_resized) gtkmenu = self.menu.get_menu() self.sd_sid = gtkmenu.connect("selection-done", self.menu_closed) gtkmenu.popup(None, None, self.position_menu, event.button, event.time) def menu_closed(self, *args): if self.menu is not None: for key in self.sids.keys(): sid = self.sids.pop(key) self.menu.disconnect(sid) self.sd_sid = self.menu.get_menu().disconnect(self.sd_sid) self.menu.delete_menu() self.menu = None def on_menuitem_activated(self, menu_item, identifier): if identifier.startswith("unity_"): identifier = int(identifier.rsplit("_", 1)[-1]) data = dbus.String("", variant_level=1) t = dbus.UInt32(0) self.dbusmenu.send_event(identifier, "clicked", data, t) def on_icon_changed(self, icon_name=None, icon_desc=None): if self.icon_name == icon_name: return if icon_name is not None: self.icon_name = icon_name self.update_icon() def update_icon(self): if self.icon_name in self.icon_pixbufs: pixbuf = self.icon_pixbufs[self.icon_name] else: pixbuf = self.get_icon(self.icon_name) self.icon_pixbufs[self.icon_name] = pixbuf self.icon.set_from_pixbuf(pixbuf) def get_icon(self, icon_name): if icon_name.startswith("/") and os.path.exists(icon_name): pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon_name, ICONSIZE, ICONSIZE) else: icon_theme = gtk.icon_theme_get_default() if self.icon_themepath != "" and \ os.path.exists(self.icon_themepath): icon_theme.prepend_search_path(self.icon_themepath) pixbuf = icon_theme.load_icon(self.icon_name, ICONSIZE, 0) return pixbuf def on_icon_themepath_changed(self, path): if self.icon_themepath == path: return self.icon_themepath = path #reset icon_pixbufs so that the icons will be reloaded. self.icon_pixbufs = {} # Update the icon if self.icon_name is not None: self.update_icon() def on_label_changed(self, label, guide): self.label.set_text(label) def on_title_changed(self, title): self.title = title def position_menu(self, menu): x, y = self.get_window().get_origin() a = self.get_allocation() w, h = menu.size_request() size = self.applet_r().get_size() if self.applet_r().get_position() == "left": x += size y += a.y if self.applet_r().get_position() == "right": x -= w y += a.y if self.applet_r().get_position() == "top": x += a.x y += size if self.applet_r().get_position() == "bottom": x += a.x y -= h screen = self.get_window().get_screen() if y + h > screen.get_height(): y = screen.get_height() - h if x + w >= screen.get_width(): x = screen.get_width() - w return (x, y, False)