

       		WindowMaker Programming Interface
						version 0.3

0. General Notes

	WindowMaker offers partial support for the ICCCM 2.0 
conventions. Support for unimplemented conventions will possibly 
added in future versions.

	In addition to what ICCCM 2.0 offers, WindowMaker has new 
protocols specially designed to support GNUstep, although these 
features may also be used by applications not based on GNUstep.


	To find out what protocols are supported by the window 
manager look at the _WINDOWMAKER_WM_PROTOCOLS property in the root
window. This is a list of atoms indicating what protocols are 
understood. Currently defined ones are:
	_WINDOWMAKER_MENU
	_GNUSTEP_WM_FUNCTION

	These protocols are still in development and can change
at any time.

1. WM_PROTOCOLS

	In addition to the WM_PROTOCOLS defined in ICCCM 
(WM_DELETE_WINDOW and WM_TAKE_FOCUS), WindowMaker supports
the following window manager protocols:

1.1. _GNUSTEP_WM_MINIATURIZE_WINDOW

	Clients that set this atom in the WM_PROTOCOLS property, 
will receive a ClientMessage notifying that the user requested a 
window miniaturization (pressed the miniaturize button in the window
titlebar). WindowMaker will not miniaturize such windows, unless 
explicitly told to do that by the application through a 
XIconifyWindow(3X11) call.
	The ClientMessage format is:

    event.xclient.type = ClientMessage;
    event.xclient.message_type = WM_PROTOCOLS;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = _GNUSTEP_WM_MINIATURIZE_WINDOW;
    event.xclient.data.l[1] = time;

	Window deminiaturization is done normally for all windows, 
e.g: if the user double clicks an icon the icon will be deminiaturized


2. _GNUSTEP_WM_ATTR

	The _GNUSTEP_WM_ATTR property specifies attributes that 
tell WindowMaker how to handle and decorate the window.
The structure for the property is:

typedef struct {
    CARD32 flags;
    CARD32 window_style;
    CARD32 window_level;
    CARD32 reserved2;
    Pixmap miniaturize_pixmap;
    Pixmap close_pixmap;
    Pixmap miniaturize_mask;
    Pixmap close_mask;
    CARD32 extra_flags;
} GNUstepWMAttributes;


2.1. flags
	This field specifies which fields in the property are defined.

These are the bit masks:
	#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 GSExtraAttr		(1<<7)

2.2. window_flags

	This field specifies the decorations that must be
put in the window. The decorations are the same as in the OpenStep
specification:

enum {
  NSBorderlessWindowMask = 0,
  NSTitledWindowMask = 1,
  NSClosableWindowMask = 2,
  NSMiniaturizableWindowMask = 4,
  NSResizableWindowMask = 8
};

* NSBorderlessWindowMask - The window will not receive any 
decoration, such as the titlebar and the resize handle.

* NSTitledWindowMask - A titlebar with the window name is 
displayed in the top of the window.

* NSClosableWindowMask - A close button is displayed in
the titlebar of the window. NSTitledWindowMask must be
also set. If the application sets WM_DELETE_WINDOW in
WM_PROTOCOLS, a ClientMessage will be sent when the close
button is pushed (as stated in ICCCM), otherwise a broken 
close button is displayed and the client is killed.

* NSMiniaturizableWindowMask - A miniaturize button is
displayed in the titlebar of the window. NSTitledWindowMask
must be also set. The protocol is basicaly the same as
NSClosableWindowMask, being _GNUSTEP_WM_MINIATURIZE_WINDOW
the atom name in WM_PROTOCOLS and the ClientMessage. 
See 1.1.

* NSResizableWindowMask - A handle for interactive window
resizing is displayed in the bottom of the window. The
constraints for maximal/minimal window sizes are set
through normal means (XSizeHints).


2.3. window_level

	Specifies the window stacking level for the window. 
Windows with greater level numbers are always kept on top 
of window with lower numbers. The stacking order for windows 
with the same level number is determined interactively by the 
user or by the client, through XRaiseWindow(), XLowerWindow(),
XRestackWindows() and other Xlib calls of this nature. Valid 
window level numbers are:

enum {
  NSNormalWindowLevel   = 0,
  NSFloatingWindowLevel  = 3,
  NSDockWindowLevel   = 5,
  NSSubmenuWindowLevel  = 10,
  NSMainMenuWindowLevel  = 20
};


NOTE:	If the GNUstep GUI library makes it's own window stacking
handling, it must set the window level attribute correctly or
a race condition may arise.


2.4. miniaturize_pixmap
	The pixmap to show in the left button in the titlebar
(generally the miniaturize button). 
	It's size must be 10x10 pixels. An optional pixmap to 
be shown when the button is in the pressed state can be specified. 
In this case the pixmap must be of size 20x10 pixels and the 
pressed state pixmap must be at the right of the normal pixmap. 
If this attribute is not specified, the default miniaturize 
pixmap is displayed.


2.5. close_pixmap
	The pixmap to show in the right button of the titlebar
(generally the close button). 
	The same notes for miniaturize_pixmap apply.

	This field is usually used for specifying a broken cross
pixmap to show that the window contains data that can be lost
if closed. setDocumentEdited in OpenStep.


2.6. miniaturize_mask
	A pixmap to be used as a mask for miniaturize_pixmap.
It's size must be equal to miniaturize_pixmap (e.g: 10x10 or 20x10)
and it's depth must be 1.


2.7. close_mask
	A pixmap to be used as a mask for close_pixmap.
It's size must be equal to close_pixmap (e.g: 10x10 or 20x10)
and it's depth must be 1.


2.8. extra_flags
	Flags that specify special attributes for the window. 
Valid flags are:

#define GSClientResizeFlag	(1<<0)
#define GSFullKeyboardEventsFlag (1<<1)
#define GSMenuWindowFlag	(1<<2)
#define GSIconWindowFlag	(1<<3)
#define GSDarkGrayTitlebarFlag	(1<<8)



2.8.1.	GSClientResizeFlag

	Define that the window manager shouldn't do interactive
resizing through the resizebar. A property of type Window named
_GNUSTEP_WM_RESIZEBAR will be setup in the client window with the 
resizebar window ID for it. The client must select for the
appropriate events (ButtonPress, ButtonRelease, MotionNotify,
ButtonMotion) in the resizebar and then track user interaction,
doing window raising and resizes according to user actions.

NOTE:	If the only OpenStep method that requires this behaviour is
windowWillResize:toSize:, it might be better to remove this
flag and create a willResize ClientMessage that is sent to the
app when the user has resized the window with the resizebar,
telling the size the user has chosen, but without actually 
resizing the window. setMaxSize, setMinSize, setAspectRatio,
setResizeIncrements can be done with XSizeHints.


2.8.2. 	GSFullKeyboardEventsFlag
	The window manager should not intercept keyboard events
for it's own shortcuts (call XGrabKey()) on the client window.


2.8.3.	GSMenuWindowFlag
	The window is a menu and must have a black titlebar
no matter what is it's state. It also must not get keyboard
focus when clicked.

2.8.4.	GSIconWindowFlag
	The window is a icon and must have all borders removed
(including the external 1 pixel wide black border).
It also must not get keyboard focus when clicked.


2.8.5. 	GSDarkGrayTitlebarFlag (may be unnecessary)

	Define that the window should get a dark gray titlebar
instead of a light gray one, when it is not focused.

NOTE: 	Use of WM_TRANSIENT_FOR property is prefered as
it's cleaner and allows the same behaviour.


2.9. reserved fields

	The fields named reserved should be set to 0.


3. Window manager functions

	WindowMaker can perform the following commands, on request
by an application. These commands must be requested by a ClientMessage
sent to the root window with the format below:

    event.xclient.type = ClientMessage;
    event.xclient.message_type = _GNUSTEP_WM_FUNCTION;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = command_code;


3.1. Hide Other Applications
	Hides all applications other than the requesting one.

    event.xclient.type = ClientMessage;
    event.xclient.message_type = _GNUSTEP_WM_FUNCTION;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = 10;

	Where window is the leader window of the application.

3.2. Hide Application
	Hides all windows that belong to the application.
	
    event.xclient.type = ClientMessage;
    event.xclient.message_type = _GNUSTEP_WM_FUNCTION;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = 12;

	Where window is any window that belongs to the application
group.


3.3. Focus window
	Passes the keyboard focus to the specified window (makes it
the keyWindow).
	
    event.xclient.type = ClientMessage;
    event.xclient.message_type = _GNUSTEP_WM_FUNCTION;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = 20;

	Where window is the toplevel window that must become focused.

	This is necessary to let WindowMaker know which window has the
input focus. If clients simply use XSetInputFocus(), the window highlighting
will not reflect the actual focused window.

3.3. 

Alfredo K. Kojima
kojima@inf.ufrgs.br
