Skip to content

gh-96910: IDLE - make autocomplete winnconfig handler only trigger once #28332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 17 additions & 25 deletions Lib/idlelib/autocomplete_w.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ def __init__(self, widget, tags):
self.winconfigid = self.keyreleaseid = self.doubleclickid = None
# Flag set if last keypress was a tab
self.lastkey_was_tab = False
# Flag set to avoid recursive <Configure> callback invocations.
self.is_configuring = False

def _change_start(self, newstart):
min_len = min(len(self.start), len(newstart))
Expand Down Expand Up @@ -224,30 +222,36 @@ def show_window(self, comp_lists, index, complete, mode, userWantsWin):
self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE)
self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE,
self.listselect_event)
self.is_configuring = False
self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE,
self.doubleclick_event)

# Schedule self.winconfig_event to be called once the completion
# window is rendered, since we need its size to correctly position it.
self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
return None

def winconfig_event(self, event):
if self.is_configuring:
# Avoid running on recursive <Configure> callback invocations.
return

self.is_configuring = True
if not self.is_active():
return

# Since the <Configure> event may occur after the completion window is gone,
# catch potential TclError exceptions when accessing acw. See: bpo-41611.
acw = self.autocompletewindow

# Unbind this event handler, since it should only run once.
try:
acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
except TclError:
pass
self.winconfigid = None

# Since the <Configure> event may occur after the completion window is
# gone, catch potential TclError exceptions when accessing acw.
# See: bpo-41611.
try:
# Position the completion list window
text = self.widget
text.see(self.startindex)
x, y, cx, cy = text.bbox(self.startindex)
acw = self.autocompletewindow
if platform.system().startswith('Windows'):
if platform.system() == 'Windows':
# On Windows an update() call is needed for the completion
# list window to be created, so that we can fetch its width
# and height. However, this is not needed on other platforms
Expand All @@ -271,18 +275,6 @@ def winconfig_event(self, event):
except TclError:
pass

if platform.system().startswith('Windows'):
# See issue 15786. When on Windows platform, Tk will misbehave
# to call winconfig_event multiple times, we need to prevent this,
# otherwise mouse button double click will not be able to used.
try:
acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
except TclError:
pass
self.winconfigid = None

self.is_configuring = False

def _hide_event_check(self):
if not self.autocompletewindow:
return
Expand Down
Loading