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

Multiple FocusIn events

19 views
Skip to first unread message

Francois Vogel

unread,
Aug 6, 2005, 4:20:43 AM8/6/05
to
Hi,

I get multiple FocusIn events fired (Win XP) and I'm not sure I understand
why.

Launch a wish sessions, and type in:
bind . <FocusIn> {puts "FocusIn"}
text .t
pack .t

Click in the . toplevel, and you'll see that the event is fired twice. Why?

The following does not clarify this behaviour:
% bindtags .t
.t Text . all
% bind .t <FocusIn>
% bind Text <FocusIn>
% bind . <FocusIn>
puts "FocusIn"
% bind all <FocusIn>
%

If I don't pack a text widget in the . toplevel, I get the event fired once
only.

Any advice appreciated.
Francois

Schelte Bron

unread,
Aug 6, 2005, 8:10:20 AM8/6/05
to
Francois Vogel wrote:
> Launch a wish sessions, and type in:
> bind . <FocusIn> {puts "FocusIn"}
> text .t
> pack .t
>
> Click in the . toplevel, and you'll see that the event is fired
> twice. Why?
>
Things should become clearer when you change the bind command to:
bind . <FocusIn> {puts "FocusIn %W"}

This will show that you get a FocusIn event for . and .t. The
binding on . fires for .t too because . is listed in the bindtags
for .t:


bindtags .t
.t Text . all


Schelte
--
set Reply-To [string map {nospam schelte} $header(From)]

Francois Vogel

unread,
Aug 7, 2005, 3:38:27 PM8/7/05
to
> This will show that you get a FocusIn event for . and .t. The
> binding on . fires for .t too because . is listed in the bindtags
> for .t:

OK, understood.

Now, how can I make the binding fire only for . and not for .t?

I wouldn't like to change the bindtags list for .t. Actually many text
widget bindings that are useful in my application are actually bindings for
., therefore the existing bindtags list should be preserved.

Thanks,
Francois


Bryan Oakley

unread,
Aug 7, 2005, 5:14:52 PM8/7/05
to
Francois Vogel wrote:
>>This will show that you get a FocusIn event for . and .t. The
>>binding on . fires for .t too because . is listed in the bindtags
>>for .t:
>
>
> OK, understood.
>
> Now, how can I make the binding fire only for . and not for .t?
>

You must either a) accept the fact that a binding on "." will fire for
all children, and prepare for this by adding a small check to your
script or b) add a new bindtag that is unique to "." and attach your
bindings to that.

a) Accept that a binding on "." will fire for all children:

bind . <FocusIn> {doSomethingInteresting %W}
proc doSomethingInteresting {W} {
if {$W ne "."} return
<your code here>
}

b) add a new bindtag to "."

bindtags . [linsert [bindtags .] 0 "dot"]
bind dot <FocusIn> {doSomethingInteresting}
proc doSomethingInteresting {} {
<your code here>
}

Francois Vogel

unread,
Aug 8, 2005, 3:53:46 AM8/8/05
to
> a) Accept that a binding on "." will fire for all children:
>
> bind . <FocusIn> {doSomethingInteresting %W}
> proc doSomethingInteresting {W} {
> if {$W ne "."} return
> <your code here>
> }


OK, thanks, I used a somewhat different implementation of the same idea. I
accepted the multiple binding fire and arranged for not doing anything when
it was already running:

bind . <FocusIn> {doSomethingInteresting}
proc doSomethingInteresting {} {
global alreadyrunning
if {$alreadyrunning} {return}
set alreadyrunning 1
<your code here>
set alreadyrunning 0
}

But this is not as good as your solution: if the delay between binding fires
is larger than the delay required to process doSomethingInteresting, then it
will still be executed twice ;(

Thanks for your help.
Francois


Donald Arseneau

unread,
Aug 8, 2005, 6:04:09 PM8/8/05
to
Bryan Oakley <oak...@bardo.clearlight.com> writes:

> Francois Vogel wrote:
> > Now, how can I make the binding fire only for . and not for .t?
>

> bind . <FocusIn> {doSomethingInteresting %W}
> proc doSomethingInteresting {W} {
> if {$W ne "."} return
> <your code here>
> }

More generally,

if { $W ne [winfo toplevel $W] } return

--
Donald Arseneau as...@triumf.ca

Bryan Oakley

unread,
Aug 8, 2005, 6:10:41 PM8/8/05
to

<slaps forehead>

Yes, I make this same mistake constantly. You are correct; you provide a
good general solution.

0 new messages