shod

mouse-based window manager that can tile windows inside floating containers
Log | Files | Refs | README | LICENSE

shod.h (32515B)


      1 #include <sys/queue.h>
      2 
      3 #include "xutil.h"
      4 
      5 #define SHELL                   "SHELL"
      6 #define DEF_SHELL               "sh"
      7 #define DNDDIFF                 10      /* pixels from pointer to place dnd marker */
      8 #define IGNOREUNMAP             6       /* number of unmap notifies to ignore while scanning existing clients */
      9 #define NAMEMAXLEN              256     /* maximum length of window's name */
     10 #define DROPPIXELS              30      /* number of pixels from the border where a tab can be dropped in */
     11 #define DOCKBORDER              1
     12 #define LEN(x)                  (sizeof(x) / sizeof((x)[0]))
     13 #define _SHOD_MOVERESIZE_RELATIVE       ((long)(1 << 16))
     14 #define ISDUMMY(c)              ((c)->ncols == 0)
     15 
     16 #define TITLEWIDTH(c)   ((c)->isfullscreen ? 0 : config.titlewidth)
     17 
     18 #define TAB_FOREACH_BEGIN(c, tab) {                             \
     19 	struct Column *col;                                     \
     20 	struct Row *row;                                        \
     21 	TAILQ_FOREACH(col, &(c)->colq, entry) {                 \
     22 		TAILQ_FOREACH(row, &col->rowq, entry) {         \
     23 			TAILQ_FOREACH(tab, &row->tabq, entry)
     24 #define TAB_FOREACH_END }                                       \
     25 		}                                               \
     26 	}
     27 
     28 #define RESOURCES                                                                        \
     29 	/*                      CLASS                        NAME                      */\
     30 	X(RES_TYPE,            "Type",                      "type"                      )\
     31 	X(RES_STATE,           "State",                     "state"                     )\
     32 	X(RES_DESKTOP,         "Desktop",                   "desktop"                   )\
     33 	X(RES_DOCK_POS,        "Dockpos",                   "dockpos"                   )\
     34 	X(RES_FACE_NAME,       "FaceName",                  "faceName"                  )\
     35 	X(RES_FOREGROUND,      "Foreground",                "foreground"                )\
     36 	X(RES_DOCK_BACKGROUND, "DockBackground",            "dockBackground"            )\
     37 	X(RES_DOCK_BORDER,     "DockBorder",                "dockBorder"                )\
     38 	X(RES_ACTIVE_BG,       "ActiveBackground",          "activeBackground"          )\
     39 	X(RES_ACTIVE_TOP,      "ActiveTopShadowColor",      "activeTopShadowColor"      )\
     40 	X(RES_ACTIVE_BOT,      "ActiveBottomShadowColor",   "activeBottomShadowColor"   )\
     41 	X(RES_INACTIVE_BG,     "InactiveBackground",        "inactiveBackground"        )\
     42 	X(RES_INACTIVE_TOP,    "InactiveTopShadowColor",    "inactiveTopShadowColor"    )\
     43 	X(RES_INACTIVE_BOT,    "InactiveBottomShadowColor", "inactiveBottomShadowColor" )\
     44 	X(RES_URGENT_BG,       "UrgentBackground",          "urgentBackground"          )\
     45 	X(RES_URGENT_TOP,      "UrgentTopShadowColor",      "urgentTopShadowColor"      )\
     46 	X(RES_URGENT_BOT,      "UrgentBottomShadowColor",   "urgentBottomShadowColor"   )\
     47 	X(RES_BORDER_WIDTH,    "BorderWidth",               "borderWidth"               )\
     48 	X(RES_SHADOW_WIDTH,    "ShadowThickness",           "shadowThickness"           )\
     49 	X(RES_TITLE_WIDTH,     "TitleWidth",                "titleWidth"                )\
     50 	X(RES_DOCK_WIDTH,      "DockWidth",                 "dockWidth"                 )\
     51 	X(RES_DOCK_SPACE,      "DockSpace",                 "dockSpace"                 )\
     52 	X(RES_DOCK_GRAVITY,    "DockGravity",               "dockGravity"               )\
     53 	X(RES_NOTIFY_GAP,      "NotifGap",                  "notifGap"                  )\
     54 	X(RES_NOTIFY_GRAVITY,  "NotifGravity",              "notifGravity"              )\
     55 	X(RES_NDESKTOPS,       "NumOfDesktops",             "numOfDesktops"             )\
     56 	X(RES_SNAP_PROXIMITY,  "SnapProximity",             "snapProximity"             )\
     57 	X(RES_MOVE_TIME,       "MoveTime",                  "moveTime"                  )\
     58 	X(RES_RESIZE_TIME,     "ResizeTime",                "resizeTime"                )
     59 
     60 enum Resource {
     61 #define X(res, class, name) res,
     62 	RESOURCES
     63 	NRESOURCES
     64 #undef  X
     65 };
     66 
     67 enum {
     68 	/* border array indices */
     69 	BORDER_N,
     70 	BORDER_S,
     71 	BORDER_W,
     72 	BORDER_E,
     73 	BORDER_NW,
     74 	BORDER_NE,
     75 	BORDER_SW,
     76 	BORDER_SE,
     77 	BORDER_LAST
     78 };
     79 
     80 enum {
     81 	/* cursor array indices */
     82 	CURSOR_NORMAL,                          /* regular cursor */
     83 	CURSOR_MOVE,                            /* arrow-cross cursor */
     84 	CURSOR_NW,                              /* north-west pointing cursor */
     85 	CURSOR_NE,                              /* north-east pointing cursor */
     86 	CURSOR_SW,                              /* south-west pointing cursor */
     87 	CURSOR_SE,                              /* south-east pointing cursor */
     88 	CURSOR_N,                               /* north pointing cursor */
     89 	CURSOR_S,                               /* south pointing cursor */
     90 	CURSOR_W,                               /* west pointing cursor */
     91 	CURSOR_E,                               /* east pointing cursor */
     92 	CURSOR_V,                               /* vertical arrow cursor */
     93 	CURSOR_H,                               /* horizontal arrow cursor */
     94 	CURSOR_HAND,                            /* hand cursor */
     95 	CURSOR_PIRATE,                          /* pirate-cross cursor */
     96 	CURSOR_LAST
     97 };
     98 
     99 enum {
    100 	/* application window array indices */
    101 	TYPE_UNKNOWN,
    102 	TYPE_NORMAL,
    103 	TYPE_DESKTOP,
    104 	TYPE_DOCK,
    105 	TYPE_MENU,
    106 	TYPE_DIALOG,
    107 	TYPE_NOTIFICATION,
    108 	TYPE_PROMPT,
    109 	TYPE_SPLASH,
    110 	TYPE_DOCKAPP,
    111 	TYPE_POPUP,
    112 	TYPE_LAST
    113 };
    114 
    115 enum {
    116 	/* color array indices */
    117 	COLOR_BG     = 0,
    118 	COLOR_BORD   = 1,
    119 	COLOR_FG     = 2,
    120 
    121 	COLOR_MID    = 0,
    122 	COLOR_LIGHT  = 1,
    123 	COLOR_DARK   = 2,
    124 	COLOR_LAST   = 3
    125 };
    126 
    127 enum {
    128 	/* decoration style array indices */
    129 	FOCUSED,
    130 	UNFOCUSED,
    131 	URGENT,
    132 	STYLE_OTHER,
    133 	STYLE_LAST
    134 };
    135 
    136 enum {
    137 	/* window layer array indices */
    138 	LAYER_BELOW,
    139 	LAYER_NORMAL,
    140 	LAYER_ABOVE,
    141 	LAYER_MENU,
    142 	LAYER_DOCK,
    143 	LAYER_FULLSCREEN,
    144 	LAYER_LAST
    145 };
    146 
    147 enum {
    148 	/* strut elements array indices */
    149 	STRUT_LEFT              = 0,
    150 	STRUT_RIGHT             = 1,
    151 	STRUT_TOP               = 2,
    152 	STRUT_BOTTOM            = 3,
    153 	STRUT_LEFT_START_Y      = 4,
    154 	STRUT_LEFT_END_Y        = 5,
    155 	STRUT_RIGHT_START_Y     = 6,
    156 	STRUT_RIGHT_END_Y       = 7,
    157 	STRUT_TOP_START_X       = 8,
    158 	STRUT_TOP_END_X         = 9,
    159 	STRUT_BOTTOM_START_X    = 10,
    160 	STRUT_BOTTOM_END_X      = 11,
    161 	STRUT_LAST              = 12,
    162 };
    163 
    164 enum {
    165 	/* container states bits*/
    166 	ABOVE           = 0x01,
    167 	BELOW           = 0x02,
    168 	FULLSCREEN      = 0x04,
    169 	MAXIMIZED       = 0x08,
    170 	MINIMIZED       = 0x10,
    171 	SHADED          = 0x20,
    172 	STICKY          = 0x40,
    173 	USERPLACED      = 0x80,
    174 
    175 	/* dockapp states bits */
    176 	EXTEND          = 0x100,
    177 	SHRUNK          = 0x200,
    178 	RESIZED         = 0x400,
    179 };
    180 
    181 enum {
    182 	/* container state action */
    183 	REMOVE = 0,
    184 	ADD    = 1,
    185 	TOGGLE = 2
    186 };
    187 
    188 enum Octant {
    189 	/* window eight sections (aka octants) */
    190 	C  = 0,
    191 	N  = (1 << 0),
    192 	S  = (1 << 1),
    193 	W  = (1 << 2),
    194 	E  = (1 << 3),
    195 	NW = (1 << 0) | (1 << 2),
    196 	NE = (1 << 0) | (1 << 3),
    197 	SW = (1 << 1) | (1 << 2),
    198 	SE = (1 << 1) | (1 << 3),
    199 };
    200 
    201 TAILQ_HEAD(Queue, Object);
    202 struct Object {
    203 	/*
    204 	 * An object is any structure that can directly contain a
    205 	 * window of an application.  For example, an open Gimp
    206 	 * application can have two menu windows (on its multi-window
    207 	 * mode), a dialog window, and the main application window.
    208 	 * For each window of that application we have one object:
    209 	 * - The Menu struct for the menu windows.
    210 	 * - The Dialog struct for the dialog window.
    211 	 * - The Tab struct for the main window.
    212 	 *
    213 	 * The application's main window is contained inside a tab,
    214 	 * which is contained inside a row, which is contained inside a
    215 	 * column, which is contained inside a container.  but only the
    216 	 * tab is an object, in the sense that it directly contains a
    217 	 * window of the application.  The row, the column, and the
    218 	 * container are not objects in this sense, because they do not
    219 	 * directly contain an application window (they contain it
    220 	 * indirectly).
    221 	 *
    222 	 * Each object structure begins with an Object struct, so they
    223 	 * can be polymorphically manipulated as its actual type or as
    224 	 * an Object.  For example, we can cast a Dialog into an Object
    225 	 * and vice-versa (if we know that the object is a type).
    226 	 *
    227 	 * The structs that can directly contain an application window
    228 	 * are the following:
    229 	 * - struct Tab;
    230 	 * - struct Dialog;
    231 	 * - struct Menu;
    232 	 * - struct Bar;
    233 	 * - struct Dockapp;
    234 	 * - struct Splash;
    235 	 * - struct Notification;
    236 	 */
    237 	TAILQ_ENTRY(Object) entry;
    238 	Window win;
    239 	int type;
    240 };
    241 
    242 TAILQ_HEAD(RowQueue, Row);
    243 struct Row {
    244 	TAILQ_ENTRY(Row) entry;
    245 	struct Queue tabq;                      /* list of tabs */
    246 
    247 	/*
    248 	 * Each columnt is split vertically into rows; and each row
    249 	 * contains tabs.  We maintain in a row its list of tabs, and
    250 	 * a pointer to its parent column.
    251 	 */
    252 	struct Column *col;                     /* pointer to parent column */
    253 	struct Tab *seltab;                     /* pointer to selected tab */
    254 	int ntabs;                              /* number of tabs */
    255 
    256 	/* At the bottom of each column, except the bottomost one, ther
    257 	 * is a divisor handle which can be dragged to resize the row.
    258 	 * There are also other windows forming a row:
    259 	 * - The divisor.
    260 	 * - The frame below the tab windows.
    261 	 * - The title bar where the tabs are drawn.
    262 	 * - The left (row maximize) button.
    263 	 * - The right (close) button.
    264 	 */
    265 	Window div;                             /* horizontal division between rows */
    266 	Window frame;                           /* where tab frames are */
    267 	Window bar;                             /* title bar frame */
    268 	Window bl;                              /* left button */
    269 	Window br;                              /* right button */
    270 
    271 	/*
    272 	 * We only keep the vertical geometry of a row (ie', its y
    273 	 * position and its height), because, since a row horizontally
    274 	 * spans its parent column width, its horizontal geometry is
    275 	 * equal to the geometry of its parent column.
    276 	 */
    277 	double fact;                            /* factor of height relative to container */
    278 	int y, h;                               /* row geometry */
    279 
    280 	/*
    281 	 * Three of the windows of the row must be drawn.  First we draw
    282 	 * into their pixmap, and then copy the contents of the pixmap
    283 	 * into the windows thenselves whenever they are damaged.  It is
    284 	 * necessary to redraw on the pixmap only when the row resizes;
    285 	 * so we save the previous width of the row to compare with the
    286 	 * row's current width.
    287 	 */
    288 	Pixmap pixbar;                          /* pixmap for the title bar */
    289 	Pixmap pixbl;                           /* pixmap for left button */
    290 	Pixmap pixbr;                           /* pixmap for right button */
    291 	int pw;
    292 
    293 	/*
    294 	 * Whether the frame is unmapped
    295 	 */
    296 	int isunmapped;
    297 };
    298 
    299 TAILQ_HEAD(ColumnQueue, Column);
    300 struct Column {
    301 	TAILQ_ENTRY(Column) entry;
    302 	struct RowQueue rowq;                   /* list of rows */
    303 
    304 	/*
    305 	 * Each container is split horizontally into columns; and each
    306 	 * column is split vertically into rows.  We maintain in a
    307 	 * column its list of rows, and a pointer to its parent
    308 	 * container.
    309 	 */
    310 	struct Container *c;                    /* pointer to parent container */
    311 	struct Row *selrow;                     /* pointer to selected row */
    312 
    313 	/*
    314 	 * At the right of each column, except the rightmost one, there
    315 	 * is a divisor handle which can be dragged to resize the
    316 	 * columns.
    317 	 */
    318 	Window div;                             /* vertical division between columns */
    319 
    320 	/*
    321 	 * We only keep the horizontal geometry of a column (ie', its x
    322 	 * position and its width), because, since a column vertically
    323 	 * spans its parent container height, its vertical geometry is
    324 	 * equal to the geometry of its parent container.
    325 	 */
    326 	double fact;                            /* factor of width relative to container */
    327 	int nrows;                              /* number of rows */
    328 	int x, w;                               /* column geometry */
    329 };
    330 
    331 TAILQ_HEAD(ContainerQueue, Container);
    332 struct Container {
    333 	/*
    334 	 * The container is the main entity the user interact with, and
    335 	 * the windows of most applications are mapped into a container.
    336 	 *
    337 	 * A container is an element of two queues:
    338 	 * - The focus queue is a list of containers in the focus order.
    339 	 *   There is only one focus queue.
    340 	 * - A raise queue is a list of containers in the Z-axis order.
    341 	 *   There are one raise queue for each layer of containers
    342 	 *   (fullscreen, above, middle and below).
    343 	 */
    344 	TAILQ_ENTRY(Container) entry;           /* entry for the focus queue */
    345 	TAILQ_ENTRY(Container) raiseentry;      /* entry for a raise queue */
    346 
    347 	/*
    348 	 * A container contains a list of columns.
    349 	 * A column contains a list of rows.
    350 	 * A row contains a list of tabs.
    351 	 * A tab contains an application window and a list of menus and
    352 	 * a list of dialogs.
    353 	 *
    354 	 * A container with no column is a dummy container, used as
    355 	 * placeholders on the Z-axis list.
    356 	 */
    357 	struct ColumnQueue colq;                /* list of columns in container */
    358 	struct Column *selcol;                  /* pointer to selected container */
    359 	int ncols;                              /* number of columns */
    360 
    361 	/*
    362 	 * A container appears on a certain desktop of a certain monitor.
    363 	 */
    364 	struct Monitor *mon;                    /* monitor container is on */
    365 	int desk;                               /* desktop container is on */
    366 
    367 	/*
    368 	 * A container is composed of a frame window, mapped below all
    369 	 * the columns/rows/tabs/etc.  Inside the frame window, there
    370 	 * are mapped the cursor windows, one for each border and corner
    371 	 * of the container's frame.  Each cursor window is associated
    372 	 * to a pointer cursor (that's why hovering the pointer over the
    373 	 * bottom right corner of the frame turns the cursor into an
    374 	 * arrow.
    375 	 */
    376 	Window frame;                           /* window to reparent the contents of the container */
    377 	Window curswin[BORDER_LAST];            /* dummy window used for change cursor while hovering borders */
    378 
    379 	/*
    380 	 * The frame must be drawn, with all its borders and corner
    381 	 * handles.  First we draw into a pixmap, and then copy the
    382 	 * contents of the pixmap into the frame window itself whenever
    383 	 * the frame window is damaged.  It is necessary to redraw on
    384 	 * the pixmap only when the container resizes; so we save the
    385 	 * width and height of the pixmap to compare with the size of
    386 	 * the container.
    387 	 */
    388 	Pixmap pix;                             /* pixmap to draw the frame */
    389 	int pw, ph;                             /* pixmap width and height */
    390 
    391 	/*
    392 	 * A container has three geometries (position and size): one for
    393 	 * when it is maximized, one for when it is fullscreen, and one
    394 	 * for when it is floating.  The maximized and fullscreen
    395 	 * geometry of a container is obvious (they can be inferred from
    396 	 * the monitor size).  We then save the non-maximized geometry.
    397 	 * We also save the current geometry (which can be one of those
    398 	 * three).
    399 	 */
    400 	int x, y, w, h, b;                      /* current geometry */
    401 	int nx, ny, nw, nh;                     /* non-maximized geometry */
    402 
    403 	/*
    404 	 * A container can have several states.  Except for the `layer`
    405 	 * state (which has tree values), all states are boolean (can or
    406 	 * cannot be valid at a given time) and begin with "is-".  The
    407 	 * possible values for boolean states are zero and nonzero.  The
    408 	 * possible values for the `layer` state is negative (below),
    409 	 * zero (middle) or positive (above).
    410 	 */
    411 	int ismaximized, issticky;              /* window states */
    412 	int isminimized, isshaded;              /* window states */
    413 	int isobscured;                         /* whether container is obscured */
    414 	int isfullscreen;                       /* whether container is fullscreen */
    415 	int ishidden;                           /* whether container is hidden */
    416 	int abovebelow;                         /* stacking order */
    417 };
    418 
    419 TAILQ_HEAD(MonitorQueue, Monitor);
    420 struct Monitor {
    421 	/*
    422 	 * Each monitor has a focused desktop (a value between 0 and
    423 	 * config.ndesktops - 1).  A monitor also has two geometries:
    424 	 * its full actual geometry (a rectangle spanning the entire
    425 	 * monitor), and the window area (a rectangle spanning only
    426 	 * the area without any dock, bar, panel, etc (that is, the
    427 	 * area where containers can be maximized into).
    428 	 */
    429 	TAILQ_ENTRY(Monitor) entry;
    430 	int seldesk;                            /* focused desktop on that monitor */
    431 	int mx, my, mw, mh;                     /* monitor size */
    432 	int wx, wy, ww, wh;                     /* window area */
    433 };
    434 
    435 struct Tab {
    436 	struct Object obj;
    437 
    438 	/*
    439 	 * Additionally to the application window (in .obj), a tab
    440 	 * contains a list of swallowed dialogs (unless -d is given) and
    441 	 * a list of detached menus.  A tab also contains a pointer to
    442 	 * its parent row.
    443 	 */
    444 	struct Queue dialq;                     /* queue of dialogs */
    445 	struct Row *row;                        /* pointer to parent row */
    446 
    447 	/*
    448 	 * The application whose windows the tab maintains can be
    449 	 * grouped under a leader window (which is not necessarily
    450 	 * mapped on the screen).
    451 	 */
    452 	Window leader;                          /* the group leader of the window */
    453 
    454 	/*
    455 	 * Visually, a tab is composed of a title bar (aka tab); and a
    456 	 * frame window which the application window and swallowed
    457 	 * dialog windows are child of.
    458 	 */
    459 	Window title;                           /* title bar (tab) */
    460 	Window frame;                           /* window to reparent the client window */
    461 
    462 	/*
    463 	 * First we draw into pixmaps, and then copy their contents
    464 	 * into the frame and title windows themselves whenever they
    465 	 * are damaged.  It is necessary to redraw on the pixmaps only
    466 	 * when the titlebar or frame resizes; so we save the geometry
    467 	 * of hte pixmaps to compare with the size of their windows.
    468 	 */
    469 	Pixmap pix;                             /* pixmap to draw the background of the frame */
    470 	Pixmap pixtitle;                        /* pixmap to draw the background of the title window */
    471 	int ptw;                                /* pixmap width for the title window */
    472 	int pw, ph;                             /* pixmap size of the frame */
    473 
    474 	/*
    475 	 * Geometry of the title bar (aka tab).
    476 	 */
    477 	int x, w;                               /* title bar geometry */
    478 
    479 	/*
    480 	 * Dirty hack to ignore unmap notifications.
    481 	 */
    482 	int ignoreunmap;                        /* number of unmapnotifys to ignore */
    483 
    484 	/*
    485 	 * Name of the tab's application window, its size and urgency.
    486 	 */
    487 	int winw, winh;                         /* window geometry */
    488 	int isurgent;                           /* whether tab is urgent */
    489 	char *name;                             /* client name */
    490 };
    491 
    492 struct Dialog {
    493 	struct Object obj;
    494 	struct Tab *tab;                        /* pointer to parent tab */
    495 
    496 	/*
    497 	 * Frames, pixmaps, saved pixmap geometry, etc
    498 	 */
    499 	Window frame;                           /* window to reparent the client window */
    500 	Pixmap pix;                             /* pixmap to draw the frame */
    501 	int pw, ph;                             /* pixmap size */
    502 
    503 	/*
    504 	 * Dialog geometry, which can be resized as the user resizes the
    505 	 * container.  The dialog can grow up to a maximum width and
    506 	 * height.
    507 	 */
    508 	int x, y, w, h;                         /* geometry of the dialog inside the tab frame */
    509 	int maxw, maxh;                         /* maximum size of the dialog */
    510 
    511 	int ignoreunmap;                        /* number of unmapnotifys to ignore */
    512 };
    513 
    514 struct Menu {
    515 	struct Object obj;
    516 	struct Monitor *mon;
    517 	Window leader;
    518 
    519 	/*
    520 	 * Frames, pixmaps, saved pixmap geometry, etc
    521 	 */
    522 	Window titlebar;                        /* close button */
    523 	Window button;                          /* close button */
    524 	Window frame;                           /* frame window */
    525 	Pixmap pix;                             /* pixmap to draw the frame */
    526 	Pixmap pixbutton;                       /* pixmap to draw the button */
    527 	Pixmap pixtitlebar;                     /* pixmap to draw the titlebar */
    528 	int pw, ph;                             /* pixmap size */
    529 	int tw, th;                             /* titlebar pixmap size */
    530 
    531 	int x, y, w, h;                         /* geometry of the menu window + the frame */
    532 	int ignoreunmap;                        /* number of unmapnotifys to ignore */
    533 	char *name;                             /* client name */
    534 };
    535 
    536 struct Bar {
    537 	struct Object obj;
    538 	int strut[STRUT_LAST];                  /* strut values */
    539 	int ispartial;                          /* whether strut has 12 elements rather than 4 */
    540 };
    541 
    542 struct Dockapp {
    543 	struct Object obj;
    544 	int x, y, w, h;                 /* dockapp position and size */
    545 	int ignoreunmap;                /* number of unmap requests to ignore */
    546 	int dockpos;                    /* position of the dockapp in the dock */
    547 	int state;                      /* dockapp state */
    548 	int slotsize;                   /* size of the slot the dockapp is in */
    549 };
    550 
    551 struct Splash {
    552 	struct Object obj;
    553 	struct Monitor *mon;
    554 	Window frame;
    555 	int desk;
    556 	int x, y, w, h;                         /* splash screen geometry */
    557 };
    558 
    559 struct Notification {
    560 	struct Object obj;
    561 	Window frame;                           /* window to reparent the actual client window */
    562 	Pixmap pix;                             /* pixmap to draw the frame */
    563 	int w, h;                               /* geometry of the entire thing (content + decoration) */
    564 	int pw, ph;                             /* pixmap width and height */
    565 };
    566 
    567 struct WM {
    568 	int running;
    569 
    570 	/*
    571 	 * The window manager maintains a list of monitors and several
    572 	 * window-holding entities such as containers and bars.
    573 	 */
    574 	struct MonitorQueue monq;               /* queue of monitors */
    575 	struct Queue barq;                      /* queue of bars */
    576 	struct Queue splashq;                   /* queue of splash screen windows */
    577 	struct Queue notifq;                    /* queue of notifications */
    578 	struct Queue menuq;                     /* queue of menus */
    579 	struct ContainerQueue focusq;           /* queue of containers ordered by focus history */
    580 	int nclients;                           /* total number of container windows */
    581 
    582 	/*
    583 	 * Resources
    584 	 */
    585 	struct {
    586 		XrmClass class;
    587 		XrmName name;
    588 	} application, resources[NRESOURCES];
    589 	XrmQuark anyresource;
    590 
    591 	/*
    592 	 * Xrandr information.
    593 	 */
    594 	int xrandr;                             /* whether Xrandr is being used */
    595 	int xrandrev;                           /* event base for Xrandr */
    596 
    597 	/*
    598 	 * Containers are listed by the focusq queue; they are also
    599 	 * listed under the stackq list, ordered by its position on
    600 	 * the Z-axis.
    601 	 *
    602 	 * Since there are 4 layers on the Z-axis and we often need
    603 	 * to move a container to the top of its layer, we have four
    604 	 * "dummy" containers used as placeholder as the top of each
    605 	 * layer on the stackq list.
    606 	 *
    607 	 * There is also a dummy window to place the dock.
    608 	 */
    609 	struct ContainerQueue stackq;
    610 	struct Container layers[LAYER_LAST];
    611 	Window docklayer;                       /* dummy window used to set dock layer */
    612 
    613 	/*
    614 	 * We maintain a pointer to the focused container and the
    615 	 * previously focused one.  And also a pointer to the focused
    616 	 * monitor which will receive new containers.
    617 	 */
    618 	struct Container *focused;              /* pointer to focused container */
    619 	struct Container *prevfocused;          /* pointer to previously focused container */
    620 	struct Monitor *selmon;                 /* pointer to selected monitor */
    621 
    622 	/*
    623 	 * Dummy windows
    624 	 */
    625 	Window checkwin;                        /* carries _NET_SUPPORTING_WM_CHECK */
    626 	Window focuswin;                        /* gets focus when no container is visible */
    627 	Window dragwin;                         /* follows mouse while dragging */
    628 	Window restackwin;                      /* reordered in Z axis to save a position */
    629 
    630 	Cursor cursors[CURSOR_LAST];            /* cursors for the mouse pointer */
    631 	int showingdesk;                        /* whether the desktop is being shown */
    632 	int minsize;                            /* minimum size of a container */
    633 
    634 	/*
    635 	 * Some operations need to reset the list of clients, to do it
    636 	 * only once when more than one of such operations, we use this
    637 	 * value we check at the end of each main loop iteration and
    638 	 * reset at the beginning of each main loop iteration
    639 	 */
    640 	int setclientlist;
    641 
    642 	Window presswin;
    643 };
    644 
    645 struct Dock {
    646 	/* the dock */
    647 	struct Queue dappq;
    648 	Window win;                     /* dock window */
    649 	Pixmap pix;                     /* dock pixmap */
    650 	int x, y, w, h;                 /* dock geometry */
    651 	int pw, ph;                     /* dock pixmap size */
    652 	int mapped;                     /* whether dock is mapped */
    653 };
    654 
    655 struct Config {
    656 	/* default configuration, set at `config.c` */
    657 
    658 	KeySym altkeysym;                       /* key to trigger alt-tab */
    659 	KeySym tabkeysym;                       /* key to cycle alt-tab */
    660 
    661 	int disablehidden;                      /* whether -h is passed */
    662 	int disablealttab;                      /* whether -t is passed */
    663 	int floatdialog;                        /* whether -d is passed */
    664 	int honorconfig;                        /* whether -c is passed */
    665 	int sloppyfocus;                        /* whether -s is passed */
    666 	int sloppytiles;                        /* whether -S is passed */
    667 	int ndesktops;                          /* number of desktops */
    668 	int notifgap;                           /* gap between notifications */
    669 	int dockwidth, dockspace;               /* dock geometry */
    670 	int snap;                               /* snap proximity */
    671 	int borderwidth;                        /* width of the border frame */
    672 	int titlewidth;                         /* height of the title bar */
    673 	int shadowthickness;                    /* thickness of the 3D shadows */
    674 	int movetime;                           /* time (ms) to redraw containers during moving */
    675 	int resizetime;                         /* time (ms) to redraw containers during resizing */
    676 
    677 	char *menucmd;                          /* command to spawn when clicking the menu button */
    678 
    679 	/* gravities (N for north, NE for northeast, etc) */
    680 	const char *notifgravity;
    681 	const char *dockgravity;
    682 
    683 	/* font and color names */
    684 	const char *font;
    685 	const char *colors[STYLE_LAST][COLOR_LAST];
    686 
    687 	/* hardcoded rules */
    688 	struct Rule {
    689 		/* matching class, instance and role */
    690 		const char *class;
    691 		const char *instance;
    692 		const char *role;
    693 
    694 		/* type, state, etc to apply on matching windows */
    695 		int type;
    696 		int state;
    697 		int desktop;
    698 	} *rules;
    699 
    700 	/* the values below are computed from the values above */
    701 	KeyCode altkeycode;                     /* keycode of the altkeysym */
    702 	KeyCode tabkeycode;                     /* keycode of the tabkeysym */
    703 	unsigned int modifier;                  /* modifier of the altkeycode */
    704 	int corner;                             /* = .borderwidth + .titlewidth */
    705 	int divwidth;                           /* = .borderwidth */
    706 };
    707 
    708 typedef void Managefunc(struct Tab *, struct Monitor *, int, Window, Window, XRectangle, int, int);
    709 typedef int Unmanagefunc(struct Object *obj, int ignoreunmap);
    710 
    711 /* container routines */
    712 struct Container *getnextfocused(struct Monitor *mon, int desk);
    713 struct Container *containerraisetemp(struct Container *prevc, int backward);
    714 void containernewwithtab(struct Tab *tab, struct Monitor *mon, int desk, XRectangle rect, int state);
    715 void containerbacktoplace(struct Container *c, int restack);
    716 void containerdel(struct Container *c);
    717 void containermoveresize(struct Container *c, int checkstack);
    718 void containerdecorate(struct Container *c, struct Column *cdiv, struct Row *rdiv, int recursive, enum Octant o);
    719 void containerredecorate(struct Container *c, struct Column *cdiv, struct Row *rdiv, enum Octant o);
    720 void containercalccols(struct Container *c);
    721 void containersetstate(struct Tab *, Atom *, unsigned long);
    722 void containermove(struct Container *c, int x, int y, int relative);
    723 void containerraise(struct Container *c, int isfullscreen, int layer);
    724 void containerconfigure(struct Container *c, unsigned int valuemask, XWindowChanges *wc);
    725 void containersendtodeskandfocus(struct Container *c, struct Monitor *mon, unsigned long desk);
    726 void containerplace(struct Container *c, struct Monitor *mon, int desk, int userplaced);
    727 void containerdelrow(struct Row *row);
    728 void containerhide(struct Container *c, int hide);
    729 void tabdetach(struct Tab *tab, int x, int y);
    730 void tabfocus(struct Tab *tab, int gotodesk);
    731 void tabdecorate(struct Tab *t, int pressed);
    732 void tabupdateurgency(struct Tab *t, int isurgent);
    733 void rowstretch(struct Column *col, struct Row *row);
    734 void dialogconfigure(struct Dialog *d, unsigned int valuemask, XWindowChanges *wc);
    735 void dialogmoveresize(struct Dialog *dial);
    736 int tabattach(struct Container *c, struct Tab *t, int x, int y);
    737 int containerisshaded(struct Container *c);
    738 int containerisvisible(struct Container *c, struct Monitor *mon, int desk);
    739 int columncontentheight(struct Column *col);
    740 int containercontentwidth(struct Container *c);
    741 
    742 /* menu */
    743 void menufocus(struct Menu *menu);
    744 void menuhide(struct Menu *menu, int hide);
    745 void menuincrmove(struct Menu *menu, int x, int y);
    746 void menuconfigure(struct Menu *menu, unsigned int valuemask, XWindowChanges *wc);
    747 void menumoveresize(struct Menu *menu);
    748 void menudecorate(struct Menu *menu, int titlepressed);
    749 void menufocusraise(struct Menu *menu);
    750 void menuraise(struct Menu *menu);
    751 void menuplace(struct Monitor *mon, struct Menu *menu);
    752 void menuupdate(void);
    753 int istabformenu(struct Tab *tab, struct Menu *menu);
    754 
    755 /* other object routines */
    756 void dockappconfigure(struct Dockapp *dapp, unsigned int valuemask, XWindowChanges *wc);
    757 void barstrut(struct Bar *bar);
    758 void notifplace(void);
    759 void notifdecorate(struct Notification *n);
    760 void splashplace(struct Monitor *mon, struct Splash *splash);
    761 void splashhide(struct Splash *splash, int hide);
    762 void splashrise(struct Splash *splash);
    763 void dockupdate(void);
    764 void dockdecorate(void);
    765 void dockreset(void);
    766 
    767 /* monitor routines */
    768 struct Monitor *getmon(int x, int y);
    769 void mondel(struct Monitor *mon);
    770 void monupdate(void);
    771 void monupdatearea(void);
    772 void fitmonitor(struct Monitor *mon, int *x, int *y, int *w, int *h, float factor);
    773 void moninit(void);
    774 void monevent(XEvent *e);
    775 
    776 /* wm hints and messages routines */
    777 void icccmdeletestate(Window win);
    778 void icccmwmstate(Window win, int state);
    779 void ewmhinit(const char *wmname);
    780 void ewmhsetdesktop(Window win, long d);
    781 void ewmhsetframeextents(Window win, int b, int t);
    782 void ewmhsetclients(void);
    783 void ewmhsetstate(struct Container *c);
    784 void ewmhsetwmdesktop(struct Container *c);
    785 void ewmhsetactivewindow(Window w);
    786 void ewmhsetcurrentdesktop(unsigned long n);
    787 void ewmhsetshowingdesktop(int n);
    788 void shodgrouptab(struct Container *c);
    789 void shodgroupcontainer(struct Container *c);
    790 void winupdatetitle(Window win, char **name);
    791 void winnotify(Window win, int x, int y, int w, int h);
    792 void winclose(Window win);
    793 
    794 /* decoration routines */
    795 void pixmapnew(Pixmap *pix, Window win, int w, int h);
    796 void drawcommit(Pixmap pix, Window win);
    797 void drawborders(Pixmap pix, int w, int h, int style);
    798 void drawbackground(Pixmap pix, int x, int y, int w, int h, int style);
    799 void drawframe(Pixmap pix, int isshaded, int w, int h, enum Octant o, int style);
    800 void drawshadow(Pixmap pix, int x, int y, int w, int h, int style, int pressed);
    801 void drawtitle(Drawable pix, const char *text, int w, int drawlines, int style, int pressed, int ismenu);
    802 void drawprompt(Pixmap pix, int w, int h);
    803 void drawdock(Pixmap pix, int w, int h);
    804 void buttonleftdecorate(Window button, Pixmap pix, int style, int pressed);
    805 void buttonrightdecorate(Window button, Pixmap pix, int style, int pressed);
    806 void cleantheme(void);
    807 void setresources(char *xrm);
    808 int settheme(void);
    809 
    810 /* window management routines */
    811 Managefunc managedockapp;
    812 Managefunc managedialog;
    813 Managefunc managesplash;
    814 Managefunc manageprompt;
    815 Managefunc managenotif;
    816 Managefunc managemenu;
    817 Managefunc managecontainer;
    818 Managefunc managebar;
    819 Unmanagefunc unmanagedockapp;
    820 Unmanagefunc unmanagedialog;
    821 Unmanagefunc unmanagesplash;
    822 Unmanagefunc unmanageprompt;
    823 Unmanagefunc unmanagenotif;
    824 Unmanagefunc unmanagemenu;
    825 Unmanagefunc unmanagecontainer;
    826 Unmanagefunc unmanagebar;
    827 void setmod(void);
    828 void scan(void);
    829 void deskupdate(struct Monitor *mon, int desk);
    830 int getwintype(Window *win_ret, Window *leader, struct Tab **tab, int *state, XRectangle *rect, int *desk);
    831 
    832 /* function tables */
    833 extern void (*managefuncs[])(struct Tab *, struct Monitor *, int, Window, Window, XRectangle, int, int);
    834 extern int (*unmanagefuncs[])(struct Object *, int);
    835 
    836 /* extern variables */
    837 extern XSetWindowAttributes clientswa;
    838 extern unsigned long clientmask;
    839 extern void (*xevents[LASTEvent])(XEvent *);
    840 extern struct Config config;
    841 extern struct WM wm;
    842 extern struct Dock dock;