[util/popup] replace mainloop with custom loop

add a custom event loop for popups that closes the menu on mouse button
release events and - most importantly - propagates this event back to
any parent menu.

fixes #633
This commit is contained in:
tobi-wan-kenobi 2020-05-30 10:02:12 +02:00
parent b9a30ae235
commit 1c04068f89
2 changed files with 23 additions and 2 deletions

View file

@ -48,7 +48,7 @@ def build_menu(parent, current_directory, callback):
) )
else: else:
submenu = util.popup.menu(parent, leave=True) submenu = util.popup.menu(parent, leave=False)
build_menu( build_menu(
submenu, os.path.join(current_directory, entry.name), callback submenu, os.path.join(current_directory, entry.name), callback
) )
@ -88,6 +88,7 @@ class Module(core.module.Module):
"pass show -c {}".format(secret_name), "pass show -c {}".format(secret_name),
wait=False, wait=False,
env=env, env=env,
ignore_errors=True,
) )
self.__timer = threading.Timer(self.__duration, self.__reset) self.__timer = threading.Timer(self.__duration, self.__reset)
self.__timer.start() self.__timer.start()

View file

@ -15,6 +15,8 @@ class menu(object):
""" """
def __init__(self, parent=None, leave=True): def __init__(self, parent=None, leave=True):
self.running = True
self.parent = None
if not parent: if not parent:
self._root = tk.Tk() self._root = tk.Tk()
self._root.withdraw() self._root.withdraw()
@ -25,9 +27,12 @@ class menu(object):
self._root.withdraw() self._root.withdraw()
self._menu = tk.Menu(self._root, tearoff=0) self._menu = tk.Menu(self._root, tearoff=0)
self._menu.bind("<FocusOut>", self.__on_focus_out) self._menu.bind("<FocusOut>", self.__on_focus_out)
self.parent = parent
if leave: if leave:
self._menu.bind("<Leave>", self.__on_focus_out) self._menu.bind("<Leave>", self.__on_focus_out)
self._menu.bind("<ButtonRelease-1>", self.release)
"""Returns the root node of this menu """Returns the root node of this menu
:return: root node :return: root node
@ -51,6 +56,11 @@ class menu(object):
self._root.destroy() self._root.destroy()
callback() callback()
def release(self, event=None):
self.running=False
if self.parent:
self.parent.release(event)
"""Adds a cascading submenu to the current menu """Adds a cascading submenu to the current menu
:param menuitem: label to display for the submenu :param menuitem: label to display for the submenu
@ -88,7 +98,17 @@ class menu(object):
self._menu.tk_popup(event["x"] + offset_x, event["y"] + offset_y) self._menu.tk_popup(event["x"] + offset_x, event["y"] + offset_y)
finally: finally:
self._menu.grab_release() self._menu.grab_release()
self._root.mainloop()
while self.running == True:
try:
self._root.update_idletasks()
self._root.update()
except:
self.running = False
try:
self._root.destroy()
except:
pass
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4