better handling of window pop-up and toggling

This commit is contained in:
Daniel Pavel 2012-12-08 00:51:10 +02:00
parent d38bec39b6
commit d8a2ffa835
3 changed files with 42 additions and 31 deletions

View File

@ -82,8 +82,10 @@ def error(window, title, text):
def find_children(container, *child_names):
assert container is not None
assert isinstance(container, Gtk.Container)
def _iterate_children(widget, names, result, count):
assert isinstance(widget, Gtk.Widget)
wname = widget.get_name()
if wname in names:
index = names.index(wname)
@ -93,6 +95,7 @@ def find_children(container, *child_names):
if count > 0 and isinstance(widget, Gtk.Container):
for w in widget:
# if isinstance(w, Gtk.Widget):
count = _iterate_children(w, names, result, count)
if count == 0:
break

View File

@ -33,11 +33,10 @@ def _process_apply_queue():
_, setting, value, sbox = task
GObject.idle_add(_write_start, sbox)
value = setting.write(value)
GObject.idle_add(_update_setting_item, sbox, value)
elif task[0] == 'read':
_, setting, sbox, cached = task
_, setting, cached, sbox = task
value = setting.read(cached)
GObject.idle_add(_update_setting_item, sbox, value)
GObject.idle_add(_update_setting_item, sbox, value)
from threading import Thread as _Thread
_queue_processor = _Thread(name='SettingsProcessor', target=_process_apply_queue)
@ -159,19 +158,25 @@ def update(frame):
# nothing to do here
return
if not box.get_visible():
# no point in doing this, is there?
return
force_read = False
items = box.get_children()
if not items:
if device.status:
items = _add_settings(box, device)
assert len(device.settings) == len(list(items))
force_read = True
else:
# don't bother adding settings for offline devices,
# they're useless and might not guess all of them anyway
return
device_active = bool(device.status)
was_inactive = not box.get_sensitive()
force_read |= device_active and not box.get_sensitive()
box.set_sensitive(device_active)
if device_active:
for sbox, s in zip(items, device.settings):
_apply_queue.put(('read', s, sbox, was_inactive))
_apply_queue.put(('read', s, force_read, sbox))

View File

@ -239,26 +239,6 @@ def _make_device_box(index):
return frame
def toggle(window, trigger):
if window.get_visible():
position = window.get_position()
window.hide()
window.move(*position)
else:
if trigger and type(trigger) == Gtk.StatusIcon:
x, y = window.get_position()
if x == 0 and y == 0:
x, y, _ = Gtk.StatusIcon.position_menu(Gtk.Menu(), trigger)
window.move(x, y)
window.present()
return True
def _popup(window, trigger=None):
if not window.get_visible():
toggle(window, trigger)
def create(title, name, max_devices, systray=False):
window = Gtk.Window()
window.set_title(title)
@ -284,16 +264,39 @@ def create(title, name, max_devices, systray=False):
window.set_geometry_hints(vbox, geometry, Gdk.WindowHints.MIN_SIZE)
window.set_resizable(False)
window.toggle_visible = lambda i: toggle(window, i)
window.popup = lambda i=None: _popup(window, i)
def _toggle_visible(w, trigger):
if w.get_visible():
# hiding moves the window to 0,0
position = w.get_position()
w.hide()
w.move(*position)
else:
if isinstance(trigger, Gtk.StatusIcon):
x, y = w.get_position()
if x == 0 and y == 0:
# if the window hasn't been shown yet, position it next to the status icon
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)
from types import MethodType
window.toggle_visible = MethodType(_toggle_visible, window)
window.popup = MethodType(_popup, 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)
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)
@ -333,7 +336,7 @@ def _update_receiver_box(frame, receiver):
pairing_icon.set_visible(False)
toolbar.set_sensitive(False)
toolbar.get_children()[0].set_active(False)
ui.find_children('info-label').set_text('')
ui.find_children(frame, 'info-label').set_text('')
def _update_device_box(frame, dev):