updated status_icon to support future appindicator implementation
This commit is contained in:
parent
3596faed2f
commit
db53de2233
|
@ -109,6 +109,7 @@ def _run(args):
|
||||||
GLib.timeout_add(10, _base.notify_on_receivers, handle_receivers_events)
|
GLib.timeout_add(10, _base.notify_on_receivers, handle_receivers_events)
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
Gtk.main()
|
Gtk.main()
|
||||||
|
ui.status_icon.destroy(status_icon)
|
||||||
|
|
||||||
for l in listeners.values():
|
for l in listeners.values():
|
||||||
l.stop()
|
l.stop()
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
# import logging
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# from gi.repository import Indicate
|
|
||||||
# from time import time as _timestamp
|
|
||||||
|
|
||||||
# # import ui
|
|
||||||
|
|
||||||
# # necessary because the notifications daemon does not know about our XDG_DATA_DIRS
|
|
||||||
# _icons = {}
|
|
||||||
|
|
||||||
# # def _icon(title):
|
|
||||||
# # if title not in _icons:
|
|
||||||
# # _icons[title] = ui.icon_file(title)
|
|
||||||
|
|
||||||
# # return _icons.get(title)
|
|
||||||
|
|
||||||
# def init(app_title):
|
|
||||||
# global available
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# s = Indicate.Server()
|
|
||||||
# s.set_type('message.im')
|
|
||||||
# s.set_default()
|
|
||||||
# print s
|
|
||||||
# s.show()
|
|
||||||
# s.connect('server-display', server_display)
|
|
||||||
|
|
||||||
# i = Indicate.Indicator()
|
|
||||||
# i.set_property('sender', 'test message sender')
|
|
||||||
# i.set_property('body', 'test message body')
|
|
||||||
# i.set_property_time('time', _timestamp())
|
|
||||||
# i.set_subtype('im')
|
|
||||||
# print i, i.list_properties()
|
|
||||||
# i.show()
|
|
||||||
# i.connect('user-display', display)
|
|
||||||
|
|
||||||
# pass
|
|
||||||
# except:
|
|
||||||
# available = False
|
|
||||||
|
|
||||||
# init('foo')
|
|
||||||
|
|
||||||
# # assumed to be working since the import succeeded
|
|
||||||
# available = True
|
|
||||||
|
|
||||||
# def server_display(s):
|
|
||||||
# print 'server display', s
|
|
||||||
|
|
||||||
# def display(i):
|
|
||||||
# print "indicator display", i
|
|
||||||
# i.hide()
|
|
||||||
|
|
||||||
# except ImportError:
|
|
||||||
# available = False
|
|
||||||
# init = lambda app_title: False
|
|
||||||
# uninit = lambda: None
|
|
||||||
# show = lambda dev: None
|
|
|
@ -14,35 +14,94 @@ from logitech.unifying_receiver import status as _status
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
def create(activate_callback, menu_activate_callback):
|
def _create_common(icon, menu_activate_callback):
|
||||||
assert activate_callback
|
|
||||||
assert menu_activate_callback
|
|
||||||
|
|
||||||
icon = Gtk.StatusIcon()
|
|
||||||
icon.set_title(NAME)
|
|
||||||
icon.set_name(NAME)
|
|
||||||
icon.set_from_icon_name(_icons.APP_ICON[0])
|
|
||||||
icon._devices_info = []
|
icon._devices_info = []
|
||||||
icon._receivers = set()
|
|
||||||
|
|
||||||
icon.set_tooltip_text(NAME)
|
icon.set_title(NAME)
|
||||||
icon.connect('activate', activate_callback)
|
|
||||||
icon._menu_activate_callback = menu_activate_callback
|
icon._menu_activate_callback = menu_activate_callback
|
||||||
|
icon._menu = menu = Gtk.Menu()
|
||||||
|
|
||||||
menu = icon._menu = Gtk.Menu()
|
no_receiver = Gtk.MenuItem.new_with_label('No receiver found')
|
||||||
|
no_receiver.set_sensitive(False)
|
||||||
|
menu.append(no_receiver)
|
||||||
|
|
||||||
# per-device menu entries will be generated as-needed
|
# per-device menu entries will be generated as-needed
|
||||||
|
|
||||||
menu.append(Gtk.SeparatorMenuItem.new())
|
menu.append(Gtk.SeparatorMenuItem.new())
|
||||||
menu.append(_action.about.create_menu_item())
|
menu.append(_action.about.create_menu_item())
|
||||||
menu.append(_action.make('application-exit', 'Quit', Gtk.main_quit).create_menu_item())
|
menu.append(_action.make('application-exit', 'Quit', Gtk.main_quit).create_menu_item())
|
||||||
menu.show_all()
|
menu.show_all()
|
||||||
|
|
||||||
icon.connect('popup_menu',
|
|
||||||
lambda icon, button, time, menu:
|
try:
|
||||||
menu.popup(None, None, icon.position_menu, icon, button, time),
|
raise ImportError
|
||||||
menu)
|
# try:
|
||||||
return icon
|
# from gi.repository import AppIndicator3 as AppIndicator
|
||||||
|
# except ImportError:
|
||||||
|
# from gi.repository import AppIndicator
|
||||||
|
|
||||||
|
# def create(activate_callback, menu_activate_callback):
|
||||||
|
# assert activate_callback
|
||||||
|
# assert menu_activate_callback
|
||||||
|
|
||||||
|
# ind = AppIndicator.Indicator.new('indicator-solaar', _icons.APP_ICON[0], AppIndicator.IndicatorCategory.HARDWARE)
|
||||||
|
# ind.set_status(AppIndicator.IndicatorStatus.ACTIVE)
|
||||||
|
|
||||||
|
# _create_common(ind, menu_activate_callback)
|
||||||
|
# ind.set_menu(ind._menu)
|
||||||
|
|
||||||
|
# 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_image(ind, image):
|
||||||
|
# if isinstance(image, GdkPixbuf.Pixbuf):
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# ind.set_icon(image)
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
|
||||||
|
def create(activate_callback, menu_activate_callback):
|
||||||
|
assert activate_callback
|
||||||
|
assert menu_activate_callback
|
||||||
|
|
||||||
|
icon = Gtk.StatusIcon.new_from_icon_name(_icons.APP_ICON[0])
|
||||||
|
icon.set_name(NAME)
|
||||||
|
icon.set_tooltip_text(NAME)
|
||||||
|
icon.connect('activate', activate_callback)
|
||||||
|
|
||||||
|
_create_common(icon, menu_activate_callback)
|
||||||
|
icon.connect('popup_menu',
|
||||||
|
lambda icon, button, time, menu:
|
||||||
|
icon._menu.popup(None, None, icon.position_menu, icon, button, time),
|
||||||
|
icon._menu)
|
||||||
|
|
||||||
|
return icon
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
if isinstance(image, GdkPixbuf.Pixbuf):
|
||||||
|
icon.set_from_pixbuf(image)
|
||||||
|
else:
|
||||||
|
icon.set_from_icon_name(image)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -94,48 +153,41 @@ def _icon_with_battery(level, active):
|
||||||
|
|
||||||
return _PIXMAPS[name]
|
return _PIXMAPS[name]
|
||||||
|
|
||||||
def _update_image(icon):
|
|
||||||
if not icon._receivers:
|
def _generate_image(icon):
|
||||||
icon.set_from_icon_name(_icons.APP_ICON[-1])
|
if not icon._devices_info:
|
||||||
return
|
return _icons.APP_ICON[-1]
|
||||||
|
|
||||||
battery_status = None
|
battery_status = None
|
||||||
battery_level = 1000
|
battery_level = 1000
|
||||||
|
|
||||||
for _, serial, name, status in icon._devices_info:
|
for _, serial, name, status in icon._devices_info:
|
||||||
|
if serial is None: # is receiver
|
||||||
|
continue
|
||||||
level = status.get(_status.BATTERY_LEVEL)
|
level = status.get(_status.BATTERY_LEVEL)
|
||||||
if level is not None and level < battery_level:
|
if level is not None and level < battery_level:
|
||||||
battery_status = status
|
battery_status = status
|
||||||
battery_level = level
|
battery_level = level
|
||||||
|
|
||||||
if battery_status is None:
|
if battery_status is None:
|
||||||
icon.set_from_icon_name(_icons.APP_ICON[1])
|
return _icons.APP_ICON[1]
|
||||||
else:
|
else:
|
||||||
pixbuf = _icon_with_battery(battery_level, bool(battery_status))
|
pixbuf = _icon_with_battery(battery_level, bool(battery_status))
|
||||||
if pixbuf:
|
if pixbuf:
|
||||||
icon.set_from_pixbuf(pixbuf)
|
return pixbuf
|
||||||
else:
|
else:
|
||||||
icon.set_from_icon_name(_icons.APP_ICON[1])
|
return _icons.APP_ICON[1]
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
def _device_index(icon, device):
|
|
||||||
if device.receiver.serial in icon._receivers:
|
|
||||||
for index, (rserial, serial, name, _) in enumerate(icon._devices_info):
|
|
||||||
if rserial == device.receiver.serial and serial == device.serial:
|
|
||||||
return index
|
|
||||||
|
|
||||||
# print ("== device", device, device.receiver.serial, "not found in", icon._receivers, "/", icon._devices_info)
|
|
||||||
|
|
||||||
|
|
||||||
def _add_device(icon, device):
|
def _add_device(icon, device):
|
||||||
index = len(icon._devices_info)
|
index = len(icon._devices_info)
|
||||||
device_info = (device.receiver.serial, device.serial, device.name, device.status)
|
device_info = (device.receiver.serial, device.serial, device.name, device.status)
|
||||||
icon._devices_info.append(device_info)
|
icon._devices_info.append(device_info)
|
||||||
|
|
||||||
menu_item = Gtk.ImageMenuItem.new_with_label(device.name)
|
menu_item = Gtk.ImageMenuItem.new_with_label(' ' + device.name)
|
||||||
icon._menu.insert(menu_item, index)
|
icon._menu.insert(menu_item, index)
|
||||||
menu_item.set_image(Gtk.Image())
|
menu_item.set_image(Gtk.Image())
|
||||||
menu_item.show_all()
|
menu_item.show_all()
|
||||||
|
@ -152,8 +204,20 @@ def _remove_device(icon, index):
|
||||||
icon._menu.remove(menu_items[index])
|
icon._menu.remove(menu_items[index])
|
||||||
|
|
||||||
|
|
||||||
|
def _add_receiver(icon, receiver):
|
||||||
|
device_info = (receiver.serial, None, receiver.name, None)
|
||||||
|
icon._devices_info.insert(0, device_info)
|
||||||
|
|
||||||
|
menu_item = Gtk.ImageMenuItem.new_with_label(receiver.name)
|
||||||
|
icon._menu.insert(menu_item, 0)
|
||||||
|
menu_item.set_image(Gtk.Image().new_from_icon_name(receiver.name, Gtk.IconSize.LARGE_TOOLBAR))
|
||||||
|
menu_item.show_all()
|
||||||
|
menu_item.connect('activate', icon._menu_activate_callback, receiver.path, icon)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def _remove_receiver(icon, receiver):
|
def _remove_receiver(icon, receiver):
|
||||||
icon._receivers.remove(receiver.serial)
|
|
||||||
index = 0
|
index = 0
|
||||||
while index < len(icon._devices_info):
|
while index < len(icon._devices_info):
|
||||||
rserial, _, _, _ = icon._devices_info[index]
|
rserial, _, _, _ = icon._devices_info[index]
|
||||||
|
@ -170,6 +234,7 @@ def _update_menu_item(icon, index, device_status):
|
||||||
|
|
||||||
image = menu_item.get_image()
|
image = menu_item.get_image()
|
||||||
battery_level = device_status.get(_status.BATTERY_LEVEL)
|
battery_level = device_status.get(_status.BATTERY_LEVEL)
|
||||||
|
print ("device_status", dict(device_status), battery_level)
|
||||||
image.set_from_icon_name(_icons.battery(battery_level), Gtk.IconSize.LARGE_TOOLBAR)
|
image.set_from_icon_name(_icons.battery(battery_level), Gtk.IconSize.LARGE_TOOLBAR)
|
||||||
image.set_sensitive(bool(device_status))
|
image.set_sensitive(bool(device_status))
|
||||||
# menu_item.set_sensitive(bool(device_status))
|
# menu_item.set_sensitive(bool(device_status))
|
||||||
|
@ -186,12 +251,24 @@ def update(icon, device=None):
|
||||||
# receiver
|
# receiver
|
||||||
receiver = device
|
receiver = device
|
||||||
if receiver:
|
if receiver:
|
||||||
icon._receivers.add(receiver.serial)
|
index = None
|
||||||
|
for idx, (rserial, _, _, _) in enumerate(icon._devices_info):
|
||||||
|
if rserial == receiver.serial:
|
||||||
|
index = idx
|
||||||
|
break
|
||||||
|
|
||||||
|
if index is None:
|
||||||
|
_add_receiver(icon, receiver)
|
||||||
else:
|
else:
|
||||||
_remove_receiver(icon, receiver)
|
_remove_receiver(icon, receiver)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# peripheral
|
# peripheral
|
||||||
index = _device_index(icon, device)
|
index = None
|
||||||
|
for idx, (rserial, serial, name, _) in enumerate(icon._devices_info):
|
||||||
|
if rserial == device.receiver.serial and serial == device.serial:
|
||||||
|
index = idx
|
||||||
|
|
||||||
if device.status is None:
|
if device.status is None:
|
||||||
# was just unpaired
|
# was just unpaired
|
||||||
assert index is not None
|
assert index is not None
|
||||||
|
@ -201,6 +278,8 @@ def update(icon, device=None):
|
||||||
index = _add_device(icon, device)
|
index = _add_device(icon, device)
|
||||||
_update_menu_item(icon, index, device.status)
|
_update_menu_item(icon, index, device.status)
|
||||||
|
|
||||||
tooltip_lines = _generate_tooltip_lines(icon)
|
menu_items = icon._menu.get_children()
|
||||||
icon.set_tooltip_markup('\n'.join(tooltip_lines).rstrip('\n'))
|
menu_items[len(icon._devices_info)].set_visible(not icon._devices_info)
|
||||||
_update_image(icon)
|
|
||||||
|
_update_icon_tooltip(icon, _generate_tooltip_lines)
|
||||||
|
_update_icon_image(icon, _generate_image(icon))
|
||||||
|
|
Loading…
Reference in New Issue