Implementation notes
Prev |  | Next

## Implementation notes

### Desktop/workspace model

This spec assumes a desktop model that consists of one or more completely independent desktops which may or may not be larger than the screen area. When a desktop is larger than the screen it is left to the Window Manager if it will implement scrolling or paging.

### File Manager desktop

This spec suggests implementing the file manager desktop by mapping a desktop-sized window (no shape) to all desktops, with _NET_WM_WINDOW_TYPE_DESKTOP. This makes the desktop focusable and greatly simplifies implementation of the file manager. It is also faster than managing lots of small shaped windows. The file manager draws the background on this window. There should be a root property with a window handle for use in applications that want to draw the background (xearth).

### Implementing enhanced support for application transient windows

If the WM_TRANSIENT_FOR property is set to None or Root window, the window should be treated as a transient for all other windows in the same group. It has been noted that this is a slight ICCCM violation, but as this behavior is pretty standard for many toolkits and window managers, and is extremely unlikely to break anything, it seems reasonable to document it as standard.

### Urgency

Windows expecting immediate user action should indicate this using the urgency bit in the WM_HINTS.flags property, as defined in the ICCCM.

### Fixed size windows

Windows can indicate that they are non-resizable by setting minheight = maxheight and minwidth = maxwidth in the ICCCM WM_NORMAL_HINTS property. The Window Manager MAY decorate such windows differently.

### Pagers and Taskbars

This specification attempts to make reasonable provisions for window manager independent pagers and taskbars. Window Managers that require / desire additional functionality beyond what can be achieved using the mechanisms set out in this specification may choose to implement their own pagers, which communicate with the Window Manager using further, window manager specific hints, or some other means.

Pagers should decide whether to show a miniature version of a window using the following guidelines:

- If either _NET_WM_STATE_SKIP_PAGER or _NET_WM_STATE_HIDDEN are set on a window, then the pager should not show that window.

- The pager may choose not to display windows with certain semantic types; this spec has no recommendations, but common practice is to avoid displaying _NET_WM_WINDOW_TYPE_DOCK for example.

- If the _NET_WM_STATE_SKIP_PAGER and _NET_WM_STATE_HIDDEN hints are not present, and the Window Manager claims to support _NET_WM_STATE_HIDDEN, then the window should be shown if it's in either NormalState or IconicState.

- For Window Managers that do not support _NET_WM_STATE_HIDDEN, the pager should not show windows in IconicState. These Window Managers are probably using an older version of this specification.

### Window Geometry

Window manager implementors should refer to the ICCCM for definitive specifications of how to handle MapRequest and ConfigureRequest events. However, since these aspects of the ICCCM are easily misread, this document offers the following clarifications:

- Window Managers MUST honor the win_gravity field of WM_NORMAL_HINTS for both MapRequest and ConfigureRequest events (ICCCM Version 2.0, §4.1.2.3 and §4.1.5)

- When generating synthetic ConfigureNotify events, the position given MUST be the top-left corner of the client window in relation to the origin of the root window (i.e., ignoring win_gravity) (ICCCM Version 2.0, §4.2.3)

- Window Managers maintain a reference point for each client window and place the window relative to this reference point depending on the window's win_gravity as follows:

  win_gravity: | placed at the reference point
  StaticGravity | the left top corner of the client window
  NorthWestGravity | the left top corner of the frame window
  NorthGravity | the center of the frame window's top side
  NorthEastGravity | the right top corner of the frame window
  EastGravity | the center of the frame window's right side
  SouthEastGravity | the right bottom corner of the frame window
  SouthGravity | the center of the frame window's bottom side
  SouthWestGravity | the left bottom corner of the frame window
  WestGravity | the center of the frame window's left side
  CenterGravity | the center of the frame window

- Applications are free to change their win_gravity setting at any time.

  If an Application changes its win_gravity then the Window Manager should adjust the reference point, so that the client window will not move as the result. For example if the Application's win_gravity was NorthWestGravity and reference point was at the top-left corner of the frame window, then after change of win_gravity to SouthEastGravity the reference point should be adjusted to point to the lower-right corner of the frame.

  ### Note

  Changing the win_gravity for a single configure request and back afterwards is unlikely to work as intended, due to a race condition. The window manager sees a property notify for WM_NORMAL_HINTS, followed by the configure request, followed by another property notify for WM_NORMAL_HINTS. By the time the window manager gets around to request the changed WM_NORMAL_HINTS in response to the first property notify, the server may have already processed the second property change.

  If the window manager supports it, applications should use _NET_MOVERESIZE_WINDOW with a specified gravity to avoid this problem.

- If the Application requests a new position (x, y) (and possibly also a new size), the Window Manager calculates a new reference point (ref_x, ref_y), based on the client window's (possibly new) size (width, height), border width (bw) and win_gravity as explained in the table below.

  The Window Manager will use the new reference point until the next request for a new position.

  win_gravity: | ref_x: | ref_y:
  StaticGravity | x | y
  NorthWestGravity | x-bw | y-bw
  NorthGravity | x+(width/2) | y-bw
  NorthEastGravity | x+width+bw | y-bw
  EastGravity | x+width+bw | y+(height/2)
  SouthEastGravity | x+width+bw | y+height+bw
  SouthGravity | x+(width/2) | y+height+bw
  SouthWestGravity | x-bw | y+height+bw
  WestGravity | x-bw | y+(height/2)
  CenterGravity | x+(width/2) | y+(height/2)

- If an Application requests just a new size, its reference point does not move. So for example if client window has win_gravity SouthEastGravity and is resized, the bottom right corner of its frame will not move but instead the top left corner will be adjusted by the difference in size.

- When calculating the reference point at the time of initial placement, the Window Manager should take the initial window's size into consideration, as if it was the frame for this window.

### Window-in-Window MDI

The authors of this specification acknowledge that there is no standard method to allow the Window Manager to manage windows that are part of a Window-in-Window MDI application. Application authors are advised to use some other form of MDI, or to propose a mechanism to be included in a future revision of this specification.

### Killing Hung Processes

If processes fail to respond to the _NET_WM_PING protocol _NET_WM_PID may be used in combination with the ICCCM specified WM_CLIENT_MACHINE to attempt to kill a process.

WM_CLIENT_MACHINE is usually set by calling XSetWMProperties(). The hostname for the current host can be be retrieved using gethostname(), when gethostname() is not available on the platform implementors may use the value of the nodename field of struct utsname as returned by uname(). Note also that the value of WM_CLIENT_MACHINE is not guaranteed to be a fully fully-qualified domain name of the host. An example of how to retrieve the hostname:

    int net_get_hostname (char *buf, size_t maxlen)
    {
    #ifdef HAVE_GETHOSTNAME
    	if (buf == NULL) return 0;

    	gethostname (buf, maxlen);
    	buf [maxlen - 1] = '\0';

    	return strlen(buf);
    #else
    	struct utsname name;
    	size_t len;

    	if (buf == NULL) return 0;

    	uname (&name);
    	len = strlen (name.nodename);

    	if (len >= maxlen) len = maxlen - 1;
    	strncpy (buf, name.nodename, len);
    	buf[len] = '\0';

    	return len;
    #endif
    }

### Stacking order

To obtain good interoperability between different Desktop Environments, the following layered stacking order is recommended, from the bottom:

- windows of type _NET_WM_TYPE_DESKTOP

- windows having state _NET_WM_STATE_BELOW

- windows not belonging in any other layer

- windows of type _NET_WM_TYPE_DOCK (unless they have state _NET_WM_TYPE_BELOW) and windows having state _NET_WM_STATE_ABOVE

- focused windows having state _NET_WM_STATE_FULLSCREEN

Windows that are transient for another window should be kept above this window.

The window manager may choose to put some windows in different stacking positions, for example to allow the user to bring currently a active window to the top and return it back when the window looses focus.

### Source indication in requests

Some requests from Clients include type of the Client, for example the _NET_ACTIVE_WINDOW message. Currently the types can be 1 for normal applications, and 2 for pagers and other Clients that represent direct user actions (the Window Manager may decide to treat requests from applications differently than requests that are result of direct user actions). Clients that support only older version of this spec will have 0 as their source indication, thus not specifying their source at all. This also may mean that some of the fields in the message comply only with the older specification version.

Prev |  | Next
Window Manager Protocols | Home | References