Realizing, Mapping, and Showing
From: developer.gnome.org/doc/GGAD/z57.html
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.
#include <gtk/gtkwidget.h> |
void gtk_widget_realize
(GtkWidget* widget);
void gtk_widget_unrealize
(GtkWidget* widget);
void gtk_widget_map
(GtkWidget* widget);
void gtk_widget_unmap
(GtkWidget* widget);
void gtk_widget_show
(GtkWidget* widget);
void gtk_widget_hide
(GtkWidget* widget);
Figure 23. Showing/Realizing Widgets
Figure 24 summarizes macros for querying the states discussed in this section.
#include <gtk/gtkwidget.h> |
GTK_WIDGET_NO_WINDOW
(widget);
GTK_WIDGET_REALIZED
(widget);
GTK_WIDGET_MAPPED
(widget);
GTK_WIDGET_VISIBLE
(widget);
Figure 24. Widget Predicates