X11 Window Manager

Undergraduate Capstone by myself and Ian Kurzrock


How it Works

1. The X Server / Root Window

Every object in X11 is considered a window. The background/Desktop in X11 is a Window itself - it's called the Root Window. Every GUI application on your desktop is a child of the Root Window.

2. Frame Window

In a reparenting window manager, all application windows are children of a container window, which holds other elements like the title bar and buttons. In our program the frame windows and their children are stored in a linked list of structs called WMClients:


// groups frame windows and the actual app windows
typedef struct WMClient
{   
    Window frame;    // the border/container window
    Window titleBar; // the title bar to click/drag
    Window minWin; // minimize, maximize, and close subwindows
    Window maxWin;
    Window closeWin;
    Window child;  // the actual application content window
    Window task_icon;
    
    unsigned int x; // the x and y position before maximizing the window
    unsigned int y; 
    unsigned int w; // the width and height before maximizing the window
    unsigned int h;
    
    Bool maximized; // true if the window is fullscreen
    Bool minimized; // true if the window is minimized
    
    char title[50]; // title of the window
    
    struct WMClient *next;
} WMClient;
                        

3. Title Bar

The window inside the frame that you click and drag on to move and contains the application title. It's size is equal to frameWidth - (buttonSize*numberOfButtons), so there's room for the maximize, minimze, and close buttons.

4. Minimize/Maximize/Close Buttons

These are (shocker) also just windows, whose mouse press (called button presses in Xlib) are mapped to the minimize, maximize, and close functions for the window:


/* test if any special windows were pressed */
if(e.window == temp->minWin)
{
    hMinimize(e, temp);
    return True;
}
else if(e.window == temp->maxWin)
{
       hMaximize(e, temp);
       return True;
}
else if(e.window == temp->closeWin)
{
    hClose(e, temp);
    return True;
}
                        
...

Bool hMinimize(const XButtonEvent e, WMClient *c)
{
    printf("Minimize area!\n");

    ...
}

Bool hMaximize(const XButtonEvent e, WMClient *c) 
{
    printf("Maximize Button Clicked!\n");

    ...
}

Bool hClose(const XButtonEvent e, WMClient *c)
{
    printf("Close button pressed!\n");

    ...
}
                        

5. Application Window

This where the actual program contents are contained. When the program is first started it sends MapRequest event to the X server. This is when we reparent the window into a frame and give it a titlebar/ buttons:


Bool hMapRequest(const XMapRequestEvent e)
{
    printf("Map Request Event!\n");
    
    reparentWindow(e.window, False);
    
    XMapWindow(d, e.window);
    
    return True;
}
                        
...

Bool reparentWindow(Window child, Bool before_wm)
{
    ...

    XReparentWindow(
        d,
        child,
        c->frame,
        0, TITLE_HEIGHT
    );

    ...
}
                        

Source: https://github.com/williamblair/capstone-wm-github

References: Chuan Ji

<-- Back to Home