Chapter 4. Window Attributes

The window attributes control a window's background and border pattern or color, the events that should be queued for it, and so on. This chapter describes how to set and get window attributes and provides a detailed description of each attribute. Everyone should read this chapter.

Now that you know the basic X concepts and you have seen the code for an X application, we can go back and start to describe various aspects of Xlib in full detail. This chapter describes the window attributes thoroughly. The window attributes were introduced in “Window Characteristics” in Chapter 2 and described in more detail in “Window Attributes” in Chapter 2 You should read those sections before proceeding.

The setting of window attributes becomes necessary when you use XCreateWindow() instead of the simpler XCreateSimpleWindow(). However, it is not essential that you set any window attributes other than the window background and border. Therefore, this chapter is mainly about optional features that you may find useful.

You will continue to find this chapter useful as a reference even when you are an experienced X programmer. A useful quick reference to the window attributes is also provided inside the back cover of Volume Two.

Setting Window Attributes

Window attributes can be set while creating a window with XCreateWindow() or afterward with a call to XChangeWindowAttributes(). When creating a window with XCreateSimpleWindow(), most of the attributes are inherited from the parent. There are also several routines for changing individual window attributes, including the event_mask, background and border.

The procedure for setting the attributes is the same with XCreateWindow() or XChangeWindowAttributes(). You set the members of an XSetWindowAttributes structure to the desired values, create a mask indicating which members you have set, and call the routine to create the window or change the attributes.

The Window Attribute Structures

There are actually two structures associated with window attributes. XWindowAttributes is a read-only structure that contains all the attributes, while XSetWindowAttributes is a structure that contains only those attributes that a program is allowed to set. We will not show you XWindowAttributes until “Information from the XWindowAttributes Structure” since it is used in programming only for getting the values of the window attributes.

Example 4-1 shows the structure that is used to set the window attributes.

Example 4-1. The XSetWindowAttributes structure

typedef struct _XSetWindowAttributes {
   Pixmap background_pixmap;      /* Pixmap, None, or ParentRelative */
   long background_pixel;      /* Background pixel value */
   Pixmap border_pixmap;      /* Pixmap, None, or CopyFromParent */
   long border_pixel;      /* Border pixel value */
   int bit_gravity;      /* One of the bit gravity symbols */
   int win_gravity;      /* One of the window gravity symbols */
   int backing_store;      /* NotUseful, WhenMapped, or Always */
   long backing_bitplanes;      /* Planes to be preserved, if possible */
   long backing_pixel;      /* Value to use in restoring planes */
   Bool save_under;      /* Should bits under window be saved */
   long event_mask;      /* Events that should be queued */
   long do_not_propagate_mask;   /* Events that shouldn't propagate */
   Bool override_redirect;      /* Override redirected configuration
          * requests */
   Colormap colormap;      /* Colormap associated with window */
   Cursor cursor;      /* Cursor to be displayed or None */
} XSetWindowAttributes;


To set the window attributes, you need to set the elements of the XSetWindowAttributes structure to the desired values and then set a valuemask argument that represents which members are to be changed in the server's internal structure. A symbol specifying each member to be changed is combined with the bitwise OR operator (|). These symbols are shown in Table 4-1. They begin with the letters CW (“Create Window” or “Change Window”) because the routines they are used in have those capital letters in their names.

Table 4-1. Window Attribute Mask Symbols

Member

Flag

Bit

background_pixmap

CWBackPixmap

0

background_pixel

CWBackPixel

1

border_pixmap

CWBorderPixmap

2

border_pixel

CWBorderPixel

3

bit_gravity

CWBitGravity

4

win_gravity

CWWinGravity

5

backing_store

CWBackingStore

6

backing_planes

CWBackingPlanes

7

backing_pixel

CWBackingPixel

8

override_redirect

CWOverrideRedirect

9

save_under

CWSaveUnder

10

event_mask

CWEventMask

11

do_not_propagate_mask

CWDontPropagate

12

colormap

CWColormap

13

cursor

CWCursor

14

For example, if you want to set the initial values of the background and border pixel values, you would follow the procedure shown in Example 4-2.

Example 4-2. Setting window attributes while creating a window

Display *display;
Window parent, window;
int x, y;
unsigned int width, height, border_width;
int depth;
int screen_num;
Visual *visual;
unsigned int class;
XSetWindowAttributes setwinattr;
unsigned long valuemask;
/* (Must open display) */
screen_num = DefaultScreen(display);
valuemask = CWBackPixel | CWBorderPixel;
setwinattr.background_pixel = WhitePixel(display, screen_num);
setwinattr.border_pixel = BlackPixel(display, screen_num);
window = XCreateWindow(display, parent, x, y, width, height,
   border_width, depth, class, visual, valuemask, &setwinattr);

If the window already exists, you can change those same attributes with the procedure shown in Example 4-3.

Example 4-3. Changing window attributes of existing window

Display *display;
Window window;
XSetWindowAttributes setwinattr;
unsigned long valuemask;
/* (Must open display, create window) */
valuemask = CWBackPixel | CWBorderPixel;
setwinattr.background_pixel = WhitePixel(display, screen_num);
setwinattr.border_pixel = BlackPixel(display, screen_num);
XChangeWindowAttributes(display, window, valuemask, &setwinattr);

You can also use separate calls to XSetWindowBackground() and XSetWindowBorder() to set these particular attributes. These and a few other attributes have routines for setting them individually. (These routines are referred to as convenience routines. They are provided for the attributes that most often need to be set without modifying any other attributes.) Table 4-2 lists the attributes that can be set individually and the routines that set them. But it is important to realize that each of these routines would generate a separate protocol request to the server, so if more than one attribute is to be set, it is more efficient to use the procedures shown above in Examples 4-2 and 4-3.

Table 4-2. Attributes that can be Set Individually

Attribute

Routine for Setting It

background_pixmap

XSetWindowBackgroundPixmap()

background_pixel

XSetWindowBackground()

border_pixmap

XSetWindowBorderPixmap()

border_pixel

XSetWindowBorder()

event_mask

XSelectInput()

colormap

XSetWindowColormap()

cursor

XDefineCursor() or XUndefineCursor()

“Settable Attributes” describes all of the attributes and the routines for setting them.

Settable Attributes

The sections that follow describe the options and default values for each member of the XSetWindowAttributes structure. The attributes control a wide variety of ways for a window to act. They can be grouped loosely to help you understand when you might want to set each attribute.

One group of attributes controls the appearance of a window. These are background_pixel, background_pixmap, border_pixel, border_ pixmap, colormap, and cursor. Most clients will set the border, background, and cursor but use the default colormap.

A second group is provided to allow clients to improve their redrawing performance under certain conditions. These are backing_pixel, backing_planes, backing_store, bit_gravity, and save_under. These attributes do not affect the appearance or operation of a client. It is advisable to consider bit_gravity when designing a client, but the code for using these attributes can be added after a client's functionality is complete.

The event_mask and do_not_propagate_mask attributes control the selection and propagation of events. These attributes are described briefly in this chapter but also in much more detail in Chapter 8, “Events”

The win_gravity attribute provides a means for relocating a window automatically when its parent is resized. Applications can take advantage of this feature to simplify the code that positions their subwindows when they are resized.

The override_redirect attribute controls whether requests to map or reconfigure the window can be intercepted by the window manager. override_redirect is meant to be set for the most temporary types of windows such as pop-up menus. In practice, this attribute only affects the top-level windows of an application (all children of the root window).

As described in Chapter 2, there are two window classes: InputOutput and InputOnly. The class of a window is specified in the call to XCreateWindow(), or is InputOutput if the window is created with XCreateSimpleWindow().

InputOutput windows have all of the attributes described in the sections below. InputOnly windows have only the following subset of attributes:

  • win_gravity

  • event_mask

  • do_not_propagate_mask

  • override_redirect

  • cursor

Any attempt to set attributes other than these five on an InputOnly window will cause an X protocol error (BadMatch).

The Window Background

The background of a window is the drawing surface on which other graphics are drawn. It may be a solid color, or it may be patterned with a pixmap. This choice is mostly an aesthetic decision for the programmer. However, users expect to be able to specify the background color on the command line or in the resource database. Therefore, if a pixmap is used, the code for creating the pixmap should use two colors specified by the user (see “Creating Bitmaps, Pixmaps, Tiles, and Stipples” in Chapter 6 for information on creating pixmaps).

The two attributes that control the background are background_pixmap and background_pixel, set by XSetWindowBackgroundPixmap() and XSetWindowBackground(), respectively.

These two attributes are not independent since they affect the same pixels. Either attribute can take precedence over the other, the winner being the one that is set last. If both are set in the same call to XCreateWindow() or XChangeWindowAttributes(), the background_pixel value is used.

The background of exposed areas of windows is automatically repainted by the server, regardless of whether the application selects Expose events.

However, changes in background attributes will not take effect until the server generates the next Expose event on that window. If you want the new background to be visible immediately, call XClearWindow() and flush the request buffer with XFlush().

Applications must set one or the other for all windows. Otherwise, the results are undefined. Most applications set backgrounds to a solid color by setting the background_pixel attribute. The easiest way to do this is by setting the last argument of XCreateSimpleWindow() to BlackPixel or WhitePixel().

background_pixmap

If the background is set to a pixmap, the background is tiled with the pixmap. Tiling is the laying out of a pixmap to cover an area. The first pixmap is applied at the origin of the window (or its parent's origin if using the parent's background pixmap by specifying ParentRelative, as described below). Another copy of the same pixmap is applied next to that one and another below it and so on until the window is filled.

The pixmap may be any size, though some sizes may be tiled faster than others. To find the most efficient tile size for a particular screen, call XQueryBestTile().

A pixmap must be created with XCreatePixmap() or XCreatePixmapFromBitmapData() before being set as the background_pixmap attribute. The pixmap must have the same depth as the window and be created on the same screen. These characteristics are assigned to a pixmap as it is created. (For more information on creating pixmaps for tiles, see “Creating Bitmaps, Pixmaps, Tiles, and Stipples” in Chapter 6)

The background_pixmap attribute has the following possible values:

None (default) 

Specifies that the window has no defined background pixmap. The window background initially will be invisible and will share the bits of its parent but only if the background_pixel attribute is not set. When anything is drawn by any client into the area enclosed by the window, the contents will remain until the area is explicitly cleared with XClearWindow(). The background is not automatically refreshed after exposure. The main purpose of the setting None is a minor performance improvement. If the application is simply going to cover the entire window with graphics (i.e., there is no reasonable “background” that the application can set), then why bother forcing the server to spend time painting the background? None might also be useful for a subwindow when that subwindow will never be moved in relation to its parent.

a pixmap ID 

The background will be tiled with the specified pixmap, but not until the next Expose event or XClearWindow() call. The background tile origin is the window origin. If the pixmap is not explicitly referenced again, it can be freed, since a copy is maintained in the server. Because the server copies the pixmap, changes to it after you set the background_pixmap attribute are not guaranteed to be reflected in the window background. For consistent results, therefore, you need to reset the attribute after each change to the pixmap.

ParentRelative 

Specifies that the parent's background is to be used and that the origin for tiling is the parent's origin (or the parent's parent if the parent's background_pixmap attribute is also ParentRelative and so on). The difference between setting ParentRelative and explicitly setting the same pixmap as the parent is the origin of the tiling. The difference between ParentRelative and None is that for ParentRelative, the background is automatically repainted on exposure.

The window must have the same depth as the parent, or a BadMatch error will occur. If the parent has background None, then the window will also have background None. The parent's background is re-examined each time the window background is required (when it needs to be redrawn due to exposure). The window's contents will be lost when the window is moved relative to its parent, and the contents will have to be redrawn.

Changing the background_pixmap attribute of the root window to None or ParentRelative restores the default background, which is server-dependent.

By the way, the symbol CopyFromParent is not used for setting the background, but it will not cause an error, since its value is the same as None.

background_pixel

If the background pixel value is specified, the entire background will take on the color (or shade of gray) indicated for that pixel value in the current colormap.[10]

The background_pixel attribute has the following possible values:

undefined (default) 

Indicates that the background is as specified in the background_pixmap attribute. This value is possible only by creating a window with XCreateWindow() and not setting the background_pixel attribute.

a pixel value 

The background is filled with the specified pixel value. This can be set with the last argument of XCreateSimpleWindow(), XCreateWindow(), or XChangeWindowAttributes().

The Window Border

Like the window background, the window border may have a solid color or may be tiled with a pixmap. This choice is again up to the programmer, though the user should be allowed to determine the color or colors.

Unlike changes to the window background, changes to a window's border attributes are reflected immediately. No call to XClearWindow() or call to flush the request buffer is necessary. This feature makes it possible to use the window border for indicating a client's state. But you cannot use the border of the top-level window, since some window managers manipulate this border to indicate the keyboard focus window (see “The Keyboard Focus Window” in Chapter 8 for a description of the keyboard focus).

The design of a pattern for the border will be different from the background pixmap, because the border width is usually narrow (at most four pixels).

The two attributes that affect the border are border_pixmap and border_pixel. XSetWindowBorderPixmap() and XSetWindowBorder() can be used to set these attributes. Like the window background, whenever one of these routines is called, it overrides the previous setting of the border. If they are both set simultaneously with XCreateWindow() or XChangeWindowAttributes(), the border_pixel attribute takes precedence.

Most applications simply set the border_pixel to BlackPixel or WhitePixel() in the next-to-last argument of XCreateSimpleWindow().

border_pixmap

If the border_pixmap is set to a pixmap, the border is tiled with the pixmap. Tiling is performed as described previously for the background pixmap; the border tile origin is the same as the background tile origin.

The border_pixmap attribute has the following possible values:

CopyFromParent (default) 

Specifies that the border pixmap is to be copied from the parent. (Note that CopyFromParent will cause protocol errors if the window's depth is different from its parent's.) Subsequent changes to the parent's border attributes do not affect the child, but changes to the pixmap used by the parent may be reflected in the child border (server-dependent).

None 

Specifies that the window has no border pixmap. If the window has no border pixel value either, then it uses the same border pixel value as the parent.

a pixmap ID 

Specifies a pixmap to be tiled in the border. The border tile origin is always the window origin; it is not taken from the background tile origin. If the pixmap is not explicitly referenced again, it can be freed since a copy is maintained in the server.

For the root window, CopyFromParent indicates that the default border will be inherited by subsequently created children of the root window, instead of any other border that was set for the root window. Setting the border_pixmap of the root window to CopyFromParent restores the default border pixmap for later inheritance.

border_pixel

If a border pixel value is specified, the entire border will take on the color (or shade of gray) indicated for that pixel value in the current colormap.

The border_pixel attribute has the following possible values:

undefined (default) 

Indicates that the border is as specified in the border_pixmap attribute. This value is possible only by creating a window with XCreateWindow() and not setting the border_pixel attribute.

a pixel value 

Overrides the default and any border_pixmap given, and fills the border with the specified pixel value. This is set by the next-to-last argument of XCreateSimpleWindow().

Bit Gravity

When an unobscured window is moved, its contents are moved with it, since none of the pixel values need to be changed. But when a window is enlarged or shrunk, the server has no idea where in the resulting window the old contents should be placed, so it normally throws them out. The bit_gravity attribute tells the server where to put the existing bits in the larger or smaller window. By instructing the server where to place the old contents, bit gravity allows some clients (not all can take advantage of it) to avoid redrawing parts of their windows.

Bit gravity is never necessary in programs. It does not affect the appearance or functionality of the client. It is used to improve performance in certain cases. Some X servers may not implement bit gravity and may throw out the window contents on resizing regardless of the setting of this attribute. This response is the default for all servers. That is, the default bit gravity is ForgetGravity, which means that the contents of a window are always lost when the window is resized, even if they are maintained in backing store or because of a save_under (to be described in Sections 4.3.5 and 4.3.6).

The window is tiled with its background in the areas that are not preserved by the bit gravity, unless no background is defined, in which case the existing screen is not altered.

There is no routine to set the bit_gravity individually; it can be set only with XChangeWindowAttributes() or XCreateWindow().

The bit_gravity attribute has 11 possible values:

ForgetGravity (default) 

Specifies that window contents should always be discarded after a size change. Note that some X servers may not implement bit gravity and may use ForgetGravity in all cases.

StaticGravity 

Specifies that window contents should not move relative to the origin of the root window. This means that the area of intersection between the original extent of the window and the final extent of the window will not be disturbed.

Each constant below specifies where the old window contents should be placed in the resized window.

NorthWestGravity 

Upper-left corner of the resized window.

NorthGravity 

Top center of the resized window.

NorthEastGravity 

Upper-right corner of the resized window.

WestGravity 

Left center of the resized window.

CenterGravity 

Center of the resized window.

EastGravity 

Right center of the resized window.

SouthWestGravity 

Lower-left corner of the resized window.

SouthGravity 

Bottom center of the resized window.

SouthEastGravity 

Lower-right corner of the resized window.

Here are two examples of applications that could take advantage of bit gravity. Figure 4-1 shows a fictional application that draws a two-axis graph in a window, with the origin at the lower-left corner. If that window were resized, the application would want the old contents to be placed against the new lower-left corner, no matter which sides of the window were moved in or out. That application would set the bit_gravity attribute of this window to SouthWestGravity. Figure 4-1 shows the response of this window to resizing with this bit gravity setting.

Figure 4-1. bit_gravity for a graphing application

Each compass constant, such as SouthWestGravity, indicates the placement of the retained region in the window after resizing. In this case, the lower-left corner of the existing pixels is placed against the lower-left corner of the resulting window. When an Expose event arrives, the application need only redraw the two new strips of the window at the top and right side. No Expose event will be generated on the area that was saved because of bit_gravity.

For another example, think of a window containing centered text. If that window were resized either larger or smaller, we would still like the text to be centered. In this case, the bit_gravity should be set to CenterGravity. Then only if the window is resized smaller than the length of the text would we have to redraw the area and only then to break the line or use a shorter message. We could see whether changing the message would be necessary by looking at the ConfigureNotify event that occurs as a result of the resize (see basicwin in Chapter 3, “Basic Window Program”). The window would still have to be redrawn if it were obscured and then exposed, of course--bit gravity only saves some of the redrawing that would otherwise have to be done.

If the constant were NorthGravity, the top center of the pixels in the window before the resize would be placed against the top center of the resulting window. This would be appropriate if we had a line of text centered at the top of the window that we wished to preserve when possible.

Window Gravity

The win_gravity attribute controls the repositioning of subwindows when a parent window is resized. The attribute is set on the children. Normally, each child has a fixed position measured from the origin of the parent window. Window gravity can be used to tell the server to unmap the child or to move the child an amount depending on the change in size of the parent. The constants used to set win_gravity are similar to those for bit gravity, but their effect is quite different.

NorthGravity specifies that the child window should be moved horizontally by an amount one-half as great as the amount the window was resized in the horizontal direction. The child is not moved vertically. That means that if the window was originally centered along the top edge of the window, it will also be centered along the top edge of the window after resizing. If it was not originally centered, its relative distance from the center may be accentuated or reduced depending on whether the parent is resized larger or smaller.

Window gravity is only useful for children placed against or very near the outside edges of the parent or directly in its center. Furthermore, the child must be centered along one of the outside edges or in a corner. Figure 4-2 shows the nine child positions where window gravity can be useful and the setting to be used for each position.

Figure 4-2. Child positions where window gravity is useful

If any other setting is used for any of these positions, the window gravity may move the child outside the resized parent, since there are no checks to prevent this. The application can try to prevent it by getting the new position of the child from a ConfigureNotify event (see “Handling Resizing of the Window” in Chapter 3) and moving the child inside if necessary. But this will cause a flash when the child window is automatically placed incorrectly and then moved to the correct position by the application. And if an application has to go to the trouble to check the position and move the child, it might as well just forget about window gravity and place the child itself.

NorthWestGravity (the default) indicates that the child (for which this attribute is set) is not moved relative to its parent.

UnmapGravity specifies that the subwindow should be unmapped when the parent is resized. This might be used when a client wishes to recalculate the positions of its children. Normally, the children would appear in their old positions before the client could move them into their recalculated positions. This can be confusing to the user. By setting the win_gravity attribute to UnmapGravity, the server will unmap the windows. They can be repositioned at the client's leisure, and then the client can remap them (with XMapSubwindows()) in their new locations.

There is no routine to set the win_gravity attribute individually; it can be set only with XChangeWindowAttributes() or XCreateWindow().

The win_gravity attribute has the following possible values:

UnmapGravity 

Specifies that the child is unmapped (removed from the screen) when the parent is resized, and an UnmapNotify event is generated.

StaticGravity 

Specifies that the window contents should not move relative to the origin of the root window.

One of the compass constants below 

The list below shows the distance the child window will be moved; W is the amount the parent was resized in width, and H is the amount the parent was resized in height:

NorthWestGravity (default) 

(0, 0)

NorthGravity  

(W/2, 0)

NorthEastGravity  

(W, 0)

WestGravity  

(0, H/2)

CenterGravity  

(W/2, H/2)

EastGravity  

(W, H/2)

SouthWestGravity  

(0, H)

SouthGravity  

(W/2, H)

SouthEastGravity  

(W, H)

Backing Store

A backing store automatically maintains the contents of a window while it is obscured or even while it is unmapped. Backing is like having a copy of the window saved in a pixmap, automatically copied to the screen whenever necessary to keep the visible contents up to date. Backing store is only available on some servers, usually on high performance workstations.

These servers can be instructed when to back up a window and which planes to save, through the backing store attributes. Even when it is available, the backing store should be avoided since it may carry a heavy performance penalty on the server. You can find out whether backing is supported on a particular screen with the DoesBackingStore() macro.

A client might use this feature to back up a window the client is incapable of redrawing for some reason or to be able to draw into a window that is obscured or unmapped.

Three separate attributes control backing: backing_store, backing_planes, and backing_pixel. There are no routines for setting these attributes individually (use XChangeWindowAttributes() or XCreateWindow()). The backing_store attribute determines when and if a window's contents are preserved by the server. The backing_planes attribute specifies which planes must be preserved, and backing_pixel specifies the pixel value used to fill planes not specified in backing_planes. The X server is free to save only the bit planes specified in backing_planes and to regenerate the remaining planes with the specified pixel value.

When the backing store feature is active and the window is larger than its parent, the server maintains complete contents, not just the region within the parent's boundaries. If the server is maintaining the contents of a window, Expose events will not be generated when that window is exposed.

Use of the backing store does not make a window immune to the other window attributes. If the bit_gravity is ForgetGravity, the contents will still be lost whenever the window is resized.

The backing_store attribute has the following possible values:

NotUseful (default) 

Advises the server that maintaining contents is unnecessary. A server may still choose to maintain contents.

WhenMapped 

Advises the server that it would be beneficial to maintain contents of obscured regions when the window is mapped.

Always 

Advises the server that it would be beneficial to maintain contents even when the window is unmapped.

The backing_planes attribute specifies a mask (default all 1's) that indicates which planes of the window hold dynamic data that must be preserved in the backing store.

The backing_pixel attribute specifies a pixel value (default 0) to be used in planes not specified in the backing_plane attribute.

Saving Under

The save_under attribute controls whether the contents of the screen beneath a window should be preserved just before the window is mapped and replaced just after it is unmapped. This attribute is most useful for pop-up windows, which need to be on the screen only briefly. No Expose events will be sent to the windows that are exposed when the pop-up window is unmapped, saving the time necessary to redraw their contents.

Pop-up windows are usually children of the root window and, therefore, are not constrained to appear within the application's top-level window. Therefore, without save_under both your application and other applications on the screen would need to redraw areas when the pop-up window is unmapped.

Setting save_under is never necessary, but it can improve the performance of the server running clients that frequently map and unmap temporary windows. The user would otherwise have to wait for the area under the menu to be redrawn when the menu was unmapped.

There is no routine for setting the save_under attribute individually; it can only be set with XChangeWindowAttributes() or XCreateWindow().

The save_under attribute is different from the backing store; save_under may save portions of several windows beneath a window for the duration of the appearance of the window on the screen, while the backing store saves the contents of a single window while it is mapped or even when unmapped, depending on the attributes.

Not all servers are capable of saving under windows. You can find out whether this feature is supported on a particular screen with the DoesSaveUnders() macro.

The save_under attribute has the following possible values:

False (default) 

Specifies that covered clients should be sent Expose events when the window is unmapped, unless they are preserved in the backing store.

True 

Specifies that the server should save areas under the window and replace them when the window is unmapped.

Setting the save_under attribute to True does not prevent all Expose events on the area underneath. For example, assume there is a window whose bit_gravity is ForgetGravity, and this window lies under a window that has the save_under attribute set to True. The contents of the obscured window will be lost if the underlying window is resized while partially obscured, and Expose events will be generated even on the saved area.

Event Handling

The event_mask and do_not_propagate_mask attributes control the propagation of events through the window hierarchy. The event_mask attribute is normally set with XSelectInput(), but it can also be set directly with XChangeWindowAttributes() or XCreateWindow().

The event_mask attribute specifies which event types are queued for the window when they occur. The do_not_propagate_mask attribute defines which events should not be propagated to ancestor windows when the event type is not selected in this window. Both masks are made by combining the constants listed below using the bitwise OR operator (|).

     Button1MotionMask            KeyPressMask 
     Button2MotionMask            KeyReleaseMask 
     Button3MotionMask            LeaveWindowMask 
     Button4MotionMask            NoEventMask 
     Button5MotionMask            OwnerGrabButtonMask 
     ButtonMotionMask             PointerMotionHintMask 
     ButtonPressMask              PointerMotionMask 
     ButtonReleaseMask            PropertyChangeMask 
     ColormapChangeMask           ResizeRedirectMask 
     EnterWindowMask              StructureNotifyMask 
     ExposureMask                 SubstructureNotifyMask 
     FocusChangeMask              SubstructureRedirectMask 
     KeymapStateMask              VisibilityChangeMask 

Much more information on setting the event masks, including examples, is presented in Chapter 8, “Events” This is a very important topic.

Substructure Redirect Override

A feature called substructure redirect allows a window manager to intercept any requests to map, move, resize, or change the border width of windows. This allows the window manager to modify these requests, if necessary, to ensure that they meet its window layout policy.

Setting the override_redirect attribute True for a window allows a window to be mapped, moved, resized, or its border width changed without the intervention of the window manager. This override is usually done for menus that are frequently mapped and almost immediately unmapped again.

Under properly designed window managers, there is a property you can set to tell the window manager to allow a window to pop up with minimal intervention (XA_WM_TRANSIENT_FOR). This is used for dialog boxes, as described in “Transient Window Field” in Chapter 12

There is no routine for setting the override_redirect attribute individually; it must be set with XChangeWindowAttributes() or XCreateWindow().

The override_redirect attribute has the following possible values:

False (default) 

Specifies that map, move, and resize requests may be processed by the window manager.

True 

Specifies that map, move, and resize requests are to be done verbatim, bypassing any window manager involvement.

Colormap

The colormap attribute specifies which colormap should be used to interpret the pixel values in a window.

For the large majority of clients without special color needs, this attribute can be left in its default state. By default, the colormap attribute from the parent is taken, which, if all ancestors of the window have used the default, will be the default colormap. This means that the default colormap for the screen will be used to translate into colors the pixel values drawn into this window.

If the client requires its own colormap for some reason, the client can create a colormap and set the colormap attribute to the ID of the new colormap. A colormap ID is of type Colormap.

The window manager will read this attribute and install the specified colormap into the hardware colormap when the user indicates that the application should be active. If the system only has one hardware colormap, all other applications will appear in false colors. This is one good reason that applications are encouraged not to create their own colormaps but to use the default colormap instead.

To understand this process, you need to know more about colormaps in X, and for that, see Chapter 7, “Color”

XSetWindowColormap() sets the colormap attribute, which can be set to the following values:

CopyFromParent (default) 

Specifies that the colormap attribute is to be copied from the parent (subsequent changes to the parent's attribute do not affect the child), but the window must have the same visual type as the parent and the parent must not have a colormap of None (otherwise a BadMatch error occurs).

a colormap ID 

The specified colormap will be used for displaying this window, at least while the window manager considers the application active.

Cursor

The cursor is the object that tracks the pointer on the screen, sometimes called the sprite. In X, a cursor is a server resource which defines a cursor pattern, its colors, and the point within the pattern that will be reported in events (called the hotspot). The ID of a cursor is of type Cursor.

Most clients will define a suitable cursor for their top-level window and other cursors for each subwindow if needed. For example, xterm specifies the thin text cursor for the main window and a vertical bidirectional arrow for the scrollbar.

A cursor can be associated with any InputOutput or InputOnly window using the cursor attribute. Then the specified cursor will track the pointer while the pointer is within the window's borders.

A primary purpose for having a different cursor in a window is to indicate visually to the user that something different will happen to keyboard or button input while in the window. Another reason might be to change a cursor's color to increase its visibility over the background of certain windows (although there is another way to obtain contrast, with the cursor mask). There are probably other uses for a separate cursor.

A call to XDefineCursor() sets this attribute to a Cursor, and a call to XUndefineCursor() sets it back to None, which means that the cursor of the parent is used. The resource Cursor must be created before calling XDefineCursor(). This can be done with XCreateFontCursor(). XCreateGlyphCursor(), or XCreatePixmapCursor(), as described in “The Standard Cursor Font” in Chapter 6 The cursor resource can be freed with XFreeCursor() when no further explicit references to it are to be made.

The cursor attribute has the following possible values:

None (default) 

Specifies that the parent's cursor will be used when the pointer is in the window.

a cursor ID 

Specifies a cursor that will be used whenever the pointer is in the window.

The cursor of the root window is initially a large X, but this may be changed like the cursor in any other window if desired. However, this should only be done by the window manager or by the user using the xsetroot application. See Volume Three, for a description of xsetroot.

Default Attributes

Table 4-3 summarizes the default attributes for an InputOutput window. Only five of the attributes are relevant for InputOnly windows: cursor, do_not_ propagate_mask, event_mask, override_redirect, and win_gravity. These attributes have the same defaults as for InputOutput windows.

The background, border, and event_mask attributes need to be set for virtually all windows.

Table 4-3. Default Window Attributes

Member

Default Value

background_pixmap

None

background_pixel

Undefined

border_pixmap

CopyFromParent

border_pixel

Undefined

bit_gravity

ForgetGravity

win_gravity

NorthWestGravity

backing_store

NotUseful

backing_planes

All 1 's (ones)

backing_pixel

0 (zero)

override_redirect

False

save_under

False

event_mask

0

do_not_propagate_mask

0

colormap

CopyFromParent

cursor

None


Information from the XWindowAttributes Structure

We have been describing the programmable window attributes stored in the XSetWindowAttributes structure. Many of the other window characteristics described in Chapter 2, “X Concepts” including the window configuration, are also stored with the window attributes by the server but are not programmable using XChangeWindowAttributes(). For example, depth, class, and visual are assigned at window creation and cannot be changed. The window size, position, and border width are changed with a separate mechanism, because for top-level windows there must be cooperation from the window manager.

The current state of most of the programmable attributes, the read-only attributes, and the window configuration can be read with XGetWindowAttributes(). All this information is returned in an XWindowAttributes structure (not an XSetWindowAttributes structure).

Example 4-4 shows the fields of the XWindowAttributes structure that are not present in XSetWindowAttributes.

Example 4-4. Read-only XWindowAttributes members

typedef struct {
    /* Members writable with XChangeWindowAttributes omitted */
   .
   .
   .
    /* Window geometry -- set by window configuration functions
     * in cooperation with window manager */
    int x, y;             /* Location of window */
    int width, height;    /* Width and height of window */
    int border_width;     /* Border width of window */
    /* This is the event_mask attribute set by XSelectInput */
    long your_event_mask; /* My event mask */
    /* Set when the window is created, not changeable */
    Visual *visual;       /* The associated visual structure */
    int class;            /* InputOutput, InputOnly */
    int depth;            /* Depth of window */
    Screen *screen;       /* Pointer to screen the window is on */
    /* Server sets these members */
    Window root;          /* Root of screen containing window */
    Bool map_installed;   /* Is colormap currently installed */
    int map_state;        /* IsUnmapped, IsUnviewable, or
                           * IsViewable */
    long all_event_masks; /* Events all clients have interest in */
}  XWindowAttributes;

As you can see, the members of XWindowAttributes that cannot be directly written with XChangeWindowAttributes() are separated into four groups.

The first group provides a way to get the window geometry. This information is returned by XGetGeometry(), but it might be useful to use XGetWindowAttributes() instead if you need both the geometry and a few attributes.

The your_event_mask member can be useful if you want to add event mask symbols to those already selected. In a call to XSelectInput(), you must always specify all the desired event masks. If you do not know which event masks are already selected or do not want to bother passing an event_mask argument into one of your routines, you could read the existing event mask here. Then you could OR in any additional event mask symbols before calling XSelectInput() or XChangeWindowAttributes(). See Chapter 8, “Events” for more information on the use of event masks.

The depth, class, visual, and screen members are set when the window is created. If the window was created with XCreateSimpleWindow(), they were inherited from the parent. If the window was created with XCreateWindow(), these members were specified as arguments, except screen, which is indirectly specified by the parent argument. The screen member points to a structure that tells you about the screen on which this window was created. This is one of the Screen structures from the list in the Display structure, and therefore, the information it contains can also be gotten from the macros as described in “Display Macros” in Chapter 3 and Appendix C, Macros, of Volume Two. Again, these should only be needed for convenience to avoid having to pass around these values as arguments or global variables.

The root member tells you the ID of the root window on the screen on which your window was created. It is usually more convenient to use the RootWindow() macro.

The map_installed member can be monitored to tell your application whether the colormap it has set in its colormap attribute is currently installed. If not, the application may be displayed in false colors. See Chapter 7, “Color” for more details.

The map_state member can be monitored by a program and used to turn off processing while a window is unviewable. Some applications that continuously poll for input or draw (such as in action games) can stop doing so and save processor cycles when there is no chance of getting input or no point in drawing.

The all_event_masks member tells you all the event types that are selected by all clients on the window requested. This is the OR of all the event_mask attributes for that window for all clients. By contrast, your_event_mask specifies only the events selected by your client.

Also note that XWindowAttributes is missing a few fields that are present in XSetWindowAttributes. This means that there are some fields that can be set but not queried. These fields are the background and border pixel value and pixmap and the cursor. The designers of X decided to make these fields nonreadable to reduce restrictions on the implementation of backgrounds, borders, and cursors in the server.



[10] We should inform you here that a pixel value is not something you choose yourself; you choose a color name, and the pixel value is returned to you from BlackPixel or WhitePixel() or one of the routines that allocate colors. We go into this subject in detail in Chapter 7, “Color”