diff --git a/app/solaar.py b/app/solaar.py
index 720f3f96..e1f6a201 100644
--- a/app/solaar.py
+++ b/app/solaar.py
@@ -66,7 +66,6 @@ def _run(args):
icon = ui.status_icon.create(window, menu_actions)
else:
icon = None
- window.present()
from gi.repository import Gtk, GObject
@@ -94,12 +93,12 @@ def _run(args):
# callback delivering status events from the receiver/devices to the UI
def status_changed(receiver, device=None, alert=status.ALERT.NONE, reason=None):
+ if alert & status.ALERT.MED:
+ GObject.idle_add(window.present)
if window:
GObject.idle_add(ui.main_window.update, window, receiver, device)
if icon:
GObject.idle_add(ui.status_icon.update, icon, receiver, device)
- if alert & status.ALERT.MED:
- GObject.idle_add(window.popup, icon)
if ui.notify.available:
# always notify on receiver updates
@@ -109,7 +108,7 @@ def _run(args):
if receiver is DUMMY:
GObject.timeout_add(3000, check_for_listener)
- GObject.timeout_add(0, check_for_listener, True)
+ GObject.timeout_add(10, check_for_listener, True)
Gtk.main()
if listener:
diff --git a/app/ui/main_window.py b/app/ui/main_window.py
index 0d372219..b1654c04 100644
--- a/app/ui/main_window.py
+++ b/app/ui/main_window.py
@@ -278,27 +278,36 @@ def create(title, name, max_devices, systray=False):
x, y, _ = Gtk.StatusIcon.position_menu(Gtk.Menu(), trigger)
w.move(x, y)
w.present()
- w.deiconify()
return True
- def _popup(w, trigger=None):
- if not w.get_visible():
- w.toggle_visible(trigger)
+ def _set_has_systray(w, systray):
+ if systray != w._has_systray:
+ w._has_systray = systray
+ if systray:
+ if w._delete_event_connection is None or not w.get_skip_taskbar_hint():
+ w.set_skip_taskbar_hint(True)
+ w.set_skip_pager_hint(True)
+ if w._delete_event_connection:
+ w.disconnect(w._delete_event_connection)
+ w._delete_event_connection = w.connect('delete-event', _toggle_visible)
+ else:
+ if w._delete_event_connection is None or w.get_skip_taskbar_hint():
+ w.set_skip_taskbar_hint(False)
+ w.set_skip_pager_hint(False)
+ if w._delete_event_connection:
+ w.disconnect(w._delete_event_connection)
+ w._delete_event_connection = w.connect('delete-event', Gtk.main_quit)
+ w.present()
from types import MethodType
window.toggle_visible = MethodType(_toggle_visible, window)
- window.popup = MethodType(_popup, window)
+ window.set_has_systray = MethodType(_set_has_systray, window)
del MethodType
- if systray:
- window.set_keep_above(True)
- # window.set_decorated(False)
- # window.set_type_hint(Gdk.WindowTypeHint.TOOLTIP)
- window.set_skip_taskbar_hint(True)
- window.set_skip_pager_hint(True)
- window.connect('delete-event', _toggle_visible)
- else:
- window.connect('delete-event', Gtk.main_quit)
+ window.set_keep_above(True)
+ window._delete_event_connection = None
+ window._has_systray = None
+ window.set_has_systray(systray)
return window
diff --git a/app/ui/status_icon.py b/app/ui/status_icon.py
index e8ef1363..8bdc1219 100644
--- a/app/ui/status_icon.py
+++ b/app/ui/status_icon.py
@@ -4,7 +4,7 @@
from __future__ import absolute_import, division, print_function, unicode_literals
-from gi.repository import Gtk, GdkPixbuf
+from gi.repository import Gtk, GObject, GdkPixbuf
import ui
from logitech.unifying_receiver import status as _status
@@ -13,13 +13,15 @@ from logitech.unifying_receiver import status as _status
#
#
+_NO_DEVICES = [None] * 6
+
def create(window, menu_actions=None):
name = window.get_title()
icon = Gtk.StatusIcon()
icon.set_title(name)
icon.set_name(name)
icon.set_from_icon_name(ui.appicon(False))
- icon._devices = {}
+ icon._devices = list(_NO_DEVICES)
icon.set_tooltip_text(name)
icon.connect('activate', window.toggle_visible)
@@ -37,6 +39,13 @@ def create(window, menu_actions=None):
menu.popup(None, None, icon.position_menu, icon, button, time),
menu)
+ # use size-changed to detect if the systray is available or not
+ def _size_changed(i, size, w):
+ def _check_systray(i2, w2):
+ w2.set_has_systray(i2.is_embedded() and i2.get_visible())
+ GObject.timeout_add(250, _check_systray, i, w)
+ icon.connect('size-changed', _size_changed, window)
+
return icon
@@ -71,34 +80,34 @@ def update(icon, receiver, device=None):
if device:
icon._devices[device.number] = None if device.status is None else device
+ if not receiver:
+ icon._devices[:] = _NO_DEVICES
+ if not icon.is_embedded():
+ return
lines = [ui.NAME + ': ' + str(receiver.status), '']
- if receiver:
- for k in range(1, 1 + receiver.max_devices):
- dev = icon._devices.get(k)
- if dev is None:
- continue
+ for dev in icon._devices:
+ if dev is None:
+ continue
- lines.append('' + dev.name + '')
+ lines.append('' + dev.name + '')
- assert hasattr(dev, 'status') and dev.status is not None
- p = str(dev.status)
- if p:
- if not dev.status:
- p += ' (inactive)'
+ assert hasattr(dev, 'status') and dev.status is not None
+ p = str(dev.status)
+ if p:
+ if not dev.status:
+ p += ' (inactive)'
+ else:
+ if dev.status:
+ p = 'no status'
else:
- if dev.status:
- p = 'no status'
- else:
- p = '(inactive)'
+ p = '(inactive)'
- lines.append('\t' + p)
- lines.append('')
+ lines.append('\t' + p)
+ lines.append('')
- if battery_status is None and dev.status.get(_status.BATTERY_LEVEL):
- battery_status = dev.status
- else:
- icon._devices.clear()
+ if battery_status is None and dev.status.get(_status.BATTERY_LEVEL):
+ battery_status = dev.status
icon.set_tooltip_markup('\n'.join(lines).rstrip('\n'))