@node Programmer Interface, Window Manager Protocols, Installation, Top
@comment  node-name,  next,  previous,  up
@chapter Programmer Interface

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

@example 
_WINDOWMAKER_WM_PROTOCOLS
@end example

@noindent property in the root window. This is a list of atoms indicating what protocols are
understood. Currently defined ones are:

@table @samp
@item _WINDOWMAKER_MENU
@item _WINDOWMAKER_COMMAND
@end table

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

@node Window Manager Protocols, WindowMaker Commands, Programmer Interface, Top
@comment  node-name,  next,  previous,  up
@section Window Manager Protocols

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

@menu
* _GNUSTEP_WM_MINIATURIZE_WINDOW::  
* _GNUSTEP_WM_ATTR::            
@end menu

@node _GNUSTEP_WM_MINIATURIZE_WINDOW, _GNUSTEP_WM_ATTR, Window Manager Protocols, Window Manager Protocols
@comment  node-name,  next,  previous,  up
@subsection _GNUSTEP_WM_MINIATURIZE_WINDOW

Clients that set this atom in the @samp{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  @b{XIconifyWindow(3X11)} call.
The ClientMessage format is:

@example
    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;
@end example

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

@node _GNUSTEP_WM_ATTR,  , _GNUSTEP_WM_MINIATURIZE_WINDOW, Window Manager Protocols
@comment  node-name,  next,  previous,  up
@subsection _GNUSTEP_WM_ATTR

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

@example
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;
@end example

@menu
* flags::                       
* window_style::                
* window_level::                
* miniaturize_pixmap::          
* close_pixmap::                
* miniaturize_mask::            
* close_mask::                  
* extra_flags::                 
* Reserved Fields::             
@end menu


@node flags, window_style, _GNUSTEP_WM_ATTR, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection flags
This field specifies which fields in the property are defined.

These are the bit masks:

@example
	#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)
@end example

@node window_style, window_level, flags, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection window_style

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

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

@table @samp
@item NSBorderlessWindowMask
The window will not receive any decoration, such as the titlebar and the resize handle.

@item NSTitledWindowMask
A titlebar with the window name is displayed in the top of the window.

@item NSClosableWindowMask
A close button is displayed in the titlebar of the window. @samp{NSTitledWindowMask} must
be also set. If the application sets @samp{WM_DELETE_WINDOW} in @samp{WM_PROTOCOLS}, a
@samp{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.

@item NSMiniaturizableWindowMask
A miniaturize button is displayed in the titlebar of the window. @samp{NSTitledWindowMask}
must be also set. The protocol is basicaly the same as @samp{NSClosableWindowMask}, being
@samp{_GNUSTEP_WM_MINIATURIZE_WINDOW} the atom name in @samp{WM_PROTOCOLS} and the
@samp{ClientMessage}.

@item 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).

@end table


@node window_level, miniaturize_pixmap, window_style, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection 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
@b{XRaiseWindow()}, @b{XLowerWindow()}, @b{XRestackWindows()} and other Xlib calls of this
nature. Valid window level numbers are:

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

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.


@node miniaturize_pixmap, close_pixmap, window_level, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection 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.

@node close_pixmap, miniaturize_mask, miniaturize_pixmap, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection 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. Set @samp{DocumentEdited} in @b{OpenStep}.


@node miniaturize_mask, close_mask, close_pixmap, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection miniaturize_mask

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


@node close_mask, extra_flags, miniaturize_mask, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up	
@subsubsection close_mask

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


@node extra_flags, Reserved Fields, close_mask, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsubsection extra_flags
	
Flags that specify special attributes for the window.  Valid flags are:

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

@menu
* GSClientResizeFlag::          
* GSFullKeyboardEventsFlag ::   
* GSMenuWindowFlag::            
* GSIconWindowFlag::            
* GSDarkGrayTitlebarFlag ::     
@end menu

@node GSClientResizeFlag, GSFullKeyboardEventsFlag , extra_flags, extra_flags
@comment  node-name,  next,  previous,  up
@subsubsection GSClientResizeFlag

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

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


@node GSFullKeyboardEventsFlag , GSMenuWindowFlag, GSClientResizeFlag, extra_flags
@comment  node-name,  next,  previous,  up
@subsubsection GSFullKeyboardEventsFlag

The window manager should not intercept keyboard events for it's own shortcuts (call
@b{XGrabKey()}) on the client window.


@node GSMenuWindowFlag, GSIconWindowFlag, GSFullKeyboardEventsFlag , extra_flags
@comment  node-name,  next,  previous,  up
@subsubsection 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.

@node GSIconWindowFlag, GSDarkGrayTitlebarFlag , GSMenuWindowFlag, extra_flags
@comment  node-name,  next,  previous,  up
@subsubsection 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.


@node GSDarkGrayTitlebarFlag ,  , GSIconWindowFlag, extra_flags
@comment  node-name,  next,  previous,  up
@subsubsection GSDarkGrayTitlebarFlag 

@center @samp{(may be unnecessary)}

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

@b{NOTE}: Use of @samp{WM_TRANSIENT_FOR} property is prefered as it's cleaner and allows
the same behaviour.


@node Reserved Fields,  , extra_flags, _GNUSTEP_WM_ATTR
@comment  node-name,  next,  previous,  up
@subsection Reserved Fields
The fields named @dfn{reserved} should be set to 0.


@node WindowMaker Commands,  , Window Manager Protocols, Top
@comment  node-name,  next,  previous,  up
@chapter WindowMaker Commands	

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

@example
    event.xclient.type = ClientMessage;
    event.xclient.message_type = _WINDOWMAKER_COMMAND;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = command_code;
@end example


@menu
* Hide Other Applications::     
* Focus window::                
@end menu

@node Hide Other Applications, Focus window, WindowMaker Commands, WindowMaker Commands
@comment  node-name,  next,  previous,  up
@section Hide Other Applications
Hides all applications other than the requesting one.

@example
    event.xclient.type = ClientMessage;
    event.xclient.message_type = _WINDOWMAKER_COMMAND;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = 10;
@end example

Where window is the leader window of the application.
	
@node Focus window,  , Hide Other Applications, WindowMaker Commands
@comment  node-name,  next,  previous,  up
@section Focus window

Passes the keyboard focus to the specified window (makes it the keyWindow).

@example
    event.xclient.type = ClientMessage;
    event.xclient.message_type = _WINDOWMAKER_COMMAND;
    event.xclient.format = 32;
    event.xclient.window = window;
    event.xclient.data.l[0] = 20;
@end example
	
Where window is the window that must become focused.
