Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Bug Tk 8.0.3] Events passed down to incorrect windows

3 views
Skip to first unread message

j...@mrc-lmb.cam.ac.uk

unread,
Jul 1, 1999, 3:00:00 AM7/1/99
to

Tk 8.0.3 Bug: Generated by Scriptics' bug entry form at
http://www.scriptics.com/support/bugForm.html
Responses to this post are encouraged.
------

Submitted by: James Bonfield
OperatingSystem: Windows 95
OperatingSystemVersion: original version (not OSR2)
Extensions: Tix
CustomShell: No patches.
Synopsis: Events passed down to incorrect windows

ReproducibleScript:
# Highlights a problem in bug in tk on windows.
#
# 1. Bring up the main window and then press A.
# 2. Make sure that the file dialogue covers the wish root window
# 3. Double click on a file in the file dialogue
#
# Tk then reports (assuming interactive wish) "B1 event at x,y". Why
does
# this event get propagated down to this window?

#tkinit

wm geometry . 500x500
label .l -textvariable .l.Var
pack .l -side top
bind . <1> {puts "B1 event at %x,%y"}
bind . <KeyPress-a> {
set .l.Var [tk_getOpenFile]
}

ObservedBehavior:
By double clicking to select a file from a MS Windows file dialogue (it
works fine on Unix), the tk_getOpenFile returns the filename as
expected. However a button-1 event is passed down to whatever window was
underneath the now-closed file dialogue.

In some of our applications this can cause problems, although generally
it's just an annoyance.

DesiredBehavior:
No B1 event in the root window of this demo.

Jeffrey Hobbs

unread,
Jul 1, 1999, 3:00:00 AM7/1/99
to j...@mrc-lmb.cam.ac.uk
j...@mrc-lmb.cam.ac.uk wrote:
> Submitted by: James Bonfield
> OperatingSystem: Windows 95
> Synopsis: Events passed down to incorrect windows
>
> ReproducibleScript:
> # Highlights a problem in bug in tk on windows.
> #
> # 1. Bring up the main window and then press A.
> # 2. Make sure that the file dialogue covers the wish root window
> # 3. Double click on a file in the file dialogue
> #
> # Tk then reports (assuming interactive wish) "B1 event at x,y". Why
> does
> # this event get propagated down to this window?
>
> #tkinit
>
> wm geometry . 500x500
> label .l -textvariable .l.Var
> pack .l -side top
> bind . <1> {puts "B1 event at %x,%y"}
> bind . <KeyPress-a> {
> set .l.Var [tk_getOpenFile]
> }
>
> ObservedBehavior:
> By double clicking to select a file from a MS Windows file dialogue (it
> works fine on Unix), the tk_getOpenFile returns the filename as
> expected. However a button-1 event is passed down to whatever window was
> underneath the now-closed file dialogue.

OK, this one is not *really* a bug, but an odd quirk to be taken into
account when using Windows dialogs. You should refine the above button
event to trigger separately for ButtonPress-1 and ButtonRelease-1. You
will find that only the Release is getting triggered (<1> will trigger
for either). What is happening is that the Windows dialog doesn't wait
for 2 full clicks, rather just one and a half. The second you press the
button down for the second time within the acceptable double-click
interval, the Window dialog returns the file - WITHOUT needing the
release on the second button click. To drag out the example, hold the
button down on the second click. You will find that you are now over
your . window, and it will receive ONLY the release event. If you
weren't over ., then whatever other window you are over gets it.

Thus, it is not a propagation problem, but rather a problem that the
Windows file dialog only absorbs 1.5 button clicks, and the window
below it gets the last .5 (same goes in Netscape). Hopefully that
clarifies the "problem", although it doesn't give a solution.

You might try using ButtonPress-1 for the falsely triggered binding
if it is OK, or a dual binding, where Press says it is OK to trigger
on the Release (with a dialog over, you won't get the Press).

** Jeffrey Hobbs jeff.hobbs @SPAM acm.org **
** I'm really just a Tcl-bot My opinions are MY opinions **

Jeffrey.Hobbs.vcf

James Bonfield

unread,
Jul 1, 1999, 3:00:00 AM7/1/99
to
In article <377B5CEE...@icn.siemens.de> Jeffrey Hobbs <Jeffre...@icn.siemens.de> writes:
>OK, this one is not *really* a bug, but an odd quirk to be taken into
>account when using Windows dialogs. You should refine the above button
>event to trigger separately for ButtonPress-1 and ButtonRelease-1. You
>will find that only the Release is getting triggered (<1> will trigger
>for either). What is happening is that the Windows dialog doesn't wait
>for 2 full clicks, rather just one and a half. The second you press the
>button down for the second time within the acceptable double-click
>interval, the Window dialog returns the file - WITHOUT needing the
>release on the second button click.

[...]

>You might try using ButtonPress-1 for the falsely triggered binding
>if it is OK, or a dual binding, where Press says it is OK to trigger
>on the Release (with a dialog over, you won't get the Press).

But this is hardly a solution. Consider that the ButtonRelease-1
binding could be triggering on anything underneath the windows
dialogue. This goes for standard Tk buttons, where the command is
invoked on the button release instead of the button press. (I haven't
tested this, but I suspect the tk buttons manage to escape this
problem by remembering where the button down even occurred.)

In practise, there's just too many things that would need changing (in
our Unix-developed code anyway). Is there a clever way of absorbing
these rogue events into another window somewhere? The Windows
operation does seem more than a little bizarre. Why would you _want_
buttonrelease events occuring in psuedo random places!?

I'm wondering if defining ButtonRelease-1 event to do nothing by
default (using the 'all' tag so that it'd be overridden on widgets
that need it) would have drastic side effects... (it doesn't appear to
on first glances)

James
--
James Bonfield (j...@mrc-lmb.cam.ac.uk) Tel: 01223 402499 Fax: 01223 213556
Medical Research Council - Laboratory of Molecular Biology,
Hills Road, Cambridge, CB2 2QH, England.
Also see Staden Package WWW site at http://www.mrc-lmb.cam.ac.uk/pubseq/

Jeffrey Hobbs

unread,
Jul 1, 1999, 3:00:00 AM7/1/99
to James Bonfield
James Bonfield wrote:
> In practise, there's just too many things that would need changing (in
> our Unix-developed code anyway). Is there a clever way of absorbing
> these rogue events into another window somewhere? The Windows
> operation does seem more than a little bizarre. Why would you _want_
> buttonrelease events occuring in psuedo random places!?

I don't really think you would. In fact, I would label it as buggy
behavior, or extremely bad GUI design choice on behalf of the MS
dialog. Of course, saying that to them will probably end up in some
black hole...

> I'm wondering if defining ButtonRelease-1 event to do nothing by
> default (using the 'all' tag so that it'd be overridden on widgets
> that need it) would have drastic side effects... (it doesn't appear to

I think the last might work for *most* apps without problems, given
the bindtags hierarchy and event specificity.

Jeffrey.Hobbs.vcf

lvi...@cas.org

unread,
Jul 1, 1999, 3:00:00 AM7/1/99
to

According to Jeffrey Hobbs <Jeffre...@icn.siemens.de>:
:OK, this one is not *really* a bug, but an odd quirk to be taken into

:account when using Windows dialogs. You should refine the above button

Jeff - is this a quirk in Tk, or a quirk in MS Windows?

--
<URL: mailto:lvi...@cas.org> Quote: Saving the world before bedtime.
<*> O- <URL: http://www.purl.org/NET/lvirden/>
Unless explicitly stated to the contrary, nothing in this posting
should be construed as representing my employer's opinions.

Rolf Schroedter

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to
Jeffrey Hobbs wrote:
>
> OK, this one is not *really* a bug, but an odd quirk to be taken into
> account when using Windows dialogs. You should refine the above button
> event to trigger separately for ButtonPress-1 and ButtonRelease-1. You
> will find that only the Release is getting triggered (<1> will trigger
> for either). What is happening is that the Windows dialog doesn't wait

For me with both Tk8.05 and Tk8.11 and on Win95
the underlying widget (toplevel frame .)
receives *BOTH* events ButtonPress AND ButtonRelease.

bind . <ButtonPress-1> {puts stderr "%W (%x %y) Button pressed"}
bind . <ButtonRelease-1> {puts stderr "%W (%x %y) Button released"}

tk_getOpenFile ;# select a file by doubleclick over the main toplevel
'.'

stderr displays:
. (20 150) Button pressed
. (20 150) Button released


> ...
> You might try using ButtonPress-1 for the falsely triggered binding
> if it is OK, or a dual binding, where Press says it is OK to trigger
> on the Release (with a dialog over, you won't get the Press).

---------------------------------------------------------------------
German Aerospace Center Rolf Schroedter
Inst. of Planetary Exploration Tel/Fax: +49 (30) 67055-416/384
Rudower Chaussee 5, D-12489 Berlin Internet: Rolf.Sc...@dlr.de

Jeffrey Hobbs

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to lvi...@cas.org
lvi...@cas.org wrote:
> According to Jeffrey Hobbs <Jeffre...@icn.siemens.de>:
> :OK, this one is not *really* a bug, but an odd quirk to be taken into

> :account when using Windows dialogs. You should refine the above button
>
> Jeff - is this a quirk in Tk, or a quirk in MS Windows?

As I further specified in another post, I believe it to be a quirk (bug)
in MS Windows, as the file dialog behaves the same in Netscape as it
does for Tk. This means, for Windows, Tk users have to worry about <1>
bindings relating to dialogs.

Of course, this comes to another question. Should then <1> trigger
for the Release on Windows (or even Unix) at all, or only Press?

Jeffrey.Hobbs.vcf

Rolf Schroedter

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to
Jeffrey Hobbs wrote:
>
> lvi...@cas.org wrote:
> > According to Jeffrey Hobbs <Jeffre...@icn.siemens.de>:
> > :OK, this one is not *really* a bug, but an odd quirk to be taken into
> > :account when using Windows dialogs. You should refine the above button
> >
> > Jeff - is this a quirk in Tk, or a quirk in MS Windows?
>
> As I further specified in another post, I believe it to be a quirk (bug)
> in MS Windows, as the file dialog behaves the same in Netscape as it
> does for Tk. This means, for Windows, Tk users have to worry about <1>
> bindings relating to dialogs.

I am not sure, whether this is a Win32 or Tk quirks

I tried to call the analog Win32 function directly from C
(via TK-extension tkFoo.dll):

#################################################################
static int getOpenFileProc( ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj * CONST objv[] )
{
OPENFILENAME ofn;
memset( &ofn, 0, sizeof(ofn) );
ofn.lStructSize = sizeof(ofn);
GetOpenFileName( &ofn );
return TCL_OK;
}
int __declspec(dllexport) Tkfoo_Init(Tcl_Interp *interp)
{
Tcl_CreateObjCommand( interp, "foo_getOpenFile", getOpenFileProc, \
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL );
return TCL_OK;
}
#################################################################

When I call this function from wish80, I have the same bahaviour as
tk_getOpenFile, *BOTH* 2nd events ButtonPress and ButtonReleased
are propagated to the underlying TK-widget.

% load tkFoo.dll
% bind . <ButtonPress-1> {puts stderr "%W (%x %y) Button pressed"}
% bind . <ButtonRelease-1> {puts stderr "%W (%x %y) Button released"}
% foo_getOpenFile
. (55 36) Button pressed
. (55 36) Button released

This would argument for a Win32-bug.

On the other hand, when I am doubleclicking in the OpenFile-Box
over other windows (Netscape, TextPad and -surprise- also M$-Programs)
they to not receive the 2nd Press+Release.

Or do these programs know about a Win32-quirks and have a workaround ?

Jeffrey Hobbs

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to Rolf Schroedter
Rolf Schroedter wrote:

> Jeffrey Hobbs wrote:
> > OK, this one is not *really* a bug, but an odd quirk to be taken into
> > account when using Windows dialogs. You should refine the above button
> > event to trigger separately for ButtonPress-1 and ButtonRelease-1. You
> > will find that only the Release is getting triggered (<1> will trigger
> > for either). What is happening is that the Windows dialog doesn't wait
>
> For me with both Tk8.05 and Tk8.11 and on Win95
> the underlying widget (toplevel frame .)
> receives *BOTH* events ButtonPress AND ButtonRelease.
>
> bind . <ButtonPress-1> {puts stderr "%W (%x %y) Button pressed"}
> bind . <ButtonRelease-1> {puts stderr "%W (%x %y) Button released"}

You are correct, after doing this again, I get both as well (perhaps
I should have started from a clean interpreter last time). However,
I also see that this does the same to Netscape. The test is a little
harder, and you have to be quick (to see what is going on).

For example, do a message reply for a news message. Click into one of
the To: header area lines. Do an attach file. The dialog should pop
up over the text area (which didn't have the selection). When double
clicking on a file, my text area appears to get focus very shortly,
and then it is moved to the attach window above, being what Netscape
wanted. Therefore I'm not sure that this doesn't affect other programs
as well...

Jeffrey.Hobbs.vcf

Rolf Schroedter

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to
Jeffrey Hobbs wrote:

>
> Rolf Schroedter wrote:
> > For me with both Tk8.05 and Tk8.11 and on Win95
> > the underlying widget (toplevel frame .)
> > receives *BOTH* events ButtonPress AND ButtonRelease.
> >
> > bind . <ButtonPress-1> {puts stderr "%W (%x %y) Button pressed"}
> > bind . <ButtonRelease-1> {puts stderr "%W (%x %y) Button released"}
>
> You are correct, after doing this again, I get both as well (perhaps
> I should have started from a clean interpreter last time). However,
> I also see that this does the same to Netscape. The test is a little
> harder, and you have to be quick (to see what is going on).
>
> For example, do a message reply for a news message. Click into one of
> the To: header area lines. Do an attach file. The dialog should pop
> up over the text area (which didn't have the selection). When double
> clicking on a file, my text area appears to get focus very shortly,
> and then it is moved to the attach window above, being what Netscape
> wanted. Therefore I'm not sure that this doesn't affect other programs
> as well...

I could ot reproduce the decribed behaviour with my Netscape4.5
running on a Pentium-166MMX under Win95.
Which Netscape do you use, maybe netscape now works around this quirk.

But if we assume that other programs do a workaround, it is unclear,
why e.g. Netcape does not suffer from the getOpenFile dialog
*CALLED FROM TK* ???

BTW, now I had a case, where I got only the Button-Release in my
Tk-Widget.
This seems to happen when the mouse is moved quickly just after/during
doubleclick in getOpenFile.

Regards,
Rolf.

Rolf Schroedter

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to
Could this be a workaround ?
It's a quick hack, comments are welcome.

Rolf.

####################################################################################
# Test protection of the Win32 fileselection-error
# Problem:
# After double-click in tk_getOpenFile Win32 eats only
# the 1st ButtonPress & ButtonRelease
# The 2nd ButtonPress & ButtonRelease stay in the event queue
# and will be propagated to the underlying Tk-Widget.
#
namespace eval ::fserr {

variable REMOVE_BUTTON 0 ;# 1: remove next <Button-1> event

namespace export protect

rename tk_getOpenFile ::fserr::getOpenFile
rename tk_getSaveFile ::fserr::getSaveFile

# 'eat' one Button-1 event
#
proc ::fserr::check {flag args} {
variable REMOVE_BUTTON
if { $REMOVE_BUTTON } {
set REMOVE_BUTTON $flag
return -code break ;# eat button-press/release
}
}

# setup FSERR to remove the ALREADY PENDING <Button-1> event
# This protection is 'sharp' only for 1 msec
#
proc ::fserr::catch_button {} {
variable REMOVE_BUTTON
set REMOVE_BUTTON 1
after 1 set ::fserr::REMOVE-BUTTON 0
}

# protect a window and all its children from tk_getXxxxFile bug
#
proc ::fserr::protect {win} {
bindtags $win [linsert [bindtags $win] 0 FSERR]
foreach child [winfo children $win] {
::fserr::protect $child
}
}

# Define a new bindtag FSERR
#
bind FSERR <ButtonPress-1> {::fserr::check 1 %W %x %y}
bind FSERR <ButtonRelease-1> {::fserr::check 0 %W %x %y}

} ;# end-of-namespace

proc tk_getOpenFile {args} {
set code [catch {uplevel ::fserr::getOpenFile $args} result]
::fserr::catch_button
return -code $code $result
}
proc tk_getSaveFile {args} {
set code [catch {uplevel ::fserr::getSaveFile $args} result]
::fserr::catch_button
return -code $code $result
}

catch {console show}

button .b1 -text PRESS-1 -width 50 -height 4 -command {puts stderr
"OOOPS-1"}
button .b2 -text PRESS-2 -width 50 -height 4 -command {puts stderr
"OOOPS-1"}
pack .b1 .b2

toplevel .t
button .t.b -text PRESS-T -width 50 -height 4 -command {puts stderr
"OOOPS-T"}
pack .t.b

### now try:
# tk_getOpenFile

### or try
# ::fserr::protect .
# tk_getOpenFile

####################################################################################

Bryan Oakley

unread,
Jul 2, 1999, 3:00:00 AM7/2/99
to
Jeffrey Hobbs wrote:
> Thus, it is not a propagation problem, but rather a problem that the
> Windows file dialog only absorbs 1.5 button clicks, and the window
> below it gets the last .5 (same goes in Netscape). Hopefully that
> clarifies the "problem", although it doesn't give a solution.

Perhaps the solution is to add a temporary bindtag on front of the
bindtags list for the toplevel that is the parent of the dialog (most
often ".", I suspect). Before displaying the dialog do grab on that
toplevel. Display the dialog. Once the dialog is dismissed, do an update
to flush the event queue. All buttonpress events should be intercepted
by the window with the grab (and the special bindtag). Process them (ie:
throw them away), release the grab, remove the bindtag, and continue.

I'm not sure about the grab part -- perhaps one can sneak the grab in
after the dialog is dismissed, but before calling update idletasks.

I haven't tried it, but it sorta makes sense. Not sure if it would
really work in practice.


--
Bryan Oakley mailto:oak...@channelpoint.com
ChannelPoint, Inc. http://purl.oclc.org/net/oakley

Education is full of oversimplified lies which can be
refined into the truth later.

Donal K. Fellows

unread,
Jul 5, 1999, 3:00:00 AM7/5/99
to
In article <377CD7BE...@channelpoint.com>,

Bryan Oakley <oak...@channelpoint.com> wrote:
> I'm not sure about the grab part -- perhaps one can sneak the grab in
> after the dialog is dismissed, but before calling update idletasks.
>
> I haven't tried it, but it sorta makes sense. Not sure if it would
> really work in practice.

If you were to just put the grab on a label (or something else with no
bindings), do an update to drain the queue, and drop the grab, then
that should work. Watch out with grabs though - you can snarl an
application (or even a whole session) up hard with them if you are not
careful.

I've got some code somewhere that does this sort of thing. Perhaps I
should look it up and put it on the Wiki...

Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- The small advantage of not having California being part of my country would
be overweighed by having California as a heavily-armed rabid weasel on our
borders. -- David Parsons <o r c @ p e l l . p o r t l a n d . o r . u s>

0 new messages