classification
Title: Mouse wheel crashes program
Type: behavior Stage: test needed
Components: Tkinter Versions: Python 2.6
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: loewis Nosy List: ash101, corvus, garyrxx, georg.brandl, gpolo, johnfouhy, loewis, orthorim, sdati, terry.reedy
Priority: normal Keywords:

Created on 2003-11-02 00:37 by garyrxx, last changed 2009-08-03 17:14 by gpolo. This issue is now closed.

Messages (12)
msg18848 - (view) Author: Gary Richardson (garyrxx) Date: 2003-11-02 00:37
The following program (by Michael Peuser)  crashes as 
soon as the mouse wheel is moved. See my post to 
c.l.p. on Oct 29.

Gary Richardson

#-------------------------
from Tkinter import *
def _onMouseWheel(event):
    print event

root = Tk()
root.bind('<MouseWheel>',_onMouseWheel)
root.mainloop()
msg18849 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2003-11-02 18:37
Logged In: YES 
user_id=21627

What operating system are you using?
msg18850 - (view) Author: Gary Richardson (garyrxx) Date: 2003-11-03 02:42
Logged In: YES 
user_id=899035

I'm using Win98SE. 
msg18851 - (view) Author: Jon Ashley (ash101) Date: 2003-12-04 17:02
Logged In: YES 
user_id=923903

Happens for me too, on Win2K with python 2.3.2. The fault is
in TCL84.DLL at an offset of 1002a58c, if that means
anything to anyone.
msg18852 - (view) Author: John Fouhy (johnfouhy) Date: 2004-10-26 04:13
Logged In: YES 
user_id=1084032

I can reproduce this bug.  I am running Python 2.3.4 on
WinXP SP2.

tk84.dll is version 8.4.3; tcl84.dll is also 8.4.3.

The mousewheel works correctly with a Tkinter.Text object
with no additional bindings.
msg18853 - (view) Author: John Speno (corvus) Date: 2005-01-04 15:02
Logged In: YES 
user_id=2138

Me too. Python 2.3.4 with Tcl/Tk 8.4.9. Crash on Scroll Wheeling in WinXP 
SP 1. (users report it happening in SP 2 also).

I'll try to make this happen in pure Tcl/Tk rather than Tkinter too.
msg18854 - (view) Author: John Speno (corvus) Date: 2005-01-04 15:40
Logged In: YES 
user_id=2138

I wasn't able to reproduce this in pure Tcl/Tk (under Wish). No surprise 
there. In wish, I used this:

toplevel .top
bind .top <MouseWheel> {puts 'foo'}

And mouse wheeling in the Toplevel widget made a bunch of 'foo's appear in 
the wish console without crashing.

HTH.
msg18855 - (view) Author: Steve Davis (sdati) Date: 2005-02-08 02:40
Logged In: YES 
user_id=1214285

I have determined the root cause of this problem.  It actually does lie in 
Tk, but is only revealed by Python Tkinter because of the way Python 
deals with events.

From Tk source -- tkWinX.c:

case WM_MOUSEWHEEL:
...
event.xany.send_event = -1
...

This line causes Tk to call TkpGetString() when ExpandPercents() is 
called with '%A' (which is done by Python for ALL events, including 
<MouseWheel>).  This, in turn, causes segmentation fault because 
event.xkey.trans_chars and event.xkey.nbytes are not initialized.

So, the workaround from the Python side is pretty ugly, but I have 
tested it and verified that it works.  There is probably a better way, but 
this was the obvious solution to me, since I have never needed to look at 
the Tkinter interface before:

In Tkinter.py, define a new _subst_format and _subst_format_str:

    _subst_format_workaround = ('%#', '%b', '%f', '%h', '%k',
             '%s', '%t', '%w', '%x', '%y',
             '%D', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
    _subst_format_str_workaround = " ".join(_subst_format_workaround)

Note that '%A' entry in _subst_format is replaced with '%D' entry in 
_subst_format_workaround.

Now, in Misc._bind(),

if sequence == "<MouseWheel>":
    cmd = ('%sif {"[%s %s]" == "break"} break\n'
           %
           (add and '+' or '',
            funcid, self._subst_format_str_workaround))
else:
    cmd = ('%sif {"[%s %s]" == "break"} break\n'
           %
           (add and '+' or '',
            funcid, self._subst_format_str))

I am submitting this bug to Tcl/Tk maintainers to request that they fix 
(Project: Tk Toolkit Request ID 1118340), but in the meantime (and for 
all older versions of Tk), it seems like a workaround in the Tkinter code 
might be appropriate.
msg18856 - (view) Author: nikolaus heger (orthorim) Date: 2005-05-12 14:41
Logged In: YES 
user_id=933256

sdati, thanks for this workaround. it's awesome. i am now
happily mouse-wheeling :)

I did make a small improvement to it so it works for all
MouseWheel type events. Instead of 
if sequence == "<MouseWheel>":
i say
if type(sequence) == str and
sequence.__contains__("MouseWheel"):

This way, all permutations of mouse events are covered, e.g.
 "<Control-MouseWheel>"
msg18857 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2005-05-31 13:11
Logged In: YES 
user_id=1188172

Bumping, as it is still the same with 2.4 on my box.
msg84141 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-03-25 02:09
3.0.1, WinXP, with two 3.0 revisions:

from tkinter import *
def _onMouseWheel(event):
    print(event)

root = Tk()
root.bind('<MouseWheel>',_onMouseWheel)

In IDLE shell, nothing changes, wheel works normally.

In interpreter window, wheel continues to work normally.
After click on tk window, wheel generates
<tkinter.Event object at 0x00ACE970>
messages in interpreter window.

Unless someone can verify that there is a problem in 2.6.1, or in 3.0.1
on other hardware, we should close this.
msg91233 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2009-08-03 17:14
This is a tk issue, so the best way to fix this (if you don't want to
install something newer than Python 2.4 on Windows) is to install a
newer tcl/tk version.

Unfortunately the proposed workaround is way too specific, imagine if
other bindings had similar problems with different binding substitutions.

If we want to be safe, Tkinter should be passing only valid
substitutions for a given sequence but this is very awkward. But check
what the bind manual says ".. Some of the substitutions are only valid
for certain types of events; if they are used for other types of events
the value substituted is undefined.", note how it doesn't say ".. if
they are used for other types of events a segfault ensues".
History
Date User Action Args
2009-08-03 17:14:02gpolosetstatus: open -> closed
resolution: wont fix
messages: + msg91233
2009-04-26 22:21:40ajaksu2setstatus: pending -> open
nosy: + gpolo
2009-03-25 23:20:14loewissetstatus: open -> pending
2009-03-25 02:09:55terry.reedysetnosy: + terry.reedy
messages: + msg84141
2009-02-13 04:46:17ajaksu2setstage: test needed
type: behavior
versions: + Python 2.6, - Python 2.4
2003-11-02 00:37:18garyrxxcreate