diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py index b3212d29..462f8464 100644 --- a/lib/solaar/gtk.py +++ b/lib/solaar/gtk.py @@ -109,7 +109,7 @@ def _run(args): GLib.timeout_add(10, _base.notify_on_receivers, handle_receivers_events) from gi.repository import Gtk Gtk.main() - ui.status_icon.destroy(status_icon) + # ui.status_icon.destroy(status_icon) for l in listeners.values(): l.stop() diff --git a/lib/solaar/ui/main_window.py b/lib/solaar/ui/main_window.py index 60d0e2e1..1a8d661f 100644 --- a/lib/solaar/ui/main_window.py +++ b/lib/solaar/ui/main_window.py @@ -4,6 +4,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import logging +_DEBUG = logging.DEBUG +_log = logging.getLogger('solaar.ui.window') + from gi.repository import Gtk, Gdk, GLib from solaar import NAME @@ -275,29 +279,20 @@ def _hide(w, _=None): def _show(w, trigger=None): - if not w.get_visible(): + if w.get_visible() or w._was_shown: w.present() - if not w._was_shown: - w._was_shown = True - if isinstance(trigger, Gtk.StatusIcon): - # if the window hasn't been shown yet, position it relative to - # an other window (if it was shown before) or the status icon. - # TODO: need a more clever positioning algorithm like finding - # the window where space exist on the right, else pick the - # left-most window. - # for win in _windows.values(): - # x, y = win.get_position() - # if win != w and (x, y) != (0, 0): - # # position left plus some window decoration - # w_width, w_height = w.get_size() - # x -= w_width + 10 - # w.move(x, y) - # break - # else: - x, y, _ = Gtk.StatusIcon.position_menu(trigger._menu, trigger) - w.move(x, y) - elif isinstance(trigger, Gtk.MenuItem): - x, y = trigger + else: + w._was_shown = True + # if _log.isEnabledFor(_DEBUG): + # _log.debug("first show %s", trigger) + if isinstance(trigger, Gtk.StatusIcon): + x, y, _ = Gtk.StatusIcon.position_menu(trigger._menu, trigger) + w.present() + w.move(x, y) + else: + w.set_position(Gtk.WindowPosition.CENTER) + w.present() + return True @@ -333,6 +328,7 @@ def _create(receiver): window.set_skip_taskbar_hint(True) window.set_skip_pager_hint(True) window.set_keep_above(True) + # window.set_position(Gtk.WindowPosition.MOUSE) # window.set_decorations(Gdk.DECOR_BORDER | Gdk.DECOR_TITLE) window.connect('delete-event', _hide) window._was_shown = False diff --git a/lib/solaar/ui/status_icon.py b/lib/solaar/ui/status_icon.py index d8c13842..544dd2df 100644 --- a/lib/solaar/ui/status_icon.py +++ b/lib/solaar/ui/status_icon.py @@ -36,40 +36,37 @@ def _create_common(icon, menu_activate_callback): try: - raise ImportError - # try: - # from gi.repository import AppIndicator3 as AppIndicator - # except ImportError: - # from gi.repository import AppIndicator + from gi.repository import AppIndicator3 as AppIndicator - # def create(activate_callback, menu_activate_callback): - # assert activate_callback - # assert menu_activate_callback + # def _scroll(ind, delta, direction): + # print ("scroll", ind, delta, direction) - # ind = AppIndicator.Indicator.new('indicator-solaar', _icons.APP_ICON[0], AppIndicator.IndicatorCategory.HARDWARE) - # ind.set_status(AppIndicator.IndicatorStatus.ACTIVE) + def create(activate_callback, menu_activate_callback): + assert activate_callback + assert menu_activate_callback - # _create_common(ind, menu_activate_callback) - # ind.set_menu(ind._menu) + ind = AppIndicator.Indicator.new('indicator-solaar', _icons.APP_ICON[0], AppIndicator.IndicatorCategory.HARDWARE) + ind.set_status(AppIndicator.IndicatorStatus.ACTIVE) - # return ind + _create_common(ind, menu_activate_callback) + ind.set_menu(ind._menu) + + # ind.connect('scroll-event', _scroll) + + return ind # def destroy(ind): # ind.set_status(AppIndicator.IndicatorStatus.PASSIVE) - # ind.set_menu(None) - # def _update_icon_tooltip(ind, lines_generator): - # pass + def _update_icon(ind, image, tooltip): + if isinstance(image, GdkPixbuf.Pixbuf): + pass + else: + ind.set_icon_full(image, tooltip) - # def _update_icon_image(ind, image): - # if isinstance(image, GdkPixbuf.Pixbuf): - # pass - # else: - # ind.set_icon(image) - except ImportError: def create(activate_callback, menu_activate_callback): @@ -90,30 +87,26 @@ except ImportError: return icon - def destroy(icon): - icon.set_visible(False) + # def destroy(icon): + # icon.set_visible(False) - def _update_icon_tooltip(icon, lines_generator): - tooltip_lines = lines_generator(icon) - icon.set_tooltip_markup('\n'.join(tooltip_lines).rstrip('\n')) - - - def _update_icon_image(icon, image): + def _update_icon(icon, image, tooltip): if isinstance(image, GdkPixbuf.Pixbuf): icon.set_from_pixbuf(image) else: icon.set_from_icon_name(image) + icon.set_tooltip_markup(tooltip) # # # -def _generate_tooltip_lines(icon): +def _generate_tooltip_lines(devices_info): yield '%s' % NAME yield '' - for _, serial, name, status in icon._devices_info: + for _, serial, name, status in devices_info: if serial is None: # receiver continue @@ -146,7 +139,7 @@ def _icon_with_battery(level, active): mask.saturate_and_pixelate(mask, 0.7, False) battery = _icons.icon_file(battery_icon, 128) - assert battery + assert battery, "faild to find file for %s" % battery_icon battery = GdkPixbuf.Pixbuf.new_from_file(battery) assert battery.get_width() == 128 and battery.get_height() == 128 if not active: @@ -305,7 +298,8 @@ def update(icon, device=None): menu_items[no_receivers_index].set_visible(not icon._devices_info) menu_items[no_receivers_index + 1].set_visible(not icon._devices_info) - _update_icon_tooltip(icon, _generate_tooltip_lines) - _update_icon_image(icon, _generate_image(icon)) + tooltip_lines = _generate_tooltip_lines(icon._devices_info) + tooltip = '\n'.join(tooltip_lines).rstrip('\n') + _update_icon(icon, _generate_image(icon), tooltip) # print ("icon updated", device, icon._devices_info)