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 64729ea..251a84d 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) | 
