diff options
Diffstat (limited to 'Lib/idlelib/MultiCall.py')
-rw-r--r-- | Lib/idlelib/MultiCall.py | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/Lib/idlelib/MultiCall.py b/Lib/idlelib/MultiCall.py index 64729eab8c..251a84d083 100644 --- a/Lib/idlelib/MultiCall.py +++ b/Lib/idlelib/MultiCall.py @@ -32,7 +32,6 @@ Each function will be called at most once for each event. import sys import re import tkinter -from idlelib import macosxSupport # the event type constants, which define the meaning of mc_type MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; @@ -45,7 +44,7 @@ MC_SHIFT = 1<<0; MC_CONTROL = 1<<2; MC_ALT = 1<<3; MC_META = 1<<5 MC_OPTION = 1<<6; MC_COMMAND = 1<<7 # define the list of modifiers, to be used in complex event types. -if macosxSupport.runningAsOSXApp(): +if sys.platform == "darwin": _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",)) _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND) else: @@ -57,6 +56,12 @@ _modifier_names = dict([(name, number) for number in range(len(_modifiers)) for name in _modifiers[number]]) +# In 3.4, if no shell window is ever open, the underlying Tk widget is +# destroyed before .__del__ methods here are called. The following +# is used to selectively ignore shutdown exceptions to avoid +# 'Exception ignored' messages. See http://bugs.python.org/issue20167 +APPLICATION_GONE = "application has been destroyed" + # A binder is a class which binds functions to one type of event. It has two # methods: bind and unbind, which get a function and a parsed sequence, as # returned by _parse_sequence(). There are two types of binders: @@ -98,7 +103,12 @@ class _SimpleBinder: def __del__(self): if self.handlerid: - self.widget.unbind(self.widgetinst, self.sequence, self.handlerid) + try: + self.widget.unbind(self.widgetinst, self.sequence, + self.handlerid) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # An int in range(1 << len(_modifiers)) represents a combination of modifiers # (if the least significent bit is on, _modifiers[0] is on, and so on). @@ -227,7 +237,11 @@ class _ComplexBinder: def __del__(self): for seq, id in self.handlerids: - self.widget.unbind(self.widgetinst, seq, id) + try: + self.widget.unbind(self.widgetinst, seq, id) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # define the list of event types to be handled by MultiEvent. the order is # compatible with the definition of event type constants. @@ -390,15 +404,21 @@ def MultiCallCreator(widget): func, triplets = self.__eventinfo[virtual] if func: for triplet in triplets: - self.__binders[triplet[1]].unbind(triplet, func) - + try: + self.__binders[triplet[1]].unbind(triplet, func) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise _multicall_dict[widget] = MultiCall return MultiCall -if __name__ == "__main__": - # Test + +def _multi_call(parent): root = tkinter.Tk() + root.title("Test MultiCall") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) text = MultiCallCreator(tkinter.Text)(root) text.pack() def bindseq(seq, n=[0]): @@ -414,8 +434,13 @@ if __name__ == "__main__": bindseq("<Alt-Control-Key-a>") bindseq("<Key-b>") bindseq("<Control-Button-1>") + bindseq("<Button-2>") bindseq("<Alt-Button-1>") bindseq("<FocusOut>") bindseq("<Enter>") bindseq("<Leave>") root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_multi_call) |