From 94a66f0a8743bb748816f8e4d962953ee4d0b682 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Tue, 9 May 2017 21:14:22 +0800 Subject: [PATCH 1/6] bpo-15786: Fix autocomletetion box mouse behavior --- Lib/idlelib/autocomplete_w.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 3374c6e94510aa..1137c97b8b4db2 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -201,9 +201,11 @@ def show_window(self, comp_lists, index, complete, mode, userWantsWin): self._selection_changed() # bind events - self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, - self.hide_event) + self.hideaid = self.autocompletewindow.bind(HIDE_VIRTUAL_EVENT_NAME, + self.hide_event) + self.hidewid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event) for seq in HIDE_SEQUENCES: + self.autocompletewindow.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypress_event) @@ -241,8 +243,10 @@ def winconfig_event(self, event): acw.wm_geometry("+%d+%d" % (new_x, new_y)) def hide_event(self, event): + # This will be trigger when focus on widget or autocompletewindow if self.is_active(): - self.hide_window() + if self.widget == self.widget.focus_get() or not self.widget.focus_get(): + self.hide_window() def listselect_event(self, event): if self.is_active(): @@ -392,9 +396,12 @@ def hide_window(self): # unbind events for seq in HIDE_SEQUENCES: + self.autocompletewindow.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq) - self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid) - self.hideid = None + self.autocompletewindow.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideaid) + self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hidewid) + self.hideaid = None + self.hidewid = None for seq in KEYPRESS_SEQUENCES: self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq) self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid) From 1da0c6adbd31a920d1d2efdedc857204212420a6 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Wed, 10 May 2017 11:47:31 +0800 Subject: [PATCH 2/6] Fix MacOS double click autocomplete box will freeze The root cause is we destory autocompletewindow to fast, thus tk can't focusOn widget, we should re-focus on widget first, then destory autocompletewindow. --- Lib/idlelib/autocomplete_w.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 1137c97b8b4db2..709846ac3adc8c 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -415,6 +415,9 @@ def hide_window(self): self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid) self.winconfigid = None + # Re-focusOn frame.text (issue15786) + self.widget.focus_set() + # destroy widgets self.scrollbar.destroy() self.scrollbar = None From 83081cdc9b37f2e2b8f90471182b58e0021c376b Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Wed, 10 May 2017 11:55:08 +0800 Subject: [PATCH 3/6] Refactor comment issue number --- Lib/idlelib/autocomplete_w.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 709846ac3adc8c..28a4e0b5f3dd37 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -415,7 +415,7 @@ def hide_window(self): self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid) self.winconfigid = None - # Re-focusOn frame.text (issue15786) + # Re-focusOn frame.text (See issue #15786) self.widget.focus_set() # destroy widgets From b70825bf0de21f140931bffb02da448833b70e58 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Thu, 11 May 2017 15:43:21 +0800 Subject: [PATCH 4/6] Fix windows can't trigger double click event --- Lib/idlelib/autocomplete_w.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 28a4e0b5f3dd37..4e80469e8f273a 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -1,6 +1,8 @@ """ An auto-completion window for IDLE, used by the autocomplete extension """ +import platform + from tkinter import * from tkinter.ttk import Scrollbar @@ -242,6 +244,13 @@ def winconfig_event(self, event): new_y -= acw_height acw.wm_geometry("+%d+%d" % (new_x, new_y)) + if platform.system().startswith('Windows'): + # See issue 15786. When on windows platform, Tk will misbehaive + # to call winconfig_event multiple times, we need to prevent this, + # otherwise mouse button double click will not be able to used. + acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid) + self.winconfigid = None + def hide_event(self, event): # This will be trigger when focus on widget or autocompletewindow if self.is_active(): @@ -412,8 +421,9 @@ def hide_window(self): self.keyreleaseid = None self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid) self.listupdateid = None - self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid) - self.winconfigid = None + if self.winconfigid: + self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid) + self.winconfigid = None # Re-focusOn frame.text (See issue #15786) self.widget.focus_set() From 0d6782979cc768a72571a058de14ba2bd7b56ff8 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Thu, 11 May 2017 15:44:51 +0800 Subject: [PATCH 5/6] Reuse acw in show_window --- Lib/idlelib/autocomplete_w.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 4e80469e8f273a..6e3a705b780d13 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -203,11 +203,10 @@ def show_window(self, comp_lists, index, complete, mode, userWantsWin): self._selection_changed() # bind events - self.hideaid = self.autocompletewindow.bind(HIDE_VIRTUAL_EVENT_NAME, - self.hide_event) + self.hideaid = acw.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event) self.hidewid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event) for seq in HIDE_SEQUENCES: - self.autocompletewindow.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) + acw.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq) self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypress_event) From 1618206efda28072e46c88c90fa7c8a1cffc59e5 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Thu, 11 May 2017 15:46:36 +0800 Subject: [PATCH 6/6] Addressed terry suggestion --- Lib/idlelib/autocomplete_w.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 6e3a705b780d13..a0f581fd92e9a6 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -251,10 +251,11 @@ def winconfig_event(self, event): self.winconfigid = None def hide_event(self, event): - # This will be trigger when focus on widget or autocompletewindow - if self.is_active(): - if self.widget == self.widget.focus_get() or not self.widget.focus_get(): - self.hide_window() + # Hide autocomplete list if it exists and does not have focus + if (self.is_active() and + (self.widget == self.widget.focus_get() or + not self.widget.focus_get())): + self.hide_window() def listselect_event(self, event): if self.is_active():