commit ef17619b86100b7a822880030a5ce6bb679abb57
parent 93383968512b03e78976a9324e7e114e58f8062a
Author: seninha <lucas@seninha.org>
Date: Fri, 24 Jun 2022 11:29:19 -0300
use BSD queue.h
Diffstat:
M | shod.c | | | 2698 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
1 file changed, 1138 insertions(+), 1560 deletions(-)
diff --git a/shod.c b/shod.c
@@ -1,3 +1,4 @@
+#include <sys/queue.h>
#include <sys/wait.h>
#include <err.h>
@@ -33,7 +34,7 @@
#define LEN(x) (sizeof(x) / sizeof((x)[0]))
#define _SHOD_MOVERESIZE_RELATIVE ((long)(1 << 16))
-#define TITLEWIDTH(c) (((c)->isfullscreen && (c)->ncols == 1 && (c)->cols->nrows == 1) ? 0 : config.titlewidth)
+#define TITLEWIDTH(c) (((c)->isfullscreen && (c)->ncols == 1 && TAILQ_FIRST(&(c)->colq)->nrows == 1) ? 0 : config.titlewidth)
/* window type */
enum {
@@ -45,7 +46,8 @@ enum {
TYPE_NOTIFICATION,
TYPE_PROMPT,
TYPE_SPLASH,
- TYPE_DOCKAPP
+ TYPE_DOCKAPP,
+ TYPE_LAST
};
/* floating object type */
@@ -290,67 +292,29 @@ enum Octant {
SE = (1 << 1) | (1 << 3),
};
-/* structure returned by getwintype */
-struct Wintype {
- struct Tab *parent; /* window parent tab */
- Window leader; /* window leader */
- int type; /* window type */
- int dockpos; /* position of the dockapp in the dock */
-};
-
-/* struct returned by getwindow */
-struct Winres {
- struct Dock *dock; /* dock of window */
- struct Dockapp *dapp; /* dockapp of window */
- struct Bar *bar; /* bar of window */
- struct Notification *n; /* notification of window */
- struct Container *c; /* container of window */
- struct Row *row; /* row (with buttons) of window */
- struct Tab *t; /* tab of window */
- struct Dialog *d; /* dialog of window */
- struct Splash *splash; /* splash window */
- struct Menu *menu; /* menu of window */
-};
-
-/* dialog window structure */
-struct Dialog {
- struct Dialog *prev, *next; /* pointer for list of dialogs */
- struct Tab *t; /* pointer to parent tab */
- Window frame; /* window to reparent the client window */
- Window win; /* actual client window */
- Pixmap pix; /* pixmap to draw the frame */
- int x, y, w, h; /* geometry of the dialog inside the tab frame */
- int maxw, maxh; /* maximum size of the dialog */
- int pw, ph; /* pixmap size */
- int ignoreunmap; /* number of unmapnotifys to ignore */
+/* data of a monitor */
+TAILQ_HEAD(MonitorQueue, Monitor);
+struct Monitor {
+ TAILQ_ENTRY(Monitor) entry;
+ int seldesk; /* focused desktop on that monitor */
+ int mx, my, mw, mh; /* monitor size */
+ int wx, wy, ww, wh; /* window area */
};
-/* tab structure */
-struct Tab {
- struct Tab *prev, *next; /* pointer for list of tabs */
- struct Row *row; /* pointer to parent row */
- struct Dialog *ds; /* pointer to list of dialogs */
- struct Menu *menus; /* pointer to list of menus */
- Window title; /* title bar */
- Window win; /* actual client window */
- Window frame; /* window to reparent the client window */
- Window leader; /* the group leader of the window */
- Pixmap pix; /* pixmap to draw the background of the frame */
- Pixmap pixtitle; /* pixmap to draw the background of the title window */
- char *name; /* client name */
- int ignoreunmap; /* number of unmapnotifys to ignore */
- int isurgent; /* whether tab is urgent */
- int winw, winh; /* window geometry */
- int x, w; /* tab geometry */
- int ptw; /* pixmap width for the title window */
- int pw, ph; /* pixmap size of the frame */
+/* managed object */
+TAILQ_HEAD(Queue, Object);
+struct Object {
+ TAILQ_ENTRY(Object) entry;
+ Window win;
+ int type;
};
/* row of tiled container */
+TAILQ_HEAD(RowQueue, Row);
struct Row {
- struct Row *prev, *next; /* pointer for list of rows */
+ TAILQ_ENTRY(Row) entry;
+ struct Queue tabq; /* list of tabs */
struct Column *col; /* pointer to parent column */
- struct Tab *tabs; /* list of tabs */
struct Tab *seltab; /* pointer to selected tab */
Window div; /* horizontal division between rows */
Window frame; /* where tab frames are */
@@ -367,10 +331,11 @@ struct Row {
};
/* column of tiled container */
+TAILQ_HEAD(ColumnQueue, Column);
struct Column {
- struct Column *prev, *next; /* pointers for list of columns */
+ TAILQ_ENTRY(Column) entry;
+ struct RowQueue rowq; /* list of rows */
struct Container *c; /* pointer to parent container */
- struct Row *rows; /* list of rows */
struct Row *selrow; /* pointer to selected row */
struct Row *maxrow; /* maximized row */
Window div; /* vertical division between columns */
@@ -380,17 +345,17 @@ struct Column {
};
/* container structure */
+TAILQ_HEAD(ContainerQueue, Container);
struct Container {
- struct Container *prev, *next; /* pointers for list of containers */
- struct Container *fprev, *fnext; /* pointers for list of containers in decrescent focus order */
- struct Container *rprev, *rnext; /* pointers for list of containers from raised to lowered */
+ TAILQ_ENTRY(Container) entry;
+ TAILQ_ENTRY(Container) raiseentry;
+ struct ColumnQueue colq; /* list of columns in container */
struct Monitor *mon; /* monitor container is on */
- struct Desktop *desk; /* desktop container is on */
- struct Column *cols; /* list of columns in container */
struct Column *selcol; /* pointer to selected container */
Window curswin[BORDER_LAST]; /* dummy window used for change cursor while hovering borders */
Window frame; /* window to reparent the contents of the container */
Pixmap pix; /* pixmap to draw the frame */
+ int desk; /* desktop container is on */
int ncols; /* number of columns */
int ismaximized, issticky; /* window states */
int isminimized, isshaded; /* window states */
@@ -402,14 +367,45 @@ struct Container {
int nx, ny, nw, nh; /* non-maximized geometry */
};
+/* tab structure */
+struct Tab {
+ struct Object obj;
+ struct Queue dialq; /* queue of dialogs */
+ struct Queue menuq; /* queue of menus */
+ struct Row *row; /* pointer to parent row */
+ Window title; /* title bar */
+ Window frame; /* window to reparent the client window */
+ Window leader; /* the group leader of the window */
+ Pixmap pix; /* pixmap to draw the background of the frame */
+ Pixmap pixtitle; /* pixmap to draw the background of the title window */
+ char *name; /* client name */
+ int ignoreunmap; /* number of unmapnotifys to ignore */
+ int isurgent; /* whether tab is urgent */
+ int winw, winh; /* window geometry */
+ int x, w; /* tab geometry */
+ int ptw; /* pixmap width for the title window */
+ int pw, ph; /* pixmap size of the frame */
+};
+
+/* dialog window structure */
+struct Dialog {
+ struct Object obj;
+ struct Tab *tab; /* pointer to parent tab */
+ Window frame; /* window to reparent the client window */
+ Pixmap pix; /* pixmap to draw the frame */
+ int x, y, w, h; /* geometry of the dialog inside the tab frame */
+ int maxw, maxh; /* maximum size of the dialog */
+ int pw, ph; /* pixmap size */
+ int ignoreunmap; /* number of unmapnotifys to ignore */
+};
+
/* menu structure */
struct Menu {
- struct Menu *prev, *next; /* pointers for list of menus */
- struct Tab *t; /* pointer to parent tab */
+ struct Object obj;
+ struct Tab *tab; /* pointer to parent tab */
Window titlebar; /* close button */
Window button; /* close button */
Window frame; /* frame window */
- Window win; /* the actual menu window */
Pixmap pix; /* pixmap to draw the frame */
Pixmap pixbutton; /* pixmap to draw the button */
Pixmap pixtitlebar; /* pixmap to draw the titlebar */
@@ -420,24 +416,16 @@ struct Menu {
char *name; /* client name */
};
-/* desktop of a monitor */
-struct Desktop {
- struct Monitor *mon; /* monitor the desktop is in */
- int n; /* desktop number */
-};
-
/* bar (aka dock or panel) */
struct Bar {
- struct Bar *prev, *next; /* pointers for list of bars */
- Window win; /* bar window */
+ struct Object obj;
int strut[STRUT_LAST]; /* strut values */
int partial; /* strut has 12 elements rather than 4 */
};
/* docked application */
struct Dockapp {
- struct Dockapp *prev, *next;
- Window win; /* dockapp window */
+ struct Object obj;
int x, y, w, h; /* dockapp position and size */
int ignoreunmap; /* number of unmap requests to ignore */
int dockpos; /* position of the dockapp in the dock */
@@ -445,31 +433,27 @@ struct Dockapp {
/* splash screen window */
struct Splash {
- struct Splash *prev, *next; /* pointers for list of splash windows */
- Window win; /* actual client window */
+ struct Object obj;
int x, y, w, h; /* splash screen geometry */
};
-/* data of a monitor */
-struct Monitor {
- struct Monitor *prev, *next; /* pointers for list of monitors */
- struct Desktop *desks; /* array of desktops */
- struct Desktop *seldesk; /* pointer to focused desktop on that monitor */
- int mx, my, mw, mh; /* monitor size */
- int wx, wy, ww, wh; /* window area */
- int n; /* monitor number */
-};
-
/* notification structure */
struct Notification {
- struct Notification *prev, *next; /* pointers for list of notifications */
+ struct Object obj;
Window frame; /* window to reparent the actual client window */
- Window win; /* actual client window */
Pixmap pix; /* pixmap to draw the frame */
int w, h; /* geometry of the entire thing (content + decoration) */
int pw, ph; /* pixmap width and height */
};
+/* structure returned by getwintype */
+struct Wintype {
+ struct Tab *parent; /* window parent tab */
+ Window leader; /* window leader */
+ int type; /* window type */
+ int dockpos; /* position of the dockapp in the dock */
+};
+
/* prompt structure, used only when calling promptisvalid() */
struct Prompt {
Window win, frame; /* actual client window and its frame */
@@ -491,7 +475,7 @@ struct Theme {
/* the dock */
struct Dock {
- struct Dockapp *head, *tail; /* list of dockapps */
+ struct Queue dappq;
Window win; /* dock window */
Pixmap pix; /* dock pixmap */
int x, y, w, h; /* dock geometry */
@@ -510,16 +494,15 @@ struct MwmHints {
/* window manager stuff */
struct WM {
- struct Bar *bars; /* list of bars */
- struct Splash *splashlist; /* list of splash screen windows */
- struct Monitor *monhead, *montail; /* list of monitors */
- struct Notification *nhead, *ntail; /* list of notifications */
- struct Container *c; /* list of containers */
- struct Container *focuslist; /* list of containers ordered by focus history */
- struct Container *fulllist; /* list of containers ordered from topmost to bottommost */
- struct Container *abovelist; /* list of containers ordered from topmost to bottommost */
- struct Container *centerlist; /* list of containers ordered from topmost to bottommost */
- struct Container *belowlist; /* list of containers ordered from topmost to bottommost */
+ struct MonitorQueue monq; /* queue of monitors */
+ struct Queue barq; /* queue of bars */
+ struct Queue splashq; /* queue of splash screen windows */
+ struct Queue notifq; /* queue of notifications */
+ struct ContainerQueue focusq; /* queue of containers ordered by focus history */
+ struct ContainerQueue fullq; /* queue of containers ordered from topmost to bottommost */
+ struct ContainerQueue aboveq; /* queue of containers ordered from topmost to bottommost */
+ struct ContainerQueue centerq; /* queue of containers ordered from topmost to bottommost */
+ struct ContainerQueue belowq; /* queue of containers ordered from topmost to bottommost */
struct Container *focused; /* pointer to focused container */
struct Container *prevfocused; /* pointer to previously focused container */
struct Monitor *selmon; /* pointer to selected monitor */
@@ -1078,6 +1061,7 @@ initdock(void)
{
XSetWindowAttributes swa;
+ TAILQ_INIT(&dock.dappq);
dock.pix = None;
swa.event_mask = SubstructureNotifyMask | SubstructureRedirectMask | ExposureMask;
swa.background_pixel = BlackPixel(dpy, screen);
@@ -1087,98 +1071,57 @@ initdock(void)
depth, InputOutput, visual, clientmask, &swa);
}
-/* get pointer to proper structure given a window */
-static struct Winres
-getwin(Window win)
+#define GETMANAGED(type, head, p, w) \
+ TAILQ_FOREACH(p, &(head), entry) \
+ if (p->win == w) \
+ return (p); \
+
+/* get pointer to managed object given a window */
+static struct Object *
+getmanaged(Window win)
{
- struct Winres res;
- struct Dockapp *dapp;
- struct Bar *bar;
+ struct Object *p, *tab, *dial, *menu;
struct Container *c;
struct Column *col;
struct Row *row;
- struct Tab *t;
- struct Dialog *d;
- struct Menu *menu;
- struct Splash *splash;
- struct Notification *n;
int i;
- res = (struct Winres){0};
- if (win == dock.win) {
- res.dock = &dock;
- return res;
- }
- for (dapp = dock.head; dapp != NULL; dapp = dapp->next) {
- if (win == dapp->win) {
- res.dapp = dapp;
- return res;
- }
- }
- for (bar = wm.bars; bar != NULL; bar = bar->next) {
- if (win == bar->win) {
- res.bar = bar;
- return res;
- }
- }
- for (n = wm.nhead; n != NULL; n = n->next) {
- if (win == n->frame || win == n->win) {
- res.n = n;
- return res;
- }
- }
- for (splash = wm.splashlist; splash != NULL; splash = splash->next) {
- if (win == splash->win) {
- res.splash = splash;
- return res;
- }
- }
- for (c = wm.c; c != NULL; c = c->next) {
- if (win == c->frame) {
- res.c = c;
- return res;
- }
- for (i = 0; i < BORDER_LAST; i++) {
- if (win == c->curswin[i]) {
- res.c = c;
- return res;
- }
- }
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- if (win == row->bar || win == row->bl || win == row->br) {
- res.c = c;
- res.row = row;
- return res;
- }
- for (t = row->tabs; t != NULL; t = t->next) {
- if (win == t->win || win == t->frame || win == t->title) {
- res.c = c;
- res.t = t;
- return res;
- }
- for (d = t->ds; d != NULL; d = d->next) {
- if (win == d->win || win == d->frame) {
- res.c = c;
- res.t = t;
- res.d = d;
- return res;
- }
- }
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- if (win == menu->win || win == menu->frame || win == menu->button || win == menu->titlebar) {
- res.c = c;
- res.t = t;
- res.menu = menu;
- return res;
+ GETMANAGED(Dockapp, dock.dappq, p, win)
+ GETMANAGED(Bar, wm.barq, p, win)
+ GETMANAGED(Notification, wm.notifq, p, win)
+ GETMANAGED(Splash, wm.splashq, p, win)
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
+ if (c->frame == win)
+ return (struct Object *)c->selcol->selrow->seltab;
+ for (i = 0; i < BORDER_LAST; i++)
+ if (c->curswin[i] == win)
+ return (struct Object *)c->selcol->selrow->seltab;
+ TAILQ_FOREACH(col, &(c)->colq, entry) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
+ if (row->bar == win || row->bl == win || row->br == win)
+ return (struct Object *)row->seltab;
+ TAILQ_FOREACH(tab, &row->tabq, entry) {
+ if (tab->win == win ||
+ ((struct Tab *)tab)->frame == win ||
+ ((struct Tab *)tab)->title == win)
+ return tab;
+ TAILQ_FOREACH(dial, &((struct Tab *)tab)->dialq, entry) {
+ if (dial->win == win ||
+ ((struct Dialog *)dial)->frame == win)
+ return dial;
}
+ TAILQ_FOREACH(menu, &((struct Tab *)tab)->menuq, entry) {
+ if (menu->win == win ||
+ ((struct Menu *)menu)->frame == win ||
+ ((struct Menu *)menu)->button == win ||
+ ((struct Menu *)menu)->titlebar == win)
+ return menu;
}
}
}
}
-
}
- return res;
+ return NULL;
}
/* get monitor given coordinates */
@@ -1187,9 +1130,8 @@ getmon(int x, int y)
{
struct Monitor *mon;
- for (mon = wm.monhead; mon; mon = mon->next)
- if (x >= mon->mx && x <= mon->mx + mon->mw &&
- y >= mon->my && y <= mon->my + mon->mh)
+ TAILQ_FOREACH(mon, &wm.monq, entry)
+ if (x >= mon->mx && x <= mon->mx + mon->mw && y >= mon->my && y <= mon->my + mon->mh)
return mon;
return NULL;
}
@@ -1262,31 +1204,41 @@ getmwmhints(Window win)
static struct Tab *
getdialogfor(Window win)
{
- struct Winres res;
+ struct Object *obj;
Window tmpwin;
if (XGetTransientForHint(dpy, win, &tmpwin)) {
- res = getwin(tmpwin);
- return res.t;
+ obj = getmanaged(tmpwin);
+ if (obj->type == TYPE_NORMAL) {
+ return (struct Tab *)obj;
+ }
}
return NULL;
}
+#define TAB_FOREACH_BEGIN(c, tab) { \
+ struct Column *col; \
+ struct Row *row; \
+ TAILQ_FOREACH(col, &(c)->colq, entry) { \
+ TAILQ_FOREACH(row, &col->rowq, entry) { \
+ TAILQ_FOREACH(tab, &row->tabq, entry)
+#define TAB_FOREACH_END } \
+ } \
+ }
+
/* get tab equal to leader or having leader as group leader */
static struct Tab *
getleaderof(Window leader)
{
struct Container *c;
- struct Column *col;
- struct Row *row;
- struct Tab *t;
+ struct Object *tab;
- for (c = wm.c; c != NULL; c = c->next)
- for (col = c->cols; col != NULL; col = col->next)
- for (row = col->rows; row != NULL; row = row->next)
- for (t = row->tabs; t != NULL; t = t->next)
- if (t->win == leader || t->leader == leader)
- return t;
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
+ TAB_FOREACH_BEGIN(c, tab){
+ if (tab->win == leader || ((struct Tab *)tab)->leader == leader)
+ return (struct Tab *)tab;
+ }TAB_FOREACH_END
+ }
return NULL;
}
@@ -1437,11 +1389,11 @@ clientsdecr(void)
/* get focused fullscreen window in given monitor and desktop */
static struct Container *
-getfullscreen(struct Monitor *mon, struct Desktop *desk)
+getfullscreen(struct Monitor *mon, int desk)
{
struct Container *c;
- for (c = wm.fulllist; c != NULL; c = c->rnext)
+ TAILQ_FOREACH(c, &wm.fullq, raiseentry)
if (!c->isminimized && c->mon == mon && (c->issticky || c->desk == desk))
return c;
return NULL;
@@ -1449,110 +1401,16 @@ getfullscreen(struct Monitor *mon, struct Desktop *desk)
/* get next focused container after old on given monitor and desktop */
static struct Container *
-getnextfocused(struct Monitor *mon, struct Desktop *desk)
-{
- struct Container *c;
-
- for (c = wm.focuslist; c != NULL; c = c->fnext) {
- if (c->mon == mon && (c->issticky || c->desk == desk)) {
- break;
- }
- }
- return c;
-}
-
-/* get next focused container in given direction from rel (relative) */
-static struct Container *
-getfocusedbydirection(struct Container *rel, int dir)
-{
- struct Monitor *mon;
- struct Desktop *desk;
- struct Container *c, *ret;
- int retx, rety, relx, rely, x, y;
-
- ret = NULL;
- relx = rel->x + rel->w / 2;
- rely = rel->y + rel->h / 2;
- mon = rel->mon;
- desk = rel->issticky ? rel->mon->seldesk : rel->desk;
- for (c = wm.focuslist; c != NULL; c = c->fnext) {
- if (c == rel || c->isminimized)
- continue;
- if (c->mon == mon && (c->issticky || c->desk == desk)) {
- x = c->x + c->w / 2;
- y = c->y + c->h / 2;
- switch (dir) {
- case _SHOD_FOCUS_LEFT_CONTAINER:
- if (x <= relx && (ret == NULL || x > retx))
- ret = c;
- break;
- case _SHOD_FOCUS_RIGHT_CONTAINER:
- if (x >= relx && (ret == NULL || x < retx))
- ret = c;
- break;
- case _SHOD_FOCUS_TOP_CONTAINER:
- if (y <= rely && (ret == NULL || y > rety))
- ret = c;
- break;
- case _SHOD_FOCUS_BOTTOM_CONTAINER:
- if (y >= rely && (ret == NULL || y < rety))
- ret = c;
- break;
- default:
- return NULL;
- }
- if (ret != NULL) {
- retx = ret->x + ret->w / 2;
- rety = ret->y + ret->h / 2;
- }
- }
- }
- return ret;
-}
-
-/* get first focused container in the same monitor and desktop of rel */
-static struct Container *
-getfirstfocused(struct Container *rel)
+getnextfocused(struct Monitor *mon, int desk)
{
- struct Monitor *mon;
- struct Desktop *desk;
struct Container *c;
- mon = rel->mon;
- desk = rel->issticky ? rel->mon->seldesk : rel->desk;
- for (c = wm.focuslist; c != NULL; c = c->fnext) {
- if (c == rel)
- return NULL;
- if (c->isminimized)
- continue;
- if (c->mon == mon && (c->issticky || c->desk == desk)) {
+ TAILQ_FOREACH(c, &wm.focusq, entry)
+ if (c->mon == mon && (c->issticky || c->desk == desk))
return c;
- }
- }
return NULL;
}
-/* get last focused container in the same monitor and desktop of rel */
-static struct Container *
-getlastfocused(struct Container *rel)
-{
- struct Monitor *mon;
- struct Desktop *desk;
- struct Container *c, *ret;
-
- ret = NULL;
- mon = rel->mon;
- desk = rel->issticky ? rel->mon->seldesk : rel->desk;
- for (c = rel; c != NULL; c = c->fnext) {
- if (c->isminimized)
- continue;
- if (c != rel && c->mon == mon && (c->issticky || c->desk == desk)) {
- ret = c;
- }
- }
- return ret;
-}
-
/* get pointer position within a container */
static enum Octant
getoctant(struct Container *c, int x, int y)
@@ -1588,14 +1446,14 @@ getdivisions(struct Container *c, struct Column **cdiv, struct Row **rdiv, int x
*cdiv = NULL;
*rdiv = NULL;
- for (col = c->cols; col != NULL; col = col->next) {
- if (col->next != NULL && x >= col->x + col->w && x < col->x + col->w + config.divwidth) {
+ TAILQ_FOREACH(col, &c->colq, entry) {
+ if (TAILQ_NEXT(col, entry) != NULL && x >= col->x + col->w && x < col->x + col->w + config.divwidth) {
*cdiv = col;
return;
}
if (x >= col->x && x < col->x + col->w) {
- for (row = col->rows; row != NULL; row = row->next) {
- if (row->next != NULL && y >= row->y + row->h && y < row->y + row->h + config.divwidth) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
+ if (TAILQ_NEXT(row, entry) != NULL && y >= row->y + row->h && y < row->y + row->h + config.divwidth) {
*rdiv = row;
return;
}
@@ -1604,28 +1462,6 @@ getdivisions(struct Container *c, struct Column **cdiv, struct Row **rdiv, int x
}
}
-/* get pointer to nth desktop in focused monitor */
-static struct Desktop *
-getdesk(long int n, long int m)
-{
- struct Monitor *mon, *tmp;
- long int i;
-
- if (n < 0 || n >= config.ndesktops)
- return NULL;
- if (m == 0) {
- return &wm.selmon->desks[n];
- } else {
- mon = NULL;
- for (i = 0, tmp = wm.selmon; i < m && tmp != NULL; i++, tmp = tmp->next)
- mon = tmp;
- if (mon != NULL) {
- return &mon->desks[n];
- }
- }
- return NULL;
-}
-
/* check whether window was placed by the user */
static int
isuserplaced(Window win)
@@ -1689,10 +1525,8 @@ ewmhsetshowingdesktop(int n)
static void
ewmhsetclients(void)
{
+ struct Object *tab;
struct Container *c;
- struct Column *col;
- struct Row *row;
- struct Tab *t;
Window *wins = NULL;
int i = 0;
@@ -1701,49 +1535,46 @@ ewmhsetclients(void)
return;
}
wins = ecalloc(wm.nclients, sizeof *wins);
- for (c = wm.c; c != NULL; c = c->next) {
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- wins[i++] = t->win;
- }
- }
- }
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
+ TAB_FOREACH_BEGIN(c, tab){
+ wins[i++] = tab->win;
+ }TAB_FOREACH_END
}
XChangeProperty(dpy, root, atoms[_NET_CLIENT_LIST], XA_WINDOW, 32, PropModeReplace, (unsigned char *)wins, i);
free(wins);
}
-#define LOOPSTACKING(array, list, index) { \
- struct Container *c; \
- struct Column *col; \
- struct Row *row; \
- struct Tab *t; \
- \
- for (c = (list); c != NULL; c = c->rnext) { \
- for (col = c->cols; col != NULL; col = col->next) { \
- if (col->selrow != NULL) { \
- if (col->selrow->seltab != NULL) \
- (array)[--(index)] = col->selrow->seltab->win; \
- for (t = col->selrow->tabs; t != NULL; t = t->next) { \
- if (t != col->selrow->seltab) { \
- (array)[--(index)] = t->win; \
- } \
- } \
- } \
- for (row = col->rows; row != NULL; row = row->next) { \
- if (row == col->selrow) \
- continue; \
- if (row->seltab != NULL) \
- (array)[--(index)] = row->seltab->win; \
- for (t = row->tabs; t != NULL; t = t->next) { \
- if (t != row->seltab) { \
- (array)[--(index)] = t->win; \
- } \
- } \
- } \
- } \
- } \
+#define LOOPSTACKING(array, list, index) { \
+ struct Container *c; \
+ struct Column *col; \
+ struct Row *row; \
+ struct Object *p; \
+ struct Tab *t; \
+ \
+ TAILQ_FOREACH(c, &(list), raiseentry) { \
+ TAILQ_FOREACH(col, &c->colq, entry) { \
+ if (col->selrow->seltab != NULL) \
+ (array)[--(index)] = col->selrow->seltab->obj.win; \
+ TAILQ_FOREACH(p, &col->selrow->tabq, entry) { \
+ t = (struct Tab *)p; \
+ if (t != col->selrow->seltab) { \
+ (array)[--(index)] = t->obj.win; \
+ } \
+ } \
+ TAILQ_FOREACH(row, &col->rowq, entry) { \
+ if (row == col->selrow) \
+ continue; \
+ if (row->seltab != NULL) \
+ (array)[--(index)] = row->seltab->obj.win; \
+ TAILQ_FOREACH(p, &row->tabq, entry) { \
+ t = (struct Tab *)p; \
+ if (t != row->seltab) { \
+ (array)[--(index)] = t->obj.win; \
+ } \
+ } \
+ } \
+ } \
+ } \
}
/* set stacking list of clients hint */
@@ -1759,10 +1590,10 @@ ewmhsetclientsstacking(void)
}
wins = ecalloc(wm.nclients, sizeof *wins);
i = wm.nclients;
- LOOPSTACKING(wins, wm.fulllist, i)
- LOOPSTACKING(wins, wm.abovelist, i)
- LOOPSTACKING(wins, wm.centerlist, i)
- LOOPSTACKING(wins, wm.belowlist, i)
+ LOOPSTACKING(wins, wm.fullq, i)
+ LOOPSTACKING(wins, wm.aboveq, i)
+ LOOPSTACKING(wins, wm.centerq, i)
+ LOOPSTACKING(wins, wm.belowq, i)
XChangeProperty(dpy, root, atoms[_NET_CLIENT_LIST_STACKING], XA_WINDOW, 32, PropModeReplace, (unsigned char *)wins+i, wm.nclients-i);
free(wins);
}
@@ -1785,23 +1616,13 @@ ewmhsetdesktop(Window win, long d)
static void
ewmhsetwmdesktop(struct Container *c)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
- struct Dialog *d;
- long n;
+ struct Object *t;
+ unsigned long n;
- n = (c->issticky || c->isminimized) ? 0xFFFFFFFF : c->desk->n;
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- ewmhsetdesktop(t->win, n);
- for (d = t->ds; d; d = d->next) {
- ewmhsetdesktop(d->win, n);
- }
- }
- }
- }
+ n = (c->issticky || c->isminimized) ? 0xFFFFFFFF : (unsigned long)c->desk;
+ TAB_FOREACH_BEGIN(c, t){
+ ewmhsetdesktop(t->win, n);
+ }TAB_FOREACH_END
}
/* set frames of window */
@@ -1819,10 +1640,7 @@ ewmhsetframeextents(Window win, int b, int t)
static void
ewmhsetstate(struct Container *c)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
- struct Dialog *d;
+ struct Object *t;
Atom data[9];
int n = 0;
@@ -1846,66 +1664,31 @@ ewmhsetstate(struct Container *c)
data[n++] = atoms[_NET_WM_STATE_ABOVE];
else if (c->layer < 0)
data[n++] = atoms[_NET_WM_STATE_BELOW];
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- XChangeProperty(dpy, t->win, atoms[_NET_WM_STATE], XA_ATOM, 32, PropModeReplace, (unsigned char *)data, n);
- for (d = t->ds; d != NULL; d = d->next) {
- XChangeProperty(dpy, d->win, atoms[_NET_WM_STATE], XA_ATOM, 32, PropModeReplace, (unsigned char *)data, n);
- }
- }
- }
- }
+ TAB_FOREACH_BEGIN(c, t){
+ XChangeProperty(dpy, t->win, atoms[_NET_WM_STATE], XA_ATOM, 32, PropModeReplace, (unsigned char *)data, n);
+ }TAB_FOREACH_END
}
/* set group of windows in client */
static void
shodgrouptab(struct Container *c)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
- struct Dialog *d;
- struct Menu *menu;
+ struct Object *t;
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- XChangeProperty(dpy, t->win, atoms[_SHOD_GROUP_TAB], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&row->seltab->win, 1);
- for (d = t->ds; d != NULL; d = d->next) {
- XChangeProperty(dpy, d->win, atoms[_SHOD_GROUP_TAB], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&row->seltab->win, 1);
- }
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- XChangeProperty(dpy, menu->win, atoms[_SHOD_GROUP_TAB], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&row->seltab->win, 1);
- }
- }
- }
- }
+ TAB_FOREACH_BEGIN(c, t){
+ XChangeProperty(dpy, t->win, atoms[_SHOD_GROUP_TAB], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&row->seltab->obj.win, 1);
+ }TAB_FOREACH_END
}
/* set group of windows in client */
static void
shodgroupcontainer(struct Container *c)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
- struct Dialog *d;
- struct Menu *menu;
+ struct Object *t;
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- XChangeProperty(dpy, t->win, atoms[_SHOD_GROUP_CONTAINER], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&c->selcol->selrow->seltab->win, 1);
- for (d = t->ds; d != NULL; d = d->next) {
- XChangeProperty(dpy, d->win, atoms[_SHOD_GROUP_CONTAINER], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&c->selcol->selrow->seltab->win, 1);
- }
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- XChangeProperty(dpy, menu->win, atoms[_SHOD_GROUP_CONTAINER], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&c->selcol->selrow->seltab->win, 1);
- }
- }
- }
- }
+ TAB_FOREACH_BEGIN(c, t){
+ XChangeProperty(dpy, t->win, atoms[_SHOD_GROUP_CONTAINER], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&c->selcol->selrow->seltab->obj.win, 1);
+ }TAB_FOREACH_END
}
/* send a WM_DELETE message to client */
@@ -2005,18 +1788,7 @@ tabgetstyle(struct Tab *t)
static int
containergetstyle(struct Container *c)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
-
- if (c == wm.focused)
- return FOCUSED;
- for (col = c->cols; col != NULL; col = col->next)
- for (row = col->rows; row != NULL; row = row->next)
- for (t = row->tabs; t != NULL; t = t->next)
- if (t->isurgent)
- return URGENT;
- return UNFOCUSED;
+ return (c == wm.focused) ? FOCUSED : UNFOCUSED;
}
/* check if container can be shaded */
@@ -2028,27 +1800,30 @@ containerisshaded(struct Container *c)
/* calculate size of dialogs of a tab */
static void
-dialogcalcsize(struct Dialog *d)
+dialogcalcsize(struct Dialog *dial)
{
- struct Tab *t;
+ struct Tab *tab;
- t = d->t;
- d->w = max(1, min(d->maxw, t->winw - 2 * config.borderwidth));
- d->h = max(1, min(d->maxh, t->winh - 2 * config.borderwidth));
- d->x = t->winw / 2 - d->w / 2;
- d->y = t->winh / 2 - d->h / 2;
+ tab = dial->tab;
+ dial->w = max(1, min(dial->maxw, tab->winw - 2 * config.borderwidth));
+ dial->h = max(1, min(dial->maxh, tab->winh - 2 * config.borderwidth));
+ dial->x = tab->winw / 2 - dial->w / 2;
+ dial->y = tab->winh / 2 - dial->h / 2;
}
/* calculate position and width of tabs of a row */
static void
rowcalctabs(struct Row *row)
{
+ struct Object *p, *q;
struct Dialog *d;
struct Tab *t;
int i, x;
x = config.titlewidth;
- for (i = 0, t = row->tabs; t != NULL; t = t->next, i++) {
+ i = 0;
+ TAILQ_FOREACH(p, &row->tabq, entry) {
+ t = (struct Tab *)p;
if (row == row->col->maxrow)
t->winh = max(1, row->col->c->h - 2 * row->col->c->b - row->col->nrows * config.titlewidth);
else
@@ -2057,9 +1832,11 @@ rowcalctabs(struct Row *row)
t->w = max(1, ((i + 1) * (t->winw - 2 * config.titlewidth) / row->ntabs) - (i * (t->winw - 2 * config.titlewidth) / row->ntabs));
t->x = x;
x += t->w;
- for (d = t->ds; d != NULL; d = d->next) {
+ TAILQ_FOREACH(q, &t->dialq, entry) {
+ d = (struct Dialog *)q;
dialogcalcsize(d);
}
+ i++;
}
}
@@ -2079,9 +1856,9 @@ colcalcrows(struct Column *col, int recalcfact, int recursive)
content = c->h - (col->nrows - 1) * config.divwidth - 2 * c->b;
sumh = 0;
recalc = 0;
- for (row = col->rows; row != NULL; row = row->next) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
if (!recalcfact) {
- if (row->next == NULL) {
+ if (TAILQ_NEXT(row, entry) == NULL) {
row->h = content - sumh;
} else {
row->h = row->fact * content;
@@ -2103,16 +1880,17 @@ colcalcrows(struct Column *col, int recalcfact, int recursive)
h = col->c->h - 2 * c->b - (col->nrows - 1) * config.divwidth;
y = c->b;
}
- for (i = 0, row = col->rows; row != NULL; row = row->next, i++) {
+ i = 0;
+ TAILQ_FOREACH(row, &col->rowq, entry) {
if (recalc)
row->h = max(1, ((i + 1) * h / col->nrows) - (i * h / col->nrows));
if (recalc || recalcfact)
row->fact = (double)row->h/(double)c->h;
row->y = y;
y += row->h + config.divwidth;
- if (recursive) {
+ if (recursive)
rowcalctabs(row);
- }
+ i++;
}
}
@@ -2153,9 +1931,9 @@ containercalccols(struct Container *c, int recalcfact, int recursive)
content = c->w - (c->ncols - 1) * config.divwidth - 2 * c->b;
sumw = 0;
recalc = 0;
- for (col = c->cols; col != NULL; col = col->next) {
+ TAILQ_FOREACH(col, &c->colq, entry) {
if (!recalcfact) {
- if (col->next == NULL) {
+ if (TAILQ_NEXT(col, entry) == NULL) {
col->w = content - sumw;
} else {
col->w = col->fact * content;
@@ -2171,19 +1949,19 @@ containercalccols(struct Container *c, int recalcfact, int recursive)
w = c->w - 2 * c->b - (c->ncols - 1) * config.divwidth;
x = c->b;
- for (i = 0, col = c->cols; col != NULL; col = col->next, i++) {
- if (containerisshaded(c)) {
+ i = 0;
+ TAILQ_FOREACH(col, &c->colq, entry) {
+ if (containerisshaded(c))
c->h = max(c->h, col->nrows * config.titlewidth);
- }
if (recalc)
col->w = max(1, ((i + 1) * w / c->ncols) - (i * w / c->ncols));
if (recalc || recalcfact)
col->fact = (double)col->w/(double)c->w;
col->x = x;
x += col->w + config.divwidth;
- if (recursive) {
+ if (recursive)
colcalcrows(col, recalcfact, 1);
- }
+ i++;
}
if (containerisshaded(c)) {
c->h += 2 * c->b;
@@ -2192,9 +1970,8 @@ containercalccols(struct Container *c, int recalcfact, int recursive)
/* find best position to place a container on screen */
static void
-containerplace(struct Container *c, struct Desktop *desk, int userplaced)
+containerplace(struct Container *c, struct Monitor *mon, int desk, int userplaced)
{
- struct Monitor *mon;
struct Container *tmp;
int grid[DIV][DIV] = {{0}, {0}};
int lowest;
@@ -2204,10 +1981,9 @@ containerplace(struct Container *c, struct Desktop *desk, int userplaced)
int subx, suby; /* position of the larger subregion */
int subw, subh; /* larger subregion width and height */
- if (desk == NULL || c == NULL || c->isminimized)
+ if (desk < 0 || desk >= config.ndesktops || c == NULL || c->isminimized)
return;
- mon = desk->mon;
fitmonitor(mon, &c->nx, &c->ny, &c->nw, &c->nh, 1.0);
/* if the user placed the window, we should not re-place it */
@@ -2232,7 +2008,7 @@ containerplace(struct Container *c, struct Desktop *desk, int userplaced)
*/
/* increment cells of grid a window is in */
- for (tmp = wm.c; tmp; tmp = tmp->next) {
+ TAILQ_FOREACH(tmp, &wm.focusq, entry) {
if (tmp != c && !tmp->isminimized && ((tmp->issticky && tmp->mon == mon) || tmp->desk == desk)) {
for (i = 0; i < DIV; i++) {
for (j = 0; j < DIV; j++) {
@@ -2383,7 +2159,7 @@ dialogdecorate(struct Dialog *d)
unsigned long *decor;
int fullw, fullh; /* size of dialog window + borders */
- decor = theme.border[tabgetstyle(d->t)];
+ decor = theme.border[tabgetstyle(d->tab)];
fullw = d->w + 2 * config.borderwidth;
fullh = d->h + 2 * config.borderwidth;
@@ -2594,8 +2370,7 @@ containerdecorate(struct Container *c, struct Column *cdiv, struct Row *rdiv, in
{
struct Column *col;
struct Row *row;
- struct Tab *t;
- struct Dialog *d;
+ struct Object *t, *d;
XRectangle *recs;
XGCValues val;
unsigned long *decor;
@@ -2771,17 +2546,17 @@ containerdecorate(struct Container *c, struct Column *cdiv, struct Row *rdiv, in
}
}
- for (col = c->cols; col != NULL; col = col->next) {
+ TAILQ_FOREACH(col, &c->colq, entry) {
/* draw column division */
- if (col->next != NULL) {
+ if (TAILQ_NEXT(col, entry) != NULL) {
drawrectangle(c->pix, col->x + col->w, c->b, config.divwidth, c->h - 2 * c->b,
(col == cdiv ? decor[COLOR_DARK] : decor[COLOR_LIGHT]),
(col == cdiv ? decor[COLOR_LIGHT] : decor[COLOR_DARK]));
}
- for (row = col->rows; row != NULL; row = row->next) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
/* draw row division */
- if (!isshaded && col->maxrow == NULL && row->next != NULL) {
+ if (TAILQ_NEXT(row, entry) != NULL) {
drawrectangle(c->pix, col->x, row->y + row->h, col->w, config.divwidth,
(row == rdiv ? decor[COLOR_DARK] : decor[COLOR_LIGHT]),
(row == rdiv ? decor[COLOR_LIGHT] : decor[COLOR_DARK]));
@@ -2808,10 +2583,10 @@ containerdecorate(struct Container *c, struct Column *cdiv, struct Row *rdiv, in
/* decorate tabs, if necessary */
if (recursive) {
- for (t = row->tabs; t != NULL; t = t->next) {
- tabdecorate(t, 0);
- for (d = t->ds; d != NULL; d = d->next) {
- dialogdecorate(d);
+ TAILQ_FOREACH(t, &row->tabq, entry) {
+ tabdecorate((struct Tab *)t, 0);
+ TAILQ_FOREACH(d, &((struct Tab *)t)->dialq, entry) {
+ dialogdecorate((struct Dialog *)d);
}
}
}
@@ -2948,41 +2723,42 @@ menudecorate(struct Menu *menu, int titlepressed)
/* map menus */
static void
-menumap(struct Tab *t)
+menumap(struct Tab *tab)
{
- struct Menu *menu;
+ struct Object *menu;
- if (t == NULL)
+ if (tab == NULL)
return;
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- XMapWindow(dpy, menu->frame);
+ TAILQ_FOREACH(menu, &tab->menuq, entry) {
+ XMapWindow(dpy, ((struct Menu *)menu)->frame);
icccmwmstate(menu->win, NormalState);
}
}
/* unmap menus */
static void
-menuunmap(struct Tab *t)
+menuunmap(struct Tab *tab)
{
- struct Menu *menu;
+ struct Object *menu;
- if (t == NULL)
+ if (tab == NULL)
return;
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- XUnmapWindow(dpy, menu->frame);
+ TAILQ_FOREACH(menu, &tab->menuq, entry) {
+ XUnmapWindow(dpy, ((struct Menu *)menu)->frame);
icccmwmstate(menu->win, IconicState);
}
}
/* raise menus */
static void
-menuraise(struct Tab *t)
+menuraise(struct Tab *tab)
{
struct Container *c;
+ struct Object *p;
struct Menu *menu;
Window wins[2], layer;
- c = t->row->col->c;
+ c = tab->row->col->c;
if (c == NULL || c->isminimized)
return;
if (c->isfullscreen)
@@ -2994,7 +2770,8 @@ menuraise(struct Tab *t)
else
layer = wm.layerwins[LAYER_NORMAL];
wins[0] = layer;
- for (menu = t->menus; menu != NULL; menu = menu->next) {
+ TAILQ_FOREACH(p, &tab->menuq, entry) {
+ menu = (struct Menu *)p;
wins[1] = menu->frame;
XRestackWindows(dpy, wins, 2);
wins[0] = menu->frame;
@@ -3003,30 +2780,19 @@ menuraise(struct Tab *t)
/* remove menu from the menu list */
static void
-menudelraise(struct Tab *t, struct Menu *menu)
+menudelraise(struct Tab *tab, struct Menu *menu)
{
- if (menu->next != NULL) {
- menu->next->prev = menu->prev;
- }
- if (menu->prev != NULL) {
- menu->prev->next = menu->next;
- } else if (t->menus == menu) {
- t->menus = menu->next;
- }
- menu->next = NULL;
- menu->prev = NULL;
+ if (TAILQ_EMPTY(&tab->menuq))
+ return;
+ TAILQ_REMOVE(&tab->menuq, (struct Object *)menu, entry);
}
/* put menu on beginning of menu list */
static void
-menuaddraise(struct Tab *t, struct Menu *menu)
+menuaddraise(struct Tab *tab, struct Menu *menu)
{
- menudelraise(t, menu);
- menu->next = t->menus;
- menu->prev = NULL;
- if (t->menus != NULL)
- t->menus->prev = menu;
- t->menus = menu;
+ menudelraise(tab, menu);
+ TAILQ_INSERT_HEAD(&tab->menuq, (struct Object *)menu, entry);
}
/* place menu next to its container */
@@ -3035,7 +2801,7 @@ menuplace(struct Menu *menu)
{
struct Container *c;
- c = menu->t->row->col->c;
+ c = menu->tab->row->col->c;
if (menu->x < c->mon->wx || menu->x + menu->w >= c->mon->wx + c->mon->ww)
menu->x = c->mon->wx;
if (menu->y < c->mon->wy || menu->y + menu->h >= c->mon->wy + c->mon->wh)
@@ -3043,29 +2809,32 @@ menuplace(struct Menu *menu)
XMoveWindow(dpy, menu->frame, menu->x, menu->y);
}
-/* delete dialog */
-static void
-menudel(struct Menu *menu)
+/* delete menu; return whether menu was deleted */
+static int
+menudel(struct Object *obj, int ignoreunmap)
{
- if (menu->next != NULL)
- menu->next->prev = menu->prev;
- if (menu->prev != NULL)
- menu->prev->next = menu->next;
- else
- menu->t->menus = menu->next;
+ struct Menu *menu;
+
+ menu = (struct Menu *)obj;
+ if (ignoreunmap && menu->ignoreunmap) {
+ menu->ignoreunmap--;
+ return 0;
+ }
+ menudelraise(menu->tab, menu);
if (menu->pix != None)
XFreePixmap(dpy, menu->pix);
if (menu->pixbutton != None)
XFreePixmap(dpy, menu->pixbutton);
if (menu->pixtitlebar != None)
XFreePixmap(dpy, menu->pixtitlebar);
- icccmdeletestate(menu->win);
- XReparentWindow(dpy, menu->win, root, 0, 0);
+ icccmdeletestate(menu->obj.win);
+ XReparentWindow(dpy, menu->obj.win, root, 0, 0);
XDestroyWindow(dpy, menu->frame);
XDestroyWindow(dpy, menu->titlebar);
XDestroyWindow(dpy, menu->button);
free(menu->name);
free(menu);
+ return 1;
}
/* commit menu geometry */
@@ -3073,23 +2842,21 @@ static void
menumoveresize(struct Menu *menu)
{
XMoveResizeWindow(dpy, menu->frame, menu->x, menu->y, menu->w, menu->h);
- XResizeWindow(dpy, menu->win, menu->w - 2 * config.borderwidth, menu->h - 2 * config.borderwidth - config.titlewidth);
+ XResizeWindow(dpy, menu->obj.win, menu->w - 2 * config.borderwidth, menu->h - 2 * config.borderwidth - config.titlewidth);
}
/* remove container from the focus list */
static void
containerdelfocus(struct Container *c)
{
- if (c->fnext != NULL) {
- c->fnext->fprev = c->fprev;
- }
- if (c->fprev != NULL) {
- c->fprev->fnext = c->fnext;
- } else if (wm.focuslist == c) {
- wm.focuslist = c->fnext;
- }
- c->fnext = NULL;
- c->fprev = NULL;
+ TAILQ_REMOVE(&wm.focusq, c, entry);
+}
+
+/* add container into head of focus queue */
+static void
+containerinsertfocus(struct Container *c)
+{
+ TAILQ_INSERT_HEAD(&wm.focusq, c, entry);
}
/* put container on beginning of focus list */
@@ -3099,21 +2866,14 @@ containeraddfocus(struct Container *c)
if (c == NULL || c->isminimized)
return;
containerdelfocus(c);
- c->fnext = wm.focuslist;
- c->fprev = NULL;
- if (wm.focuslist)
- wm.focuslist->fprev = c;
- wm.focuslist = c;
+ containerinsertfocus(c);
}
/* hide container */
static void
containerhide(struct Container *c, int hide)
{
- struct Column *col;
- struct Row *row;
- struct Tab *t;
- struct Dialog *d;
+ struct Object *t, *d;
if (c == NULL)
return;
@@ -3124,36 +2884,32 @@ containerhide(struct Container *c, int hide)
} else {
XMapWindow(dpy, c->frame);
}
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- icccmwmstate(t->win, (hide ? IconicState : NormalState));
- for (d = t->ds; d != NULL; d = d->next) {
- icccmwmstate(d->win, (hide ? IconicState : NormalState));
- }
- }
+ TAB_FOREACH_BEGIN(c, t) {
+ icccmwmstate(t->win, (hide ? IconicState : NormalState));
+ TAILQ_FOREACH(d, &((struct Tab *)t)->dialq, entry) {
+ icccmwmstate(d->win, (hide ? IconicState : NormalState));
}
- }
+ }TAB_FOREACH_END
}
/* commit dialog size and position */
static void
-dialogmoveresize(struct Dialog *d)
+dialogmoveresize(struct Dialog *dial)
{
struct Container *c;
int dx, dy, dw, dh;
- dialogcalcsize(d);
- c = d->t->row->col->c;
- dx = d->x - config.borderwidth;
- dy = d->y - config.borderwidth;
- dw = d->w + 2 * config.borderwidth;
- dh = d->h + 2 * config.borderwidth;
- XMoveResizeWindow(dpy, d->frame, dx, dy, dw, dh);
- XMoveResizeWindow(dpy, d->win, config.borderwidth, config.borderwidth, d->w, d->h);
- winnotify(d->win, c->x + d->t->row->col->x + d->x, c->y + d->t->row->y + d->y, d->w, d->h);
- if (d->pw != dw || d->ph != dh) {
- dialogdecorate(d);
+ dialogcalcsize(dial);
+ c = dial->tab->row->col->c;
+ dx = dial->x - config.borderwidth;
+ dy = dial->y - config.borderwidth;
+ dw = dial->w + 2 * config.borderwidth;
+ dh = dial->h + 2 * config.borderwidth;
+ XMoveResizeWindow(dpy, dial->frame, dx, dy, dw, dh);
+ XMoveResizeWindow(dpy, dial->obj.win, config.borderwidth, config.borderwidth, dial->w, dial->h);
+ winnotify(dial->obj.win, c->x + dial->tab->row->col->x + dial->x, c->y + dial->tab->row->y + dial->y, dial->w, dial->h);
+ if (dial->pw != dw || dial->ph != dh) {
+ dialogdecorate(dial);
}
}
@@ -3178,7 +2934,7 @@ tabmoveresize(struct Tab *t)
if (t->ptw != t->w) {
tabdecorate(t, 0);
}
- winnotify(t->win, t->row->col->c->x + t->row->col->x, t->row->col->c->y + t->row->y + config.titlewidth, t->winw, t->winh);
+ winnotify(t->obj.win, t->row->col->c->x + t->row->col->x, t->row->col->c->y + t->row->y + config.titlewidth, t->winw, t->winh);
}
/* commit titlebar size and position */
@@ -3194,10 +2950,11 @@ titlebarmoveresize(struct Row *row, int x, int y, int w)
static void
containermoveresize(struct Container *c)
{
+ struct Object *t, *d;
struct Column *col;
struct Row *row;
- struct Tab *t;
- struct Dialog *d;
+ struct Tab *tab;
+ struct Dialog *dial;
int rowy, rowh;
int isshaded;
@@ -3213,17 +2970,17 @@ containermoveresize(struct Container *c)
XMoveResizeWindow(dpy, c->curswin[BORDER_SW], 0, c->h - config.corner, config.corner, config.corner);
XMoveResizeWindow(dpy, c->curswin[BORDER_SE], c->w - config.corner, c->h - config.corner, config.corner, config.corner);
isshaded = containerisshaded(c);
- for (col = c->cols; col != NULL; col = col->next) {
+ TAILQ_FOREACH(col, &c->colq, entry) {
rowy = c->b;
rowh = max(1, c->h - 2 * c->b - col->nrows * config.titlewidth);
- if (col->next != NULL) {
+ if (TAILQ_NEXT(col, entry) != NULL) {
XMoveResizeWindow(dpy, col->div, col->x + col->w, c->b, config.divwidth, c->h - 2 * c->b);
XMapWindow(dpy, col->div);
} else {
XUnmapWindow(dpy, col->div);
}
- for (row = col->rows; row != NULL; row = row->next) {
- if (!isshaded && row->next != NULL && col->maxrow == NULL) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
+ if (!isshaded && TAILQ_NEXT(row, entry) != NULL && col->maxrow == NULL) {
XMoveResizeWindow(dpy, row->div, col->x, row->y + row->h, col->w, config.divwidth);
XMapWindow(dpy, row->div);
} else {
@@ -3243,15 +3000,17 @@ containermoveresize(struct Container *c)
XUnmapWindow(dpy, row->frame);
}
rowy += config.titlewidth;
- for (t = row->tabs; t != NULL; t = t->next) {
- XMoveResizeWindow(dpy, t->frame, 0, 0, t->winw, t->winh);
- for (d = t->ds; d != NULL; d = d->next) {
- dialogmoveresize(d);
- ewmhsetframeextents(d->win, c->b, 0);
+ TAILQ_FOREACH(t, &row->tabq, entry) {
+ tab = (struct Tab *)t;
+ XMoveResizeWindow(dpy, tab->frame, 0, 0, tab->winw, tab->winh);
+ TAILQ_FOREACH(d, &tab->dialq, entry) {
+ dial = (struct Dialog *)d;
+ dialogmoveresize(dial);
+ ewmhsetframeextents(dial->obj.win, c->b, 0);
}
- XResizeWindow(dpy, t->win, t->winw, t->winh);
- ewmhsetframeextents(t->win, c->b, TITLEWIDTH(c));
- tabmoveresize(t);
+ XResizeWindow(dpy, tab->obj.win, tab->winw, tab->winh);
+ ewmhsetframeextents(tab->obj.win, c->b, TITLEWIDTH(c));
+ tabmoveresize(tab);
}
}
}
@@ -3289,64 +3048,57 @@ containerconfigure(struct Container *c, unsigned int valuemask, XWindowChanges *
static void
containerdelraise(struct Container *c)
{
- if (c->rnext != NULL) {
- c->rnext->rprev = c->rprev;
- }
- if (c->rprev != NULL) {
- c->rprev->rnext = c->rnext;
- } else if (wm.fulllist == c) {
- wm.fulllist = c->rnext;
- } else if (wm.abovelist == c) {
- wm.abovelist = c->rnext;
- } else if (wm.centerlist == c) {
- wm.centerlist = c->rnext;
- } else if (wm.belowlist == c) {
- wm.belowlist = c->rnext;
+ if (c->isfullscreen) {
+ if (!TAILQ_EMPTY(&wm.fullq)) {
+ TAILQ_REMOVE(&wm.fullq, c, raiseentry);
+ }
+ } else if (c->layer > 0) {
+ if (!TAILQ_EMPTY(&wm.aboveq)) {
+ TAILQ_REMOVE(&wm.aboveq, c, raiseentry);
+ }
+ } else if (c->layer < 0) {
+ if (!TAILQ_EMPTY(&wm.belowq)) {
+ TAILQ_REMOVE(&wm.belowq, c, raiseentry);
+ }
+ } else {
+ if (!TAILQ_EMPTY(&wm.centerq)) {
+ TAILQ_REMOVE(&wm.centerq, c, raiseentry);
+ }
}
- c->rnext = NULL;
- c->rprev = NULL;
}
-/* put container on beginning of a raise list */
+/* add container into head of focus queue */
static void
-containeraddraise(struct Container *c)
+containerinsertraise(struct Container *c)
{
- struct Container **list;
-
- containerdelraise(c);
- if (c->isfullscreen)
- list = &wm.fulllist;
- else if (c->layer > 0)
- list = &wm.abovelist;
- else if (c->layer < 0)
- list = &wm.belowlist;
- else
- list = &wm.centerlist;
- c->rnext = *list;
- c->rprev = NULL;
- if (*list != NULL)
- (*list)->rprev = c;
- *list = c;
+ TAILQ_INSERT_HEAD(&wm.centerq, c, raiseentry);
}
/* raise container */
static void
-containerraise(struct Container *c)
+containerraise(struct Container *c, int isfullscreen, int layer)
{
Window wins[2];
if (c == NULL || c->isminimized)
return;
- containeraddraise(c);
+ containerdelraise(c);
wins[1] = c->frame;
- if (c->isfullscreen)
+ if (isfullscreen) {
+ TAILQ_INSERT_HEAD(&wm.fullq, c, raiseentry);
wins[0] = wm.layerwins[LAYER_FULLSCREEN];
- else if (c->layer > 0)
+ } else if (layer > 0) {
+ TAILQ_INSERT_HEAD(&wm.aboveq, c, raiseentry);
wins[0] = wm.layerwins[LAYER_ABOVE];
- else if (c->layer < 0)
+ } else if (layer < 0) {
+ TAILQ_INSERT_HEAD(&wm.belowq, c, raiseentry);
wins[0] = wm.layerwins[LAYER_BELOW];
- else
+ } else {
+ TAILQ_INSERT_HEAD(&wm.centerq, c, raiseentry);
wins[0] = wm.layerwins[LAYER_NORMAL];
+ }
+ c->isfullscreen = isfullscreen;
+ c->layer = layer;
XRestackWindows(dpy, wins, 2);
menuraise(c->selcol->selrow->seltab);
ewmhsetclientsstacking();
@@ -3354,21 +3106,21 @@ containerraise(struct Container *c)
/* send container to desktop, raise it and optionally place it */
static void
-containersendtodesk(struct Container *c, struct Desktop *desk, int place, int userplaced)
+containersendtodesk(struct Container *c, struct Monitor *mon, int desk, int place, int userplaced)
{
- if (c == NULL || desk == NULL || c->isminimized)
+ if (c == NULL || desk < 0 || desk >= config.ndesktops || c->isminimized)
return;
c->desk = desk;
- c->mon = desk->mon;
+ c->mon = mon;
if (c->issticky) {
c->issticky = 0;
ewmhsetstate(c);
}
if (place)
- containerplace(c, c->desk, userplaced);
- if (desk != desk->mon->seldesk) /* container was sent to invisible desktop */
+ containerplace(c, mon, desk, userplaced);
+ if (desk != mon->seldesk) /* container was sent to invisible desktop */
containerhide(c, 1);
- containerraise(c);
+ containerraise(c, c->isfullscreen, c->layer);
ewmhsetwmdesktop(c);
}
@@ -3392,7 +3144,7 @@ containerminimize(struct Container *c, int minimize, int focus)
}
} else if (minimize != ADD && c->isminimized) {
c->isminimized = 0;
- containersendtodesk(c, wm.selmon->seldesk, 1, 0);
+ containersendtodesk(c, wm.selmon, wm.selmon->seldesk, 1, 0);
containermoveresize(c);
containerhide(c, 0);
tabfocus(c->selcol->selrow->seltab, 0);
@@ -3407,12 +3159,11 @@ static void
containerfullscreen(struct Container *c, int fullscreen)
{
if (fullscreen != REMOVE && !c->isfullscreen)
- c->isfullscreen = 1;
+ containerraise(c, 1, c->layer);
else if (fullscreen != ADD && c->isfullscreen)
- c->isfullscreen = 0;
+ containerraise(c, 0, c->layer);
else
return;
- containerraise(c);
containercalccols(c, 0, 1);
containermoveresize(c);
containerredecorate(c, NULL, NULL, 0);
@@ -3473,7 +3224,7 @@ containerstick(struct Container *c, int stick)
c->issticky = 1;
} else if (stick != ADD && c->issticky) {
c->issticky = 0;
- containersendtodesk(c, c->mon->seldesk, 0, 0);
+ containersendtodesk(c, c->mon, c->mon->seldesk, 0, 0);
} else {
return;
}
@@ -3486,12 +3237,11 @@ static void
containerabove(struct Container *c, int above)
{
if (above != REMOVE && c->layer != 1)
- c->layer = 1;
+ containerraise(c, c->isfullscreen, 1);
else if (above != ADD && c->layer != 0)
- c->layer = 0;
+ containerraise(c, c->isfullscreen, 0);
else
return;
- containerraise(c);
ewmhsetstate(c);
}
@@ -3500,12 +3250,11 @@ static void
containerbelow(struct Container *c, int below)
{
if (below != REMOVE && c->layer != -1)
- c->layer = -1;
+ containerraise(c, c->isfullscreen, -1);
else if (below != ADD && c->layer != 0)
- c->layer = 0;
+ containerraise(c, c->isfullscreen, 0);
else
return;
- containerraise(c);
ewmhsetstate(c);
}
@@ -3527,6 +3276,7 @@ containernew(int x, int y, int w, int h)
.b = config.borderwidth,
.pix = None,
};
+ TAILQ_INIT(&c->colq);
c->frame = XCreateWindow(dpy, root, c->x, c->y, c->w, c->h, 0, depth, CopyFromParent, visual, clientmask, &clientswa);
c->curswin[BORDER_N] = XCreateWindow(dpy, c->frame, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWCursor, &(XSetWindowAttributes){.cursor = theme.cursors[CURSOR_N]});
c->curswin[BORDER_S] = XCreateWindow(dpy, c->frame, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWCursor, &(XSetWindowAttributes){.cursor = theme.cursors[CURSOR_S]});
@@ -3538,82 +3288,82 @@ containernew(int x, int y, int w, int h)
c->curswin[BORDER_SE] = XCreateWindow(dpy, c->frame, 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, CWCursor, &(XSetWindowAttributes){.cursor = theme.cursors[CURSOR_SE]});
for (i = 0; i < BORDER_LAST; i++)
XMapWindow(dpy, c->curswin[i]);
- if (wm.c)
- wm.c->prev = c;
- c->next = wm.c;
- wm.c = c;
- containeraddfocus(c);
+ containerinsertfocus(c);
+ containerinsertraise(c);
return c;
}
-/* delete dialog */
-static void
-dialogdel(struct Dialog *d)
+/* delete dialog; return whether dialog was deleted */
+static int
+dialogdel(struct Object *obj, int ignoreunmap)
{
- if (d->next)
- d->next->prev = d->prev;
- if (d->prev)
- d->prev->next = d->next;
- else
- d->t->ds = d->next;
- if (d->pix != None)
- XFreePixmap(dpy, d->pix);
- icccmdeletestate(d->win);
- XReparentWindow(dpy, d->win, root, 0, 0);
- XDestroyWindow(dpy, d->frame);
- free(d);
+ struct Dialog *dial;
+
+ dial = (struct Dialog *)obj;
+ if (ignoreunmap && dial->ignoreunmap) {
+ dial->ignoreunmap--;
+ return 0;
+ }
+ TAILQ_REMOVE(&dial->tab->dialq, (struct Object *)dial, entry);
+ if (dial->pix != None)
+ XFreePixmap(dpy, dial->pix);
+ icccmdeletestate(dial->obj.win);
+ XReparentWindow(dpy, dial->obj.win, root, 0, 0);
+ XDestroyWindow(dpy, dial->frame);
+ free(dial);
+ return 1;
}
/* detach tab from row */
static void
-tabdetach(struct Tab *t, int x, int y, int w, int h)
+tabdetach(struct Tab *tab, int x, int y, int w, int h)
{
struct Row *row;
- row = t->row;
- if (row->seltab == t)
- row->seltab = (t->prev != NULL) ? t->prev : t->next;
+ row = tab->row;
+ if (row->seltab == tab) {
+ row->seltab = (struct Tab *)TAILQ_PREV((struct Object *)tab, Queue, entry);
+ if (row->seltab == NULL) {
+ row->seltab = (struct Tab *)TAILQ_NEXT((struct Object *)tab, entry);
+ }
+ }
row->ntabs--;
- t->ignoreunmap = IGNOREUNMAP;
- XReparentWindow(dpy, t->title, root, x, y);
- if (t->next)
- t->next->prev = t->prev;
- if (t->prev)
- t->prev->next = t->next;
- else
- row->tabs = t->next;
- t->winw = w;
- t->winh = h;
- t->next = NULL;
- t->prev = NULL;
- t->row = NULL;
+ tab->ignoreunmap = IGNOREUNMAP;
+ XReparentWindow(dpy, tab->title, root, x, y);
+ TAILQ_REMOVE(&row->tabq, (struct Object *)tab, entry);
+ tab->winw = w;
+ tab->winh = h;
+ tab->row = NULL;
rowcalctabs(row);
}
/* delete tab */
static void
-tabdel(struct Tab *t)
-{
- while (t->ds) {
- XDestroyWindow(dpy, t->ds->win);
- dialogdel(t->ds);
- }
- while (t->menus) {
- XDestroyWindow(dpy, t->menus->win);
- menudel(t->menus);
- }
- tabdetach(t, 0, 0, t->winw, t->winh);
- if (t->pixtitle != None)
- XFreePixmap(dpy, t->pixtitle);
- if (t->pix != None)
- XFreePixmap(dpy, t->pix);
- icccmdeletestate(t->win);
- XReparentWindow(dpy, t->win, root, 0, 0);
- XDestroyWindow(dpy, t->title);
- XDestroyWindow(dpy, t->frame);
+tabdel(struct Tab *tab)
+{
+ struct Dialog *dial;
+ struct Menu *menu;
+
+ while ((dial = (struct Dialog *)TAILQ_FIRST(&tab->dialq)) != NULL) {
+ XDestroyWindow(dpy, dial->obj.win);
+ dialogdel((struct Object *)dial, 0);
+ }
+ while ((menu = (struct Menu *)TAILQ_FIRST(&tab->menuq)) != NULL) {
+ XDestroyWindow(dpy, menu->obj.win);
+ menudel((struct Object *)menu, 0);
+ }
+ tabdetach(tab, 0, 0, tab->winw, tab->winh);
+ if (tab->pixtitle != None)
+ XFreePixmap(dpy, tab->pixtitle);
+ if (tab->pix != None)
+ XFreePixmap(dpy, tab->pix);
+ icccmdeletestate(tab->obj.win);
+ XReparentWindow(dpy, tab->obj.win, root, 0, 0);
+ XDestroyWindow(dpy, tab->title);
+ XDestroyWindow(dpy, tab->frame);
clientsdecr();
- free(t->name);
- free(t);
+ free(tab->name);
+ free(tab);
}
/* stack rows */
@@ -3637,19 +3387,19 @@ rowstack(struct Column *col, struct Row *row)
static void
rowdetach(struct Row *row, int recalc)
{
- if (row->col->selrow == row)
- row->col->selrow = (row->prev != NULL) ? row->prev : row->next;
- row->col->nrows--;
- if (row->next)
- row->next->prev = row->prev;
- if (row->prev)
- row->prev->next = row->next;
- else
- row->col->rows = row->next;
+ struct Column *col;
+
+ col = row->col;
+ if (col->selrow == row) {
+ col->selrow = TAILQ_PREV(row, RowQueue, entry);
+ if (col->selrow == NULL) {
+ col->selrow = TAILQ_NEXT(row, entry);
+ }
+ }
+ col->nrows--;
+ TAILQ_REMOVE(&col->rowq, row, entry);
if (row == row->col->maxrow)
row->col->maxrow = NULL;
- row->next = NULL;
- row->prev = NULL;
if (recalc) {
colcalcrows(row->col, 1, 0);
}
@@ -3659,8 +3409,10 @@ rowdetach(struct Row *row, int recalc)
static void
rowdel(struct Row *row)
{
- while (row->tabs)
- tabdel(row->tabs);
+ struct Tab *tab;
+
+ while ((tab = (struct Tab *)TAILQ_FIRST(&row->tabq)) != NULL)
+ tabdel(tab);
rowdetach(row, 1);
XDestroyWindow(dpy, row->frame);
XDestroyWindow(dpy, row->bar);
@@ -3678,17 +3430,17 @@ rowdel(struct Row *row)
static void
coldetach(struct Column *col)
{
- if (col->c->selcol == col)
- col->c->selcol = (col->prev != NULL) ? col->prev : col->next;
- col->c->ncols--;
- if (col->next)
- col->next->prev = col->prev;
- if (col->prev)
- col->prev->next = col->next;
- else
- col->c->cols = col->next;
- col->next = NULL;
- col->prev = NULL;
+ struct Container *c;
+
+ c = col->c;
+ if (c->selcol == col) {
+ c->selcol = TAILQ_PREV(col, ColumnQueue, entry);
+ if (c->selcol == NULL) {
+ c->selcol = TAILQ_NEXT(col, entry);
+ }
+ }
+ c->ncols--;
+ TAILQ_REMOVE(&c->colq, col, entry);
containercalccols(col->c, 1, 0);
}
@@ -3696,8 +3448,10 @@ coldetach(struct Column *col)
static void
coldel(struct Column *col)
{
- while (col->rows)
- rowdel(col->rows);
+ struct Row *row;
+
+ while ((row = TAILQ_FIRST(&col->rowq)) != NULL)
+ rowdel(row);
coldetach(col);
XDestroyWindow(dpy, col->div);
free(col);
@@ -3707,20 +3461,16 @@ coldel(struct Column *col)
static void
containerdel(struct Container *c)
{
+ struct Column *col;
int i;
containerdelfocus(c);
containerdelraise(c);
if (wm.focused == c)
wm.focused = NULL;
- if (c->next)
- c->next->prev = c->prev;
- if (c->prev)
- c->prev->next = c->next;
- else
- wm.c = c->next;
- while (c->cols)
- coldel(c->cols);
+ TAILQ_REMOVE(&wm.focusq, c, entry);
+ while ((col = TAILQ_FIRST(&c->colq)) != NULL)
+ coldel(col);
if (c->pix != None)
XFreePixmap(dpy, c->pix);
XDestroyWindow(dpy, c->frame);
@@ -3739,19 +3489,10 @@ containeraddcol(struct Container *c, struct Column *col, struct Column *prev)
col->c = c;
c->selcol = col;
c->ncols++;
- if (prev == NULL || c->cols == NULL) {
- col->prev = NULL;
- col->next = c->cols;
- if (c->cols != NULL)
- c->cols->prev = col;
- c->cols = col;
- } else {
- if (prev->next != NULL)
- prev->next->prev = col;
- col->next = prev->next;
- col->prev = prev;
- prev->next = col;
- }
+ if (prev == NULL || TAILQ_EMPTY(&c->colq))
+ TAILQ_INSERT_HEAD(&c->colq, col, entry);
+ else
+ TAILQ_INSERT_AFTER(&c->colq, prev, col, entry);
XReparentWindow(dpy, col->div, c->frame, 0, 0);
containercalccols(c, 1, 0);
if (oldc != NULL && oldc->ncols == 0) {
@@ -3767,6 +3508,7 @@ colnew(void)
col = emalloc(sizeof(*col));
*col = (struct Column){ };
+ TAILQ_INIT(&col->rowq);
col->div = XCreateWindow(dpy, root, 0, 0, 1, 1, 0,
CopyFromParent, InputOnly, CopyFromParent, CWCursor,
&(XSetWindowAttributes){.cursor = theme.cursors[CURSOR_H]});
@@ -3785,19 +3527,10 @@ coladdrow(struct Column *col, struct Row *row, struct Row *prev)
row->col = col;
col->selrow = row;
col->nrows++;
- if (prev == NULL || col->rows == NULL) {
- row->prev = NULL;
- row->next = col->rows;
- if (col->rows != NULL)
- col->rows->prev = row;
- col->rows = row;
- } else {
- if (prev->next)
- prev->next->prev = row;
- row->next = prev->next;
- row->prev = prev;
- prev->next = row;
- }
+ if (prev == NULL || TAILQ_EMPTY(&col->rowq))
+ TAILQ_INSERT_HEAD(&col->rowq, row, entry);
+ else
+ TAILQ_INSERT_AFTER(&col->rowq, prev, row, entry);
colcalcrows(col, 1, 0); /* set row->y, row->h, etc */
XReparentWindow(dpy, row->div, c->frame, col->x + col->w, c->b);
XReparentWindow(dpy, row->bar, c->frame, col->x, row->y);
@@ -3819,6 +3552,7 @@ rownew(void)
*row = (struct Row){
.pixbar = None,
};
+ TAILQ_INIT(&row->tabq);
row->frame = XCreateWindow(dpy, root, 0, 0, 1, 1, 0,
depth, CopyFromParent, visual,
clientmask, &clientswa);
@@ -3845,38 +3579,29 @@ rownew(void)
/* add tab to row */
static void
-rowaddtab(struct Row *row, struct Tab *t, struct Tab *prev)
+rowaddtab(struct Row *row, struct Tab *tab, struct Tab *prev)
{
struct Row *oldrow;
- oldrow = t->row;
- t->row = row;
- row->seltab = t;
+ oldrow = tab->row;
+ tab->row = row;
+ row->seltab = tab;
row->ntabs++;
- if (prev == NULL || row->tabs == NULL) {
- t->prev = NULL;
- t->next = row->tabs;
- if (row->tabs != NULL)
- row->tabs->prev = t;
- row->tabs = t;
- } else {
- if (prev->next)
- prev->next->prev = t;
- t->next = prev->next;
- t->prev = prev;
- prev->next = t;
- }
- rowcalctabs(row); /* set t->x, t->w, etc */
- if (t->title == None) {
- t->title = XCreateWindow(dpy, row->bar, t->x, 0, t->w, config.titlewidth, 0,
+ if (prev == NULL || TAILQ_EMPTY(&row->tabq))
+ TAILQ_INSERT_HEAD(&row->tabq, (struct Object *)tab, entry);
+ else
+ TAILQ_INSERT_AFTER(&row->tabq, (struct Object *)prev, (struct Object *)tab, entry);
+ rowcalctabs(row); /* set tab->x, tab->w, etc */
+ if (tab->title == None) {
+ tab->title = XCreateWindow(dpy, row->bar, tab->x, 0, tab->w, config.titlewidth, 0,
depth, CopyFromParent, visual,
clientmask, &clientswa);
} else {
- XReparentWindow(dpy, t->title, row->bar, t->x, 0);
+ XReparentWindow(dpy, tab->title, row->bar, tab->x, 0);
}
- XReparentWindow(dpy, t->frame, row->frame, 0, 0);
- XMapWindow(dpy, t->frame);
- XMapWindow(dpy, t->title);
+ XReparentWindow(dpy, tab->frame, row->frame, 0, 0);
+ XMapWindow(dpy, tab->frame);
+ XMapWindow(dpy, tab->title);
if (oldrow != NULL) { /* deal with the row this tab came from */
if (oldrow->ntabs == 0) {
rowdel(oldrow);
@@ -3888,9 +3613,9 @@ rowaddtab(struct Row *row, struct Tab *t, struct Tab *prev)
/* check if desktop is visible */
static int
-deskisvisible(struct Desktop *desk)
+deskisvisible(struct Monitor *mon, int desk)
{
- return desk->mon->seldesk == desk;
+ return mon->seldesk == desk;
}
/* (un)show desktop */
@@ -3899,7 +3624,7 @@ deskshow(int show)
{
struct Container *c;
- for (c = wm.c; c != NULL; c = c->next)
+ TAILQ_FOREACH(c, &wm.focusq, entry)
if (!c->isminimized)
containerhide(c, show);
wm.showingdesk = show;
@@ -3908,35 +3633,35 @@ deskshow(int show)
/* change desktop */
static void
-deskfocus(struct Desktop *desk, int focus)
+deskfocus(struct Monitor *mon, int desk, int focus)
{
void tabfocus(struct Tab *t, int gotodesk);
struct Container *c;
- if (desk == NULL || desk == wm.selmon->seldesk)
+ if (desk < 0 || desk >= config.ndesktops || desk == wm.selmon->seldesk)
return;
- if (!deskisvisible(desk)) {
+ if (!deskisvisible(mon, desk)) {
/* unhide cointainers of new current desktop
* hide containers of previous current desktop */
- for (c = wm.c; c != NULL; c = c->next) {
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
if (!c->isminimized && c->desk == desk) {
containerhide(c, 0);
- } else if (!c->issticky && c->desk == desk->mon->seldesk) {
+ } else if (!c->issticky && c->desk == mon->seldesk) {
containerhide(c, 1);
}
}
}
/* update current desktop */
- wm.selmon = desk->mon;
+ wm.selmon = mon;
wm.selmon->seldesk = desk;
if (wm.showingdesk)
deskshow(0);
- ewmhsetcurrentdesktop(desk->n);
+ ewmhsetcurrentdesktop(desk);
/* focus client on the new current desktop */
if (focus) {
- c = getnextfocused(desk->mon, desk);
+ c = getnextfocused(mon, desk);
if (c != NULL) {
tabfocus(c->selcol->selrow->seltab, 0);
} else {
@@ -3953,19 +3678,15 @@ snaptoedge(int *x, int *y, int w, int h)
if (config.snap <= 0)
return;
- if (abs(*y - wm.selmon->wy) < config.snap) {
+ if (abs(*y - wm.selmon->wy) < config.snap)
*y = wm.selmon->wy;
- }
- if (abs(*y + h - wm.selmon->wy - wm.selmon->wh) < config.snap) {
+ if (abs(*y + h - wm.selmon->wy - wm.selmon->wh) < config.snap)
*y = wm.selmon->wy + wm.selmon->wh - h;
- }
- if (abs(*x - wm.selmon->wx) < config.snap) {
+ if (abs(*x - wm.selmon->wx) < config.snap)
*x = wm.selmon->wx;
- }
- if (abs(*x + w - wm.selmon->wx - wm.selmon->ww) < config.snap) {
+ if (abs(*x + w - wm.selmon->wx - wm.selmon->ww) < config.snap)
*x = wm.selmon->wx + wm.selmon->ww - w;
- }
- for (c = wm.c; c != NULL; c = c->next) {
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
if (!c->isminimized && c->mon == wm.selmon &&
(c->issticky || c->desk == wm.selmon->seldesk)) {
if (*x + w >= c->x && *x <= c->x + c->w) {
@@ -4005,9 +3726,8 @@ static void
containerincrmove(struct Container *c, int x, int y, int done)
{
struct Monitor *monto;
- struct Column *col;
- struct Row *row;
- struct Tab *t;
+ struct Object *t;
+ struct Tab *tab;
if (c == NULL || c->isminimized || c->ismaximized || c->isfullscreen)
return;
@@ -4020,20 +3740,17 @@ containerincrmove(struct Container *c, int x, int y, int done)
containermoveresize(c);
} else {
XMoveWindow(dpy, c->frame, c->x, c->y);
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- winnotify(t->win, c->x + col->x, c->y + row->y + config.titlewidth, t->winw, t->winh);
- }
- }
- }
+ TAB_FOREACH_BEGIN(c, t){
+ tab = (struct Tab *)t;
+ winnotify(tab->obj.win, c->x + col->x, c->y + row->y + config.titlewidth, tab->winw, tab->winh);
+ }TAB_FOREACH_END
}
if (!c->issticky) {
monto = getmon(c->nx + c->nw / 2, c->ny + c->nh / 2);
if (monto != NULL && monto != c->mon) {
- containersendtodesk(c, monto->seldesk, 0, 0);
+ containersendtodesk(c, monto, monto->seldesk, 0, 0);
if (wm.focused == c) {
- deskfocus(monto->seldesk, 0);
+ deskfocus(monto, monto->seldesk, 0);
}
}
}
@@ -4043,33 +3760,37 @@ containerincrmove(struct Container *c, int x, int y, int done)
static struct Tab *
tabnew(Window win, Window leader, int ignoreunmap)
{
- struct Tab *t;
+ struct Tab *tab;
- t = emalloc(sizeof(*t));
- *t = (struct Tab){
+ tab = emalloc(sizeof(*tab));
+ *tab = (struct Tab){
.ignoreunmap = ignoreunmap,
.pix = None,
.pixtitle = None,
.title = None,
.leader = leader,
- .win = win,
+ .obj.win = win,
+ .obj.type = TYPE_NORMAL,
};
- t->frame = XCreateWindow(dpy, root, 0, 0, 1, 1, 0, depth, CopyFromParent, visual, clientmask, &clientswa),
- XReparentWindow(dpy, t->win, t->frame, 0, 0);
- XMapWindow(dpy, t->win);
+ TAILQ_INIT(&tab->dialq);
+ TAILQ_INIT(&tab->menuq);
+ ((struct Object *)tab)->type = TYPE_NORMAL;
+ tab->frame = XCreateWindow(dpy, root, 0, 0, 1, 1, 0, depth, CopyFromParent, visual, clientmask, &clientswa),
+ XReparentWindow(dpy, tab->obj.win, tab->frame, 0, 0);
+ XMapWindow(dpy, tab->obj.win);
icccmwmstate(win, NormalState);
clientsincr();
- return t;
+ return tab;
}
/* clear window urgency */
static void
-tabclearurgency(struct Tab *t)
+tabclearurgency(struct Tab *tab)
{
XWMHints wmh = {0};
- XSetWMHints(dpy, t->win, &wmh);
- t->isurgent = 0;
+ XSetWMHints(dpy, tab->obj.win, &wmh);
+ tab->isurgent = 0;
}
/* update tab urgency */
@@ -4090,50 +3811,52 @@ tabupdateurgency(struct Tab *t, int isurgent)
/* focus tab */
void
-tabfocus(struct Tab *t, int gotodesk)
+tabfocus(struct Tab *tab, int gotodesk)
{
struct Container *c;
+ struct Dialog *dial;
wm.prevfocused = wm.focused;
- if (t == NULL) {
+ if (tab == NULL) {
wm.focused = NULL;
XSetInputFocus(dpy, wm.focuswin, RevertToParent, CurrentTime);
ewmhsetactivewindow(None);
} else {
- c = t->row->col->c;
+ c = tab->row->col->c;
if (!c->isfullscreen && getfullscreen(c->mon, c->desk) != NULL)
return; /* we should not focus a client below a fullscreen client */
wm.focused = c;
- t->row->seltab = t;
- t->row->col->selrow = t->row;
- t->row->col->c->selcol = t->row->col;
+ tab->row->seltab = tab;
+ tab->row->col->selrow = tab->row;
+ tab->row->col->c->selcol = tab->row->col;
if (gotodesk)
- deskfocus(c->issticky ? c->mon->seldesk : c->desk, 0);
- if (t->row->col->maxrow != NULL && t->row->col->maxrow != t->row)
- rowstack(t->row->col, t->row);
- XRaiseWindow(dpy, t->frame);
+ deskfocus(c->mon, c->issticky ? c->mon->seldesk : c->desk, 0);
+ if (tab->row->col->maxrow != NULL && tab->row->col->maxrow != tab->row)
+ rowstack(tab->row->col, tab->row);
+ XRaiseWindow(dpy, tab->frame);
if (c->isshaded) {
XSetInputFocus(dpy, c->frame, RevertToParent, CurrentTime);
- } else if (t->ds != NULL) {
- XRaiseWindow(dpy, t->ds->frame);
- XSetInputFocus(dpy, t->ds->win, RevertToParent, CurrentTime);
+ } else if (!TAILQ_EMPTY(&tab->dialq)) {
+ dial = (struct Dialog *)TAILQ_FIRST(&tab->dialq);
+ XRaiseWindow(dpy, dial->frame);
+ XSetInputFocus(dpy, dial->obj.win, RevertToParent, CurrentTime);
} else {
- XSetInputFocus(dpy, t->win, RevertToParent, CurrentTime);
+ XSetInputFocus(dpy, tab->obj.win, RevertToParent, CurrentTime);
}
- ewmhsetactivewindow(t->win);
- if (t->isurgent)
- tabclearurgency(t);
- menumap(t);
+ ewmhsetactivewindow(tab->obj.win);
+ if (tab->isurgent)
+ tabclearurgency(tab);
+ menumap(tab);
containeraddfocus(c);
containerdecorate(c, NULL, NULL, 1, 0);
containerminimize(c, 0, 0);
- containerraise(c);
+ containerraise(c, c->isfullscreen, c->layer);
shodgrouptab(c);
shodgroupcontainer(c);
ewmhsetstate(c);
}
if (wm.prevfocused != NULL) {
- if (t != wm.prevfocused->selcol->selrow->seltab)
+ if (tab != wm.prevfocused->selcol->selrow->seltab)
menuunmap(wm.prevfocused->selcol->selrow->seltab);
containerdecorate(wm.prevfocused, NULL, NULL, 1, 0);
ewmhsetstate(wm.prevfocused);
@@ -4150,18 +3873,19 @@ winupdatetitle(Window win, char **name)
/* try to attach tab in a client of specified client list */
static int
-tryattach(struct Container *list, struct Tab *det, int xroot, int yroot)
+tryattach(struct ContainerQueue *queue, struct Tab *det, int xroot, int yroot)
{
struct Container *c;
struct Column *col, *ncol;
struct Row *row, *nrow;
- struct Tab *t, *next;
+ struct Tab *tab, *next;
+ struct Object *t;
int rowy, rowh;
- for (c = list; c != NULL; c = c->rnext) {
+ for (c = TAILQ_FIRST(queue); c != NULL; c = TAILQ_NEXT(c, raiseentry)) {
if (c->ishidden || xroot < c->x || xroot >= c->x + c->w || yroot < c->y || yroot >= c->y + c->h)
continue;
- for (col = c->cols; col != NULL; col = col->next) {
+ TAILQ_FOREACH(col, &c->colq, entry) {
if (xroot - c->x >= col->x - DROPPIXELS &&
xroot - c->x < col->x + col->w + DROPPIXELS) {
if (yroot - c->y < c->b) {
@@ -4172,7 +3896,7 @@ tryattach(struct Container *list, struct Tab *det, int xroot, int yroot)
goto done;
}
rowy = c->b;
- for (row = col->rows; row != NULL; row = row->next) {
+ TAILQ_FOREACH(row, &col->rowq, entry) {
if (col->maxrow != NULL) {
if (row == col->maxrow) {
rowh = c->h - 2 * c->b - (col->nrows - 1) * config.titlewidth;
@@ -4184,10 +3908,10 @@ tryattach(struct Container *list, struct Tab *det, int xroot, int yroot)
}
if (yroot - c->y >= rowy &&
yroot - c->y < rowy + config.titlewidth) {
- for (next = t = row->tabs; t != NULL; t = t->next) {
- next = t;
- if (xroot - c->x + col->x < col->x + t->x + t->w / 2) {
- rowaddtab(row, det, t->prev);
+ TAILQ_FOREACH(t, &row->tabq, entry) {
+ next = tab = (struct Tab *)t;
+ if (xroot - c->x + col->x < col->x + tab->x + tab->w / 2) {
+ rowaddtab(row, det, (struct Tab *)TAILQ_PREV(t, Queue, entry));
rowcalctabs(row);
goto done;
}
@@ -4246,13 +3970,13 @@ done:
static int
tabattach(struct Tab *t, int xroot, int yroot)
{
- if (tryattach(wm.fulllist, t, xroot, yroot))
+ if (tryattach(&wm.fullq, t, xroot, yroot))
return 1;
- if (tryattach(wm.abovelist, t, xroot, yroot))
+ if (tryattach(&wm.aboveq, t, xroot, yroot))
return 1;
- if (tryattach(wm.centerlist, t, xroot, yroot))
+ if (tryattach(&wm.centerq, t, xroot, yroot))
return 1;
- if (tryattach(wm.belowlist, t, xroot, yroot))
+ if (tryattach(&wm.belowq, t, xroot, yroot))
return 1;
return 0;
}
@@ -4261,20 +3985,21 @@ tabattach(struct Tab *t, int xroot, int yroot)
static struct Dialog *
dialognew(Window win, int maxw, int maxh, int ignoreunmap)
{
- struct Dialog *d;
+ struct Dialog *dial;
- d = emalloc(sizeof(*d));
- *d = (struct Dialog){
+ dial = emalloc(sizeof(*dial));
+ *dial = (struct Dialog){
.pix = None,
.maxw = maxw,
.maxh = maxh,
.ignoreunmap = ignoreunmap,
- .win = win,
+ .obj.win = win,
+ .obj.type = TYPE_DIALOG,
};
- d->frame = XCreateWindow(dpy, root, 0, 0, maxw, maxh, 0, depth, CopyFromParent, visual, clientmask, &clientswa),
- XReparentWindow(dpy, d->win, d->frame, 0, 0);
- XMapWindow(dpy, d->win);
- return d;
+ dial->frame = XCreateWindow(dpy, root, 0, 0, maxw, maxh, 0, depth, CopyFromParent, visual, clientmask, &clientswa),
+ XReparentWindow(dpy, dial->obj.win, dial->frame, 0, 0);
+ XMapWindow(dpy, dial->obj.win);
+ return dial;
}
/* create new splash screen */
@@ -4285,10 +4010,12 @@ splashnew(Window win, int w, int h)
splash = emalloc(sizeof(*splash));
*splash = (struct Splash){
- .win = win,
+ .obj.win = win,
+ .obj.type = TYPE_SPLASH,
.w = w,
.h = h,
};
+ ((struct Object *)splash)->type = TYPE_SPLASH;
XReparentWindow(dpy, win, root, 0, 0);
return splash;
}
@@ -4301,24 +4028,24 @@ splashplace(struct Splash *splash)
fitmonitor(wm.selmon, &splash->x, &splash->y, &splash->w, &splash->h, 0.5);
splash->x = wm.selmon->wx + (wm.selmon->ww - splash->w) / 2;
splash->y = wm.selmon->wy + (wm.selmon->wh - splash->h) / 2;
- wins[1] = splash->win;
+ wins[1] = splash->obj.win;
wins[0] = wm.layerwins[LAYER_SPLASH];
- XMoveWindow(dpy, splash->win, splash->x, splash->y);
+ XMoveWindow(dpy, splash->obj.win, splash->x, splash->y);
XRestackWindows(dpy, wins, 2);
}
/* delete splash screen window */
-static void
-splashdel(struct Splash *splash)
+static int
+splashdel(struct Object *obj, int dummy)
{
- if (splash->next != NULL)
- splash->next->prev = splash->prev;
- if (splash->prev != NULL)
- splash->prev->next = splash->next;
- else
- wm.splashlist = splash->next;
- icccmdeletestate(splash->win);
+ struct Splash *splash;
+
+ splash = (struct Splash *)obj;
+ (void)dummy;
+ TAILQ_REMOVE(&wm.splashq, (struct Object *)splash, entry);
+ icccmdeletestate(splash->obj.win);
free(splash);
+ return 0;
}
/* check if monitor geometry is unique */
@@ -4337,7 +4064,6 @@ static void
monnew(XineramaScreenInfo *info)
{
struct Monitor *mon;
- int i;
mon = emalloc(sizeof *mon);
*mon = (struct Monitor){
@@ -4350,19 +4076,8 @@ monnew(XineramaScreenInfo *info)
.ww = info->width,
.wh = info->height,
};
- mon->desks = ecalloc(config.ndesktops, sizeof(*mon->desks));
- for (i = 0; i < config.ndesktops; i++) {
- mon->desks[i].mon = mon;
- mon->desks[i].n = i;
- }
- mon->seldesk = &mon->desks[0];
- if (wm.montail != NULL) {
- wm.montail->next = mon;
- mon->prev = wm.montail;
- } else {
- wm.monhead = mon;
- }
- wm.montail = mon;
+ mon->seldesk = 0;
+ TAILQ_INSERT_TAIL(&wm.monq, mon, entry);
}
/* delete monitor and set monitor of clients on it to NULL */
@@ -4371,18 +4086,10 @@ mondel(struct Monitor *mon)
{
struct Container *c;
- if (mon->next)
- mon->next->prev = mon->prev;
- else
- wm.montail = mon->prev;
- if (mon->prev)
- mon->prev->next = mon->next;
- else
- wm.monhead = mon->next;
- for (c = wm.c; c; c = c->next)
+ TAILQ_REMOVE(&wm.monq, mon, entry);
+ TAILQ_FOREACH(c, &wm.focusq, entry)
if (c->mon == mon)
c->mon = NULL;
- free(mon->desks);
free(mon);
}
@@ -4392,14 +4099,9 @@ monupdate(void)
{
XineramaScreenInfo *info = NULL;
XineramaScreenInfo *unique = NULL;
- struct Monitor *mon;
- struct Monitor *tmp;
+ struct Monitor *mon, *tmp;
struct Container *c, *focus;
- struct Column *col;
- struct Splash *splash;
- struct Row *row;
- struct Tab *t;
- struct Menu *menu;
+ struct Object *t, *m, *s;
int delselmon = 0;
int del, add;
int i, j, n;
@@ -4416,8 +4118,8 @@ monupdate(void)
moncount = j;
/* look for monitors that do not exist anymore and delete them */
- mon = wm.monhead;
- while (mon) {
+ mon = TAILQ_FIRST(&wm.monq);
+ while (mon != NULL) {
del = 1;
for (i = 0; i < moncount; i++) {
if (unique[i].x_org == mon->mx && unique[i].y_org == mon->my &&
@@ -4427,7 +4129,7 @@ monupdate(void)
}
}
tmp = mon;
- mon = mon->next;
+ mon = TAILQ_NEXT(mon, entry);
if (del) {
if (tmp == wm.selmon)
delselmon = 1;
@@ -4438,7 +4140,7 @@ monupdate(void)
/* look for new monitors and add them */
for (i = 0; i < moncount; i++) {
add = 1;
- for (mon = wm.monhead; mon; mon = mon->next) {
+ TAILQ_FOREACH(mon, &wm.monq, entry) {
if (unique[i].x_org == mon->mx && unique[i].y_org == mon->my &&
unique[i].width == mon->mw && unique[i].height == mon->mh) {
add = 0;
@@ -4450,34 +4152,26 @@ monupdate(void)
}
}
if (delselmon)
- wm.selmon = wm.monhead;
-
- /* update monitor number */
- for (i = 0, mon = wm.monhead; mon; mon = mon->next, i++)
- mon->n = i;
+ wm.selmon = TAILQ_FIRST(&wm.monq);
/* send containers which do not belong to a window to selected desktop */
focus = NULL;
- for (c = wm.c; c; c = c->next) {
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
if (!c->isminimized && c->mon == NULL) {
focus = c;
- containersendtodesk(c, wm.selmon->seldesk, 1, 0);
+ containersendtodesk(c, wm.selmon, wm.selmon->seldesk, 1, 0);
containermoveresize(c);
/* move menus to new monitor */
- for (col = c->cols; col != NULL; col = col->next) {
- for (row = col->rows; row != NULL; row = row->next) {
- for (t = row->tabs; t != NULL; t = t->next) {
- for (menu = t->menus; menu != NULL; menu = menu->next) {
- menuplace(menu);
- }
- }
+ TAB_FOREACH_BEGIN(c, t) {
+ TAILQ_FOREACH(m, &((struct Tab *)t)->menuq, entry) {
+ menuplace((struct Menu *)m);
}
- }
+ } TAB_FOREACH_END
}
}
- for (splash = wm.splashlist; splash != NULL; splash = splash->next)
- splashplace(splash);
+ TAILQ_FOREACH(s, &wm.splashq, entry)
+ splashplace((struct Splash *)s);
if (focus != NULL) /* if a contained changed desktop, focus it */
tabfocus(focus->selcol->selrow->seltab, 1);
@@ -4490,16 +4184,17 @@ monupdatearea(void)
{
struct Monitor *mon;
struct Bar *bar;
+ struct Object *p;
struct Container *c;
int t, b, l, r;
- for (mon = wm.monhead; mon != NULL; mon = mon->next) {
+ TAILQ_FOREACH(mon, &wm.monq, entry) {
mon->wx = mon->mx;
mon->wy = mon->my;
mon->ww = mon->mw;
mon->wh = mon->mh;
t = b = l = r = 0;
- if (mon == wm.monhead && dock.mapped) {
+ if (mon == TAILQ_FIRST(&wm.monq) && dock.mapped) {
switch (config.dockgravity[0]) {
case 'N':
t = config.dockwidth;
@@ -4516,7 +4211,8 @@ monupdatearea(void)
break;
}
}
- for (bar = wm.bars; bar != NULL; bar = bar->next) {
+ TAILQ_FOREACH(p, &wm.barq, entry) {
+ bar = (struct Bar *)p;
if (bar->strut[STRUT_TOP] != 0) {
if (bar->strut[STRUT_TOP] >= mon->my &&
bar->strut[STRUT_TOP] < mon->my + mon->mh &&
@@ -4556,7 +4252,7 @@ monupdatearea(void)
mon->wx += l;
mon->ww -= l + r;
}
- for (c = wm.c; c != NULL; c = c->next) {
+ TAILQ_FOREACH(c, &wm.focusq, entry) {
if (c->ismaximized) {
containercalccols(c, 0, 1);
containermoveresize(c);
@@ -4619,83 +4315,84 @@ promptcalcgeom(int *x, int *y, int *w, int *h, int *fw, int *fh)
static void
notifnew(Window win, int w, int h)
{
- struct Notification *n;
+ struct Notification *notif;
- n = emalloc(sizeof(*n));
- *n = (struct Notification){
+ notif = emalloc(sizeof(*notif));
+ *notif = (struct Notification){
.w = w + 2 * config.borderwidth,
.h = h + 2 * config.borderwidth,
};
- n->prev = wm.ntail;
- n->next = NULL;
- if (wm.ntail != NULL)
- wm.ntail->next = n;
- else
- wm.nhead = n;
- wm.ntail = n;
- n->pix = None;
- n->win = win;
- n->frame = XCreateWindow(dpy, root, 0, 0, 1, 1, 0,
- depth, CopyFromParent, visual,
- clientmask,
- &(XSetWindowAttributes){.event_mask = SubstructureNotifyMask | SubstructureRedirectMask,
- .colormap = colormap});
- XReparentWindow(dpy, n->win, n->frame, 0, 0);
- XMapWindow(dpy, n->win);
+ ((struct Object *)notif)->type = TYPE_NOTIFICATION;
+ TAILQ_INSERT_TAIL(&wm.notifq, (struct Object *)notif, entry);
+ notif->pix = None;
+ notif->obj.win = win;
+ notif->frame = XCreateWindow(
+ dpy, root, 0, 0, 1, 1, 0,
+ depth, CopyFromParent, visual,
+ clientmask,
+ &(XSetWindowAttributes){
+ .event_mask = SubstructureNotifyMask | SubstructureRedirectMask,
+ .colormap = colormap
+ }
+ );
+ XReparentWindow(dpy, notif->obj.win, notif->frame, 0, 0);
+ XMapWindow(dpy, notif->obj.win);
}
/* place notifications */
static void
notifplace(void)
{
- struct Notification *n;
+ struct Object *n;
+ struct Notification *notif;
int x, y, h;
h = 0;
- for (n = wm.nhead; n; n = n->next) {
- x = wm.monhead->wx;
- y = wm.monhead->wy;
+ TAILQ_FOREACH(n, &wm.notifq, entry) {
+ notif = (struct Notification *)n;
+ x = TAILQ_FIRST(&wm.monq)->wx;
+ y = TAILQ_FIRST(&wm.monq)->wy;
switch (config.notifgravity[0]) {
case 'N':
switch (config.notifgravity[1]) {
case 'W':
break;
case 'E':
- x += wm.monhead->ww - n->w;
+ x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
break;
default:
- x += (wm.monhead->ww - n->w) / 2;
+ x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
break;
}
break;
case 'S':
switch(config.notifgravity[1]) {
case 'W':
- y += wm.monhead->wh - n->h;
+ y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
break;
case 'E':
- x += wm.monhead->ww - n->w;
- y += wm.monhead->wh - n->h;
+ x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
+ y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
break;
default:
- x += (wm.monhead->ww - n->w) / 2;
- y += wm.monhead->wh - n->h;
+ x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
+ y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
break;
}
break;
case 'W':
- y += (wm.monhead->wh - n->h) / 2;
+ y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
break;
case 'C':
- x += (wm.monhead->ww - n->w) / 2;
- y += (wm.monhead->wh - n->h) / 2;
+ x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
+ y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
break;
case 'E':
- x += wm.monhead->ww - n->w;
- y += (wm.monhead->wh - n->h) / 2;
+ x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
+ y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
break;
default:
- x += wm.monhead->ww - n->w;
+ x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
break;
}
@@ -4703,36 +4400,34 @@ notifplace(void)
y -= h;
else
y += h;
- h += n->h + config.notifgap + config.borderwidth * 2;
+ h += notif->h + config.notifgap + config.borderwidth * 2;
- XMoveResizeWindow(dpy, n->frame, x, y, n->w, n->h);
- XMoveResizeWindow(dpy, n->win, config.borderwidth, config.borderwidth, n->w - 2 * config.borderwidth, n->h - 2 * config.borderwidth);
- XMapWindow(dpy, n->frame);
- if (n->pw != n->w || n->ph != n->h) {
- notifdecorate(n);
+ XMoveResizeWindow(dpy, notif->frame, x, y, notif->w, notif->h);
+ XMoveResizeWindow(dpy, notif->obj.win, config.borderwidth, config.borderwidth, notif->w - 2 * config.borderwidth, notif->h - 2 * config.borderwidth);
+ XMapWindow(dpy, notif->frame);
+ if (notif->pw != notif->w || notif->ph != notif->h) {
+ notifdecorate(notif);
}
- winnotify(n->win, x + config.borderwidth, y + config.borderwidth, n->w - 2 * config.borderwidth, n->h - 2 * config.borderwidth);
+ winnotify(notif->obj.win, x + config.borderwidth, y + config.borderwidth, notif->w - 2 * config.borderwidth, notif->h - 2 * config.borderwidth);
}
}
/* delete notification */
-static void
-notifdel(struct Notification *n)
-{
- if (n->next)
- n->next->prev = n->prev;
- else
- wm.ntail = n->prev;
- if (n->prev)
- n->prev->next = n->next;
- else
- wm.nhead = n->next;
- if (n->pix != None)
- XFreePixmap(dpy, n->pix);
- XReparentWindow(dpy, n->win, root, 0, 0);
- XDestroyWindow(dpy, n->frame);
- free(n);
+static int
+notifdel(struct Object *obj, int dummy)
+{
+ struct Notification *notif;
+
+ (void)dummy;
+ notif = (struct Notification *)obj;
+ TAILQ_REMOVE(&wm.notifq, (struct Object *)notif, entry);
+ if (notif->pix != None)
+ XFreePixmap(dpy, notif->pix);
+ XReparentWindow(dpy, notif->obj.win, root, 0, 0);
+ XDestroyWindow(dpy, notif->frame);
+ free(notif);
notifplace();
+ return 0;
}
/* fill strut array of bar */
@@ -4745,10 +4440,10 @@ barstrut(struct Bar *bar)
for (i = 0; i < STRUT_LAST; i++)
bar->strut[i] = 0;
bar->partial = 1;
- l = getcardprop(bar->win, atoms[_NET_WM_STRUT_PARTIAL], &arr);
+ l = getcardprop(bar->obj.win, atoms[_NET_WM_STRUT_PARTIAL], &arr);
if (arr == NULL) {
bar->partial = 0;
- l = getcardprop(bar->win, atoms[_NET_WM_STRUT], &arr);
+ l = getcardprop(bar->obj.win, atoms[_NET_WM_STRUT], &arr);
if (arr == NULL) {
return;
}
@@ -4759,17 +4454,17 @@ barstrut(struct Bar *bar)
}
/* delete bar */
-static void
-bardel(struct Bar *bar)
+static int
+bardel(struct Object *obj, int dummy)
{
- if (bar->next != NULL)
- bar->next->prev = bar->prev;
- if (bar->prev != NULL)
- bar->prev->next = bar->next;
- else
- wm.bars = bar->next;
+ struct Bar *bar;
+
+ (void)dummy;
+ bar = (struct Bar *)obj;
+ TAILQ_REMOVE(&wm.barq, (struct Object *)bar, entry);
free(bar);
monupdatearea();
+ return 0;
}
/* decorate dock */
@@ -4799,13 +4494,15 @@ dockdecorate(void)
static void
dockupdate(void)
{
+ struct Object *p;
struct Dockapp *dapp;
Window wins[2];
int size;
int n;
size = 0;
- for (dapp = dock.head; dapp != NULL; dapp = dapp->next) {
+ TAILQ_FOREACH(p, &dock.dappq, entry) {
+ dapp = (struct Dockapp *)p;
switch (config.dockgravity[0]) {
case 'N':
dapp->x = DOCKBORDER + size;
@@ -4857,7 +4554,7 @@ dockupdate(void)
break;
case 'S':
dock.h = config.dockwidth;
- dock.y = wm.monhead->mh - config.dockwidth;
+ dock.y = TAILQ_FIRST(&wm.monq)->mh - config.dockwidth;
break;
case 'W':
dock.w = config.dockwidth;
@@ -4866,45 +4563,46 @@ dockupdate(void)
case 'E':
default:
dock.w = config.dockwidth;
- dock.x = wm.monhead->mw - config.dockwidth;
- dock.h = min(size, wm.monhead->mh);
- dock.y = wm.monhead->mh / 2 - size / 2;
+ dock.x = TAILQ_FIRST(&wm.monq)->mw - config.dockwidth;
+ dock.h = min(size, TAILQ_FIRST(&wm.monq)->mh);
+ dock.y = TAILQ_FIRST(&wm.monq)->mh / 2 - size / 2;
break;
}
if (config.dockgravity[0] == 'N' || config.dockgravity[0] == 'S') {
switch (config.dockgravity[1]) {
case 'W':
- dock.w = min(size, wm.monhead->mw);
+ dock.w = min(size, TAILQ_FIRST(&wm.monq)->mw);
dock.x = 0;
break;
case 'E':
- dock.w = min(size, wm.monhead->mw);
- dock.x = wm.monhead->mw - size;
+ dock.w = min(size, TAILQ_FIRST(&wm.monq)->mw);
+ dock.x = TAILQ_FIRST(&wm.monq)->mw - size;
break;
default:
- dock.w = min(size, wm.monhead->mw);
- dock.x = wm.monhead->mw / 2 - size / 2;
+ dock.w = min(size, TAILQ_FIRST(&wm.monq)->mw);
+ dock.x = TAILQ_FIRST(&wm.monq)->mw / 2 - size / 2;
break;
}
} else if (config.dockgravity[0] != '\0') {
switch (config.dockgravity[1]) {
case 'N':
- dock.h = min(size, wm.monhead->mh);
+ dock.h = min(size, TAILQ_FIRST(&wm.monq)->mh);
dock.y = 0;
break;
case 'S':
- dock.h = min(size, wm.monhead->mh);
- dock.y = wm.monhead->mh - size;
+ dock.h = min(size, TAILQ_FIRST(&wm.monq)->mh);
+ dock.y = TAILQ_FIRST(&wm.monq)->mh - size;
break;
default:
- dock.h = min(size, wm.monhead->mh);
- dock.y = wm.monhead->mh / 2 - size / 2;
+ dock.h = min(size, TAILQ_FIRST(&wm.monq)->mh);
+ dock.y = TAILQ_FIRST(&wm.monq)->mh / 2 - size / 2;
break;
}
}
- for (dapp = dock.head; dapp != NULL; dapp = dapp->next) {
- XMoveWindow(dpy, dapp->win, dapp->x, dapp->y);
- winnotify(dapp->win, dock.x + dapp->x, dock.y + dapp->y, dapp->w, dapp->h);
+ TAILQ_FOREACH(p, &dock.dappq, entry) {
+ dapp = (struct Dockapp *)p;
+ XMoveWindow(dpy, dapp->obj.win, dapp->x, dapp->y);
+ winnotify(dapp->obj.win, dock.x + dapp->x, dock.y + dapp->y, dapp->w, dapp->h);
}
dockdecorate();
wins[0] = wm.layerwins[LAYER_DOCK];
@@ -4919,55 +4617,45 @@ dockupdate(void)
static void
dockappnew(Window win, int w, int h, int dockpos, int ignoreunmap)
{
- struct Dockapp *dapp, *tmp;
+ struct Dockapp *dapp;
+ struct Object *prev;
dapp = emalloc(sizeof(*dapp));
*dapp = (struct Dockapp){
- .win = win,
+ .obj.type = TYPE_DOCKAPP,
+ .obj.win = win,
.w = w,
.h = h,
.ignoreunmap = ignoreunmap,
.dockpos = dockpos,
};
- for (tmp = dock.tail; tmp != NULL; tmp = tmp->prev)
- if (tmp->dockpos <= dockpos)
+ TAILQ_FOREACH_REVERSE(prev, &dock.dappq, Queue, entry)
+ if (((struct Dockapp *)prev)->dockpos <= dockpos)
break;
- if (tmp != NULL) {
- dapp->prev = tmp;
- dapp->next = tmp->next;
- if (tmp->next != NULL)
- tmp->next->prev = dapp;
- else
- dock.tail = dapp;
- tmp->next = dapp;
+ if (prev != NULL) {
+ TAILQ_INSERT_AFTER(&dock.dappq, prev, (struct Object *)dapp, entry);
} else {
- dapp->next = dock.head;
- dapp->prev = NULL;
- if (dock.head != NULL)
- dock.head->prev = dapp;
- else
- dock.tail = dapp;
- dock.head = dapp;
+ TAILQ_INSERT_HEAD(&dock.dappq, (struct Object *)dapp, entry);
}
- printf("\n");
}
/* delete dockapp */
-static void
-dockappdel(struct Dockapp *dapp)
+static int
+dockappdel(struct Object *obj, int ignoreunmap)
{
- if (dapp->next != NULL)
- dapp->next->prev = dapp->prev;
- else
- dock.tail = dapp->prev;
- if (dapp->prev != NULL)
- dapp->prev->next = dapp->next;
- else
- dock.head = dapp->next;
- XReparentWindow(dpy, dapp->win, root, 0, 0);
+ struct Dockapp *dapp;
+
+ dapp = (struct Dockapp *)obj;
+ if (ignoreunmap && dapp->ignoreunmap) {
+ dapp->ignoreunmap--;
+ return 0;
+ }
+ TAILQ_REMOVE(&dock.dappq, (struct Object *)dapp, entry);
+ XReparentWindow(dpy, dapp->obj.win, root, 0, 0);
free(dapp);
dockupdate();
monupdatearea();
+ return 0;
}
/* create new menu */
@@ -4980,7 +4668,8 @@ menunew(Window win, int x, int y, int w, int h, int ignoreunmap)
*menu = (struct Menu){
.titlebar = None,
.button = None,
- .win = win,
+ .obj.win = win,
+ .obj.type = TYPE_MENU,
.pix = None,
.pixbutton = None,
.pixtitlebar = None,
@@ -5006,8 +4695,8 @@ menunew(Window win, int x, int y, int w, int h, int ignoreunmap)
clientmask, &clientswa);
menu->pixbutton = XCreatePixmap(dpy, menu->button, config.titlewidth, config.titlewidth, depth);
XDefineCursor(dpy, menu->button, theme.cursors[CURSOR_PIRATE]);
- XReparentWindow(dpy, menu->win, menu->frame, config.borderwidth, config.borderwidth + config.titlewidth);
- XMapWindow(dpy, menu->win);
+ XReparentWindow(dpy, menu->obj.win, menu->frame, config.borderwidth, config.borderwidth + config.titlewidth);
+ XMapWindow(dpy, menu->obj.win);
XMapWindow(dpy, menu->button);
XMapWindow(dpy, menu->titlebar);
return menu;
@@ -5015,33 +4704,57 @@ menunew(Window win, int x, int y, int w, int h, int ignoreunmap)
/* call the proper decorate function */
static void
-decorate(struct Winres *res)
+decorate(Window win)
{
+ struct Object *obj;
+ struct Container *c;
+ struct Row *row;
+ struct Notification *notif;
+ struct Dialog *dial;
+ struct Menu *menu;
+ struct Tab *tab;
int fullw, fullh;
- if (res->dock) {
- XCopyArea(dpy, res->dock->pix, res->dock->win, gc, 0, 0, res->dock->w, res->dock->h, 0, 0);
- } else if (res->n) {
- XCopyArea(dpy, res->n->pix, res->n->frame, gc, 0, 0, res->n->w, res->n->h, 0, 0);
- } else if (res->menu != NULL) {
- XCopyArea(dpy, res->menu->pix, res->menu->frame, gc, 0, 0, res->menu->pw, res->menu->ph, 0, 0);
- XCopyArea(dpy, res->menu->pixbutton, res->menu->button, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
- XCopyArea(dpy, res->menu->pixtitlebar, res->menu->titlebar, gc, 0, 0, res->menu->tw, res->menu->th, 0, 0);
- } else if (res->d != NULL) {
- fullw = res->d->w + 2 * config.borderwidth;
- fullh = res->d->h + 2 * config.borderwidth;
- XCopyArea(dpy, res->d->pix, res->d->frame, gc, 0, 0, fullw, fullh, 0, 0);
- } else if (res->t != NULL) {
- XCopyArea(dpy, res->t->pixtitle, res->t->title, gc, 0, 0, res->t->w, config.titlewidth, 0, 0);
- XCopyArea(dpy, res->t->pix, res->t->frame, gc, 0, 0, res->t->winw, res->t->winh, 0, 0);
- } else if (res->row != NULL) {
- XCopyArea(dpy, res->row->pixbar, res->row->bar, gc, 0, 0, res->row->pw, config.titlewidth, 0, 0);
- XCopyArea(dpy, res->row->pixbl, res->row->bl, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
- XCopyArea(dpy, res->row->pixbr, res->row->br, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
- } else if (res->c != NULL) {
- fullw = res->c->w;
- fullh = res->c->h;
- XCopyArea(dpy, res->c->pix, res->c->frame, gc, 0, 0, fullw, fullh, 0, 0);
+ if (win == dock.win) {
+ XCopyArea(dpy, dock.pix, dock.win, gc, 0, 0, dock.w, dock.h, 0, 0);
+ return;
+ }
+ if ((obj = getmanaged(win)) == NULL)
+ return;
+ switch (obj->type) {
+ case TYPE_MENU:
+ menu = (struct Menu *)obj;
+ XCopyArea(dpy, menu->pix, menu->frame, gc, 0, 0, menu->pw, menu->ph, 0, 0);
+ XCopyArea(dpy, menu->pixbutton, menu->button, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
+ XCopyArea(dpy, menu->pixtitlebar, menu->titlebar, gc, 0, 0, menu->tw, menu->th, 0, 0);
+ break;
+ case TYPE_DIALOG:
+ dial = (struct Dialog *)obj;
+ fullw = dial->w + 2 * config.borderwidth;
+ fullh = dial->h + 2 * config.borderwidth;
+ XCopyArea(dpy, dial->pix, dial->frame, gc, 0, 0, fullw, fullh, 0, 0);
+ break;
+ case TYPE_NOTIFICATION:
+ notif = (struct Notification *)obj;
+ XCopyArea(dpy, notif->pix, notif->frame, gc, 0, 0, notif->w, notif->h, 0, 0);
+ break;
+ case TYPE_NORMAL:
+ tab = (struct Tab *)obj;
+ c = tab->row->col->c;
+ row = tab->row;
+ if (win == c->frame)
+ XCopyArea(dpy, c->pix, c->frame, gc, 0, 0, c->w, c->h, 0, 0);
+ else if (win == row->bar)
+ XCopyArea(dpy, row->pixbar, row->bar, gc, 0, 0, row->pw, config.titlewidth, 0, 0);
+ else if (win == row->bl)
+ XCopyArea(dpy, row->pixbl, row->bl, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
+ else if (win == row->br)
+ XCopyArea(dpy, row->pixbr, row->br, gc, 0, 0, config.titlewidth, config.titlewidth, 0, 0);
+ else if (win == tab->title)
+ XCopyArea(dpy, tab->pixtitle, tab->title, gc, 0, 0, tab->w, config.titlewidth, 0, 0);
+ else if (win == tab->frame)
+ XCopyArea(dpy, tab->pix, tab->frame, gc, 0, 0, tab->winw, tab->winh, 0, 0);
+ break;
}
}
@@ -5049,48 +4762,39 @@ decorate(struct Winres *res)
static void
managesplash(struct Splash *splash)
{
- if (wm.splashlist != NULL)
- wm.splashlist->prev = splash;
- splash->next = wm.splashlist;
- wm.splashlist = splash;
- icccmwmstate(splash->win, NormalState);
+ TAILQ_INSERT_HEAD(&wm.splashq, (struct Object *)splash, entry);
+ icccmwmstate(splash->obj.win, NormalState);
splashplace(splash);
- XMapWindow(dpy, splash->win);
+ XMapWindow(dpy, splash->obj.win);
}
/* add dialog window into tab */
static void
-managedialog(struct Tab *t, struct Dialog *d)
+managedialog(struct Tab *tab, struct Dialog *dial)
{
- d->t = t;
- if (t->ds != NULL)
- t->ds->prev = d;
- d->next = t->ds;
- t->ds = d;
- XReparentWindow(dpy, d->frame, t->frame, 0, 0);
- icccmwmstate(d->win, NormalState);
- dialogmoveresize(d);
- XMapRaised(dpy, d->frame);
- if (wm.focused != NULL && wm.focused->selcol->selrow->seltab == t)
- tabfocus(t, 0);
+ dial->tab = tab;
+ TAILQ_INSERT_HEAD(&tab->dialq, (struct Object *)dial, entry);
+ XReparentWindow(dpy, dial->frame, tab->frame, 0, 0);
+ icccmwmstate(dial->obj.win, NormalState);
+ dialogmoveresize(dial);
+ XMapRaised(dpy, dial->frame);
+ if (wm.focused != NULL && wm.focused->selcol->selrow->seltab == tab)
+ tabfocus(tab, 0);
ewmhsetclients();
ewmhsetclientsstacking();
}
/* assign menu to tab */
static void
-managemenu(struct Tab *t, struct Menu *menu)
+managemenu(struct Tab *tab, struct Menu *menu)
{
- menu->t = t;
- if (t->menus != NULL)
- t->menus->prev = menu;
- menu->next = t->menus;
- t->menus = menu;
- icccmwmstate(menu->win, NormalState);
+ menu->tab = tab;
+ TAILQ_INSERT_HEAD(&tab->menuq, (struct Object *)menu, entry);
+ icccmwmstate(menu->obj.win, NormalState);
menudecorate(menu, 0);
menuplace(menu);
- if (wm.focused != NULL && wm.focused->selcol->selrow->seltab == t)
- tabfocus(t, 0);
+ if (wm.focused != NULL && wm.focused->selcol->selrow->seltab == tab)
+ tabfocus(tab, 0);
ewmhsetclients();
ewmhsetclientsstacking();
}
@@ -5100,7 +4804,6 @@ static void
manageprompt(Window win, int w, int h)
{
struct Prompt prompt;
- struct Winres res;
XEvent ev;
int x, y, fw, fh;
@@ -5122,8 +4825,7 @@ manageprompt(Window win, int w, int h)
if (ev.xexpose.window == prompt.frame) {
promptdecorate(&prompt, fw, fh);
} else {
- res = getwin(ev.xexpose.window);
- decorate(&res);
+ decorate(ev.xexpose.window);
}
}
break;
@@ -5185,7 +4887,7 @@ managenotif(Window win, int w, int h)
/* create container for tab */
static void
-managecontainer(struct Container *c, struct Tab *t, struct Desktop *desk, int userplaced)
+managecontainer(struct Container *c, struct Tab *tab, struct Monitor *mon, int desk, int userplaced)
{
struct Column *col;
struct Row *row;
@@ -5194,14 +4896,14 @@ managecontainer(struct Container *c, struct Tab *t, struct Desktop *desk, int us
col = colnew();
containeraddcol(c, col, NULL);
coladdrow(col, row, NULL);
- rowaddtab(row, t, NULL);
- containersendtodesk(c, desk, 1, userplaced);
+ rowaddtab(row, tab, NULL);
+ containersendtodesk(c, mon, desk, 1, userplaced);
containercalccols(c, 1, 1);
containermoveresize(c);
containerredecorate(c, NULL, NULL, 0);
XMapSubwindows(dpy, c->frame);
containerhide(c, 0);
- tabfocus(t, 0);
+ tabfocus(tab, 0);
/* no need to call shodgrouptab() and shodgroupcontainer(); tabfocus() already calls them */
ewmhsetclients();
ewmhsetclientsstacking();
@@ -5215,12 +4917,8 @@ managebar(Window win)
Window wins[2] = {wm.layerwins[LAYER_DOCK], win};
bar = emalloc(sizeof(*bar));
- bar->prev = bar->next = NULL;
- bar->win = win;
- if (wm.bars != NULL)
- wm.bars->prev = bar;
- bar->next = wm.bars;
- wm.bars = bar;
+ bar->obj.win = win;
+ TAILQ_INSERT_HEAD(&wm.barq, (struct Object *)bar, entry);
XRestackWindows(dpy, wins, 2);
XMapWindow(dpy, win);
barstrut(bar);
@@ -5231,7 +4929,6 @@ managebar(Window win)
static void
manage(Window win, int x, int y, int w, int h, int ignoreunmap)
{
- struct Winres res;
struct Tab *t;
struct Container *c;
struct Dialog *d;
@@ -5239,8 +4936,7 @@ manage(Window win, int x, int y, int w, int h, int ignoreunmap)
struct Menu *menu;
struct Wintype wintype;
int userplaced;
- res = getwin(win);
- if (res.dock != NULL || res.c != NULL || res.bar != NULL || res.dapp != NULL || res.n != NULL || res.menu != NULL)
+ if (getmanaged(win) != NULL)
return;
getwintype(win, &wintype);
switch (wintype.type) {
@@ -5275,35 +4971,43 @@ manage(Window win, int x, int y, int w, int h, int ignoreunmap)
case TYPE_MENU:
preparewin(win);
menu = menunew(win, x, y, w, h, ignoreunmap);
- winupdatetitle(menu->win, &menu->name);
+ winupdatetitle(menu->obj.win, &menu->name);
managemenu(wintype.parent, menu);
break;
default:
preparewin(win);
userplaced = isuserplaced(win);
t = tabnew(win, wintype.leader, ignoreunmap);
- winupdatetitle(t->win, &t->name);
+ winupdatetitle(t->obj.win, &t->name);
c = containernew(x, y, w, h);
- managecontainer(c, t, wm.selmon->seldesk, userplaced);
+ managecontainer(c, t, wm.selmon, wm.selmon->seldesk, userplaced);
break;
}
}
-/* unmanage tab (and delete its row if it is the only tab) */
-static void
-unmanage(struct Tab *t)
+/* unmanage tab (and delete its row if it is the only tab); return whether deletion occurred */
+static int
+unmanage(struct Object *obj, int ignoreunmap)
{
struct Container *c, *next;
struct Column *col;
struct Row *row;
- struct Desktop *desk;
+ struct Tab *t;
+ struct Monitor *mon;
+ int desk;
int moveresize;
int focus;
+ t = (struct Tab *)obj;
+ if (ignoreunmap && t->ignoreunmap) {
+ t->ignoreunmap--;
+ return 0;
+ }
row = t->row;
col = row->col;
c = col->c;
desk = c->desk;
+ mon = c->mon;
moveresize = 1;
next = c;
tabdel(t);
@@ -5314,7 +5018,7 @@ unmanage(struct Tab *t)
coldel(col);
if (c->ncols == 0) {
containerdel(c);
- next = getnextfocused(desk->mon, desk);
+ next = getnextfocused(mon, desk);
moveresize = 0;
}
}
@@ -5329,6 +5033,7 @@ unmanage(struct Tab *t)
if (focus) {
tabfocus((next != NULL) ? next->selcol->selrow->seltab : NULL, 0);
}
+ return 1;
}
/* scan for already existing windows and adopt them */
@@ -5378,7 +5083,6 @@ mouseretab(struct Tab *t, int xroot, int yroot, int x, int y)
struct Container *c, *newc;
struct Column *col;
struct Row *row;
- struct Winres res;
XEvent ev;
int recalc, redraw;
@@ -5396,8 +5100,7 @@ mouseretab(struct Tab *t, int xroot, int yroot, int x, int y)
if (ev.xexpose.window == t->title) {
XCopyArea(dpy, t->pixtitle, t->title, gc, 0, 0, t->w, config.titlewidth, 0, 0);
} else {
- res = getwin(ev.xexpose.window);
- decorate(&res);
+ decorate(ev.xexpose.window);
}
}
break;
@@ -5419,7 +5122,7 @@ done:
if (mon == NULL)
mon = wm.selmon;
newc = containernew(xroot - x - config.titlewidth, yroot - y, t->winw, t->winh);
- managecontainer(newc, t, mon->seldesk, 1);
+ managecontainer(newc, t, mon, mon->seldesk, 1);
}
recalc = 1;
redraw = 0;
@@ -5452,7 +5155,6 @@ mouseresize(int type, void *obj, int xroot, int yroot, enum Octant o)
{
struct Container *c;
struct Menu *menu;
- struct Winres res;
Window frame;
Cursor curs;
XEvent ev;
@@ -5533,10 +5235,8 @@ mouseresize(int type, void *obj, int xroot, int yroot, enum Octant o)
while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
switch (ev.type) {
case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
+ if (ev.xexpose.count == 0)
+ decorate(ev.xexpose.window);
break;
case ButtonRelease:
goto done;
@@ -5601,13 +5301,12 @@ done:
XUngrabPointer(dpy, CurrentTime);
}
-/* move floating object (container or menu) with mouse */
+/* move floating entity (container or menu) with mouse */
static void
-mousemove(int type, void *obj, int xroot, int yroot, enum Octant o)
+mousemove(int type, void *p, int xroot, int yroot, enum Octant o)
{
struct Container *c;
struct Menu *menu;
- struct Winres res;
Window frame;
XEvent ev;
Time lasttime;
@@ -5615,11 +5314,11 @@ mousemove(int type, void *obj, int xroot, int yroot, enum Octant o)
int floatx, floaty;
if (type == FLOAT_MENU) {
- menu = (struct Menu *)obj;
+ menu = (struct Menu *)p;
menudecorate(menu, o);
frame = menu->frame;
} else {
- c = (struct Container *)obj;
+ c = (struct Container *)p;
containerdecorate(c, NULL, NULL, 0, o);
frame = c->frame;
}
@@ -5630,10 +5329,8 @@ mousemove(int type, void *obj, int xroot, int yroot, enum Octant o)
while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
switch (ev.type) {
case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
+ if (ev.xexpose.count == 0)
+ decorate(ev.xexpose.window);
break;
case ButtonRelease:
goto done;
@@ -5667,110 +5364,24 @@ done:
XUngrabPointer(dpy, CurrentTime);
}
-/* control placement of row with mouse */
-static void
-mousererow(struct Row *row)
-{
- struct Container *c;
- struct Column *origcol, *col, *newcol, *prevcol;
- struct Row *prev, *r;
- struct Tab *t;
- struct Winres res;
- XEvent ev;
- int dy, y, sumh;
-
- origcol = row->col;
- if (origcol->maxrow != NULL)
- return;
- prevcol = origcol;
- c = row->col->c;
- newcol = NULL;
- y = 0;
- buttonleftdecorate(row, 1);
- XRaiseWindow(dpy, row->bar);
- if (XGrabPointer(dpy, row->bar, False, ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime) != GrabSuccess)
- goto done;
- while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
- switch(ev.type) {
- case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
- break;
- case MotionNotify:
- for (col = c->cols; col != NULL; col = col->next) {
- if (ev.xmotion.x_root >= c->x + col->x &&
- ev.xmotion.x_root < c->x + col->x + col->w &&
- ev.xmotion.y_root >= c->y + c->b &&
- ev.xmotion.y_root < c->y + c->h - c->b - config.titlewidth) {
- newcol = col;
- y = ev.xmotion.y_root - c->y;
- if (prevcol != newcol) {
- row->col = col;
- rowcalctabs(row);
- for (t = row->tabs; t != NULL; t = t->next) {
- tabmoveresize(t);
- tabdecorate(t, 0);
- }
- row->col = origcol;
- }
- titlebarmoveresize(row, col->x, y, col->w);
- prevcol = col;
- }
- }
- break;
- case ButtonRelease:
- goto done;
- }
- }
-done:
- sumh = c->b;
- prev = NULL;
- col = row->col;
- if (newcol != NULL) {
- for (r = newcol->rows; r != NULL; r = r->next) {
- sumh += row->h;
- prev = r;
- if (y < sumh)
- break;
- }
- if (prev != row && prev != NULL) {
- rowdetach(row, 0);
- coladdrow(newcol, row, prev);
- }
- if (row->prev != NULL) {
- dy = y - row->y;
- row->h -= dy;
- row->prev->h += dy;
- }
- }
- containercalccols(c, 0, 1);
- containermoveresize(c);
- buttonleftdecorate(row, 0);
- containerdecorate(c, NULL, NULL, 0, 0);
- XUngrabPointer(dpy, CurrentTime);
-}
-
/* close tab with mouse */
static void
mouseclose(int type, void *obj)
{
struct Row *row;
struct Menu *menu;
- struct Winres res;
Window win, button;
XEvent ev;
if (type == FLOAT_MENU) {
menu = (struct Menu *)obj;
button = menu->button;
- win = menu->win;
+ win = menu->obj.win;
buttonrightdecorate(button, menu->pixbutton, FOCUSED, 1);
} else {
row = (struct Row *)obj;
button = row->br;
- win = row->seltab->ds != NULL ? row->seltab->ds->win : row->seltab->win;
+ win = TAILQ_EMPTY(&row->seltab->dialq) ? row->seltab->obj.win : TAILQ_FIRST(&row->seltab->dialq)->win;
buttonrightdecorate(button, row->pixbr, tabgetstyle(row->seltab), 1);
}
if (XGrabPointer(dpy, button, False, ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime) != GrabSuccess)
@@ -5778,10 +5389,8 @@ mouseclose(int type, void *obj)
while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
switch(ev.type) {
case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
+ if (ev.xexpose.count == 0)
+ decorate(ev.xexpose.window);
break;
case ButtonRelease:
if (ev.xbutton.window == button &&
@@ -5805,16 +5414,15 @@ done:
static void
mouseretile(struct Container *c, struct Column *cdiv, struct Row *rdiv, int xroot, int yroot)
{
- struct Winres res;
XEvent ev;
Cursor curs;
Time lasttime;
int x, y;
int update;
- if (cdiv != NULL && cdiv->next != NULL)
+ if (cdiv != NULL && TAILQ_NEXT(cdiv, entry) != NULL)
curs = theme.cursors[CURSOR_H];
- else if (rdiv != NULL && rdiv->next != NULL && rdiv->col->maxrow == NULL)
+ else if (rdiv != NULL && TAILQ_NEXT(rdiv, entry) != NULL && rdiv->col->maxrow == NULL)
curs = theme.cursors[CURSOR_V];
else
return;
@@ -5827,10 +5435,8 @@ mouseretile(struct Container *c, struct Column *cdiv, struct Row *rdiv, int xroo
while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
switch (ev.type) {
case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
+ if (ev.xexpose.count == 0)
+ decorate(ev.xexpose.window);
break;
case ButtonRelease:
goto done;
@@ -5841,12 +5447,12 @@ mouseretile(struct Container *c, struct Column *cdiv, struct Row *rdiv, int xroo
if (cdiv != NULL) {
if (x < 0 && cdiv->w + x > wm.minsize) {
cdiv->w += x;
- cdiv->next->w -= x;
+ TAILQ_NEXT(cdiv, entry)->w -= x;
if (ev.xmotion.time - lasttime > RESIZETIME) {
update = 1;
}
- } else if (x > 0 && cdiv->next->w - x > wm.minsize) {
- cdiv->next->w -= x;
+ } else if (x > 0 && TAILQ_NEXT(cdiv, entry)->w - x > wm.minsize) {
+ TAILQ_NEXT(cdiv, entry)->w -= x;
cdiv->w += x;
if (ev.xmotion.time - lasttime > RESIZETIME) {
update = 1;
@@ -5855,12 +5461,12 @@ mouseretile(struct Container *c, struct Column *cdiv, struct Row *rdiv, int xroo
} else if (rdiv != NULL) {
if (y < 0 && rdiv->h + y > wm.minsize) {
rdiv->h += y;
- rdiv->next->h -= y;
+ TAILQ_NEXT(rdiv, entry)->h -= y;
if (ev.xmotion.time - lasttime > RESIZETIME) {
update = 1;
}
- } else if (y > 0 && rdiv->next->h - y > wm.minsize) {
- rdiv->next->h -= y;
+ } else if (y > 0 && TAILQ_NEXT(rdiv, entry)->h - y > wm.minsize) {
+ TAILQ_NEXT(rdiv, entry)->h -= y;
rdiv->h += y;
if (ev.xmotion.time - lasttime > RESIZETIME) {
update = 1;
@@ -5890,7 +5496,6 @@ done:
static void
mousestack(struct Row *row)
{
- struct Winres res;
XEvent ev;
buttonleftdecorate(row, 1);
@@ -5899,10 +5504,8 @@ mousestack(struct Row *row)
while (!XMaskEvent(dpy, MOUSEEVENTMASK, &ev)) {
switch(ev.type) {
case Expose:
- if (ev.xexpose.count == 0) {
- res = getwin(ev.xexpose.window);
- decorate(&res);
- }
+ if (ev.xexpose.count == 0)
+ decorate(ev.xexpose.window);
break;
case ButtonRelease:
if (row->col->nrows > 1 &&
@@ -5925,107 +5528,110 @@ done:
static void
xeventbuttonpress(XEvent *e)
{
- struct Winres res;
+ struct Object *obj;
struct Monitor *mon;
struct Container *c;
struct Column *cdiv;
struct Row *rdiv;
- struct Tab *t;
+ struct Tab *tab;
+ struct Menu *menu;
enum Octant o;
XButtonPressedEvent *ev;
Window dw;
int x, y;
ev = &e->xbutton;
- res = getwin(ev->window);
-
- /* if user clicked in no window, focus the monitor below cursor */
- c = res.c;
- if (c == NULL) {
- mon = getmon(ev->x_root, ev->y_root);
- if (mon)
- deskfocus(mon->seldesk, 1);
+
+ if ((obj = getmanaged(ev->window)) == NULL) {
+ /* if user clicked in no window, focus the monitor below cursor */
+ if ((mon = getmon(ev->x_root, ev->y_root)) != NULL)
+ deskfocus(mon, mon->seldesk, 1);
goto done;
}
- if (res.t != NULL) {
- t = res.t;
- } else if (res.d != NULL) {
- t = res.d->t;
- } else if (res.menu != NULL) {
- t = res.menu->t;
- } else if (res.row != NULL) {
- t = res.row->seltab;
- } else {
- t = c->selcol->selrow->seltab;
- }
- if (t == NULL) {
+ menu = NULL;
+ tab = NULL;
+ switch (obj->type) {
+ case TYPE_NORMAL:
+ tab = (struct Tab *)obj;
+ c = tab->row->col->c;
+ break;
+ case TYPE_DIALOG:
+ tab = ((struct Dialog *)obj)->tab;
+ c = tab->row->col->c;
+ break;
+ case TYPE_MENU:
+ menu = (struct Menu *)obj;
+ tab = menu->tab;
+ c = tab->row->col->c;
+ break;
+ default:
+ if ((mon = getmon(ev->x_root, ev->y_root)) != NULL)
+ deskfocus(mon, mon->seldesk, 1);
goto done;
}
/* raise menu above others */
- if (res.menu != NULL)
- menuaddraise(t, res.menu);
+ if (menu != NULL)
+ menuaddraise(tab, menu);
/* focus client */
- if ((wm.focused == NULL || t != wm.focused->selcol->selrow->seltab) && ev->button == Button1)
- tabfocus(t, 1);
+ if ((wm.focused == NULL || tab != wm.focused->selcol->selrow->seltab) && ev->button == Button1)
+ tabfocus(tab, 1);
/* raise client */
if (ev->button == Button1)
- containerraise(c);
-
- /* do action performed by mouse on non-maximized windows */
- if (XTranslateCoordinates(dpy, ev->window, c->frame, ev->x, ev->y, &x, &y, &dw) != True)
- goto done;
- o = getoctant(c, x, y);
- if (res.menu != NULL) {
- if (ev->window == res.menu->titlebar && ev->button == Button1) {
- mousemove(FLOAT_MENU, res.menu, ev->x_root, ev->y_root, 1);
- } else if (ev->window == res.menu->button && ev->button == Button1) {
- mouseclose(FLOAT_MENU, res.menu);
- } else if (ev->window == res.menu->frame && ev->button == Button3) {
- mousemove(FLOAT_MENU, res.menu, ev->x_root, ev->y_root, 0);
+ containerraise(c, c->isfullscreen, c->layer);
+
+ /* do action performed by mouse */
+ if (menu != NULL) {
+ if (ev->window == menu->titlebar && ev->button == Button1) {
+ mousemove(FLOAT_MENU, menu, ev->x_root, ev->y_root, 1);
+ } else if (ev->window == menu->button && ev->button == Button1) {
+ mouseclose(FLOAT_MENU, menu);
+ } else if (ev->window == menu->frame && ev->button == Button3) {
+ mousemove(FLOAT_MENU, menu, ev->x_root, ev->y_root, 0);
}
- } else if (ev->window == t->title && ev->button == Button3) {
- mouseretab(t, ev->x_root, ev->y_root, ev->x, ev->y);
- } else if (res.row != NULL && ev->window == res.row->bl && ev->button == Button1) {
- mousestack(res.row);
- } else if (res.row != NULL && ev->window == res.row->bl && ev->button == Button3) {
- mousererow(res.row);
- } else if (res.row != NULL && ev->window == res.row->br && ev->button == Button1) {
- mouseclose(FLOAT_CONTAINER, res.row);
- } else if (ev->window == c->frame && ev->button == Button1 && o == C) {
- getdivisions(c, &cdiv, &rdiv, x, y);
- if (cdiv != NULL || rdiv != NULL) {
- mouseretile(c, cdiv, rdiv, ev->x_root, ev->y_root);
- }
- } else if (!c->isfullscreen && !c->isminimized && !c->ismaximized) {
- if (ev->state == config.modifier && ev->button == Button1) {
- mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, 0);
- } else if (ev->window == c->frame && ev->button == Button3) {
- mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, o);
- } else if ((ev->state == config.modifier && ev->button == Button3) ||
- (o != C && ev->window == c->frame && ev->button == Button1)) {
- if (o == C) {
- if (x >= c->w / 2 && y >= c->h / 2) {
- o = SE;
- }
- if (x >= c->w / 2 && y <= c->h / 2) {
- o = NE;
- }
- if (x <= c->w / 2 && y >= c->h / 2) {
- o = SW;
- }
- if (x <= c->w / 2 && y <= c->h / 2) {
- o = NW;
+ } else if (XTranslateCoordinates(dpy, ev->window, c->frame, ev->x, ev->y, &x, &y, &dw)) {
+ o = getoctant(c, x, y);
+ if (ev->window == tab->title && ev->button == Button3) {
+ mouseretab(tab, ev->x_root, ev->y_root, ev->x, ev->y);
+ } else if (ev->window == tab->row->bl && ev->button == Button1) {
+ mousestack(tab->row);
+ } else if (ev->window == tab->row->br && ev->button == Button1) {
+ mouseclose(FLOAT_CONTAINER, tab->row);
+ } else if (ev->window == c->frame && ev->button == Button1 && o == C) {
+ getdivisions(c, &cdiv, &rdiv, x, y);
+ if (cdiv != NULL || rdiv != NULL) {
+ mouseretile(c, cdiv, rdiv, ev->x_root, ev->y_root);
+ }
+ } else if (!c->isfullscreen && !c->isminimized && !c->ismaximized) {
+ if (ev->state == config.modifier && ev->button == Button1) {
+ mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, 0);
+ } else if (ev->window == c->frame && ev->button == Button3) {
+ mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, o);
+ } else if ((ev->state == config.modifier && ev->button == Button3) ||
+ (o != C && ev->window == c->frame && ev->button == Button1)) {
+ if (o == C) {
+ if (x >= c->w / 2 && y >= c->h / 2) {
+ o = SE;
+ }
+ if (x >= c->w / 2 && y <= c->h / 2) {
+ o = NE;
+ }
+ if (x <= c->w / 2 && y >= c->h / 2) {
+ o = SW;
+ }
+ if (x <= c->w / 2 && y <= c->h / 2) {
+ o = NW;
+ }
}
+ mouseresize(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, o);
+ } else if (ev->window == tab->title && ev->button == Button1) {
+ tabdecorate(tab, 1);
+ mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, 0);
+ tabdecorate(tab, 0);
}
- mouseresize(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, o);
- } else if (ev->window == t->title && ev->button == Button1) {
- tabdecorate(t, 1);
- mousemove(FLOAT_CONTAINER, c, ev->x_root, ev->y_root, 0);
- tabdecorate(t, 0);
}
}
@@ -6038,165 +5644,146 @@ static void
xeventclientmessage(XEvent *e)
{
struct Monitor *mon;
- struct Desktop *prevdesk, *desk;
- struct Container *c;
- struct Tab *t;
- struct Winres res;
+ struct Container *c = NULL;
+ struct Tab *tab = NULL;
+ struct Menu *menu = NULL;
+ struct Object *obj;
XClientMessageEvent *ev;
XWindowChanges wc;
unsigned value_mask = 0;
+ int prevdesk;
int floattype;
int i;
- void *obj;
+ void *p;
ev = &e->xclient;
- res = getwin(ev->window);
+ if ((obj = getmanaged(ev->window)) != NULL) {
+ switch (obj->type) {
+ case TYPE_NORMAL:
+ tab = (struct Tab *)obj;
+ c = tab->row->col->c;
+ break;
+ case TYPE_DIALOG:
+ tab = ((struct Dialog *)obj)->tab;
+ c = tab->row->col->c;
+ break;
+ case TYPE_MENU:
+ menu = (struct Menu *)obj;
+ tab = menu->tab;
+ c = tab->row->col->c;
+ break;
+ }
+ }
if (ev->message_type == atoms[_NET_CURRENT_DESKTOP]) {
- deskfocus(getdesk(ev->data.l[0], ev->data.l[2]), 1);
+ deskfocus(wm.selmon, ev->data.l[0], 1);
} else if (ev->message_type == atoms[_NET_SHOWING_DESKTOP]) {
if (ev->data.l[0]) {
deskshow(1);
} else {
- deskfocus(wm.selmon->seldesk, 1);
+ deskfocus(wm.selmon, wm.selmon->seldesk, 1);
}
} else if (ev->message_type == atoms[_NET_WM_STATE]) {
- if (res.c == NULL || res.d != NULL || res.menu != NULL)
+ if (obj == NULL || obj->type != TYPE_NORMAL)
return;
if (((Atom)ev->data.l[1] == atoms[_NET_WM_STATE_MAXIMIZED_VERT] ||
(Atom)ev->data.l[1] == atoms[_NET_WM_STATE_MAXIMIZED_HORZ]) &&
((Atom)ev->data.l[2] == atoms[_NET_WM_STATE_MAXIMIZED_VERT] ||
(Atom)ev->data.l[2] == atoms[_NET_WM_STATE_MAXIMIZED_HORZ])) {
- containermaximize(res.c, ev->data.l[0]);
+ containermaximize(c, ev->data.l[0]);
}
for (i = 1; i < 3; i++) {
if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_FULLSCREEN]) {
- containerfullscreen(res.c, ev->data.l[0]);
+ containerfullscreen(c, ev->data.l[0]);
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_SHADED]) {
- containershade(res.c, ev->data.l[0]);
+ containershade(c, ev->data.l[0]);
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_STICKY]) {
- containerstick(res.c, ev->data.l[0]);
+ containerstick(c, ev->data.l[0]);
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_HIDDEN]) {
- containerminimize(res.c, ev->data.l[0], (res.c == wm.focused));
+ containerminimize(c, ev->data.l[0], (c == wm.focused));
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_ABOVE]) {
- containerabove(res.c, ev->data.l[0]);
+ containerabove(c, ev->data.l[0]);
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_BELOW]) {
- containerbelow(res.c, ev->data.l[0]);
+ containerbelow(c, ev->data.l[0]);
} else if ((Atom)ev->data.l[i] == atoms[_NET_WM_STATE_DEMANDS_ATTENTION]) {
- tabupdateurgency(res.t, ev->data.l[0] == ADD || (ev->data.l[0] == TOGGLE && !res.t->isurgent));
+ tabupdateurgency(tab, ev->data.l[0] == ADD || (ev->data.l[0] == TOGGLE && !tab->isurgent));
}
}
} else if (ev->message_type == atoms[_NET_ACTIVE_WINDOW]) {
- if (res.t == NULL && wm.focused != NULL) {
- res.c = wm.focused;
- res.t = wm.focused->selcol->selrow->seltab;
+#define ACTIVATECOL(col) { if ((col) != NULL) tabfocus((col)->selrow->seltab, 1); }
+#define ACTIVATEROW(row) { if ((row) != NULL) tabfocus((row)->seltab, 1); }
+ if (tab == NULL && wm.focused != NULL) {
+ c = wm.focused;
+ tab = wm.focused->selcol->selrow->seltab;
}
- c = NULL;
- t = NULL;
+ if (tab == NULL)
+ return;
switch (ev->data.l[3]) {
case _SHOD_FOCUS_LEFT_CONTAINER:
case _SHOD_FOCUS_RIGHT_CONTAINER:
case _SHOD_FOCUS_TOP_CONTAINER:
case _SHOD_FOCUS_BOTTOM_CONTAINER:
- if (res.c != NULL && (c = getfocusedbydirection(res.c, ev->data.l[3])) != NULL)
- t = c->selcol->selrow->seltab;
- break;
case _SHOD_FOCUS_PREVIOUS_CONTAINER:
- if (res.c != NULL && res.c->fprev != NULL) {
- c = res.c->fprev;
- t = c->selcol->selrow->seltab;
- } else if (ev->data.l[4] && res.c != NULL && (c = getlastfocused(res.c)) != NULL) {
- t = c->selcol->selrow->seltab;
- }
- break;
case _SHOD_FOCUS_NEXT_CONTAINER:
- if (res.c != NULL && res.c->fnext != NULL) {
- c = res.c->fnext;
- t = c->selcol->selrow->seltab;
- } else if (ev->data.l[4] && res.c != NULL && (c = getfirstfocused(res.c)) != NULL) {
- t = c->selcol->selrow->seltab;
- }
+ // removed
break;
case _SHOD_FOCUS_LEFT_WINDOW:
- if (res.t != NULL && res.t->row->col->prev != NULL) {
- c = res.c;
- t = res.t->row->col->prev->selrow->seltab;
- }
+ ACTIVATECOL(TAILQ_PREV(tab->row->col, ColumnQueue, entry))
break;
case _SHOD_FOCUS_RIGHT_WINDOW:
- if (res.t != NULL && res.t->row->col->next != NULL) {
- c = res.c;
- t = res.t->row->col->next->selrow->seltab;
- }
+ ACTIVATECOL(TAILQ_NEXT(tab->row->col, entry))
break;
case _SHOD_FOCUS_TOP_WINDOW:
- if (res.t != NULL && res.t->row->prev != NULL) {
- c = res.c;
- t = res.t->row->prev->seltab;
- }
+ ACTIVATEROW(TAILQ_PREV(tab->row, RowQueue, entry))
break;
case _SHOD_FOCUS_BOTTOM_WINDOW:
- if (res.t != NULL && res.t->row->next != NULL) {
- c = res.c;
- t = res.t->row->next->seltab;
- }
+ ACTIVATEROW(TAILQ_NEXT(tab->row, entry))
break;
case _SHOD_FOCUS_PREVIOUS_WINDOW:
- c = res.c;
- if (res.t != NULL && res.t->prev != NULL) {
- t = res.t->prev;
- } else if (ev->data.l[4] && res.t != NULL) {
- for (t = res.t->row->tabs; t != NULL; t = t->next) {
- if (t->next == NULL) {
- break;
- }
- }
- }
+ obj = (struct Object *)tab;
+ if (TAILQ_PREV(obj, Queue, entry) != NULL)
+ tabfocus((struct Tab *)TAILQ_PREV(obj, Queue, entry), 1);
+ else
+ tabfocus((struct Tab *)TAILQ_LAST(&tab->row->tabq, Queue), 1);
break;
case _SHOD_FOCUS_NEXT_WINDOW:
- c = res.c;
- if (res.t != NULL && res.t->next != NULL) {
- t = res.t->next;
- } else if (ev->data.l[4] && res.t != NULL) {
- t = res.t->row->tabs;
- }
+ obj = (struct Object *)tab;
+ if (TAILQ_NEXT(obj, entry) != NULL)
+ tabfocus((struct Tab *)TAILQ_NEXT(obj, entry), 1);
+ else
+ tabfocus((struct Tab *)TAILQ_FIRST(&tab->row->tabq), 1);
break;
default:
- c = res.c;
- t = res.t;
+ tabfocus(tab, 1);
break;
}
- if (c == NULL || t == NULL)
- return;
- tabfocus(t, 1);
} else if (ev->message_type == atoms[_NET_CLOSE_WINDOW]) {
winclose(ev->window);
} else if (ev->message_type == atoms[_NET_MOVERESIZE_WINDOW]) {
- value_mask = 0;
- if (res.c == NULL)
+ if (c == NULL)
return;
value_mask = CWX | CWY | CWWidth | CWHeight;
- wc.x = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? res.c->x + ev->data.l[1] : ev->data.l[1];
- wc.y = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? res.c->y + ev->data.l[2] : ev->data.l[2];
- wc.width = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? res.c->w + ev->data.l[3] : ev->data.l[3];
- wc.height = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? res.c->h + ev->data.l[4] : ev->data.l[4];
- if (res.d != NULL) {
- dialogconfigure(res.d, value_mask, &wc);
- } else {
- containerconfigure(res.c, value_mask, &wc);
+ wc.x = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? c->x + ev->data.l[1] : ev->data.l[1];
+ wc.y = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? c->y + ev->data.l[2] : ev->data.l[2];
+ wc.width = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? c->w + ev->data.l[3] : ev->data.l[3];
+ wc.height = (ev->data.l[0] & _SHOD_MOVERESIZE_RELATIVE) ? c->h + ev->data.l[4] : ev->data.l[4];
+ if (obj->type == TYPE_DIALOG) {
+ dialogconfigure((struct Dialog *)obj, value_mask, &wc);
+ } else if (obj->type == TYPE_NORMAL) {
+ containerconfigure(c, value_mask, &wc);
}
} else if (ev->message_type == atoms[_NET_WM_DESKTOP]) {
- if (res.c == NULL)
+ if (obj == NULL || obj->type != TYPE_NORMAL)
return;
if (ev->data.l[0] == 0xFFFFFFFF) {
- containerstick(res.c, ADD);
- } else if (!res.c->isminimized) {
- if ((desk = getdesk(ev->data.l[0], ev->data.l[2])) == NULL || desk == res.c->desk)
+ containerstick(c, ADD);
+ } else if (!c->isminimized) {
+ if (ev->data.l[0] < 0 || ev->data.l[0] >= config.ndesktops || c->desk == ev->data.l[0])
return;
- if (res.c->issticky)
- containerstick(res.c, REMOVE);
- mon = res.c->mon;
- prevdesk = res.c->desk;
- containersendtodesk(res.c, desk, 0, 0);
+ if (c->issticky)
+ containerstick(c, REMOVE);
+ mon = c->mon;
+ prevdesk = c->desk;
+ containersendtodesk(c, mon, ev->data.l[0], 0, 0);
c = getnextfocused(mon, prevdesk);
if (c != NULL) {
tabfocus(c->selcol->selrow->seltab, 0);
@@ -6205,7 +5792,7 @@ xeventclientmessage(XEvent *e)
}
}
} else if (ev->message_type == atoms[_NET_REQUEST_FRAME_EXTENTS]) {
- if (res.c == NULL) {
+ if (c == NULL) {
/*
* A client can request an estimate for the frame size
* which the window manager will put around it before
@@ -6214,49 +5801,49 @@ xeventclientmessage(XEvent *e)
*/
ewmhsetframeextents(ev->window, config.borderwidth, config.titlewidth);
} else {
- ewmhsetframeextents(ev->window, res.c->b, (res.d != NULL ? 0 : TITLEWIDTH(res.c)));
+ ewmhsetframeextents(ev->window, c->b, (obj->type == TYPE_DIALOG ? 0 : TITLEWIDTH(c)));
}
} else if (ev->message_type == atoms[_NET_WM_MOVERESIZE]) {
/*
* Client-side decorated Gtk3 windows emit this signal when being
* dragged by their GtkHeaderBar
*/
- if (res.d != NULL || res.c == NULL || res.c != wm.focused)
+ if (obj == NULL || (obj->type != TYPE_NORMAL && obj->type != TYPE_MENU))
return;
- if (res.menu != NULL) {
- obj = res.menu;
+ if (menu != NULL) {
+ p = menu;
floattype = FLOAT_MENU;
} else {
- obj = res.c;
+ p = c;
floattype = FLOAT_CONTAINER;
}
switch (ev->data.l[2]) {
case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], NW);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], NW);
break;
case _NET_WM_MOVERESIZE_SIZE_TOP:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], N);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], N);
break;
case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], NE);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], NE);
break;
case _NET_WM_MOVERESIZE_SIZE_RIGHT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], E);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], E);
break;
case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], SE);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], SE);
break;
case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], S);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], S);
break;
case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], SW);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], SW);
break;
case _NET_WM_MOVERESIZE_SIZE_LEFT:
- mouseresize(floattype, obj, ev->data.l[0], ev->data.l[1], W);
+ mouseresize(floattype, p, ev->data.l[0], ev->data.l[1], W);
break;
case _NET_WM_MOVERESIZE_MOVE:
- mousemove(floattype, obj, ev->data.l[0], ev->data.l[1], C);
+ mousemove(floattype, p, ev->data.l[0], ev->data.l[1], C);
break;
default:
XUngrabPointer(dpy, CurrentTime);
@@ -6286,7 +5873,7 @@ xeventconfigurerequest(XEvent *e)
{
XConfigureRequestEvent *ev;
XWindowChanges wc;
- struct Winres res;
+ struct Object *obj;
ev = &e->xconfigurerequest;
wc.x = ev->x;
@@ -6296,66 +5883,68 @@ xeventconfigurerequest(XEvent *e)
wc.border_width = ev->border_width;
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
- res = getwin(ev->window);
- if (res.d != NULL) {
- dialogconfigure(res.d, ev->value_mask, &wc);
- } else if (res.c != NULL) {
+ obj = getmanaged(ev->window);
+ if (obj == NULL) {
+ XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
+ } else if (obj->type == TYPE_DIALOG) {
+ dialogconfigure((struct Dialog *)obj, ev->value_mask, &wc);
+ } else if (obj->type == TYPE_NORMAL) {
if (config.honorconfig) {
- containerconfigure(res.c, ev->value_mask, &wc);
+ containerconfigure(((struct Tab *)obj)->row->col->c, ev->value_mask, &wc);
} else {
- containermoveresize(res.c);
+ containermoveresize(((struct Tab *)obj)->row->col->c);
}
- } else if (res.c == NULL && res.dapp == NULL){
- XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
}
}
+static int (*unmanagetab[TYPE_LAST])(struct Object *, int) = {
+ [TYPE_DOCKAPP] = dockappdel,
+ [TYPE_SPLASH] = splashdel,
+ [TYPE_NOTIFICATION] = notifdel,
+ [TYPE_DOCK] = bardel,
+ [TYPE_DIALOG] = dialogdel,
+ [TYPE_MENU] = menudel,
+ [TYPE_NORMAL] = unmanage,
+};
+
/* forget about client */
static void
xeventdestroynotify(XEvent *e)
{
XDestroyWindowEvent *ev;
- struct Winres res;
+ struct Object *obj;
ev = &e->xdestroywindow;
- res = getwin(ev->window);
- if (res.dapp && ev->window == res.dapp->win) {
- dockappdel(res.dapp);
- } else if (res.splash != NULL) {
- splashdel(res.splash);
- return;
- } else if (res.n && ev->window == res.n->win) {
- notifdel(res.n);
- return;
- } else if (res.bar != NULL && ev->window == res.bar->win) {
- bardel(res.bar);
- return;
- } else if (res.d && ev->window == res.d->win) {
- dialogdel(res.d);
- } else if (res.menu && ev->window == res.menu->win) {
- menudel(res.menu);
- } else if (res.t && ev->window == res.t->win) {
- unmanage(res.t);
- } else {
- return;
+ if ((obj = getmanaged(ev->window)) != NULL) {
+ if (obj->win == ev->window && (*unmanagetab[obj->type])(obj, 0)) {
+ ewmhsetclients();
+ ewmhsetclientsstacking();
+ }
}
- ewmhsetclients();
- ewmhsetclientsstacking();
}
/* focus window when cursor enter it (only if there is no focus button) */
static void
xevententernotify(XEvent *e)
{
- struct Winres res;
+ struct Object *obj;
if (!config.sloppyfocus)
return;
while (XCheckTypedEvent(dpy, EnterNotify, e))
;
- res = getwin(e->xcrossing.window);
- if (res.t != NULL) {
- tabfocus(res.t, 1);
+ if ((obj = getmanaged(e->xcrossing.window)) == NULL)
+ return;
+ switch (obj->type) {
+ case TYPE_MENU:
+ tabfocus(((struct Menu *)obj)->tab, 1);
+ break;
+ case TYPE_DIALOG:
+ tabfocus(((struct Dialog *)obj)->tab, 1);
+ break;
+ case TYPE_NORMAL:
+ tabfocus((struct Tab *)obj, 1);
+ break;
}
}
@@ -6364,12 +5953,10 @@ static void
xeventexpose(XEvent *e)
{
XExposeEvent *ev;
- struct Winres res;
ev = &e->xexpose;
if (ev->count == 0) {
- res = getwin(ev->window);
- decorate(&res);
+ decorate(ev->window);
}
}
@@ -6378,15 +5965,33 @@ static void
xeventfocusin(XEvent *e)
{
XFocusChangeEvent *ev;
- struct Winres res;
+ struct Object *obj;
ev = &e->xfocus;
- res = getwin(ev->window);
if (wm.focused == NULL) {
tabfocus(NULL, 0);
- } else if (wm.focused != res.c) {
- tabfocus(wm.focused->selcol->selrow->seltab, 1);
+ return;
}
+ obj = getmanaged(ev->window);
+ if (obj == NULL)
+ goto focus;
+ switch (obj->type) {
+ case TYPE_MENU:
+ if (((struct Menu *)obj)->tab != wm.focused->selcol->selrow->seltab)
+ goto focus;
+ break;
+ case TYPE_DIALOG:
+ if (((struct Dialog *)obj)->tab != wm.focused->selcol->selrow->seltab)
+ goto focus;
+ break;
+ case TYPE_NORMAL:
+ if ((struct Tab *)obj != wm.focused->selcol->selrow->seltab)
+ goto focus;
+ break;
+ }
+ return;
+focus:
+ tabfocus(wm.focused->selcol->selrow->seltab, 1);
}
/* manage window */
@@ -6409,26 +6014,32 @@ static void
xeventpropertynotify(XEvent *e)
{
XPropertyEvent *ev;
- struct Winres res;
+ struct Object *obj;
+ struct Tab *tab;
+ struct Menu *menu;
ev = &e->xproperty;
if (ev->state == PropertyDelete)
return;
- res = getwin(ev->window);
- if (res.t != NULL && ev->window == res.t->win) {
+ obj = getmanaged(ev->window);
+ if (obj == NULL)
+ return;
+ if (obj->type == TYPE_NORMAL && ev->window == obj->win) {
+ tab = (struct Tab *)obj;
if (ev->atom == XA_WM_NAME || ev->atom == atoms[_NET_WM_NAME]) {
- winupdatetitle(res.t->win, &res.t->name);
- tabdecorate(res.t, 0);
+ winupdatetitle(tab->obj.win, &tab->name);
+ tabdecorate(tab, 0);
} else if (ev->atom == XA_WM_HINTS) {
- tabupdateurgency(res.t, winisurgent(res.t->win));
- } else if (res.bar != NULL && (ev->atom == _NET_WM_STRUT_PARTIAL || ev->atom == _NET_WM_STRUT)) {
- barstrut(res.bar);
- monupdatearea();
+ tabupdateurgency(tab, winisurgent(tab->obj.win));
}
- } else if (res.menu != NULL && ev->window == res.menu->win) {
+ } else if (obj->type == TYPE_DOCK && (ev->atom == _NET_WM_STRUT_PARTIAL || ev->atom == _NET_WM_STRUT)) {
+ barstrut((struct Bar *)obj);
+ monupdatearea();
+ } else if (obj->type == TYPE_MENU && ev->window == obj->win) {
+ menu = (struct Menu *)obj;
if (ev->atom == XA_WM_NAME || ev->atom == atoms[_NET_WM_NAME]) {
- winupdatetitle(res.menu->win, &res.menu->name);
- menudecorate(res.menu, 0);
+ winupdatetitle(menu->obj.win, &menu->name);
+ menudecorate(menu, 0);
}
}
}
@@ -6438,52 +6049,15 @@ static void
xeventunmapnotify(XEvent *e)
{
XUnmapEvent *ev;
- struct Winres res;
+ struct Object *obj;
ev = &e->xunmap;
- res = getwin(ev->window);
- if (res.bar != NULL && ev->window == res.bar->win) {
- bardel(res.bar);
- return;
- } else if (res.splash != NULL) {
- splashdel(res.splash);
- return;
- } else if (res.n && ev->window == res.n->win) {
- notifdel(res.n);
- return;
- } else if (res.dapp && ev->window == res.dapp->win) {
- if (res.dapp->ignoreunmap) {
- res.dapp->ignoreunmap--;
- } else {
- dockappdel(res.dapp);
- }
- return;
- } else if (res.d && ev->window == res.d->win) {
- if (res.d->ignoreunmap) {
- res.d->ignoreunmap--;
- return;
- } else {
- dialogdel(res.d);
- }
- } else if (res.menu && ev->window == res.menu->win) {
- if (res.menu->ignoreunmap) {
- res.menu->ignoreunmap--;
- return;
- } else {
- menudel(res.menu);
- }
- } else if (res.t && ev->window == res.t->win) {
- if (res.t->ignoreunmap) {
- res.t->ignoreunmap--;
- return;
- } else {
- unmanage(res.t);
+ if ((obj = getmanaged(ev->window)) != NULL) {
+ if (obj->win == ev->window && (*unmanagetab[obj->type])(obj, 1)) {
+ ewmhsetclients();
+ ewmhsetclientsstacking();
}
- } else {
- return;
}
- ewmhsetclients();
- ewmhsetclientsstacking();
}
/* run stdin on sh */
@@ -6531,30 +6105,24 @@ cleancursors(void)
static void
cleanwm(void)
{
- while (wm.c != NULL) {
- containerdel(wm.c);
- }
- while (wm.nhead != NULL) {
- notifdel(wm.nhead);
- }
- while (wm.bars != NULL) {
- bardel(wm.bars);
- }
- while (wm.monhead != NULL) {
- mondel(wm.monhead);
- }
-}
+ struct Monitor *mon;
+ struct Object *obj;
+ struct Container *c;
-/* clean dock */
-static void
-cleandock(void)
-{
- while (dock.head != NULL) {
- dockappdel(dock.head);
- }
- if (dock.pix != None) {
+ while ((mon = TAILQ_FIRST(&wm.monq)) != NULL)
+ mondel(mon);
+ while ((c = TAILQ_FIRST(&wm.focusq)) != NULL)
+ containerdel(c);
+ while ((obj = TAILQ_FIRST(&wm.notifq)) != NULL)
+ (void)notifdel(obj, 0);
+ while ((obj = TAILQ_FIRST(&wm.barq)) != NULL)
+ (void)bardel(obj, 0);
+ while ((obj = TAILQ_FIRST(&wm.splashq)) != NULL)
+ (void)splashdel(obj, 0);
+ while ((obj = TAILQ_FIRST(&dock.dappq)) != NULL)
+ (void)dockappdel(obj, 0);
+ if (dock.pix != None)
XFreePixmap(dpy, dock.pix);
- }
XDestroyWindow(dpy, dock.win);
}
@@ -6616,9 +6184,20 @@ main(int argc, char *argv[])
inittheme();
initdock();
+ /* initialize queues */
+ TAILQ_INIT(&wm.monq);
+ TAILQ_INIT(&wm.barq);
+ TAILQ_INIT(&wm.splashq);
+ TAILQ_INIT(&wm.notifq);
+ TAILQ_INIT(&wm.focusq);
+ TAILQ_INIT(&wm.fullq);
+ TAILQ_INIT(&wm.aboveq);
+ TAILQ_INIT(&wm.centerq);
+ TAILQ_INIT(&wm.belowq);
+
/* set up list of monitors */
monupdate();
- wm.selmon = wm.monhead;
+ wm.selmon = TAILQ_FIRST(&wm.monq);
/* initialize ewmh hints */
ewmhinit();
@@ -6644,7 +6223,6 @@ main(int argc, char *argv[])
cleandummywindows();
cleancursors();
cleantheme();
- cleandock();
cleanwm();
/* clear ewmh hints */