1from functools import wraps 2import logging 3 4import gi 5gi.require_version('Gtk', '3.0') 6 7# AppIndicator support is optional. It'll work if you install 8# gir1.2-ayatanaappindicator3-0.1 or an equivalent package for your distro 9# pylint: disable=wrong-import-position 10appIndicatorSupported = False 11try: 12 gi.require_version('AppIndicator3', '0.1') 13 appIndicatorSupported = True 14except ValueError: 15 pass 16 17try: 18 gi.require_version('AyatanaAppIndicator3', '0.1') 19 appIndicatorSupported = True 20except ValueError: 21 pass 22 23try: 24 from gi.repository import AppIndicator3 25except ImportError: 26 pass 27 28try: 29 from gi.repository import AyatanaAppIndicator3 as AppIndicator3 # noqa: F811 30except ImportError: 31 pass 32 33from gi.repository import Gtk 34from ulauncher.utils.decorator.singleton import singleton 35 36logger = logging.getLogger(__name__) 37 38 39def onlyIfAppindicatorIsSupported(func): 40 @wraps(func) 41 def wrapped(*args, **kwargs): 42 if appIndicatorSupported: 43 return func(*args, **kwargs) 44 return None 45 return wrapped 46 47 48class AppIndicator: 49 50 @classmethod 51 @singleton 52 def get_instance(cls): 53 from ulauncher.ui.windows.UlauncherWindow import UlauncherWindow 54 window = UlauncherWindow.get_instance() 55 indicator = cls("ulauncher") 56 indicator.set_icon('ulauncher-indicator') 57 indicator.add_menu_item(window.on_mnu_preferences_activate, "Preferences") 58 indicator.add_menu_item(window.on_mnu_about_activate, "About") 59 indicator.add_seperator() 60 indicator.add_menu_item(Gtk.main_quit, "Exit") 61 return indicator 62 63 def __init__(self, iconname): 64 if appIndicatorSupported: 65 self.__menu = Gtk.Menu() 66 self.__indicator = AppIndicator3.Indicator.new( 67 iconname, 68 "", 69 AppIndicator3.IndicatorCategory.APPLICATION_STATUS 70 ) 71 self.__indicator.set_menu(self.__menu) 72 73 @onlyIfAppindicatorIsSupported 74 def set_icon(self, path): 75 self.__indicator.set_icon(path) 76 77 @onlyIfAppindicatorIsSupported 78 def switch(self, on=False): 79 if on: 80 self.show() 81 else: 82 self.hide() 83 84 @onlyIfAppindicatorIsSupported 85 def add_menu_item(self, command, title): 86 menu_item = Gtk.MenuItem() 87 menu_item.set_label(title) 88 menu_item.connect("activate", command) 89 self.__menu.append(menu_item) 90 91 @onlyIfAppindicatorIsSupported 92 def add_seperator(self): 93 menu_item = Gtk.SeparatorMenuItem() 94 self.__menu.append(menu_item) 95 96 @onlyIfAppindicatorIsSupported 97 def show(self): 98 self.__indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) 99 self.__menu.show_all() 100 101 @onlyIfAppindicatorIsSupported 102 def hide(self): 103 self.__indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE) 104 105 @onlyIfAppindicatorIsSupported 106 def right_click_event_statusicon(self, icon, button, time): 107 self._get_tray_menu() 108 109 def pos(menu, aicon): 110 return Gtk.StatusIcon.position_menu(menu, aicon) 111 112 self.__menu.popup(None, None, pos, icon, button, time) 113 114 def _get_tray_menu(self): 115 return self.__menu 116