Stacking Order

Stacking Order (Geometry Management)

Each Tk widget of a GUI application belongs to two hierarchies: one whose levels are ordered by the master/slave relationship, and another whose levels are ordered by the parent/child relationship.

Parent/Child Hierarchy and Stacking Order

A widget's place in the parent/child hierarchy can be determined from the widget's name. The levels of the hierarchy are separated by dots in the widget name. For example, a widget .w1 is the parent of the widgets .w1.a, .w1.b, .w1.anything

The winfo children command

  winfo children $widgetname

will return a list of the children of the widget $widgetname

The parent/child hierarchy is a convenient way to organise the naming of widgets; but it also determines the stacking order, which is discussed at the end of this page.

Master/Slave Hierarchy and Geometry Management

For more on Geometry Management, see

The master/slave hierarchy is defined by geometry management: if widget $A manages the geometry of widget $B, then $B is the slave of $A. Working out the hierarchy is a little complicated, because there is more than one geometry manager.

The winfo manager command

  winfo manager $B

returns the name of the geometry manager for $B - in plain Tcl/Tk the possible values are pack, grid, place, panedwindow, text and canvas. pack, grid, place and panedwindow are full-featured geometry managers; text and canvas are classes of widget that have a limited capability to manage the geometry of widgets that are embedded in them. Add-ons to Tcl/Tk may provide alternative geometry managers, or indeed alternative widgets with geometry-management capability.

If $A uses the packer to manage $B, then the command

  pack info $B

will return a list that begins

  -in $A

followed by the other parameters used by the packer to manage $B

The command

  pack slaves $A

will return a list of widgets, including $B, that are packed in $A

(insert note on canvas and text items)

Very often, the master/slave and parent/child hierarchies are the same: this is the case if an application has only one toplevel window ("."), and always uses the default master (the parent) in geometry management: for example

  pack .frame.text

does not specify a master widget, and so the widget's parent, .frame, is used as the master.

If the programmer requires a different master, this may be specified with the pack option -in, or (indirectly) with the pack options -before or -after.

The master/slave hierarchy is an essential part of geometry management, and is the major factor that determines the layout of the widgets in a GUI application.

Stacking Order - Rules

The parent/child hierarchy influences the widget layout in a more subtle way: the widget's place in the parent/child hierarchy influences its position in the stacking order of widgets.

The stacking order determines which widget is "on top of" which, and therefore which widget is visible when two or more widgets overlap.

In Tk, the stacking order of widgets in a toplevel window is determined by these rules:

  • children are always above their parents
  • if $B is above its sibling $C, then every descendant of $B is above every descendant of $C
  • the stacking order of siblings may be inspected using the command
  winfo children $widgetname
  • which returns a list of the children of the widget $widgetname, in stacking order with the lowest first (except that toplevel windows are not returned in stacking order).
  • the default stacking order of sibling widgets is the order in which the widgets were created, not the order in which they were packed (or otherwise geometry-managed)
  • the stacking order of siblings may be altered using the raise and lower commands

Problems with stacking order

  • Where you expect to see a widget, you may see only a grey rectangle. This happens if the widget is lower in the stacking order than its master.
  • A geometry manager may refuse to let a widget be the master of its parent or other ancestor, and will throw an error. It does this because children are always above their parents in the stacking order, and so it would be impossible to make the slave widget visible.

Problems with stacking order can usually be solved by

  • choosing the name of each widget to reflect its intended place in the stacking order (e.g. name a widget so that it is the child of its master)
  • creating sibling widgets in the intended stacking order, with the lowest first; or, if this is not possible, using the raise and lower commands to change the stacking order

KJN - I'm not sure why Tk manages stacking order this way. It seems wasteful and confusing to maintain two independent hierarchies, and can give rise to obscure bugs. Is there any situation in which the following rules would be inadequate?

  • the parent/child hierarchy is only a naming convention, and has no effect on stacking order or geometry management
  • the stacking order is determined by the master/slave hierarchy
  • a slave is always above its master
  • if $B and $C are slaves of the same master, and $B is above $C, then every slave of $B is above every slave of $C
  • the default stacking order of slaves of the same master is the order in which the widgets were packed (or otherwise geometry-managed)
  • the stacking order of slaves of the same master may be altered using the raise and lower commands

DKF: You are aware that parent/child also controls clipping?

KJN: but is that a feature or a bug? When trying to pack a widget inside a megawidget from a different branch of the parent/child tree, it seems to me that it is a bug - I can't find a way to configure the slave widget so it appropriately clipped (and is also above some parts of the megawidget, but below others). The workaround is to name the slave widget in the same branch of the parent/child tree as the megawidget itself. However, this does not allow you to unmap the slave and then map it into a different megawidget.

Are there any circumstances where control of clipping by parent/child is useful?

HaO: Yes, to have different clipping orders and focus orders (example on the page of tk_focusNext) ?

SeS (3rd Feb 2013)

I have stumbled upon this subject of stack ordering during early phases of the layout editor of tG² v1.06.01, as a preliminary solution provided only the "lower" command to layout objects. Finally, made some progress with beta release 02 of tG² v1.07.01:

The user is now able to change the creation/stacking order by simple drag/drop of layout objects inside the TreeBase viewer (herewith, the TreeBase viewer is not just a viewer anymore I guess). Unfortunately, stacking reordering can not be undone (Ctrl-z)...yet.

ABU (11 Nov 2014) I have a question:

Let's take a (complex) window made of several widgets like buttons, labels, text, frames,.. and nested frames ..

Is there a way to discover which widgets are "under" a given (X,Y) point ?

I can use the [winfo containing $X $Y] command to discover the name of the 'top' widget at (X,Y), but how can I discover which widget is under this top widget, .. and so on till the deepest widget ?

original version by KJN

See also: