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« ...