Window manager

From GNUstepWiki
Revision as of 04:26, 30 March 2007 by Martin (talk | contribs)
Jump to navigation Jump to search

In Windows and Mac OS X the window manager is tied into the OS. That's not the case for Linux or BSD. Window Maker is the recommended window manager for GNUstep, but a standard feature-set is needed. GNUstep-based applications have additional needs beyond traditional window managers, like handling the dock icon or the menus. Collecting the requirements here will lead to a specification, so any window manager can clearly state whether or not it is GNUstep-compliant.

Backend WM Attributes

Headers/x11/XGServerWindow.h defines

 unsigned long flags
 unsigned long window_style
 unsigned long window_level
 unsigned long reserved
 Pixmap miniaturize_pixmap;    // pixmap for miniaturize button
 Pixmap close_pixmap;          // pixmap for close button.
 Pixmap miniaturize_mask;      // miniaturize pixmap mask
 Pixmap close_mask;            // close pixmap mask
 unsigned long extra_flags;
 #define GSWindowStyleAttr                   (1<<0)
 #define GSWindowLevelAttr                   (1<<1)
 #define GSMiniaturizePixmapAttr             (1<<3)
 #define GSClosePixmapAttr                   (1<<4)
 #define GSMiniaturizeMaskAttr               (1<<5)
 #define GSCloseMaskAttr                     (1<<6)
 #define GSExtraFlagsAttr                    (1<<7)
 #define GSDocumentEditedFlag                (1<<0)
 #define GSWindowWillResizeNotificationsFlag (1<<1)
 #define GSWindowWillMoveNotificationsFlag   (1<<2)
 #define GSNoApplicationIconFlag             (1<<5)
 #define WMFHideOtherApplications            10
 #define WMFHideApplication                  12

Window Level

GNUstep needs arbitrary window levels. EWMH defines these two:

 _NET_WM_STATE_ABOVE, ATOM
 _NET_WM_STATE_BELOW, ATOM

The rest depends on the function of a window. To obtain good interoperability between different Desktop Environments, the following layered stacking order is recommended, from the bottom to the top:

  1. windows of type _NET_WM_TYPE_DESKTOP
  2. windows having state _NET_WM_STATE_BELOW
  3. windows not belonging in any other layer
  4. windows of type _NET_WM_TYPE_DOCK (unless they have state _NET_WM_TYPE_BELOW) and windows having state _NET_WM_STATE_ABOVE
  5. 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 active window to the top and return it back when the window loses focus.

Window Style

Window style is more or less unchanged, except GNUstep want to display edited document: GSDocumentEditedFlag

Window Type

EWMH defines:

 _NET_WM_WINDOW_TYPE_DESKTOP, ATOM
 _NET_WM_WINDOW_TYPE_DOCK, ATOM
 _NET_WM_WINDOW_TYPE_TOOLBAR, ATOM
 _NET_WM_WINDOW_TYPE_MENU, ATOM
 _NET_WM_WINDOW_TYPE_UTILITY, ATOM
 _NET_WM_WINDOW_TYPE_SPLASH, ATOM
 _NET_WM_WINDOW_TYPE_DIALOG, ATOM
 _NET_WM_WINDOW_TYPE_DROPDOWN_MENU, ATOM
 _NET_WM_WINDOW_TYPE_POPUP_MENU, ATOM
 _NET_WM_WINDOW_TYPE_TOOLTIP, ATOM
 _NET_WM_WINDOW_TYPE_NOTIFICATION, ATOM
 _NET_WM_WINDOW_TYPE_COMBO, ATOM
 _NET_WM_WINDOW_TYPE_DND, ATOM
 _NET_WM_WINDOW_TYPE_NORMAL, ATOM

Comments from Yen-Ju Chen: "GNUstep has no such definition and use window level for this purpose. Personally, I wish GNUstep had a better way to tell which window is for which functions, like app icon, floating panel, menu, key window, main window. The window level is not that reliable when people want to do some tricks. It may not match EWMH one-to-one, but it will be useful for various reasons."

App Icon

GNUstep used to have NSDockWindowLevel, but it is deprecated. So to know which window is the app icon, you have to first find a GNUstep window, check its group_leader, (See XWMHints in X protocols), then check its icon_window which points to app icon. Again, it will be easier if there is hint (see above).

EWMH defines _NET_WM_ICON for app icon image. GNUstep supports it, but I am not sure if it is updated when the app icon image is changed. And if people use app icon as a NSWindow and draw directly on it, there is no way the window manager will know. The solution is that if there is a notification that the icon is redrawn, the window manager or GNUstep can copy (or take a screenshot of) the image from that NSWindow and put it into _NET_WM_ICON. It requires something like XCopyArea().

Focus

X has focused and unfocused window, GNUstep has key window and main window, plus menu and app icon. I don't know how the chain of focus should go when the window and menu are up and down. But again, if there is a hint for the main window, key window, main menu, etc, it will be easy for the window manager to know where the focus should go. A documentation of how the focus should shift from which to which may help.

Menus

Again, because there are no real hints about which one is the main menu and submenu besides window level, it is hard to find the correct one. So menus are treated as regular windows in most cases.

Besides the focus issue, there is also a boundary issue. Say the user puts the mouse on the right edge of the screen and clicks the right button (bringing up a menu): the main menu will be off of the right boundary. GNUstep tries to move it back, and some window managers also try to move it back. When a window is moved, the mouse tracking may be offset. After the main menu is open, a user clicks on a submenu, which will also be off of the right boundary. Then should the window manager move both the main menu and submenu to the left? Does GNUstep do that? It is not clear which one should do what.

And now, some people like to have a horizontal menu (like Mac OS X) instead of a vertical menu (like NEXTSTEP). They behave differently for submenus. For a horizontal menu, the submenu will close on an action fire. For a vertical menu, the submenu will stay open after an action fire. So I guess only GNUstep can handle it.

Window Resizing and Moving

GNUstep defines:

 #define GSWindowWillResizeNotificationsFlag  (1<<1)
 #define GSWindowWillMoveNotificationsFlag    (1<<2)

I didn't see it in Window Maker, therefore, I don't know whether it is really supported. But it may be key for some windows turning black when resizing.