Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Gtk UI: Fix submenu activation/focus issues (bug 1778)

This fixes the same problem as outlined in bug 1778, but also
makes sure that keyboard navigation still works.
  • Loading branch information...
commit a09b204ad67c2ef1f95c5858f5bdf48a77815bc0 1 parent 7fcbb39
Thomas Perl authored March 09, 2013

Showing 1 changed file with 26 additions and 5 deletions. Show diff stats Hide diff stats

  1. 31  src/gpodder/gtkui/main.py
31  src/gpodder/gtkui/main.py
@@ -29,6 +29,7 @@
29 29
 import subprocess
30 30
 import glob
31 31
 import time
  32
+import threading
32 33
 import tempfile
33 34
 import collections
34 35
 import urllib
@@ -1675,6 +1676,27 @@ def _add_sub_menu(self, menu, label):
1675 1676
         root_item.set_submenu(sub_menu)
1676 1677
         return sub_menu
1677 1678
 
  1679
+    def _submenu_item_activate_hack(self, item, callback, *args):
  1680
+        # See http://stackoverflow.com/questions/5221326/submenu-item-does-not-call-function-with-working-solution
  1681
+        # Note that we can't just call the callback on button-press-event, as
  1682
+        # it might be blocking (see http://gpodder.org/bug/1778), so we run
  1683
+        # this in the GUI thread at a later point in time (util.idle_add).
  1684
+        # Also, we also have to connect to the activate signal, as this is the
  1685
+        # only signal that is fired when keyboard navigation is used.
  1686
+
  1687
+        # It can happen that both (button-release-event and activate) signals
  1688
+        # are fired, and we must avoid calling the callback twice. We do this
  1689
+        # using a semaphore and only acquiring (but never releasing) it, making
  1690
+        # sure that the util.idle_add() call below is only ever called once.
  1691
+        only_once = threading.Semaphore(1)
  1692
+
  1693
+        def handle_event(item, event=None):
  1694
+            if only_once.acquire(False):
  1695
+                util.idle_add(callback, *args)
  1696
+
  1697
+        item.connect('button-press-event', handle_event)
  1698
+        item.connect('activate', handle_event)
  1699
+
1678 1700
     def treeview_available_show_context_menu(self, treeview, event=None):
1679 1701
         model, paths = self.treeview_handle_context_menu_click(treeview, event)
1680 1702
         if not paths:
@@ -1732,9 +1754,8 @@ def treeview_available_show_context_menu(self, treeview, event=None):
1732 1754
                 submenus = {}
1733 1755
                 for label, callback in result:
1734 1756
                     key, sep, title = label.rpartition('/')
1735  
-                    item = gtk.MenuItem(title)
1736  
-                    item.connect('activate', lambda item, callback:
1737  
-                            callback(episodes), callback)
  1757
+                    item = gtk.ImageMenuItem(title)
  1758
+                    self._submenu_item_activate_hack(item, callback, episodes)
1738 1759
                     if key:
1739 1760
                         if key not in submenus:
1740 1761
                             sub_menu = self._add_sub_menu(menu, key)
@@ -1752,12 +1773,12 @@ def treeview_available_show_context_menu(self, treeview, event=None):
1752 1773
 
1753 1774
                 item = gtk.ImageMenuItem(_('Local folder'))
1754 1775
                 item.set_image(gtk.image_new_from_stock(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_MENU))
1755  
-                item.connect('button-press-event', lambda w, ee: self.save_episodes_as_file(episodes))
  1776
+                self._submenu_item_activate_hack(item, self.save_episodes_as_file, episodes)
1756 1777
                 share_menu.append(item)
1757 1778
                 if self.bluetooth_available:
1758 1779
                     item = gtk.ImageMenuItem(_('Bluetooth device'))
1759 1780
                     item.set_image(gtk.image_new_from_icon_name('bluetooth', gtk.ICON_SIZE_MENU))
1760  
-                    item.connect('button-press-event', lambda w, ee: self.copy_episodes_bluetooth(episodes))
  1781
+                    self._submenu_item_activate_hack(item, self.copy_episodes_bluetooth, episodes)
1761 1782
                     share_menu.append(item)
1762 1783
 
1763 1784
             menu.append(gtk.SeparatorMenuItem())

0 notes on commit a09b204

Please sign in to comment.
Something went wrong with that request. Please try again.