[comp.windows.x] Geometry Control with Different Window Managers

schwarze@isa.de (Jochen Schwarze) (06/12/91)

I had problems placing windows to specific coordinates running different
window managers. 

For test purposes I wrote a program that creates a window at (100, 100).
The program tries to figure out the coordinates that excatly represent the
current window position. On every KeyPress event, the window is moved to
this location using XMoveWindow.

The three window managers I tested (TWM, MWM-1.1.1, OLWM) initially
place the window so that the upper left outer corner of its frame is
at the specified position.

Results:

TWM:        After each KeyPress, the window skips down to the left by
            (-borderwidth, titleheight) pixels.

MWM-1.1.1:  The window always stays at its current position.

OLWM:       If a key is pressed *before* the window is moved for the 
            first time (with either mouse or XMoveWindow), it skips down 
            to the right by (borderwidth, borderwidth) pixels. *After*
            the first move it always stays at its current position.

I suppose that the MWM behavior is the correct one (intuitively, you
wouldn't expect your window to jump around when you move it to its current
location :-). Running OLWM there is an additional ConfigureNotify event
that seems to confuse the initial location.

What is the correct way to control window positions?
How do I have to resize a window so that its window manager border occupies
some defined space on the screen (full screen resize e.g.)?
Which of the above window managers implements the correct behavior?

Thank you very much.


/*** Test program follows ***/

#include <X11/Xlib.h>
#include <X11/Xutil.h>

main()
{
    Display *dpy;
    int scr;
    Window root, win;
    int x = 100, y = 100;
    unsigned width = 300, height = 200, border = 5;
    XSizeHints hints;
    XWMHints wmhints;
    XEvent xev;
    
    if (!(dpy  = XOpenDisplay((char *) 0)))
        exit(1);

    scr  = DefaultScreen(dpy);
    root = DefaultRootWindow(dpy);
    
    win = XCreateSimpleWindow(dpy, root, x, y, width, height, border,
                              BlackPixel(dpy, scr), WhitePixel(dpy, scr));
    
    hints.flags = USPosition | USSize;
    hints.x = x, hints.y = y;
    hints.width = width, hints.height = height;
    XSetNormalHints(dpy, win, &hints);
    
    wmhints.flags = InputHint, wmhints.input = True;
    XSetWMHints(dpy, win, &wmhints);
    
    XSelectInput(dpy, win, StructureNotifyMask | KeyPressMask);
    XMapWindow(dpy, win);
    
    for (;;)
    {
        XNextEvent(dpy, &xev);
        
        switch (xev.type)
        {
          case ConfigureNotify:
            
            if (xev.xconfigure.send_event)
            {
                x = xev.xconfigure.x,
                y = xev.xconfigure.y;
            }
            else
            {
                Window w;
                XTranslateCoordinates(dpy, win, root, 0, 0, &x, &y, &w);
            }
            
            width  = xev.xconfigure.width;
            height = xev.xconfigure.height;
            break;
            
          case KeyPress:
            XMoveResizeWindow(dpy, win, x, y, width, height);
            break;
        }
    }
}

/*** End of test program ***/

--

Jochen Schwarze                     Domain: schwarze@isa.de
ISA GmbH, Stuttgart, West Germany   UUCP:   schwarze@isaak.uucp
                                    Bang:   ...!uunet!unido!isaak!schwarze