Fully understanding GTK+ requires some minimal
understanding of the X Window System. This book assumes
you have a user-level understanding---you know what an X
server is, that X is network transparent, what a window
manager does, and so on. A few more details are needed to
write programs, however.
One detail is particularly important: the X Window System
maintains a tree of windows.
"Window" in this sense refers to an X window, not a GtkWindow---GtkWindow is a GTK+-specific concept, a
widget that corresponds to an application's toplevel X
window. An X window is not the user-visible concept
"window" represented by
GtkWindow; rather, it's an abstraction used by the X
server to partition the screen. The "background"
displayed by your X server is the
root window; the root window has no parent.
Application windows are typically near-children of the
root window; most window managers create a child of the
root window to hold the window's titlebar and other
decorations, and place the application window inside.
Window managers have total control over application
windows---they can reposition them, reparent them, and
iconify them at will. Application windows can in turn
contain subwindows, which are controlled by the
application. Note that GTK+ uses the GDK library, rather
than using X directly; in GDK, there is a thin X window
wrapper called GdkWindow.
Don't confuse GdkWindow
and GtkWindow.
An X window, or a
GdkWindow, gives the X server hints about the
structure of the graphics being displayed. Since X is
network transparent, this helps reduce network traffic.
The X server knows how to show windows on the screen;
hide them; move them around (keeping children in position
relative to their parents); capture events such as mouse
movements on a per-window basis; and so on. A GdkWindow is also the
fundamental unit for drawing graphics---you can't draw to
"the screen" as a whole, you must draw on a GdkWindow.
Most GTK+ widgets have a corresponding GdkWindow. There are exceptions, such
as GtkLabel; these are
referred to as "no window widgets," and are relatively
lightweight. Widgets with no associated GdkWindow draw into their parent's
GdkWindow. Some
operations, such as capturing events, require a GdkWindow; thus they are
impossible on no-window widgets.
Widgets pass through a number of states related to their
GdkWindow:
-
A widget is said to be
realized if its corresponding GdkWindow has been created.
Widgets are realized via
gtk_widget_realize(), and unrealized via gtk_widget_unrealize(). Since
an X window must have a parent, if a widget is
realized its parent must also be.
-
A widget is mapped if gdk_window_show() has been
called on its
GdkWindow. This means the server has been
asked to display the window on the screen; obviously
the GdkWindow must
exist, implying that the widget is realized.
-
A widget is visible if it
will automatically be mapped when its parent is
mapped. This means that
gtk_widget_show() has been called on the widget.
A widget can be rendered invisible by calling gtk_widget_hide(); this will
either unschedule the pending map, or unmap the
widget (hide its
GdkWindow). Since toplevel widgets have no
parent, they are mapped as soon as they are
shown.
In typical user code, you only need to call gtk_widget_show(); this implies realizing
and mapping the widget as soon as its parent is realized
and mapped. It's important to understand that gtk_widget_show() has no immediate
effect, it merely schedules the widget to be shown. This
means you don't have to worry about showing widgets in
any particular order; it also means that you can't
immediately access the
GdkWindow of a widget. Sometimes you need to
access the GdkWindow; in
those cases you'll want to manually call gtk_widget_realize() to create it. gtk_widget_realize() will also
realize a widget's parents, if appropriate. It's uncommon
to need gtk_widget_realize();
if you find that you do, perhaps you are approaching the
problem incorrectly.
Destroying a widget automatically reverses the entire
sequence of events, recursively unrealizing the widget's
children and the widget itself.
Figure 23
summarizes the functions discussed in this section.
Figure 24 summarizes
macros for querying the states discussed in this section.