Extended Window Manager Hints 15 March 2000 Introduction Version This spec is version 1.0pre2. What is this spec? This spec defines interactions between window managers, applications and the utilities that form part of a desktop environment. It builds on the ICCCM, which defines wm/client interactions at a lower level. It was born out of a need to replace the original Gnome WM specification, although this specification has been designed to be independent of any one desktop environment. Language used in this specification The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. The key words "Window Manager" refer to a window manager which is adopting this specification. "Pager" refers to desktop utility applications, including pagers and taskbars. "Application" refers to other clients. "Clients" refers to Pagers + Applications ie. all X clients, except for the Window Manager. Prerequisites for adoption of this specification Window Managers and Clients which aim to fulfil this specification MUST adhere to the ICCCM on which this specification builds. If this specification explicitly modifies the ICCCM Window Managers and Clients MUST fulfil these modifications. Changes since 1.0pre1 Removed implementation note concerning Gnome's (potential) file manager behaviour. The Window Movement section of the implementation notes has been revised. Changes since 1.9f Revised revision number for first accepted release 1.9XX -> 1.0preXX. Prerequisites for adoption of this specification added. Tidied formatting of _NET_CURRENT_DESKTOP for consistency. Tidied formatting of _NET_ACTIVE_WINDOW for consistency. Removed doubled text. Tidied formatting of _NET_WM_DESKTOP for consistency. Killing Hung Processes implementation note added. _NET_WM_PID and _NET_WM_PING now link to this. Clarified x_root and y_root meaning for _NET_WM_MOVERESIZE. Added contributor list. Changes since 1.9e Added _NET_WM_VISIBLE_NAME_STRING Removed ambiguity from _NET_NUMBER_OF_DESKTOPS and _NET_DESKTOP_NAMES in combination. Set _NET_WM_MOVERESIZE format to 32 for consistency. Removed _NET_PROPERTIES. Removed comment from _NET_WM_MOVERESIZE. Changes since 1.9d Added _NET_VIRTUAL_ROOTS Added note about ICCCM compliant window moves. Added _NET_WM_HANDLED_ICONS Added _NET_SUPPORTING_WM_CHECK Removed degrees of activation Changes since 1.9c Removed packaging of hints into 2 X properties. Jim Gettys points out that the performance gains of fewer round trips can be better achieved using Xlib routines. Clarified that _NET_DESKTOP_VIEWPORT is in pixels _NET_DESKTOP_VIEWPORT is now an array, one for each desktop, to allow for different active viewports on different desktops _NET_WM_STRUT now only applies on desktops on which the client is visible Introduced RFC 2119 language, and attempted to clarify the roles of the Window Manager, Pagers and Applications Added _NET_WM_NAME _NET_DESKTOP_NAMES now in UTF8 Desktops now start from 0 Added _NET_WM_PID Added _NET_WM_PING protocol Added _NET_WM_STATE_SKIP_TASKBAR Changes since 1.9b Removed _NET_NUMBER_OF_DESKTOPS client message, as it overlaps unnecessarily with _NET_{INSERT/DELETE}_DESKTOP. Replaced _NET_WM_LAYER and _NET_WM_HINTS with _NET_WM_WINDOW_TYPE functional hint. Changed _NET_WM_STATE to a list of atoms, for extensibility. Expanded description of _NET_WORKAREA and _NET_WM_STRUT. Removed _NET_WM_SIZEMOVE_NOTIFY protocol. Added degrees of activation to _NET_ACTIVE_WINDOW client message Added _NET_WM_ICON My comments are in [[ ]]. Comments from Marko's draft are in [[MM: ]] Root Window Properties (+Related Messages) _NET_SUPPORTED This property MUST be set by the Window Manager to indicate which hints it supports. This assumes that backwards incompatible changes will not be made to the hints (without being renamed). _NET_CLIENT_LIST An array of all X Windows managed by the Window Manager. _NET_CLIENT_LIST has mapping order. _NET_CLIENT_LIST_STACKING has stacking order. This property SHOULD be set and updated by the Window Manager. _NET_NUMBER_OF_DESKTOPS This property SHOULD be set and updated by the Window Manager to indicate the number of virtual desktops. A Pager can request change in the desktops number by sending a _NET_SET_NUMBER_OF_DESKTOPS message to the root window: The Window Manager is free to honor or reject this request. If request is honored _NET_NUMBER_OF_DESKTOPS MUST be set to the new number of desktops and _NET_VIRTUAL_ROOTS MUST be set to store the new number of desktop virtual root window IDs. The _NET_DESKTOP_NAMES property MAY remain unchanged. If the number of desktops is shrinking and _NET_CURRENT_DESKTOP is out of the new range of of available desktops, then this MUST must be set to the last available desktop from the new set. If number of desktops is shrinking then clients that are still present on desktops, that are out of the new range, MUST be moved to the very last desktop from the new set. For these _NET_WM_DESKTOP MUST be updated. _NET_DESKTOP_GEOMETRY Array of two cardinals that defines the width and height of each desktop in pixels. This property SHOULD be set by the Window Manager. A Pager can change the desktop geometry by sending a _NET_DESKTOP_GEOMETRY client message to the root window _NET_DESKTOP_VIEWPORT Array of two cardinals that define the top left corner of the current view in pixel, for each desktop. For window managers that don't support paged desktops, this MUST always be set to (0,0). A Pager can change the viewport for the current desktop by sending a _NET_DESKTOP_VIEWPORT client message to the root window _NET_CURRENT_DESKTOP , CARDINAL[1]/32 ]]> The index of the current desktop, starts with desktop 0. This MUST be set and updated by the Window Manager If a Pager wants to switch to another virtual desktop, it MUST send a _NET_CURRENT_DESKTOP client message to the root window: _NET_DESKTOP_NAMES The names of all virtual desktops in UTF8 encoding. This property MAY be changed by a Pager or the Window Mangaer at any time. _NET_ACTIVE_WINDOW The window handle of the currently active window. This is a read-only property set by the window manager. If a client (for example, a taskbar) wants to activate another window, it MUST send a _NET_ACTIVE_WINDOW client message to the root window: _NET_WORKAREA This property MUST be set by WM upon calculating the work area for each desktop (the first quadruple = desktop 1). Contains the left, right, top, bottom co-ordinates for each desktop. Work area SHOULD be used by desktop applications to place desktop icons apropriately. The window manager SHOULD calculate this space by taking the current page minus space occupied by dock and panel windows, as indicated by the _NET_WM_STRUT property set on client windows. _NET_SUPPORTING_WM_CHECK The Window Manager MUST set this property on the root window to be the ID of a child window created by the WM, to indicate that a compliant WM is active. The child window MUST also have the _NET_SUPPORTING_WM_CHECK property set with the same value. The child window MUST also have the _NET_WM_NAME property set to the name of the Window Manager. Rationale: The child window is used to guard against stale properties being left on the root window by a crashed WM. _NET_VIRTUAL_ROOTS The Window Manager MUST set this to a list of IDs for windows that are acting as virtual root windows. To implement virtual desktops, some window managers reparent client windows to a child of the root window. The property is present so that Pagers can determine which windows to watch for substructure notifies. Other Root Window Messages _NET_CLOSE_WINDOW Pagers wanting to close a window MUST send a _NET_CLOSE_WINDOW client message request to the root window (type _NET_ACTIVE_WINDOW, format 32, l[0]=0 /*may be used later*/, window should be set to the window to close). The Window Manager MUST then attempt to close the window specified. Rationale: A window manager might be more clever than the usual method (send WM_DELETE message if the protocol is selected, XKillClient otherwise). It might introduce a timeout, for example. Instead of duplicating the code, the Window Manager can easily do the job. _NET_WM_MOVERESIZE This message allows an application to initiate window movement or resizing. This allows the application to define its own move and size "grips", whilst letting the window manager control the actual move/resize. This means that all moves / resizes can happen in a consistent manner as defined by the WM. When sending this message, x_root and y_root MUST indicate the position of the mouse click with respect to the root window and direction MUST indicate whether this is a move or resize event, and if it is a resize event, which edges of the window the size grip applies to. Application Window Properties _NET_WM_NAME The Client SHOULD set this to the title of the window in UTF8 encoding. If set, the Window Manager should use this in preference to WM_NAME. _NET_WM_VISIBLE_NAME_STRING If the Window Manager displays a window name other than _NET_WM_NAME the Window Manager MUST set this to the title displayed in UTF8 encoding. Rationale: For window managers that display a title different from the _NET_WM_NAME or WM_NAME of the window (i.e. xterm <1>, xterm <2>, ... is shown, but _NET_WM_NAME / WM_NAME is still xterm for each window). This property allows taskbars / pagers to display the same title as the window manager. _NET_WM_DESKTOP , CARDINAL/32 ]]> Cardinal to determine the desktop the window is in (or wants to be) starting with 0 for the first desktop. A Client MAY choose not to set this property, in which case the Window Manager SHOULD place as it wishes. 0xFFFFFFFF indicates that the window SHOULD appear on all desktops/workspaces. The Window Manager should honor _NET_WM_DESKTOP whenever a withdrawn window requests to be mapped. A Client can request a change of desktop for a non-withdrawn window by sending a _NET_WM_DESKTOP client message to the root window: The Window Manager MUST keep this property updated on all windows. _NET_WM_WINDOW_TYPE This MUST be set by the Client before mapping, to a list of atoms indicating the functional type of the window. This property SHOULD be used by the window manager in determining the decoration, stacking position and other behaviour of the window. The Client SHOULD specify window types in order of preference (the first being most preferable), but MUST include at least one of the basic window type atoms from the list below. This is to allow for extension of the list of types, whilst providing default behaviour for window managers that do not recognise the extensions. Rationale: This hint is intend to replace the MOTIF hints. One of the objections to the MOTIF hints is that they are a purely visual description of the window decoration. By describing the function of the window, the window manager can apply consistent decoration and behaviour to windows of the same type. Possible examples of behaviour include keeping dock/panels on top or allowing pinnable menus / toolbars to only be hidden when another window has focus (NextStep style). _NET_WM_WINDOW_TYPE_DESKTOP indicates a desktop feature. This can include a single window containing desktop icons with the same dimensions as the screen, allowing the desktop environment to have full control of the desktop, without the need for proxying root window clicks. _NET_WM_WINDOW_TYPE_DOCK indicates a dock or panel feature. Typically a window manager would keep such windows on top of all other windows. _NET_WM_WINDOW_TYPE_TOOLBAR and _NET_WM_WINDOW_TYPE_MENU indicate toolbar and pinnable menu windows, respectively. _NET_WM_WINDOW_TYPE_DIALOG indicates that this is a dialog window. If _NET_WM_WINDOW_TYPE is not set, then windows with WM_TRANSIENT_FOR set MUST be taken as this type. _NET_WM_WINDOW_TYPE_NORMAL indicates that this is a normal, top-level window. Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR are set MUST be taken as this type. _NET_WM_STATE A list of hints describing the state window. The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn window requests to be mapped. A Client wishing to change the state of a window MUST send a _NET_WM_STATE client message to the root window (see below). The Window Manager MUST keep this property updated to reflect the current state of the window. Possible atoms are: _NET_WM_STATE_MODAL indicates that this is a modal dialog box. The WM_TRANSIENT_FOR hint MUST be set to indicate which window the dialog is a modal for, or set to the root window if the dialog is a modal for its window group. _NET_WM_STATE_STICKY indicates that the Window Manager SHOULD keep the window's position fixed on the screen, even when the virtual desktop scrolls. _NET_WM_STATE_MAXIMIZED_{VERT,HORZ} indicates that the window is {vertically,horizontally} maximised. _NET_WM_STATE_SHADED indicates that the window is shaded. _NET_WM_SKIP_TASKBAR indicates that a window should not be included on a taskbar. To change the state of a mapped window, a Client MUST send a _NET_WM_STATE client message to the root window (window is the respective window, type _NET_WM_STATE, format 32, l[0]=<the action, as listed below>, l[1]=<First property to alter>, l[2]=<Second property to alter>). This message allows two properties to be changed simultaneously, specifically to allow both horizontal and vertical maximisation to be altered together. l[2] MUST be set to zero if only one property is to be changed. l[0], the action, MUST be one of: See also the implementation notes on urgency and fixed size windows. _NET_WM_STRUT This property MUST be set by the Client if the window is to reserve space at the edge of the screen. The property is a 4-tupel of cardinals, one for each border of the screen. The order of the borders is left, right, top, bottom. The client MAY change this property anytime, therefore the Window Manager MUST watch out for property notify events. The purpose of struts is to reserve space at the borders of the desktop. This is very useful for a docking area, a taskbar or a panel, for instance. The window manager should know about this reserved space in order to be able to preserve the space. Also maximized windows should not cover that reserved space. Rationale: A simple "do not cover" hint is not enough for dealing with e.g. auto-hide panels. Notes: An auto-hide panel SHOULD set the strut to be its minimum, hidden size. A "corner" panel that does not extend for the full length of a screen border SHOULD only set one strut. _NET_WM_ICON_GEOMETRY An array of x,y,w,h of type CARDINAL, format 32. This optional property MAY be set by standalone tools like a taskbar or an iconbox. It specifies the geometry of a possible icon in case the window is iconified. Rationale: This makes it possible for a window manager to display a nice animation like morphing the window into its icon. _NET_WM_ICON This is an array of possible icons for the client. This specification does not stipulate what size these icons should be, but individual desktop environments or toolkits may do so. The Window Manager MAY scale any of these icons to an appropriate size. This is an array of 32bit packed CARDINAL ARGB with high byte being A, low byte being B. First two bytes are width, height. Data is in rows, left to right and top to bottom. _NET_WM_PID If set, this property MUST contain the process ID of the client owning this window. This MAY be used by the Window Manager to kill windows which do not respond to the _NET_WM_PING protocol. See also the implementation notes on killing hung processes. _NET_WM_HANDLED_ICONS This property can be set by clients to indicate that the Window Manager need not provide icons for iconified windows, for example if the client is a taskbar and provides buttons for iconified windows. Window Manager Protocols _NET_WM_PING This protocol allows the Window Manager to determine if the Client is still processing X events. This can be used by the Window Manager to determine if a window which fails to close after being sent WM_DELETE_WINDOW has stopped responding, or has stalled for some other reason, such as waiting for user confirmation. A Client SHOULD indicate that it is willing to participate in this protocol by listing _NET_WM_PING in the WM_PROTOCOLS property of the client window. A Window Manager can use this protocol at any time by sending a client message as follows: message_type = WM_PROTOCOLS format = 32 data.l[0] = _NET_WM_PING data.l[1] = ]]> A participating Client receiving this message MUST send it back to the root window immediately, by setting window = root, and calling XSendEvent. The Client MUST NOT alter the timestamp, as this can be used by the Window Manager to uniquely identify the ping. The Window Manager MAY kill the Client (using _NET_WM_PID) if it fails to respond to this protocol within a reasonable time. See also the implementation notes on killing hung processes. 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 behaviour 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 Dialog boxes should indicate their urgency level (information or warning) 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 WM independant pagers and taskbars. Window Managers that require / desire additional functionality beyond what can be acheived using the mechanisms set out in this specification may choose to implement their own pagers, which communicates with the Window Manager using further, WM-specific hints, or some other means. Window Movement 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 honour the win_gravity field of WM_NORMAL_HINTS for both MapRequest _and_ ConfigureRequest events [1] Applications are free to change their win_gravity setting at any time If application changes its gravity then Window manager should adjust the reference point, so that client window will not move as the result. For example if client's gravity was NorthWestGravity and reference point was at the top-left corner of the frame window, then after change of gravity to the SouthEast reference point should be adjusted to point to the lower-right corner of the frame. 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) [2] XMoveWindow( w, x, y) behaviour depends on the window gravity: StaticGravity: window's left top corner will be placed at (x,y) NorthWestGravity: window frame's left top corner will be placed at (x,y) NorthEastGravity: window frame's right top corner will be placed at (x,y) SouthWestGravity: window frame's left bottom corner will be placed at (x,y) SouthEastGravity: window frame's right bottom corner will be placed at (x,y) CenterGravity: window frame's center will be placed at (x,y) (x,y) will become a new "reference point" for the client window. Implementation Note for Application developers: When client window is resized - its reference point does not move. So for example if window has SouthEastGravity and it is resized - the bottom-right corner of its frame will not move but instead top-left corner will be adjusted by the difference in size. Implementation Note for WM developers : when calculating reference point at the time of initial placement - initial window's width should be taken into consideration, as if it was the frame for this window. [1] ICCCM Version 2.0, §4.1.2.3 and §4.1.5 [2] ICCCM Version 2.0, §4.2.3 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 a 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 the next 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(STRING) to attempt to kill a process. Contributors Sasha Vasko Bradley T. Hughes Dominik Vogt Havoc Pennington Jeff Raven Jim Gettys John Harper Julian Adams Matthias Ettrich Micheal Rogers Nathan Clemons Tim Janik Tomi Ollila Sam Lantinga The Rasterman Paul Warren Owen Taylor Marko Macek Greg Badros