GdkWindow

GdkWindow is a wrapper around Xlib's Window object. (It was discussed briefly in the section called Realizing, Mapping, and Showing in the chapter called GTK+ Basics.) A GdkWindow represents a region on the screen. It can be shown or hidden (called mapping and unmapping the window in Xlib). You can capture events received by a GdkWindow, draw graphics inside it, and move or resize it. GdkWindows are arranged in a tree structure; that is, each window can have child windows. Child windows are positioned relative to their parent window, and move when the parent moves. Child windows don't draw outside of their parent's bounds (i.e. they are clipped by the parent window).

The tree of GdkWindows is not specific to each application; there is a global tree of windows controlled by the X server and the window manager. The root window has no parent; all windows derive from it. All or part of it is visible as your desktop background. Each window can be owned by a different UNIX process; some windows will be created by the window manager, some will come from user applications.

GdkWindow and GtkWindow are very different things; GtkWindow is a GTK+ widget used to represent toplevel windows (toplevel windows are the highest application-controlled windows in the window hierarchy). Window managers typically create decorations for toplevel windows; decorations include title bars, close buttons, and the like.

It's important to understand that an X window is primarily an object on the X server. X clients receive a unique integer ID for each window, and refer to windows by ID. Thus, all window operations take place on the server; all functions that deal with X windows go across the network.

GdkWindow is a wrapper around the integer ID returned by X. It does keep local copies of some information (such as the window's dimensions), so some GDK operations are more efficient than the corresponding Xlib operations. Still, GdkWindow is essentially a handle for a server-side object. Many GDK objects are similar; fonts, pixmaps, cursors, and so on are also handles for server-side objects.

GdkWindow and GtkWidget

Many GtkWidget subclasses have an associated GdkWindow. In theory, GTK+ applications could create only toplevel windows, and have all widgets draw into them. However, it would make little sense to do so; GdkWindow allows the X Window System to automatically handle many details. For example, events received from GDK are marked with the window they occurred in; GTK+ can rapidly determine which widget each event corresponds to.

There are some widgets with no associated GdkWindow; these are called "no window" widgets, an allusion to the GTK_NO_WINDOW flag that marks them. (You can test this flag with the macro GTK_WIDGET_NO_WINDOW().) Widgets without a window render themselves into their parent container's GdkWindow. Windowless widgets are relatively small and lightweight; GtkLabel is the most common example. Because events are always received on a GdkWindow, windowless widgets do not receive events. (The GtkEventBox container can be used if you need to capture events on a windowless widget.)

GdkWindow Attributes

gdk_window_new() (shown in Figure 1) allows you to specify all of a window's attributes when you create it; many of them can be changed later as well. To specify a block of attributes, you pass in a GdkWindowAttr object; its contents will give you an idea what attributes a GdkWindow can have:


typedef struct _GdkWindowAttr GdkWindowAttr;

struct _GdkWindowAttr
{
  gchar *title;
  gint event_mask;
  gint16 x, y;
  gint16 width;
  gint16 height;
  GdkWindowClass wclass;
  GdkVisual *visual;
  GdkColormap *colormap;
  GdkWindowType window_type;
  GdkCursor *cursor;
  gchar *wmclass_name;
  gchar *wmclass_class;
  gboolean override_redirect;
};

Because some of the fields in GdkWindowAttr are optional, gdk_window_new() is used with an attributes_mask to specify which optional fields contain valid information (bit flags are available representing each optional field). GDK will only examine the optional fields given in the mask, so you can let the default values remain for fields you aren't interested in. Table 1 summarizes them briefly; fields with no attributes_mask flag are required and have no default value.

gdk_window_new() is typically used in widget implementations to create the widget's GdkWindow; you will rarely use it in any other context. gdk_window_destroy() destroys a window when you are done with it. Windows are also reference counted; be sure to read the section called GDK Resource Management for more details on this.

#include <gdk/gdk.h>

GdkWindow* gdk_window_new(GdkWindow* parent, GdkWindowAttr* attributes, gint attributes_mask);

void gdk_window_destroy(GdkWindow* window);

Figure 1. GdkWindow

A GdkWindow's title is only really important for toplevel windows; most window managers will place it in the titlebar. Usually you should not specify it when creating a GdkWindow, however; instead, let your widget's users call gtk_window_set_title().

The window's event mask determines which events will be received on this window; the section called Events goes into more detail about events.

The X and Y coordinates for a window are specified in pixels, relative to the parent window's origin. The origin of each window is its top left ("northwest") corner. Notice that a 16-bit signed integer is used; X windows have a maximum size of 32768 pixels. Negative values are allowed, but the window will be clipped by its parent window (only the portion inside the parent window will be visible).

The width and height of a window are given in pixels, and are also 16-bit signed integers.

A window's GdkWindowClass can have one of two values:

A visual describes the color-handling characteristics of a display; a colormap contains the colors you can use to draw. the section called Visuals and Colormaps gives details on visuals and colormaps.

Windows can be one of several different types, specified by the GdkWindowType enumeration:

Only GDK_WINDOW_TOPLEVEL, GDK_WINDOW_CHILD, GDK_WINDOW_TEMP, and GDK_WINDOW_DIALOG are valid for gdk_window_new(). Library users may not create a GDK_WINDOW_ROOT. Pixmaps (GDK_WINDOW_PIXMAP) are created with gdk_pixmap_new(). Foreign windows (GDK_WINDOW_FOREIGN) are X windows created outside of GDK and wrapped using gdk_window_foreign_new() (declared in gdk/gdkx.h, since you will only need this function if you are using Xlib directly).

The cursor field specifies the mouse pointer (cursor) to use in this window; see the section called The Mouse Pointer for information about cursors.

The "class hint" is described in the section called Setting Window Class Hints in the chapter called The Main Window: GnomeApp. When writing widgets, you will not usually set the class hint. It is only relevant for toplevel windows; GTK+ provides gtk_window_set_wmclass() so application authors can set it to something sensible.

The last field in GdkWindowAttr determines whether the window is "override redirect." Normally, window managers intercept all requests to show, hide, move, or resize a toplevel window. They can then redirect or cancel these requests, to force windows to behave according to the window manager's layout policy. You can override this behavior by setting override_redirect to TRUE. Since window managers can not move windows with this flag set, they will normally not put a title bar or other decorations on them. Note that all GDK_WINDOW_TEMP windows use TRUE for this field; recall that GDK_WINDOW_TEMP is often used for popup menus, which are not controlled by the window manager.

Typically you should not change the override_redirect field; the default is almost always right, if you specify the correct GdkWindowType. However, there are some exceptions; the Gnome panel application sets this field, for example.

Table 1. GdkWindowAttr Fields

Field Type Flag Default Value Purpose
title gchar* GDK_WA_TITLE Program Name The window's title
event_mask gint none none Events to receive on this window
x gint16 GDK_WA_X 0 X position relative to parent window
y gint16 GDK_WA_Y 0 Y position relative to parent window
width gint16 none none Width of window
height gint16 none none Height of window
wclass GdkWindowClass none none GDK_INPUT_ONLY vs. GDK_INPUT_OUTPUT
visual GdkVisual* GDK_WA_VISUAL X's "default visual" Visual for this window
colormap GdkColormap* GDK_WA_COLORMAP X's "default colormap" [PD]footnote! Colormap for this window
window_type GdkWindowType none none Window type (see text)
cursor GdkCursor* GDK_WA_CURSOR Parent window's cursor Mouse pointer for this window
wmclass_name gchar* GDK_WA_WMCLASS none (doesn't set hint) Set the "name" part of the class hint (see text)
wmclass_class gchar* GDK_WA_WMCLASS none (doesn't set hint) Set the "class" part of the class hint (see text)
override_redirect gboolean GDK_WA_NOREDIR FALSE [PD] footnote! Make the window "override redirect" (see text)