scrolling over the tray icon switches among devices; fixes #101

It now works for the standard systray as well, not just the
appindicator.
This commit is contained in:
Daniel Pavel 2013-08-08 19:22:47 +02:00
parent c0874220d2
commit 6a66370ffe
1 changed files with 79 additions and 74 deletions

View File

@ -67,6 +67,82 @@ def _create_menu(quit_handler):
return menu
_last_scroll = 0
def _scroll(tray_icon, event, direction=None):
if direction is None:
direction = event.direction
now = event.time / 1000.0
else:
now = None
if direction != ScrollDirection.UP and direction != ScrollDirection.DOWN:
# ignore all other directions
return
if len(_devices_info) < 4:
# don't bother with scrolling when there's only one receiver
# with only one device (3 = [receiver, device, separator])
return
# scroll events come way too fast (at least 5-6 at once)
# so take a little break between them
global _last_scroll
now = now or _timestamp()
if now - _last_scroll < 0.33: # seconds
return
_last_scroll = now
# if _log.isEnabledFor(_DEBUG):
# _log.debug("scroll direction %s", direction)
global _picked_device
candidate = None
if _picked_device is None:
for info in _devices_info:
# pick first peripheral found
if info[1] is not None:
candidate = info
break
else:
found = False
for info in _devices_info:
if not info[1]:
# only conside peripherals
continue
# compare peripherals
if info[0:2] == _picked_device[0:2]:
if direction == ScrollDirection.UP and candidate:
# select previous device
break
found = True
else:
if found:
candidate = info
if direction == ScrollDirection.DOWN:
break
# if direction is up, but no candidate found before _picked,
# let it run through all candidates, will get stuck with the last one
else:
if direction == ScrollDirection.DOWN:
# only use the first one, in case no candidates are after _picked
if candidate is None:
candidate = info
else:
candidate = info
# if the last _picked_device is gone, clear it
# the candidate will be either the first or last one remaining,
# depending on the scroll direction
if not found:
_picked_device = None
_picked_device = candidate or _picked_device
if _log.isEnabledFor(_DEBUG):
_log.debug("scroll: picked %s", _picked_device)
_update_tray_icon()
try:
# raise ImportError
from gi.repository import AppIndicator3
@ -74,76 +150,6 @@ try:
if _log.isEnabledFor(_DEBUG):
_log.debug("using AppIndicator3")
_last_scroll = 0
def _scroll(ind, _ignore, direction):
if direction != ScrollDirection.UP and direction != ScrollDirection.DOWN:
# ignore all other directions
return
if len(_devices_info) < 4:
# don't bother with scrolling when there's only one receiver
# with only one device (3 = [receiver, device, separator])
return
# scroll events come way too fast (at least 5-6 at once)
# so take a little break between them
global _last_scroll
now = _timestamp()
if now - _last_scroll < 0.33: # seconds
return
_last_scroll = now
# if _log.isEnabledFor(_DEBUG):
# _log.debug("scroll direction %s", direction)
global _picked_device
candidate = None
if _picked_device is None:
for info in _devices_info:
# pick first peripheral found
if info[1] is not None:
candidate = info
break
else:
found = False
for info in _devices_info:
if not info[1]:
# only conside peripherals
continue
# compare peripherals
if info[0:2] == _picked_device[0:2]:
if direction == ScrollDirection.UP and candidate:
# select previous device
break
found = True
else:
if found:
candidate = info
if direction == ScrollDirection.DOWN:
break
# if direction is up, but no candidate found before _picked,
# let it run through all candidates, will get stuck with the last one
else:
if direction == ScrollDirection.DOWN:
# only use the first one, in case no candidates are after _picked
if candidate is None:
candidate = info
else:
candidate = info
# if the last _picked_device is gone, clear it
# the candidate will be either the first or last one remaining,
# depending on the scroll direction
if not found:
_picked_device = None
_picked_device = candidate or _picked_device
if _log.isEnabledFor(_DEBUG):
_log.debug("scroll: picked %s", _picked_device)
_update_tray_icon()
def _create(menu):
theme_paths = Gtk.IconTheme.get_default().get_search_path()
@ -210,10 +216,9 @@ except ImportError:
icon.set_title(NAME)
icon.set_tooltip_text(NAME)
icon.connect('activate', _window_toggle)
icon.connect('popup_menu',
lambda icon, button, time:
menu.popup(None, None, icon.position_menu, icon, button, time))
icon.connect('scroll-event', _scroll)
icon.connect('popup-menu',
lambda icon, button, time: menu.popup(None, None, icon.position_menu, icon, button, time))
return icon