Skip to content
Prev Previous commit
Next Next commit
Only set user_data for virtual events and detail for corresponding ev…
…ents.
  • Loading branch information
serhiy-storchaka committed Feb 24, 2026
commit e3e3cd02b24c495db7037f95e9c3ba66f7c00f1c
17 changes: 12 additions & 5 deletions Lib/test/test_tkinter/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ def test_focus(self):
self.assertEqual(e.x_root, '??')
self.assertEqual(e.y_root, '??')
self.assertEqual(e.delta, 0)
self.assertEqual(e.user_data, 'NotifyAncestor')
self.assertEqual(e.user_data, '??')
self.assertEqual(e.detail, 'NotifyAncestor')
self.assertEqual(repr(e), '<FocusIn event>')

Expand Down Expand Up @@ -746,10 +746,17 @@ def test_event_generate_enter(self):
self.assertEqual(e.x_root, 100 + f.winfo_rootx())
self.assertEqual(e.y_root, 50 + f.winfo_rooty())
self.assertEqual(e.delta, 0)
self.assertEqual(e.user_data, 'NotifyAncestor')
self.assertEqual(e.user_data, '??')
self.assertEqual(e.detail, 'NotifyAncestor')
self.assertEqual(repr(e), '<Enter event focus=False x=100 y=50>')

f.event_generate('<Enter>', x=100, y=50, detail='NotifyPointer')
self.assertEqual(len(events), 2, events)
e = events[1]
self.assertIs(e.type, tkinter.EventType.Enter)
self.assertEqual(e.user_data, '??')
self.assertEqual(e.detail, 'NotifyPointer')

def test_event_generate_button_press(self):
f = tkinter.Frame(self.root, width=150, height=100)
f.pack()
Expand Down Expand Up @@ -858,7 +865,7 @@ def test_event_generate_mouse_wheel(self):
self.assertEqual(e.detail, '??')
self.assertEqual(repr(e), '<MouseWheel event delta=-5 x=100 y=50>')

def test_generate_event_virtual_event(self):
def test_event_generate_virtual_event(self):
f = tkinter.Frame(self.root, width=150, height=100)
f.pack()
self.root.wait_visibility() # needed on Windows
Expand Down Expand Up @@ -891,7 +898,7 @@ def test_generate_event_virtual_event(self):
self.assertEqual(e.y_root, -1)
self.assertEqual(e.delta, 0)
self.assertEqual(e.user_data, '')
self.assertEqual(e.detail, '')
self.assertEqual(e.detail, '??')
self.assertEqual(repr(e),
f"<VirtualEvent event x=50 y=0>")

Expand All @@ -900,7 +907,7 @@ def test_generate_event_virtual_event(self):
e = events[1]
self.assertIs(e.type, tkinter.EventType.VirtualEvent)
self.assertEqual(e.user_data, 'spam')
self.assertEqual(e.detail, 'spam')
self.assertEqual(e.detail, '??')


class BindTest(AbstractTkTest, unittest.TestCase):
Expand Down
18 changes: 11 additions & 7 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,10 @@ class Event:
type - type of the event as a number
widget - widget in which the event occurred
delta - delta of wheel movement (MouseWheel)
detail - certain fixed strings (see tcl/tk documentation)
detail - certain fixed strings (see Tcl/Tk documentation)
(Enter, Leave, FocusIn, FocusOut, ConfigureRequest)
user_data - data string which was passed to event_generate or empty string
(VirtualEvent)
user_data - data string which was passed to event_generate() or empty
string (VirtualEvent)
"""

def __repr__(self):
Expand Down Expand Up @@ -1542,7 +1542,7 @@ def bind(self, sequence=None, func=None, add=None):
<Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
An event pattern can also be a virtual event of the form
<<AString>> where AString can be arbitrary. This
event can be generated by event_generate.
event can be generated by event_generate().
If events are concatenated they must appear shortly
after each other.

Expand Down Expand Up @@ -1754,7 +1754,7 @@ def getint_event(s):
# serial field: valid for all events
# number of button: ButtonPress and ButtonRelease events only
# detail: for Enter, Leave, FocusIn, FocusOut and ConfigureRequest
# events certain fixed strings (see tcl/tk documentation)
# events certain fixed strings (see Tcl/Tk documentation)
# user_data: data string from a virtual event or an empty string
# height field: Configure, ConfigureRequest, Create,
# ResizeRequest, and Expose events only
Expand All @@ -1769,8 +1769,12 @@ def getint_event(s):
# KeyRelease, and Motion events
e.serial = getint(nsign)
e.num = getint_event(b)
e.user_data = d
e.detail = d
if T == EventType.VirtualEvent:
e.user_data = d
e.detail = '??'
else:
e.user_data = '??'
e.detail = d
try: e.focus = getboolean(f)
except TclError: pass
e.height = getint_event(h)
Expand Down