/*
- * Copyright (c) 2011, Andy Spencer <andy753421@gmail.com>
+ * Copyright (c) 2011-2012, Andy Spencer <andy753421@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include "wm.h"
/* Configuration */
-static int BORDER = 2;
-static int NO_CAPTURE = 0;
+static int border = 2;
+static int no_capture = 0;
/* Internal structures */
struct win_sys {
struct {
int left, right, top, bottom;
} strut;
- state_t state;
};
typedef struct {
- Key_t key;
- int sym;
-} keymap_t;
+ event_t ev;
+ int sym;
+} event_map_t;
typedef enum {
- wm_proto, wm_focus, net_strut, natoms
+ WM_PROTO, WM_FOCUS, WM_DELETE,
+ NET_STATE, NET_FULL, NET_STRUT,
+ NATOMS
} atom_t;
typedef enum {
- clr_focus, clr_unfocus, clr_urgent, ncolors
+ CLR_FOCUS, CLR_UNFOCUS, CLR_URGENT, NCOLORS
} color_t;
/* Global data */
static int running;
static void *cache;
-static Atom atoms[natoms];
+static Atom atoms[NATOMS];
static int (*xerrorxlib)(Display *, XErrorEvent *);
-static unsigned long colors[ncolors];
+static unsigned long colors[NCOLORS];
static list_t *screens;
+static list_t *struts;
/* Conversion functions */
-static keymap_t key2sym[] = {
- {key_left , XK_Left },
- {key_right , XK_Right},
- {key_up , XK_Up },
- {key_down , XK_Down },
- {key_home , XK_Home },
- {key_end , XK_End },
- {key_pageup , XK_Prior},
- {key_pagedown, XK_Next },
- {key_f1 , XK_F1 },
- {key_f2 , XK_F2 },
- {key_f3 , XK_F3 },
- {key_f4 , XK_F4 },
- {key_f5 , XK_F5 },
- {key_f6 , XK_F6 },
- {key_f7 , XK_F7 },
- {key_f8 , XK_F8 },
- {key_f9 , XK_F9 },
- {key_f10 , XK_F10 },
- {key_f11 , XK_F11 },
- {key_f12 , XK_F12 },
+static event_map_t ev2sym[] = {
+ {EV_LEFT , XK_Left },
+ {EV_RIGHT , XK_Right},
+ {EV_UP , XK_Up },
+ {EV_DOWN , XK_Down },
+ {EV_HOME , XK_Home },
+ {EV_END , XK_End },
+ {EV_PAGEUP , XK_Prior},
+ {EV_PAGEDOWN, XK_Next },
+ {EV_F1 , XK_F1 },
+ {EV_F2 , XK_F2 },
+ {EV_F3 , XK_F3 },
+ {EV_F4 , XK_F4 },
+ {EV_F5 , XK_F5 },
+ {EV_F6 , XK_F6 },
+ {EV_F7 , XK_F7 },
+ {EV_F8 , XK_F8 },
+ {EV_F9 , XK_F9 },
+ {EV_F10 , XK_F10 },
+ {EV_F11 , XK_F11 },
+ {EV_F12 , XK_F12 },
};
/* - Modifiers */
}
/* - Keycodes */
-static Key_t x2key(KeySym sym)
+static event_t xk2ev(KeySym sym)
{
- keymap_t *km = map_getr(key2sym,sym);
- return km ? km->key : sym;
+ event_map_t *em = map_getr(ev2sym,sym);
+ return em ? em->ev : sym;
}
-static KeySym key2x(Key_t key)
+static KeySym ev2xk(event_t ev)
{
- keymap_t *km = map_get(key2sym,key);
- return km ? km->sym : key;
+ event_map_t *em = map_get(ev2sym,ev);
+ return em ? em->sym : ev;
}
-static Key_t x2btn(int btn)
+static event_t xb2ev(int btn)
{
- return btn + key_mouse0;
+ return btn + EV_MOUSE0;
}
-static int btn2x(Key_t key)
+static int ev2xb(event_t ev)
{
- return key - key_mouse0;
+ return ev - EV_MOUSE0;
}
/* - Pointers */
-static ptr_t x2ptr(XEvent *_ev)
+static ptr_t x2ptr(XEvent *xe)
{
- XKeyEvent *ev = &_ev->xkey;
- return (ptr_t){ev->x, ev->y, ev->x_root, ev->y_root};
+ XKeyEvent *xke = &xe->xkey;
+ return (ptr_t){xke->x, xke->y, xke->x_root, xke->y_root};
}
-static Window getfocus(win_t *root, XEvent *event)
+static Window getfocus(win_t *root, XEvent *xe)
{
int revert;
Window focus = PointerRoot;
- if (event->type == KeyPress || event->type == KeyRelease)
+ if (xe->type == KeyPress || xe->type == KeyRelease)
XGetInputFocus(root->sys->dpy, &focus, &revert);
if (focus == PointerRoot)
- focus = event->xkey.subwindow;
+ focus = xe->xkey.subwindow;
if (focus == None)
- focus = event->xkey.window;
+ focus = xe->xkey.window;
return focus;
}
to->y += scale*(top );
to->w -= scale*(left+right);
to->h -= scale*(top+bottom);
+ to->sys->strut.left += scale*left;
+ to->sys->strut.right += scale*right;
+ to->sys->strut.top += scale*top;
+ to->sys->strut.bottom += scale*bottom;
return 1;
}
unsigned long ret_items, bytes_left;
unsigned char *xdata;
int status = XGetWindowProperty(win->sys->dpy, win->sys->xid,
- atoms[net_strut], 0L, 4L, False, XA_CARDINAL,
+ atoms[NET_STRUT], 0L, 4L, False, XA_CARDINAL,
&ret_type, &ret_size, &ret_items, &bytes_left, &xdata);
if (status != Success || ret_size != 32 || ret_items != 4)
return 0;
win->sys->strut.right = ((int*)xdata)[1];
win->sys->strut.top = ((int*)xdata)[2];
win->sys->strut.bottom = ((int*)xdata)[3];
+ struts = list_insert(struts, win);
for (list_t *cur = screens; cur; cur = cur->next)
strut_copy(cur->data, win, 1);
return strut_copy(root, win, 1);
static int strut_del(win_t *root, win_t *win)
{
+ list_t *lwin = list_find(struts, win);
+ if (lwin)
+ struts = list_remove(struts, lwin, 0);
for (list_t *cur = screens; cur; cur = cur->next)
strut_copy(cur->data, win, -1);
return strut_copy(root, win, -1);
return True;
}
+static int win_msg(win_t *win, atom_t msg)
+{
+ int n, found = 0;
+ Atom *protos;
+ if (!XGetWMProtocols(win->sys->dpy, win->sys->xid, &protos, &n))
+ return 0;
+
+ while (!found && n--)
+ found = protos[n] == atoms[msg];
+ XFree(protos);
+ if (!found)
+ return 0;
+
+ XSendEvent(win->sys->dpy, win->sys->xid, False, NoEventMask, &(XEvent){
+ .type = ClientMessage,
+ .xclient.window = win->sys->xid,
+ .xclient.message_type = atoms[WM_PROTO],
+ .xclient.format = 32,
+ .xclient.data.l[0] = atoms[msg],
+ .xclient.data.l[1] = CurrentTime,
+ });
+ return 1;
+}
+
+#if 0
+static int win_full(win_t *win)
+{
+ Atom ret_type;
+ int ret_size;
+ unsigned long ret_items, bytes_left;
+ unsigned char *xdata;
+ int status = XGetWindowProperty(win->sys->dpy, win->sys->xid,
+ atoms[NET_FULL], 0L, 1L, False, XA_ATOM,
+ &ret_type, &ret_size, &ret_items, &bytes_left, &xdata);
+ printf("is_fullscreen:\n");
+ printf("\t%d\n", status);
+ printf("\t%d\n", ret_size);
+ printf("\t%ld\n", ret_items);
+ printf("\t%p\n", xdata);
+ if (xdata)
+ printf("\t%d\n", xdata[0]);
+ return status == Success && ret_size == 32 && ret_items == 1 &&
+ xdata[0] == atoms[NET_FULL];
+}
+#endif
+
/* Drawing functions */
static unsigned long get_color(Display *dpy, const char *name)
{
}
/* Callbacks */
-static void process_event(int type, XEvent *ev, win_t *root)
+static void process_event(int type, XEvent *xe, win_t *root)
{
Display *dpy = root->sys->dpy;
win_t *win = NULL;
if (type == KeyPress || type == KeyRelease ||
type == ButtonPress || type == ButtonRelease ||
type == MotionNotify) {
- Window xid = getfocus(root, ev);
+ Window xid = getfocus(root, xe);
if (!(win = win_find(dpy,xid,0)))
return;
- ptr = x2ptr(ev);
- mod = x2mod(ev->xkey.state, type==KeyRelease||type==ButtonRelease);
+ //printf("button-press %p\n", win);
+ ptr = x2ptr(xe);
+ mod = x2mod(xe->xkey.state, type==KeyRelease||type==ButtonRelease);
}
/* Split based on event */
if (type == KeyPress) {
- while (XCheckTypedEvent(dpy, KeyPress, ev));
- KeySym sym = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0);
- printf("got key %c %hhx\n", x2key(sym), mod2int(mod));
- wm_handle_key(win, x2key(sym), mod, ptr);
+ while (XCheckTypedEvent(dpy, KeyPress, xe));
+ KeySym sym = XKeycodeToKeysym(dpy, xe->xkey.keycode, 0);
+ printf("got xe %c %hhx\n", xk2ev(sym), mod2int(mod));
+ wm_handle_event(win, xk2ev(sym), mod, ptr);
}
else if (type == KeyRelease) {
//printf("release: %d\n", type);
}
else if (type == ButtonPress) {
- if (wm_handle_key(win, x2btn(ev->xbutton.button), mod, ptr))
- XGrabPointer(dpy, ev->xbutton.root, True, PointerMotionMask|ButtonReleaseMask,
+ if (wm_handle_event(win, xb2ev(xe->xbutton.button), mod, ptr)) {
+ //printf("grab pointer\n");
+ XGrabPointer(dpy, xe->xbutton.root, True, PointerMotionMask|ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
- else {
- printf("resending event\n");
- XSendEvent(win->sys->dpy, ev->xbutton.window, True, NoEventMask, ev);
- XSendEvent(win->sys->dpy, ev->xbutton.window, False, NoEventMask, ev);
- XSendEvent(win->sys->dpy, ev->xbutton.root, True, NoEventMask, ev);
- XSendEvent(win->sys->dpy, ev->xbutton.root, False, NoEventMask, ev);
- XSendEvent(win->sys->dpy, ev->xbutton.subwindow, True, NoEventMask, ev);
- XSendEvent(win->sys->dpy, ev->xbutton.subwindow, False, NoEventMask, ev);
+ } else {
+ //printf("allow events\n");
+ XAllowEvents(win->sys->dpy, ReplayPointer, xe->xbutton.time);
}
}
else if (type == ButtonRelease) {
XUngrabPointer(dpy, CurrentTime);
- wm_handle_key(win, x2btn(ev->xbutton.button), mod, ptr);
+ wm_handle_event(win, xb2ev(xe->xbutton.button), mod, ptr);
}
else if (type == MotionNotify) {
- while (XCheckTypedEvent(dpy, MotionNotify, ev));
+ while (XCheckTypedEvent(dpy, MotionNotify, xe));
wm_handle_ptr(win, ptr);
}
else if (type == EnterNotify || type == LeaveNotify) {
- printf("enter: %d\n", type);
- key_t key = EnterNotify ? key_enter : key_leave;
- if ((win = win_find(dpy,ev->xcrossing.window,0)))
- wm_handle_key(win, key, MOD(), PTR());
+ printf("%s: %d\n", type==EnterNotify?"enter":"leave", type);
+ event_t ev = type == EnterNotify ? EV_ENTER : EV_LEAVE;
+ if ((win = win_find(dpy,xe->xcrossing.window,0)))
+ wm_handle_event(win, ev, MOD(), PTR());
}
else if (type == FocusIn || type == FocusOut) {
//printf("focus: %d\n", type);
- key_t key = FocusIn ? key_focus : key_unfocus;
- if ((win = win_find(dpy,ev->xfocus.window,0)))
- wm_handle_key(win, key, MOD(), PTR());
+ event_t ev = FocusIn ? EV_FOCUS : EV_UNFOCUS;
+ if ((win = win_find(dpy,xe->xfocus.window,0)))
+ wm_handle_event(win, ev, MOD(), PTR());
}
else if (type == ConfigureNotify) {
printf("configure: %d\n", type);
printf("map: %d\n", type);
}
else if (type == UnmapNotify) {
- if ((win = win_find(dpy,ev->xunmap.window,0)) &&
- win->sys->state == st_show) {
+ if ((win = win_find(dpy,xe->xunmap.window,0)) &&
+ win->state != ST_HIDE) {
if (!strut_del(root, win))
wm_remove(win);
else
wm_update();
- win->sys->state = st_hide;
+ win->state = ST_HIDE;
}
}
else if (type == DestroyNotify) {
//printf("destroy: %d\n", type);
- if ((win = win_find(dpy,ev->xdestroywindow.window,0)))
+ if ((win = win_find(dpy,xe->xdestroywindow.window,0)))
win_remove(win);
}
else if (type == ConfigureRequest) {
- XConfigureRequestEvent *cre = &ev->xconfigurerequest;
+ XConfigureRequestEvent *cre = &xe->xconfigurerequest;
printf("configure_req: %d - %x, (0x%lx) %dx%d @ %d,%d\n",
type, (int)cre->window, cre->value_mask,
cre->height, cre->width, cre->x, cre->y);
- XConfigureWindow(dpy, cre->window, cre->value_mask, &(XWindowChanges){
- .x = cre->x,
- .y = cre->y,
- .width = cre->width,
- .height = cre->height,
- });
-
- /* This seems necessary for, but causes flicker
- * there could be a better way to do this */
- if ((win = win_find(dpy,ev->xmaprequest.window,0)))
- sys_move(win, win->x, win->y, win->w, win->h);
+ if ((win = win_find(dpy,xe->xconfigurerequest.window,1))) {
+ XSendEvent(dpy, cre->window, False, StructureNotifyMask, &(XEvent){
+ .xconfigure.type = ConfigureNotify,
+ .xconfigure.display = win->sys->dpy,
+ .xconfigure.event = win->sys->xid,
+ .xconfigure.window = win->sys->xid,
+ .xconfigure.x = win->x,
+ .xconfigure.y = win->y,
+ .xconfigure.width = win->w,
+ .xconfigure.height = win->h,
+ .xconfigure.border_width = border,
+ });
+ XSync(win->sys->dpy, False);
+ }
}
else if (type == MapRequest) {
printf("map_req: %d\n", type);
- if ((win = win_find(dpy,ev->xmaprequest.window,1))) {
+ if ((win = win_find(dpy,xe->xmaprequest.window,1)) &&
+ win->state == ST_HIDE) {
+ XSelectInput(win->sys->dpy, win->sys->xid, PropertyChangeMask);
if (!strut_add(root, win))
wm_insert(win);
else
wm_update();
}
- XMapWindow(dpy,ev->xmaprequest.window);
+ sys_show(win, ST_SHOW);
+ }
+ else if (type == ClientMessage) {
+ XClientMessageEvent *cme = &xe->xclient;
+ printf("msg: %d - %ld %ld,%ld,%ld,%ld,%ld\n",
+ type, cme->message_type,
+ cme->data.l[0], cme->data.l[1], cme->data.l[2],
+ cme->data.l[3], cme->data.l[4]);
+ if ((win = win_find(dpy,cme->window,0)) &&
+ (cme->message_type == atoms[NET_STATE]) &&
+ (cme->data.l[1] == atoms[NET_FULL] ||
+ cme->data.l[2] == atoms[NET_FULL])) {
+ if (cme->data.l[0] == 1 || /* _NET_WM_STATE_ADD */
+ (cme->data.l[0] == 2 && /* _NET_WM_STATE_TOGGLE */
+ win->state != ST_FULL))
+ sys_show(win, ST_FULL);
+ else
+ sys_show(win, ST_SHOW);
+ }
+ }
+ else if (type == PropertyNotify) {
+ printf("prop: %d - %d\n", type, xe->xproperty.state);
}
else {
printf("unknown event: %d\n", type);
(err->request_code == X_GrabKey && err->error_code == BadAccess ) ||
(err->request_code == X_CopyArea && err->error_code == BadDrawable))
return 0;
+ if (err->request_code == X_ChangeWindowAttributes && err->error_code == BadAccess)
+ error("Another window manager is already running");
return xerrorxlib(dpy, err);
}
+static int xnoerror(Display *dpy, XErrorEvent *err)
+{
+ return 0;
+}
+
+
/********************
* System functions *
********************/
void sys_move(win_t *win, int x, int y, int w, int h)
{
//printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h);
- int b = 2*BORDER;
+ int b = 2*border;
win->x = x; win->y = y;
win->w = MAX(w,1+b); win->h = MAX(h,1+b);
w = MAX(w-b,1); h = MAX(h-b,1);
/* Flush events, so moving window doesn't cause re-focus
* There's probably a better way to do this */
- XEvent ev;
+ XEvent xe;
XSync(win->sys->dpy, False);
- while (XCheckMaskEvent(win->sys->dpy, EnterWindowMask|LeaveWindowMask, &ev))
+ while (XCheckMaskEvent(win->sys->dpy, EnterWindowMask|LeaveWindowMask, &xe))
printf("Skipping enter/leave event\n");
}
{
//printf("sys_raise: %p\n", win);
XRaiseWindow(win->sys->dpy, win->sys->xid);
+ for (list_t *cur = struts; cur; cur = cur->next)
+ XRaiseWindow(((win_t*)cur->data)->sys->dpy,
+ ((win_t*)cur->data)->sys->xid);
}
void sys_focus(win_t *win)
{
- //printf("sys_focus: %p\n", win);
+ printf("sys_focus: %p\n", win);
+
+ /* Set actual focus */
+ XSetInputFocus(win->sys->dpy, win->sys->xid,
+ RevertToPointerRoot, CurrentTime);
+ win_msg(win, WM_FOCUS);
/* Set border on focused window */
static win_t *last = NULL;
if (last)
- XSetWindowBorder(last->sys->dpy, last->sys->xid, colors[clr_unfocus]);
- XSetWindowBorder(win->sys->dpy, win->sys->xid, colors[clr_focus]);
- XSetWindowBorderWidth(win->sys->dpy, win->sys->xid, BORDER);
+ XSetWindowBorder(last->sys->dpy, last->sys->xid, colors[CLR_UNFOCUS]);
+ XSync(win->sys->dpy, False);
+ XSetWindowBorder(win->sys->dpy, win->sys->xid, colors[CLR_FOCUS]);
last = win;
-
- /* Set actual focus */
- XSetInputFocus(win->sys->dpy, win->sys->xid,
- RevertToPointerRoot, CurrentTime);
- XSendEvent(win->sys->dpy, win->sys->xid, False, NoEventMask, &(XEvent){
- .type = ClientMessage,
- .xclient.window = win->sys->xid,
- .xclient.message_type = atoms[wm_proto],
- .xclient.format = 32,
- .xclient.data.l[0] = atoms[wm_focus],
- .xclient.data.l[1] = CurrentTime,
- });
}
void sys_show(win_t *win, state_t state)
{
- win->sys->state = state;
switch (state) {
- case st_show:
- printf("sys_show: show\n");
+ case ST_HIDE:
+ printf("sys_show: hide %p\n", win);
+ XUnmapWindow(win->sys->dpy, win->sys->xid);
+ break;
+ case ST_SHOW:
+ printf("sys_show: show %p\n", win);
+ if (win->state == ST_FULL)
+ sys_move(win, win->x, win->y, win->w, win->h);
+ XSetWindowBorderWidth(win->sys->dpy, win->sys->xid, border);
XMapWindow(win->sys->dpy, win->sys->xid);
XSync(win->sys->dpy, False);
- return;
- case st_full:
- printf("sys_show: full\n");
- return;
- case st_shade:
- printf("sys_show: shade\n");
- return;
- case st_icon:
- printf("sys_show: icon\n");
- return;
- case st_hide:
- printf("sys_show: hide\n");
- XUnmapWindow(win->sys->dpy, win->sys->xid);
- return;
+ break;
+ case ST_FULL:
+ printf("sys_show: full %p\n", win);
+ win_t *screen = NULL;
+ for (list_t *cur = screens; cur; cur = cur->next) {
+ screen = cur->data;
+ if (win->x >= screen->x && win->x <= screen->x+screen->w &&
+ win->y >= screen->y && win->y <= screen->y+screen->h)
+ break;
+ }
+ XSetWindowBorderWidth(win->sys->dpy, win->sys->xid, 0);
+ XMapWindow(win->sys->dpy, win->sys->xid);
+ XMoveResizeWindow(win->sys->dpy, win->sys->xid,
+ screen->x - screen->sys->strut.left,
+ screen->y - screen->sys->strut.top,
+ screen->w + screen->sys->strut.left + screen->sys->strut.right,
+ screen->h + screen->sys->strut.top + screen->sys->strut.bottom);
+ XRaiseWindow(win->sys->dpy, win->sys->xid);
+ break;
+ case ST_SHADE:
+ printf("sys_show: shade %p\n", win);
+ XMapWindow(win->sys->dpy, win->sys->xid);
+ break;
+ case ST_ICON:
+ printf("sys_show: icon %p\n", win);
+ break;
+ case ST_CLOSE:
+ printf("sys_show: close %p\n", win);
+ if (!win_msg(win, WM_DELETE)) {
+ XGrabServer(win->sys->dpy);
+ XSetErrorHandler(xnoerror);
+ XSetCloseDownMode(win->sys->dpy, DestroyAll);
+ XKillClient(win->sys->dpy, win->sys->xid);
+ XSync(win->sys->dpy, False);
+ XSetErrorHandler(xerror);
+ XUngrabServer(win->sys->dpy);
+ }
+ XDestroyWindow(win->sys->dpy, win->sys->xid);
+ break;
}
+ win->state = state;
}
-void sys_watch(win_t *win, Key_t key, mod_t mod)
+void sys_watch(win_t *win, event_t ev, mod_t mod)
{
- //printf("sys_watch: %p - %x %hhx\n", win, key, mod);
+ //printf("sys_watch: %p - %x %hhx\n", win, ev, mod);
XWindowAttributes attr;
XGetWindowAttributes(win->sys->dpy, win->sys->xid, &attr);
long mask = attr.your_event_mask;
- if (key_mouse0 <= key && key <= key_mouse7)
- XGrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->xid, False,
+ if (EV_MOUSE0 <= ev && ev <= EV_MOUSE7)
+ XGrabButton(win->sys->dpy, ev2xb(ev), mod2x(mod), win->sys->xid, False,
mod.up ? ButtonReleaseMask : ButtonPressMask,
- GrabModeAsync, GrabModeAsync, None, None);
- else if (key == key_enter)
+ GrabModeSync, GrabModeAsync, None, None);
+ else if (ev == EV_ENTER)
XSelectInput(win->sys->dpy, win->sys->xid, EnterWindowMask|mask);
- else if (key == key_leave)
+ else if (ev == EV_LEAVE)
XSelectInput(win->sys->dpy, win->sys->xid, LeaveWindowMask|mask);
- else if (key == key_focus || key == key_unfocus)
+ else if (ev == EV_FOCUS || ev == EV_UNFOCUS)
XSelectInput(win->sys->dpy, win->sys->xid, FocusChangeMask|mask);
else
- XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, key2x(key)),
+ XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, ev2xk(ev)),
mod2x(mod), win->sys->xid, True, GrabModeAsync, GrabModeAsync);
}
-void sys_unwatch(win_t *win, Key_t key, mod_t mod)
+void sys_unwatch(win_t *win, event_t ev, mod_t mod)
{
- if (key_mouse0 <= key && key <= key_mouse7)
- XUngrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->xid);
+ if (EV_MOUSE0 <= ev && ev <= EV_MOUSE7)
+ XUngrabButton(win->sys->dpy, ev2xb(ev), mod2x(mod), win->sys->xid);
}
list_t *sys_info(win_t *win)
screen->y = info[i].y_org;
screen->w = info[i].width;
screen->h = info[i].height;
+ screen->sys = new0(win_sys_t);
screens = list_append(screens, screen);
}
}
Window xid;
/* Load configuration */
- BORDER = conf_get_int("main.border", BORDER);
- NO_CAPTURE = conf_get_int("main.no-capture", NO_CAPTURE);
+ border = conf_get_int("main.border", border);
+ no_capture = conf_get_int("main.no-capture", no_capture);
/* Open the display */
if (!(dpy = XOpenDisplay(NULL)))
error("Unable to get root window");
/* Setup X11 data */
- atoms[wm_proto] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- atoms[wm_focus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
- atoms[net_strut] = XInternAtom(dpy, "_NET_WM_STRUT", False);
-
- colors[clr_focus] = get_color(dpy, "#a0a0ff");
- colors[clr_unfocus] = get_color(dpy, "#101066");
- colors[clr_urgent] = get_color(dpy, "#ff0000");
- printf("colors = #%06lx #%06lx #%06lx\n", colors[0], colors[1], colors[2]);
+ atoms[WM_PROTO] = XInternAtom(dpy, "WM_PROTOCOLS", False);
+ atoms[WM_FOCUS] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
+ atoms[WM_DELETE] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ atoms[NET_STATE] = XInternAtom(dpy, "_NET_WM_STATE", False);
+ atoms[NET_FULL] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
+ atoms[NET_STRUT] = XInternAtom(dpy, "_NET_WM_STRUT", False);
+
+ colors[CLR_FOCUS] = get_color(dpy, "#a0a0ff");
+ colors[CLR_UNFOCUS] = get_color(dpy, "#101066");
+ colors[CLR_URGENT] = get_color(dpy, "#ff0000");
+ //printf("colors = #%06lx #%06lx #%06lx\n", colors[0], colors[1], colors[2]);
/* Select window management events */
XSelectInput(dpy, xid, SubstructureRedirectMask|SubstructureNotifyMask);
void sys_run(win_t *root)
{
/* Add each initial window */
- if (!NO_CAPTURE) {
+ if (!no_capture) {
unsigned int nkids;
Window par, xid, *kids = NULL;
if (XQueryTree(root->sys->dpy, root->sys->xid,
running = 1;
while (running)
{
- XEvent ev;
- XNextEvent(root->sys->dpy, &ev);
- process_event(ev.type, &ev, root);
+ XEvent xe;
+ XNextEvent(root->sys->dpy, &xe);
+ process_event(xe.type, &xe, root);
}
}
void sys_free(win_t *root)
{
XCloseDisplay(root->sys->dpy);
- while (screens)
- screens = list_remove(screens, screens, 1);
+ while (screens) {
+ win_free(screens->data);
+ screens = list_remove(screens, screens, 0);
+ }
tdestroy(cache, (void(*)(void*))win_free);
}