Let application decides on how to handle signals.
[laditools.git] / ladi-system-tray
bloba3a5194f67f31d0c21493eed8181cf13a483d463
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 set_tooltip_text(self, text): pass
68 def __init__ (self, config_filename = None):
69 # Handle the configuration
70 self.icon_state = ""
71 self.last_status_text = ""
72 self.diagnose_text = None
73 self.status_icons = {'started' : 'ladi-started',
74 'stopped' : 'ladi-stopped',
75 'starting' : 'ladi-starting'}
76 self.global_config = LadiConfiguration(self.appname,
77 self._default_config,
78 config_filename)
79 self.config_dict = self.global_config.get_config_section (self.appname)
80 autostart = bool(eval(self.config_dict['autostart']))
81 # Build the UI
82 LadiMenu.__init__(self, autostart)
84 def menu_activate(self, status_icon, button, activate_time, user_data=None):
85 menu = self.create_menu()
86 menu.popup (parent_menu_shell=None,
87 parent_menu_item=None,
88 func=self.position_menu,
89 data=self,
90 button=button,
91 activate_time=activate_time)
92 menu.reposition ()
94 def set_starting_status (self):
95 self.set_tooltip_safe ("JACK is starting")
96 self.set_icon ("starting")
98 def set_tooltip_safe (self, text):
99 if text != self.last_status_text:
100 self.set_tooltip_text (text)
101 self.last_status_text = text
103 def run(self):
104 Gtk.main ()
105 # Some default config might need to be injected in the config file,
106 # we handle all that before we quit.
107 self.global_config.set_config_section (self.appname, self.config_dict)
108 self.global_config.save ()
109 return 0
111 class LadiStatusTray(Gtk.StatusIcon, LadiStatusIcon):
113 def __init__(self):
114 LadiStatusIcon.__init__(self)
115 GObject.GObject.__init__ (self)
116 self.set_icon ("stopped")
117 # Get the initial status
118 self.update ()
119 # Add the auto update callback
120 self.auto_updater = timeout_add (250, self.update, None)
121 # Make the menu popup when the icon is right clicked
122 self.connect ("popup-menu", self.menu_activate)
123 self.set_title(self.appname_long)
125 def do_button_press_event(self, event):
126 if event.type != Gdk.EventType._2BUTTON_PRESS:
127 return False
128 self.on_menu_launch_handler(None, "gladish")
129 return True
131 def update (self, user_data = None):
132 try:
133 if self.jack_is_started():
134 # Get Realtime status
135 if self.jack_is_realtime():
136 status_text = "RT | "
137 else:
138 status_text = ""
139 # Get DSP Load
140 status_text += str (round (float (self.jack_get_load()),1)) + "% | "
141 # Get Xruns
142 status_text += str (self.jack_get_xruns())
143 # Set a started status
144 self.set_tooltip_safe (status_text)
145 self.set_icon ("started")
146 else:
147 self.set_tooltip_safe ("JACK is stopped")
148 self.set_icon ("stopped")
149 self.clear_diagnose_text()
150 except Exception, e:
151 self.set_tooltip_safe ("JACK is sick")
152 self.set_diagnose_text(repr(e))
153 self.set_icon ("stopped")
154 self.clear_jack_proxies()
155 finally:
156 LadiManager.update(self)
157 return True
159 def set_icon (self, newstate):
160 if self.icon_state == newstate:
161 return
162 self.icon_state = newstate
163 self.set_from_icon_name(self.status_icons[newstate])
165 class LadiStatusIndicator(LadiStatusIcon):
167 def update (self, user_data = None):
168 try:
169 if self.jack_is_started():
170 # Get Realtime status
171 if self.jack_is_realtime():
172 status_text = "RT | "
173 else:
174 status_text = ""
175 # Get DSP Load
176 status_text += str (round (float (self.jack_get_load()),1)) + "% | "
177 # Get Xruns
178 status_text += str (self.jack_get_xruns())
179 # Set a started status
180 self.set_tooltip_safe (status_text)
181 self.set_icon ("started")
182 else:
183 self.set_tooltip_safe ("JACK is stopped")
184 self.set_icon ("stopped")
185 self.clear_diagnose_text()
186 except Exception, e:
187 self.set_tooltip_safe ("JACK is sick")
188 self.set_diagnose_text(repr(e))
189 self.set_icon ("stopped")
190 self.clear_jack_proxies()
191 finally:
192 LadiManager.update(self)
193 return True
195 def set_icon (self, newstate):
196 if self.icon_state == newstate:
197 return
198 self.icon_state = newstate
199 self.indicator.set_icon(self.status_icons[newstate])
201 def create_menu(self):
202 menu_items = []
204 ladish_available = self.ladish_is_available()
206 menu_items.append((Gtk.ImageMenuItem(_("LADI Player")), self.on_menu_launch_handler, "ladi-player"))
207 if ladish_available:
208 menu_items.append((Gtk.ImageMenuItem(_("Session editor")), self.on_menu_launch_handler, "gladish"))
210 menu_items.append((Gtk.SeparatorMenuItem.new(),))
211 menu_items.append((Gtk.ImageMenuItem(_("Settings")), self.on_menu_launch_handler, "ladi-control-center"))
212 menu_items.append((Gtk.ImageMenuItem(_("Log Viewer")), self.on_menu_launch_handler, "ladi-system-log"))
214 menu_items.append((Gtk.SeparatorMenuItem.new(),))
215 if hasattr(self, 'on_about'):
216 menu_items.append((Gtk.ImageMenuItem(_("About")), self.on_about, None))
217 menu_items.append((Gtk.ImageMenuItem(_("Quit")), self.on_menu_command, Gtk.main_quit))
219 menu = Gtk.Menu()
220 for menu_tuple in menu_items:
221 item = menu_tuple[0]
222 if len(menu_tuple) > 1:
223 callback = menu_tuple[1]
224 exec_path = menu_tuple[2]
225 menu.append(item)
226 if type(item) is not Gtk.SeparatorMenuItem:
227 if callback in (self.studio_list_fill, self.configure_list_fill):
228 item.set_submenu(Gtk.Menu())
229 item.connect("activate", callback, exec_path)
230 menu.show_all()
231 return menu
234 def __init__(self):
235 LadiStatusIcon.__init__(self)
236 self.indicator = indicator = AppIndicator3.Indicator.new('ladi-indicator',
237 find_data_file('scalable/apps/laditools.svg'),
238 AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
239 self.menu = menu = self.create_menu()
241 indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
242 indicator.set_menu(menu)
243 menu.show()
244 # Get the initial status
245 self.update ()
246 # Add the auto update callback
247 self.auto_updater = timeout_add (250, self.update, None)
249 if __name__ == "__main__":
250 parser = argparse.ArgumentParser(description=_('system tray icon that allows users to start, stop and'
251 'monitor JACK, as well as start some JACK related applications'),
252 epilog=_('This program is part of the LADITools suite.'))
253 parser.add_argument('--version', action='version', version="%(prog)s " + get_version_string())
255 parser.parse_args()
257 if AppIndicator3:
258 LadiStatusIndicator().run()
259 else:
260 LadiStatusTray().run()
261 sys.exit(0)