[BUG] in win32 tcltk/ruby FocusIn/FocusOut events

Hello,

I have found a bug in win32 tcltk/ruby.
Following code demonstrates the problem:
----cut_here-------------------
require ‘tk’

root=TkRoot.new
e1=TkEntry.new root, ‘width’=>10
e2=TkEntry.new root, ‘width’=>10
e1.pack ‘side’=>'left’
e2.pack ‘side’=>‘left’

e1.bind ‘FocusIn’, proc { puts ‘focus in’}
e1.bind ‘FocusOut’, proc { puts ‘focus out’}

Tk.mainloop

···

After events trigger (by focusing entry boxes), ruby crashes:
----cut_here-------------------
focus in
C:/PROG/RUBY/lib/ruby/1.6/tk.rb:620: [BUG] Segmentation fault
ruby 1.6.7 (2002-03-01) [i586-mswin32]

abnormal program termination

If you change ‘FocusIn’ to ‘Enter’ and ‘FocusOut’ to ‘Leave’,
no bug occurs and code works fine (however with different
functionality, since original intent was to highlight TkEntry
that has keyboard focus, this does not solve my problem).

Affected versions
(both tested are from the Pragmatic Programmers distribution):

  • Ruby Installer for Windows, Ruby Version 1.6.7, Installer Version 4,
    tcl/tk readme header shows:
    Tcl/Tk 8.3 for Windows, Binary Distribution
    RCS: @(#) $Id: README.binary,v 1.19.2.1 2000/07/27 01:39:23 hobbs Exp $

  • And older version 1.6.4-3 of ruby installer.

By win32 I mean the tested windows version which was:
Windows 95 OSR2 Czech.

Unaffected:

  • linux version: ruby 1.6.7 (2002-03-19) [i386-linux] / tcltk 8.3

BUG does not seem to be in tcl/tk itself since following tcl script works
under win32 correctly:
----cut_here-------------------
entry .e1 -width 10
entry .e2 -width 10
label .l1 -text "initial"
pack .e1 -side left
pack .e2 -side left
pack .l1 -side left
bind .e1 {.l1 configure -text “focus in”}
bind .e1 {.l1 configure -text “focus out”}

Note: output to label was due to unavailable stdout.

I have also tested some older version of Python 1.5.2
under win32 with tcl/tk 8.0
----cut_here-------------------
from Tkinter import *
def myprint(x):
print x
root=Tk()
e1=Entry(root, width=10)
e2=Entry(root, width=10)
e1.pack(side=‘left’)
e2.pack(side=‘left’)
e1.bind(’’, lambda e: myprint(“focus in”))
e1.bind(’’, lambda e: myprint(“focus out”))
mainloop()

No problem ocurrs.

Ruby ran with RUBY_TCL_DLL and RUBY_TCL_DLL pointing to tcl/tk
distributed with the python (tcl/tk 8.0) does not make any difference,
the bug still happen.

I don’t have windows compiler to experiment more deeply.

BUG seems to be triggered from tcltklib to which is the
last call before crash when stepping source with ruby -rdebug.

Best regards,

Jakub Travnik
jabber://jtra@jabber.com

P.S.: searching ruby-talk archive show that this bug has been noticed
before but with no attempt to correct it. But since python can do it
and ruby tcl/tk is modeled after python’s so it should be fixable.

Jakub Travnik wrote:

Hello,

I have found a bug in win32 tcltk/ruby.
Following code demonstrates the problem:
----cut_here-------------------
require ‘tk’

root=TkRoot.new
e1=TkEntry.new root, ‘width’=>10
e2=TkEntry.new root, ‘width’=>10
e1.pack ‘side’=>‘left’
e2.pack ‘side’=>‘left’

e1.bind ‘FocusIn’, proc { puts ‘focus in’}
e1.bind ‘FocusOut’, proc { puts ‘focus out’}

Tk.mainloop

After events trigger (by focusing entry boxes), ruby crashes:
----cut_here-------------------
focus in
C:/PROG/RUBY/lib/ruby/1.6/tk.rb:620: [BUG] Segmentation fault
ruby 1.6.7 (2002-03-01) [i586-mswin32]

abnormal program termination

If you change ‘FocusIn’ to ‘Enter’ and ‘FocusOut’ to ‘Leave’,
no bug occurs and code works fine (however with different
functionality, since original intent was to highlight TkEntry
that has keyboard focus, this does not solve my problem).

Affected versions
(both tested are from the Pragmatic Programmers distribution):

  • Ruby Installer for Windows, Ruby Version 1.6.7, Installer Version 4,
    tcl/tk readme header shows:
    Tcl/Tk 8.3 for Windows, Binary Distribution
    RCS: @(#) $Id: README.binary,v 1.19.2.1 2000/07/27 01:39:23 hobbs Exp $

  • And older version 1.6.4-3 of ruby installer.

By win32 I mean the tested windows version which was:
Windows 95 OSR2 Czech.

Unaffected:

  • linux version: ruby 1.6.7 (2002-03-19) [i386-linux] / tcltk 8.3

BUG does not seem to be in tcl/tk itself since following tcl script works
under win32 correctly:
----cut_here-------------------
entry .e1 -width 10
entry .e2 -width 10
label .l1 -text “initial”
pack .e1 -side left
pack .e2 -side left
pack .l1 -side left
bind .e1 {.l1 configure -text “focus in”}
bind .e1 {.l1 configure -text “focus out”}

Note: output to label was due to unavailable stdout.

I have also tested some older version of Python 1.5.2
under win32 with tcl/tk 8.0
----cut_here-------------------
from Tkinter import *
def myprint(x):
print x
root=Tk()
e1=Entry(root, width=10)
e2=Entry(root, width=10)
e1.pack(side=‘left’)
e2.pack(side=‘left’)
e1.bind(‘’, lambda e: myprint(“focus in”))
e1.bind(‘’, lambda e: myprint(“focus out”))
mainloop()

No problem ocurrs.

Ruby ran with RUBY_TCL_DLL and RUBY_TCL_DLL pointing to tcl/tk
distributed with the python (tcl/tk 8.0) does not make any difference,
the bug still happen.

I don’t have windows compiler to experiment more deeply.

BUG seems to be triggered from tcltklib to which is the
last call before crash when stepping source with ruby -rdebug.

Best regards,

Jakub Travnik
jabber://jtra@jabber.com

P.S.: searching ruby-talk archive show that this bug has been noticed
before but with no attempt to correct it. But since python can do it
and ruby tcl/tk is modeled after python’s so it should be fixable.

Hello,

I have solved the problem. Bug is in the Tk itself, see following
tcltk code:
----cut_here-------------------
entry .e1 -width 10
entry .e2 -width 10
label .l1 -text “initial”
pack .e1 -side left
pack .e2 -side left
pack .l1 -side left
bind .e1 {.l1 configure -text %S}
bind .e1 {.l1 configure -text %S}

···

This will crash in Tk_GetHWND called from TkpPrintWindowId
called from case “%S” in ExpandPercents when FocusIn/FocusOut event
happen.

Since ruby does use %S in every bind where no explicit
percent string is supplied, bug happens. Python does not use this
so bug does not happen with it.

Quick fix for ruby is to bind with other percent string, in this
case, empty is sufficient.
----cut_here-------------------
require ‘tk’

root=TkRoot.new
e1=TkEntry.new root, ‘width’=>10
e2=TkEntry.new root, ‘width’=>10
e1.pack ‘side’=>‘left’
e2.pack ‘side’=>‘left’

e1.bind ‘FocusIn’, proc { puts ‘focus in’}, “” # <— EMPTY STRING HERE
e1.bind ‘FocusOut’, proc { puts ‘focus out’}, “” # <— EMPTY STRING HERE

Tk.mainloop

Long term fix is to remove %S from tk.rb file depending on event, or
fix tcl/tk windows version to behave in correct way for this situation.

Best regards,

Jakub Travnik,
jabber://jtra@jabber.com

Jakub Travnik wrote:

Jakub Travnik wrote:

P.S.: searching ruby-talk archive show that this bug has been noticed
before but with no attempt to correct it. But since python can do it
and ruby tcl/tk is modeled after python’s so it should be fixable.

Hello,

I have solved the problem. Bug is in the Tk itself, see following
tcltk code:
----cut_here-------------------
entry .e1 -width 10
entry .e2 -width 10
label .l1 -text “initial”
pack .e1 -side left
pack .e2 -side left
pack .l1 -side left
bind .e1 {.l1 configure -text %S}
bind .e1 {.l1 configure -text %S}

This will crash in Tk_GetHWND called from TkpPrintWindowId
called from case “%S” in ExpandPercents when FocusIn/FocusOut event
happen.

Long term fix is to remove %S from tk.rb file depending on event, or
fix tcl/tk windows version to behave in correct way for this situation.

Have you filed a bug report at sourceforge.net?
Tk Toolkit download | SourceForge.net

I can confirm the crash with tcl/tk 8.4.0 from cvs. Windows 2000.

Michael Schlenker

callstack dump:
Tk_GetHWND(unsigned long 3) line 147 + 3 bytes
TkpPrintWindowId(char * 0x0012f800, unsigned long 3) line 174 + 15 bytes
ExpandPercents(TkWindow * 0x00a23cc8, const char * 0x00a1f06c, XEvent *
0x00a7f798, unsigned long 0, Tcl_DString * 0x0012faa4) line 2576 + 19 bytes
Tk_BindEvent(Tk_BindingTable
* 0x008c4448, XEvent * 0x00a7f798,
Tk_Window
* 0x00a23cc8, int 4, void * * 0x0012fbc0) line 1670 + 40 bytes
TkBindEventProc(TkWindow * 0x00a23cc8, XEvent * 0x00a7f798) line 288 +
31 bytes
Tk_HandleEvent(XEvent * 0x00a7f798) line 1017 + 13 bytes
WindowEventProc(Tcl_Event * 0x00a7f790, int -3) line 1399 + 12 bytes
Tcl_ServiceEvent(int -3) line 622 + 11 bytes
Tcl_DoOneEvent(int -3) line 861 + 9 bytes
Tk_MainLoop() line 1457 + 13 bytes
Tk_MainEx(int 1, char * * 0x008626c8, int (Tcl_Interp ) 0x00401005
Tcl_AppInit, Tcl_Interp * 0x00864790) line 285
WinMain(HINSTANCE
* 0x00400000, HINSTANCE
_ * 0x00000000, char *
0x0013285d, int 10) line 140 + 26 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 77e7d326()

.
.
.

I have solved the problem. Bug is in the Tk itself, see following
tcltk code:
----cut_here-------------------
entry .e1 -width 10
entry .e2 -width 10
label .l1 -text “initial”
pack .e1 -side left
pack .e2 -side left
pack .l1 -side left
bind .e1 {.l1 configure -text %S}
bind .e1 {.l1 configure -text %S}

		.
		.
		.

Me, too. That is, when I run this minimal script, and begin
to tab in and out of the entries, using any of the first few
WinNT wish versions I had at hand, they all tossed a “Dr.
Watson” back. 'Anyone in a position to investigate this soon?

···

In article 3D85DD92.80508@volny.cz, Jakub Travnik jtra@volny.cz wrote:

Cameron Laird Cameron@Lairds.com
Business: http://www.Phaseit.net
Personal: Home page for Cameron Laird