Let customize menu's quit handler
[laditools.git] / ladi-system-tray
blob597d2824a69bd14935cc67baa57edda24549a689
1 #!/usr/bin/python
2 # LADITools - Linux Audio Desktop Integration Tools
3 # ladi-system-tray - System tray integration for LADI
4 # Copyright (C) 2011-2012 Alessio Treglia <quadrispro@ubuntu.com>
5 # Copyright (C) 2007-2010, Marc-Olivier Barre <marco@marcochapeau.org>
6 # Copyright (C) 2007-2009, Nedko Arnaudov <nedko@arnaudov.name>
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import os
22 import sys
23 import signal
24 import gettext
25 import argparse
27 sig_handler = signal.getsignal(signal.SIGTERM)
28 signal.signal(signal.SIGINT, sig_handler)
30 from laditools import _gettext_domain
31 gettext.install(_gettext_domain)
33 from laditools import get_version_string
34 from laditools import LadiConfiguration
35 from laditools import LadiManager
36 from laditools import LadiApp
38 from gi.repository import Gtk
39 from gi.repository import Gdk
40 from gi.repository import GObject
42 try:
43 from gi.repository import AppIndicator3
44 except:
45 AppIndicator3 = None
47 from laditools.gtk import LadiMenu
48 from laditools.gtk import find_data_file
50 timeout_add = GObject.timeout_add
52 class LadiStatusIcon (LadiMenu, LadiApp):
54 _appname = 'ladi-system-tray'
55 _appname_long = _("LADI System Tray")
56 _appid = 'org.linuxaudio.ladi.systemtray'
58 # Default configuration
59 _default_config = {
60 'autostart' : False,
63 def on_about(self, *args):
64 LadiMenu.on_about(self, version=get_version_string())
66 def quit(self, *args, **kwargs):
67 # Some default config might need to be injected in the config file,
68 # we handle all that before we quit.
69 self.global_config.set_config_section (self.appname, self.config_dict)
70 self.global_config.save ()
71 Gtk.main_quit()
73 def set_tooltip_text(self, text): pass
75 def __init__ (self, config_filename = None):
76 # Handle the configuration
77 self.icon_state = ""
78 self.last_status_text = ""
79 self.diagnose_text = None
80 self.status_icons = {'started' : 'ladi-started',
81 'stopped' : 'ladi-stopped',
82 'starting' : 'ladi-starting'}
83 self.global_config = LadiConfiguration(self.appname,
84 self._default_config,
85 config_filename)
86 self.config_dict = self.global_config.get_config_section (self.appname)
87 autostart = bool(eval(self.config_dict['autostart']))
88 # Build the UI
89 LadiMenu.__init__(self,
90 autostart,
91 quit = self.quit)
93 def menu_activate(self, status_icon, button, activate_time, user_data=None):
94 menu = self.create_menu()
95 menu.popup (parent_menu_shell=None,
96 parent_menu_item=None,
97 func=self.position_menu,
98 data=self,
99 button=button,
100 activate_time=activate_time)
101 menu.reposition ()
103 def set_starting_status (self):
104 self.set_tooltip_safe ("JACK is starting")
105 self.set_icon ("starting")
107 def set_tooltip_safe (self, text):
108 if text != self.last_status_text:
109 self.set_tooltip_text (text)
110 self.last_status_text = text
112 def run(self):
113 Gtk.main ()
115 class LadiStatusTray(Gtk.StatusIcon, LadiStatusIcon):
117 def __init__(self):
118 LadiStatusIcon.__init__(self)
119 GObject.GObject.__init__ (self)
120 self.set_icon ("stopped")
121 # Get the initial status
122 self.update ()
123 # Add the auto update callback
124 self.auto_updater = timeout_add (250, self.update, None)
125 # Make the menu popup when the icon is right clicked
126 self.connect ("popup-menu", self.menu_activate)
127 self.set_title(self.appname_long)
129 def do_button_press_event(self, event):
130 if event.type != Gdk.EventType._2BUTTON_PRESS:
131 return False
132 self.on_menu_launch_handler(None, "gladish")
133 return True
135 def update (self, user_data = None):
136 try:
137 if self.jack_is_started():
138 # Get Realtime status
139 if self.jack_is_realtime():
140 status_text = "RT | "
141 else:
142 status_text = ""
143 # Get DSP Load
144 status_text += str (round (float (self.jack_get_load()),1)) + "% | "
145 # Get Xruns
146 status_text += str (self.jack_get_xruns())
147 # Set a started status
148 self.set_tooltip_safe (status_text)
149 self.set_icon ("started")
150 else:
151 self.set_tooltip_safe ("JACK is stopped")
152 self.set_icon ("stopped")
153 self.clear_diagnose_text()
154 except Exception, e:
155 self.set_tooltip_safe ("JACK is sick")
156 self.set_diagnose_text(repr(e))
157 self.set_icon ("stopped")
158 self.clear_jack_proxies()
159 finally:
160 LadiManager.update(self)
161 return True
163 def set_icon (self, newstate):
164 if self.icon_state == newstate:
165 return
166 self.icon_state = newstate
167 self.set_from_icon_name(self.status_icons[newstate])
169 class LadiStatusIndicator(LadiStatusIcon):
171 def update (self, user_data = None):
172 try:
173 if self.jack_is_started():
174 # Get Realtime status
175 if self.jack_is_realtime():
176 status_text = "RT | "
177 else:
178 status_text = ""
179 # Get DSP Load
180 status_text += str (round (float (self.jack_get_load()),1)) + "% | "
181 # Get Xruns
182 status_text += str (self.jack_get_xruns())
183 # Set a started status
184 self.set_tooltip_safe (status_text)
185 self.set_icon ("started")
186 else:
187 self.set_tooltip_safe ("JACK is stopped")
188 self.set_icon ("stopped")
189 self.clear_diagnose_text()
190 except Exception, e:
191 self.set_tooltip_safe ("JACK is sick")
192 self.set_diagnose_text(repr(e))
193 self.set_icon ("stopped")
194 self.clear_jack_proxies()
195 finally:
196 LadiManager.update(self)
197 return True
199 def set_icon (self, newstate):
200 if self.icon_state == newstate:
201 return
202 self.icon_state = newstate
203 self.indicator.set_icon(self.status_icons[newstate])
205 def create_menu(self):
206 menu_items = []
208 ladish_available = self.ladish_is_available()
210 menu_items.append((Gtk.ImageMenuItem(_("LADI Player")), self.on_menu_launch_handler, "ladi-player"))
211 if ladish_available:
212 menu_items.append((Gtk.ImageMenuItem(_("Session editor")), self.on_menu_launch_handler, "gladish"))
214 menu_items.append((Gtk.SeparatorMenuItem.new(),))
215 menu_items.append((Gtk.ImageMenuItem(_("Settings")), self.on_menu_launch_handler, "ladi-control-center"))
216 menu_items.append((Gtk.ImageMenuItem(_("Log Viewer")), self.on_menu_launch_handler, "ladi-system-log"))
218 menu_items.append((Gtk.SeparatorMenuItem.new(),))
219 if hasattr(self, 'on_about'):
220 menu_items.append((Gtk.ImageMenuItem(_("About")), self.on_about, None))
221 menu_items.append((Gtk.ImageMenuItem(_("Quit")), self.on_menu_command, self.quit))
223 menu = Gtk.Menu()
224 for menu_tuple in menu_items:
225 item = menu_tuple[0]
226 if len(menu_tuple) > 1:
227 callback = menu_tuple[1]
228 exec_path = menu_tuple[2]
229 menu.append(item)
230 if type(item) is not Gtk.SeparatorMenuItem:
231 if callback in (self.studio_list_fill, self.configure_list_fill):
232 item.set_submenu(Gtk.Menu())
233 item.connect("activate", callback, exec_path)
234 menu.show_all()
235 return menu
238 def __init__(self):
239 LadiStatusIcon.__init__(self)
240 self.indicator = indicator = AppIndicator3.Indicator.new('ladi-indicator',
241 find_data_file('scalable/apps/laditools.svg'),
242 AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
243 self.menu = menu = self.create_menu()
245 indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
246 indicator.set_menu(menu)
247 menu.show()
248 # Get the initial status
249 self.update ()
250 # Add the auto update callback
251 self.auto_updater = timeout_add (250, self.update, None)
253 if __name__ == "__main__":
254 parser = argparse.ArgumentParser(description=_('system tray icon that allows users to start, stop and'
255 'monitor JACK, as well as start some JACK related applications'),
256 epilog=_('This program is part of the LADITools suite.'))
257 parser.add_argument('--version', action='version', version="%(prog)s " + get_version_string())
258 parser.parse_args()
260 Gtk.init(None)
262 if AppIndicator3:
263 LadiStatusIndicator().run()
264 else:
265 LadiStatusTray().run()
266 sys.exit(0)