mirror of
https://github.com/python/cpython.git
synced 2025-09-30 20:31:52 +00:00
Patch by Louie Lu.
(cherry picked from commit 778b484145
)
This commit is contained in:
parent
c2a506e40e
commit
3280579450
1 changed files with 51 additions and 9 deletions
|
@ -1,6 +1,8 @@
|
||||||
"""
|
"""
|
||||||
An auto-completion window for IDLE, used by the autocomplete extension
|
An auto-completion window for IDLE, used by the autocomplete extension
|
||||||
"""
|
"""
|
||||||
|
import platform
|
||||||
|
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
from tkinter.ttk import Scrollbar
|
from tkinter.ttk import Scrollbar
|
||||||
|
|
||||||
|
@ -8,7 +10,8 @@ from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
|
||||||
from idlelib.multicall import MC_SHIFT
|
from idlelib.multicall import MC_SHIFT
|
||||||
|
|
||||||
HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
|
HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
|
||||||
HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
|
HIDE_FOCUS_OUT_SEQUENCE = "<FocusOut>"
|
||||||
|
HIDE_SEQUENCES = (HIDE_FOCUS_OUT_SEQUENCE, "<ButtonPress>")
|
||||||
KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
|
KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
|
||||||
# We need to bind event beyond <Key> so that the function will be called
|
# We need to bind event beyond <Key> so that the function will be called
|
||||||
# before the default specific IDLE function
|
# before the default specific IDLE function
|
||||||
|
@ -201,10 +204,12 @@ class AutoCompleteWindow:
|
||||||
self._selection_changed()
|
self._selection_changed()
|
||||||
|
|
||||||
# bind events
|
# bind events
|
||||||
self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME,
|
self.hideaid = acw.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event)
|
||||||
self.hide_event)
|
self.hidewid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event)
|
||||||
|
acw.event_add(HIDE_VIRTUAL_EVENT_NAME, HIDE_FOCUS_OUT_SEQUENCE)
|
||||||
for seq in HIDE_SEQUENCES:
|
for seq in HIDE_SEQUENCES:
|
||||||
self.widget.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.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME,
|
||||||
self.keypress_event)
|
self.keypress_event)
|
||||||
for seq in KEYPRESS_SEQUENCES:
|
for seq in KEYPRESS_SEQUENCES:
|
||||||
|
@ -240,10 +245,38 @@ class AutoCompleteWindow:
|
||||||
new_y -= acw_height
|
new_y -= acw_height
|
||||||
acw.wm_geometry("+%d+%d" % (new_x, new_y))
|
acw.wm_geometry("+%d+%d" % (new_x, new_y))
|
||||||
|
|
||||||
def hide_event(self, event):
|
if platform.system().startswith('Windows'):
|
||||||
if self.is_active():
|
# 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_check(self):
|
||||||
|
if not self.autocompletewindow:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not self.autocompletewindow.focus_get():
|
||||||
|
self.hide_window()
|
||||||
|
except KeyError:
|
||||||
|
# See issue 734176, when user click on menu, acw.focus_get()
|
||||||
|
# will get KeyError.
|
||||||
self.hide_window()
|
self.hide_window()
|
||||||
|
|
||||||
|
def hide_event(self, event):
|
||||||
|
# Hide autocomplete list if it exists and does not have focus or
|
||||||
|
# mouse click on widget / text area.
|
||||||
|
if self.is_active():
|
||||||
|
if event.type == EventType.FocusOut:
|
||||||
|
# On windows platform, it will need to delay the check for
|
||||||
|
# acw.focus_get() when click on acw, otherwise it will return
|
||||||
|
# None and close the window
|
||||||
|
self.widget.after(1, self._hide_event_check)
|
||||||
|
elif event.type == EventType.ButtonPress:
|
||||||
|
# ButtonPress event only bind to self.widget
|
||||||
|
self.hide_window()
|
||||||
|
|
||||||
def listselect_event(self, event):
|
def listselect_event(self, event):
|
||||||
if self.is_active():
|
if self.is_active():
|
||||||
self.userwantswindow = True
|
self.userwantswindow = True
|
||||||
|
@ -391,10 +424,15 @@ class AutoCompleteWindow:
|
||||||
return
|
return
|
||||||
|
|
||||||
# unbind events
|
# unbind events
|
||||||
|
self.autocompletewindow.event_delete(HIDE_VIRTUAL_EVENT_NAME,
|
||||||
|
HIDE_FOCUS_OUT_SEQUENCE)
|
||||||
for seq in HIDE_SEQUENCES:
|
for seq in HIDE_SEQUENCES:
|
||||||
self.widget.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:
|
for seq in KEYPRESS_SEQUENCES:
|
||||||
self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
|
self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
|
||||||
self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
|
self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
|
||||||
|
@ -405,8 +443,12 @@ class AutoCompleteWindow:
|
||||||
self.keyreleaseid = None
|
self.keyreleaseid = None
|
||||||
self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
|
self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
|
||||||
self.listupdateid = None
|
self.listupdateid = None
|
||||||
self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
|
if self.winconfigid:
|
||||||
self.winconfigid = None
|
self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
|
||||||
|
self.winconfigid = None
|
||||||
|
|
||||||
|
# Re-focusOn frame.text (See issue #15786)
|
||||||
|
self.widget.focus_set()
|
||||||
|
|
||||||
# destroy widgets
|
# destroy widgets
|
||||||
self.scrollbar.destroy()
|
self.scrollbar.destroy()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue