Index: fix-for-539057/ui/gtk/main.py =================================================================== --- fix-for-539057.orig/ui/gtk/main.py 2011-10-28 02:24:02.609269075 +0200 +++ fix-for-539057/ui/gtk/main.py 2011-10-28 02:24:09.221185952 +0200 @@ -63,8 +63,9 @@ "Please restart ibus input platform."), \ "ibus") self.__notify.set_timeout(10 * 1000) - self.__notify.add_action("restart", _("Restart Now"), self.__restart_cb, None) - self.__notify.add_action("ignore", _("Later"), lambda *args: None, None) + if "actions" in pynotify.get_server_caps(): + self.__notify.add_action("restart", _("Restart Now"), self.__restart_cb, None) + self.__notify.add_action("ignore", _("Later"), lambda *args: None, None) def __restart_cb(self, notify, action, data): if action == "restart": Index: fix-for-539057/ui/gtk/panel.py =================================================================== --- fix-for-539057.orig/ui/gtk/panel.py 2011-10-28 02:24:02.565269629 +0200 +++ fix-for-539057/ui/gtk/panel.py 2011-10-28 02:24:14.889114698 +0200 @@ -37,6 +37,11 @@ from i18n import _, N_ +try: + import appindicator +except: + appindicator = None + ICON_KEYBOARD = ibus.get_ICON_KEYBOARD() ICON_ENGINE = "ibus-engine" @@ -62,7 +67,9 @@ self.__bus = bus self.__config = self.__bus.get_config() self.__focus_ic = None + self.__previous_focus_ic = None self.__setup_pid = None + self.__block_activate = False self.__prefix = os.getenv("IBUS_PREFIX") self.__data_dir = path.join(self.__prefix, "share", "ibus") # self.__icons_dir = path.join(self.__data_dir, "icons") @@ -102,26 +109,39 @@ lambda widget, index, button, state: self.candidate_clicked(index, button, state)) - self.__status_icon = gtk.StatusIcon() - # gnome-shell checks XClassHint.res_class with ShellTrayIcon. - # gtk_status_icon_set_name() can set XClassHint.res_class . - # However gtk_status_icon_new() also calls gtk_window_realize() so - # gtk_status_icon_set_visible() needs to be called to set WM_CLASS - # so that gtk_window_realize() is called later again. - # set_title is for gnome-shell notificationDaemon in bottom right. - self.__status_icon.set_visible(False) - # gtk_status_icon_set_name() is not available in pygtk2 2.17 - if hasattr(self.__status_icon, 'set_name'): - self.__status_icon.set_name('ibus-ui-gtk') - self.__status_icon.set_title(_("IBus Panel")) - # Hide icon until bus get the name owner. - #self.__status_icon.set_visible(True) - self.__status_icon.connect("popup-menu", self.__status_icon_popup_menu_cb) - self.__status_icon.connect("activate", self.__status_icon_activate_cb) - self.__status_icon.set_from_icon_name(ICON_KEYBOARD) - self.__status_icon.set_tooltip(_("IBus input method framework")) - # Hide icon until bus get the name owner. - #self.__status_icon.set_visible(True) + if appindicator is None: + self.__status_icon = gtk.StatusIcon() + # gnome-shell checks XClassHint.res_class with ShellTrayIcon. + # gtk_status_icon_set_name() can set XClassHint.res_class . + # However gtk_status_icon_new() also calls gtk_window_realize() so + # gtk_status_icon_set_visible() needs to be called to set WM_CLASS + # so that gtk_window_realize() is called later again. + # set_title is for gnome-shell notificationDaemon in bottom right. + self.__status_icon.set_visible(False) + # gtk_status_icon_set_name() is not available in pygtk2 2.17 + if hasattr(self.__status_icon, 'set_name'): + self.__status_icon.set_name('ibus-ui-gtk') + self.__status_icon.set_title(_("IBus Panel")) + # Hide icon until bus get the name owner. + #self.__status_icon.set_visible(True) + self.__status_icon.connect("popup-menu", self.__status_icon_popup_menu_cb) + self.__status_icon.connect("activate", self.__status_icon_activate_cb) + self.__status_icon.set_from_icon_name(ICON_KEYBOARD) + self.__status_icon.set_tooltip(_("IBus input method framework")) + # Hide icon until bus get the name owner. + #self.__status_icon.set_visible(True) + self.__appindicator = None + else: + self.__appindicator = appindicator.Indicator( + "ibus", ICON_KEYBOARD, + appindicator.CATEGORY_APPLICATION_STATUS) + if self.__config.get_value("panel", "show_icon_on_systray", True): + self.__appindicator.set_status(appindicator.STATUS_ACTIVE) + else: + self.__appindicator.set_status(appindicator.STATUS_PASSIVE) + self.__appindicator_update_menu() + self.__status_icon = None + self.__config_load_lookup_table_orientation() self.__config_load_show() @@ -209,10 +229,13 @@ if not icon_name: icon_name = ICON_ENGINE self.__language_bar.set_im_icon(icon_name) - if icon_name.startswith("/"): - self.__status_icon.set_from_file(icon_name) + if self.__appindicator: + self.__appindicator.set_icon(icon_name) else: - self.__status_icon.set_from_icon_name(icon_name) + if icon_name.startswith("/"): + self.__status_icon.set_from_file(icon_name) + else: + self.__status_icon.set_from_icon_name(icon_name) def __set_im_name(self, name): self.__language_bar.set_im_name(name) @@ -234,15 +257,24 @@ else: self.__set_im_icon(ICON_KEYBOARD) self.__set_im_name(None) + self.__language_bar.focus_in() + while gtk.events_pending(): + gtk.main_iteration(False) + if self.__appindicator: + self.__appindicator_update_menu() def focus_out(self, ic): self.reset() + self.__previous_focus_ic = self.__focus_ic self.__focus_ic = None self.__language_bar.set_enabled(False) self.__language_bar.focus_out() self.__set_im_icon(ICON_KEYBOARD) self.__set_im_name(None) + + while gtk.events_pending(): + gtk.main_iteration(False) def state_changed(self): if not self.__focus_ic: @@ -311,7 +343,13 @@ def __config_load_show_icon_on_systray(self): value = self.__config.get_value("panel", "show_icon_on_systray", True) - self.__status_icon.set_visible(True if value else False) + if self.__appindicator: + if value: + self.__appindicator.set_status(appindicator.STATUS_ACTIVE) + else: + self.__appindicator.set_status(appindicator.STATUS_PASSIVE) + else: + self.__status_icon.set_visible(True if value else False) def __config_load_show_im_name(self): value = self.__config.get_value("panel", "show_im_name", False) @@ -338,8 +376,7 @@ def __config_reloaded_cb(self, bus): pass - def __create_sys_menu(self): - menu = gtk.Menu() + def __create_sys_menu(self, menu): item = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES) item.connect("activate", self.__sys_menu_item_activate_cb, gtk.STOCK_PREFERENCES) @@ -358,8 +395,6 @@ self.__sys_menu_item_activate_cb, gtk.STOCK_QUIT) menu.add(item) - menu.show_all() - menu.set_take_focus(False) return menu # def __create_im_menu(self): @@ -422,33 +457,50 @@ size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) menu = gtk.Menu() + + group = None for i, engine in enumerate(engines): lang = ibus.get_language_name(engine.language) - item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname)) - if current_engine and current_engine.name == engine.name: - for widget in item.get_children(): - if isinstance(widget, gtk.Label): - widget.set_markup("%s" % widget.get_text()) - if engine.icon: - item.set_image(_icon.IconWidget(engine.icon, size[0])) + if self.__appindicator: + item = gtk.RadioMenuItem(group, "%s - %s" % (lang, engine.longname)) + if not group: group = item else: - item.set_image(_icon.IconWidget(ICON_ENGINE, size[0])) + item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname)) + if current_engine and current_engine.name == engine.name: + if self.__appindicator: + item.set_active(True) + else: + for widget in item.get_children(): + if isinstance(widget, gtk.Label): + widget.set_markup("%s" % widget.get_text()) + if not self.__appindicator: + if engine.icon: + item.set_image(_icon.IconWidget(engine.icon, size[0])) + else: + item.set_image(_icon.IconWidget(ICON_ENGINE, size[0])) item.connect("activate", self.__im_menu_item_activate_cb, engine) menu.add(item) - item = gtk.ImageMenuItem(_("Turn off input method")) - item.set_image(_icon.IconWidget("gtk-close", size[0])) - item.connect("activate", self.__im_menu_item_activate_cb, None) - if self.__focus_ic == None or not self.__focus_ic.is_enabled(): - item.set_sensitive(False) + + if self.__appindicator: + item = gtk.RadioMenuItem(group, _("Input method Off")) + if self.__focus_ic == None or not self.__focus_ic.is_enabled(): + item.set_active(True) + item.connect("activate", self.__im_menu_item_activate_cb, None) + else: + item = gtk.ImageMenuItem(_("Turn off input method")) + item.set_image(_icon.IconWidget("gtk-close", size[0])) + item.connect("activate", self.__im_menu_item_activate_cb, None) + if self.__focus_ic == None or not self.__focus_ic.is_enabled(): + item.set_sensitive(False) menu.add(item) - menu.show_all() - menu.set_take_focus(False) return menu def __get_im_menu_cb(self, languagebar): menu = self.__create_im_menu() + menu.set_take_focus(False) + menu.show_all() return menu def __show_engine_about_cb(self, langagebar): @@ -465,7 +517,12 @@ self.__config.set_value("panel", "y", y) def __status_icon_popup_menu_cb(self, status_icon, button, active_time): - menu = self.__create_sys_menu() + menu = gtk.Menu() + self.__create_sys_menu(menu) + + menu.show_all() + menu.set_take_focus(False) + menu.popup(None, None, gtk.status_icon_position_menu, button, @@ -479,23 +536,57 @@ size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) item.set_image(_icon.IconWidget("gtk-info", size[0])) menu.add(item) - menu.show_all() else: menu = self.__create_im_menu() self.__language_bar.create_im_menu(menu) + menu.set_take_focus(False) + menu.show_all() menu.popup(None, None, gtk.status_icon_position_menu, 0, gtk.get_current_event_time(), self.__status_icon) - def __im_menu_item_activate_cb(self, item, engine): - if not self.__focus_ic: + def __appindicator_update_menu(self): + self.__block_activate = True + if not self.__appindicator: return - if engine: - self.__focus_ic.set_engine(engine) + if not self.__previous_focus_ic: + menu = gtk.Menu() + item = gtk.ImageMenuItem(_("No input window")) + size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) + item.set_image(_icon.IconWidget("gtk-info", size[0])) + menu.add(item) else: - self.__focus_ic.disable() + menu = self.__create_im_menu() + + menu.add(gtk.SeparatorMenuItem()) + + self.__create_sys_menu(menu) + menu.set_take_focus(False) + menu.show_all() + self.__appindicator.set_menu(menu) + self.__block_activate = False + + def __im_menu_item_activate_cb(self, item, engine): + if self.__block_activate: return + self.__block_activate = True + focus_ic = self.__focus_ic + if self.__previous_focus_ic: + focus_ic = self.__previous_focus_ic + if not focus_ic: + return + + current_engine = focus_ic.get_engine() + + if not engine: + focus_ic.disable() + elif engine != current_engine: + focus_ic.enable() + focus_ic.set_engine(engine) + + item.set_active(True) + self.__block_activate = False def __sys_menu_item_activate_cb(self, item, command): if command == gtk.STOCK_PREFERENCES: