gh-43699: Defer the drag cursor in tkinter.dnd until the pointer moves by serhiy-storchaka · Pull Request #152371 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
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
14 changes: 11 additions & 3 deletions Lib/test/test_tkinter/test_dnd.py
18 changes: 17 additions & 1 deletion Lib/tkinter/dnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ class DndHandler:

root = None

# The drag cursor is shown only once the pointer has moved this many
# pixels from the initial press, so that a plain click does not flash it.
threshold = 3

def __init__(self, source, event):
if event.num > 5:
return
Expand All @@ -134,11 +138,12 @@ def __init__(self, source, event):
self.target = None
self.initial_button = button = event.num
self.initial_widget = widget = event.widget
self.dragging = False
self.x_origin, self.y_origin = event.x_root, event.y_root
self.release_pattern = "<B%d-ButtonRelease-%d>" % (button, button)
self.save_cursor = widget['cursor'] or ""
widget.bind(self.release_pattern, self.on_release)
widget.bind("<Motion>", self.on_motion)
widget['cursor'] = "hand2"

def __del__(self):
root = self.root
Expand Down Expand Up @@ -175,6 +180,17 @@ def on_motion(self, event):
if new_target is not None:
new_target.dnd_enter(source, event)
self.target = new_target
self.update_cursor(x, y)

def update_cursor(self, x, y):
# Show the drag cursor only once the pointer has actually started
# moving past the threshold, so that a plain click does not flash it.
if not self.dragging:
if (abs(x - self.x_origin) <= self.threshold and
abs(y - self.y_origin) <= self.threshold):
return
self.dragging = True
self.initial_widget['cursor'] = "hand2"

def on_release(self, event):
self.finish(event, 1)
Expand Down
Loading