Copyright © 2008, 2009 Arndt Roger Schneider
The templates Gstripes and Goolbar have event handlers for synthetic events <<Activate>> and <<Deactivate>>. These events allow to render this dialog parts active or inactivate.
I would have used <Activate> and <Deactivate> for this, but under Tk 8.4 no <Activate> is generated under AQUA®. This is the reason for why I decided to chose synthetic events.
Example 6.35. Traversing a Window hierarchy
# Function : traverseActive
# Returns : A list of mapped child windows
# Parameters : toplevel - start window,
# excluded from list
# scope - a reference to a local
# variable handed down the traversion.
#
# Description : Build a list of all the visible
# windows and store them inside a list.
proc traverseActive { toplevel {scope {}} } {
if { {} != $scope } { upvar $scope wl
} else { set wl [list] }
foreach child [winfo children $toplevel] {
if [winfo ismapped $child] {
lappend wl $child
# Use a recursive call to retrieve
# all affected sub windows. append
# them to »wl«.
traverseActive $child wl
}
}
if { {} == $scope } { return $wl }
# otherwise, leave it alone ...
}Best practice: bind the synthetic events generation for <<Activate>> and <<Deactivate>> onto <FocusIn>, <FocusOut>.
Example 6.36. FocusIn
bind »MyToplevelClass« <FocusIn> {
foreach c [traverseActive %W] {
event generate $c <<Activate>>
}
}
Example 6.37. FocusOut
bind »MyToplevelClass« <FocusOut> {
foreach c [traverseActive %W] {
event generate $c <<Deactivate>>
}
}
The Example 6.36, “FocusIn” and Example 6.37, “FocusOut” should be bound to the window class and not the individual window.
The above code is bundled into a separate package: »traverso«. Use the »register« procedure to activate it for your applications.
Example 6.38. Using Focus and traverso
package require traverso
traverso::register »MyToplevelClass1« ...