From 88f62c8e4c1e86bab9bb18f780b28c66ebc45fcc Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Fri, 16 Dec 2011 11:28:31 +0200 Subject: sort functions alphabetically --- monsterwm.c | 737 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 362 insertions(+), 375 deletions(-) (limited to 'monsterwm.c') diff --git a/monsterwm.c b/monsterwm.c index 07ca69b..1161fe6 100644 --- a/monsterwm.c +++ b/monsterwm.c @@ -30,15 +30,8 @@ #define LENGTH(x) (sizeof(x)/sizeof(*x)) -enum { WM_PROTOCOLS, WM_DELETE_WINDOW, ATOM_COUNT }; - -/* layout modes */ -enum { - TILE, - MONOCLE, - BSTACK, - GRID, -}; +enum { WM_PROTOCOLS, WM_DELETE_WINDOW, WM_COUNT }; +enum { TILE, MONOCLE, BSTACK, GRID, }; /* structs */ typedef union { @@ -78,39 +71,39 @@ typedef struct { static void add_window(Window w); static void buttonpressed(XEvent *e); static void change_desktop(const Arg *arg); +static void cleanup(void); static void client_to_desktop(const Arg *arg); +static void deletewindow(Window w); static void destroynotify(XEvent *e); -static void enternotify(XEvent *e); static void die(const char* errstr, ...); -static int xerrorstart(); +static void enternotify(XEvent *e); static unsigned long getcolor(const char* color); static void grabkeys(void); static void keypress(XEvent *e); static void killclient(); +static void last_desktop(); static void maprequest(XEvent *e); static void move_down(); static void move_up(); -static void rotate_desktop(const Arg *arg); static void next_win(); static void prev_win(); -static void cleanup(void); static void quit(const Arg *arg); static void removeclient(client *c); static void resize_master(const Arg *arg); static void resize_stack(const Arg *arg); +static void rotate_desktop(const Arg *arg); +static void run(void); static void save_desktop(int i); static void select_desktop(int i); -static void togglepanel(); -static void deletewindow(Window w); static void setup(void); static void sigchld(); static void spawn(const Arg *arg); -static void run(void); static void swap_master(); -static void last_desktop(); static void switch_mode(const Arg *arg); static void tile(void); +static void togglepanel(); static void update_current(void); +static int xerrorstart(); #include "config.h" @@ -133,9 +126,9 @@ static unsigned int win_unfocus; static unsigned int numlockmask = 0; /* dynamic key lock mask */ static Display *dis; static Window root; -static client *head = NULL; +static client *head = NULL; static client *current = NULL; -static Atom atoms[ATOM_COUNT]; +static Atom atoms[WM_COUNT]; static desktop desktops[DESKTOPS]; /* events array */ @@ -147,7 +140,6 @@ static void (*events[LASTEvent])(XEvent *e) = { [DestroyNotify] = destroynotify, }; -/* -------- Window Management -------- */ void add_window(Window w) { client *c, *t; @@ -176,91 +168,19 @@ void add_window(Window w) { if(FOLLOW_MOUSE) XSelectInput(dis, c->win, EnterWindowMask); } -void removeclient(client *c) { - if(!c->prev) { /* w is head */ - if(!c->next) { /* head is only window on screen */ - free(head); - head = NULL; - } else { /* more windows on screen */ - head->next->prev = NULL; - head = head->next; - } - current = head; - } else { /* w is on stack */ - if(!c->next) { /* w is last window on screen */ - c->prev->next = NULL; - } else { /* w is somewhere in the middle */ - c->next->prev = c->prev; - c->prev->next = c->next; - } - current = c->prev; - } - - save_desktop(current_desktop); - tile(); - if(mode == MONOCLE && current) - XMapWindow(dis, current->win); - update_current(); -} - -void killclient() { - if(!current) return; - deletewindow(current->win); - removeclient(current); -} - -void next_win() { - if(!current || (!current->next && !current->prev)) return; - if(mode == MONOCLE) XUnmapWindow(dis, current->win); - current = (current->next) ? current->next : head; - if(mode == MONOCLE) XMapWindow(dis, current->win); - update_current(); -} - -void prev_win() { - if(!current || (!current->next && !current->prev)) return; - if(mode == MONOCLE) XUnmapWindow(dis, current->win); - if(current->prev) current = current->prev; - else while(current->next) current=current->next; - if(mode == MONOCLE) XMapWindow(dis, current->win); - update_current(); -} - -void move_down() { - if(!current || current == head || !current->next) return; - Window tmpwin = current->win; - current->win = current->next->win; - current->next->win = tmpwin; - current = current->next; - save_desktop(current_desktop); - tile(); - update_current(); -} - -void move_up() { - if(!current || current == head || !current->prev) return; - Window tmpwin = current->win; - current->win = current->prev->win; - current->prev->win = tmpwin; - current = current->prev; - save_desktop(current_desktop); - tile(); - update_current(); -} +void buttonpressed(XEvent *e) { + client *c; + XButtonPressedEvent *ev = &e->xbutton; -void swap_master() { - if(!current || !head->next || mode == MONOCLE) return; - Window tmpwin = head->win; - current = (current == head) ? head->next : current; - head->win = current->win; - current->win = tmpwin; - current = head; - save_desktop(current_desktop); - tile(); - update_current(); + if(CLICK_TO_FOCUS && ev->window != current->win && ev->button == Button1) + for(c=head; c; c=c->next) + if(ev->window == c->win) { + current = c; + update_current(); + return; + } } -/* -------- Desktop Management -------- */ void change_desktop(const Arg *arg) { if(arg->i == current_desktop) return; previous_desktop = current_desktop; @@ -279,12 +199,21 @@ void change_desktop(const Arg *arg) { update_current(); } -void last_desktop() { - change_desktop(&(Arg){.i = previous_desktop}); -} +void cleanup(void) { + Window root_return; + Window parent_return; + Window *children; + unsigned int nchildren; -void rotate_desktop(const Arg *arg) { - change_desktop(&(Arg){.i = (current_desktop + DESKTOPS + arg->i) % DESKTOPS}); + XUngrabKey(dis, AnyKey, AnyModifier, root); + + XQueryTree(dis, root, &root_return, &parent_return, &children, &nchildren); + for(unsigned int i = 0; i < nchildren; i++) + deletewindow(children[i]); + if(children) XFree(children); + + XSync(dis, False); + XSetInputFocus(dis, PointerRoot, RevertToPointerRoot, CurrentTime); } void client_to_desktop(const Arg *arg) { @@ -308,189 +237,63 @@ void client_to_desktop(const Arg *arg) { if(FOLLOW_WINDOW) change_desktop(arg); } -void save_desktop(int i) { - desktops[i].master_size = master_size; - desktops[i].mode = mode; - desktops[i].growth = growth; - desktops[i].head = head; - desktops[i].current = current; - desktops[i].showpanel = showpanel; +void deletewindow(Window w) { + XEvent ev; + ev.type = ClientMessage; + ev.xclient.window = w; + ev.xclient.message_type = atoms[WM_PROTOCOLS]; + ev.xclient.format = 32; + ev.xclient.data.l[0] = atoms[WM_DELETE_WINDOW]; + ev.xclient.data.l[1] = CurrentTime; + XSendEvent(dis, w, False, NoEventMask, &ev); } -void select_desktop(int i) { - if(current_desktop == i) return; - master_size = desktops[i].master_size; - mode = desktops[i].mode; - growth = desktops[i].growth; - head = desktops[i].head; - current = desktops[i].current; - showpanel = desktops[i].showpanel; - current_desktop = i; -} +void destroynotify(XEvent *e) { + client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + int cd = current_desktop; + Bool found = False; -void togglepanel() { - showpanel = !showpanel; - save_desktop(current_desktop); - tile(); + save_desktop(cd); + for(int d=0; dnext) + if((found = ev->window == c->win)) + removeclient(c); + select_desktop(cd); } -void tile(void) { - if(!head) return; /* no need to arange anything */ +void die(const char *errstr, ...) { + va_list ap; + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} +void enternotify(XEvent *e) { client *c; - int n = 0; - int x = 0; - int panel_height = (showpanel) ? PANEL_HEIGHT : 0; - int y = (TOP_PANEL) ? panel_height : 0; - sh = XDisplayHeight(dis, screen) - panel_height - BORDER_WIDTH; + XCrossingEvent *ev = &e->xcrossing; - if(!head->next) - XMoveResizeWindow(dis, head->win, 0, y, sw + 2*BORDER_WIDTH, sh + 2*BORDER_WIDTH); - else switch(mode) { - case TILE: - /* master window */ - XMoveResizeWindow(dis, head->win, 0, y, master_size - BORDER_WIDTH, sh - BORDER_WIDTH); - /* stack */ - for(n=0, c=head->next; c; c=c->next, ++n); /* count windows */ - growth = (n == 1) ? 0 : growth; /* if only one window don't care about growth */ - XMoveResizeWindow(dis, head->next->win, master_size + BORDER_WIDTH, y, sw - master_size - 2*BORDER_WIDTH, sh/n + growth - BORDER_WIDTH); - y += sh/n + growth; - for(c=head->next->next; c; c=c->next) { - XMoveResizeWindow(dis, c->win, master_size + BORDER_WIDTH, y, sw - master_size - 2*BORDER_WIDTH, sh/n - growth/(n-1) - BORDER_WIDTH); - y += sh/n - growth / (n-1); - } - break; - case MONOCLE: - for(c=head; c; c=c->next) - XMoveResizeWindow(dis, c->win, 0, y, sw + 2*BORDER_WIDTH, sh + 2*BORDER_WIDTH); - break; - case BSTACK: - /* master window */ - XMoveResizeWindow(dis, head->win, 0, y, sw - BORDER_WIDTH, master_size - BORDER_WIDTH); - /* stack */ - for(n=0, c=head->next; c; c=c->next, ++n); /* count windows */ - growth = (n == 1) ? 0 : growth; /* if only one window don't care about growth */ - XMoveResizeWindow(dis, head->next->win, 0, y + master_size + BORDER_WIDTH, sw/n + growth - BORDER_WIDTH, sh - master_size - 2*BORDER_WIDTH); - x = sw/n + growth; - for(c=head->next->next; c; c=c->next) { - XMoveResizeWindow(dis, c->win, x, y + master_size + BORDER_WIDTH, sw/n - growth/(n-1) - BORDER_WIDTH, sh-master_size - 2*BORDER_WIDTH); - x += sw/n - growth/(n-1); + if(FOLLOW_MOUSE) { + if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; + for(c=head; c; c=c->next) + if(ev->window == c->win) { + current = c; + update_current(); + return; } - break; - case GRID: - { - int xpos = 0; - int wdt = 0; - int ht = 0; + } +} - for(c=head; c; c=c->next) ++x; +unsigned long getcolor(const char* color) { + Colormap map = DefaultColormap(dis, screen); + XColor c; - for(c=head; c; c=c->next) { - ++n; - if(x >= 7) { - wdt = sw/3 - BORDER_WIDTH; - ht = sh/3 - BORDER_WIDTH; - if(n == 1 || n == 4 || n == 7) - xpos = 0; - if(n == 2 || n == 5 || n == 8) - xpos = sw/3 + BORDER_WIDTH; - if(n == 3 || n == 6 || n == 9) - xpos = 2*(sw/3) + BORDER_WIDTH; - if(n == 4 || n == 7) - y += sh/3 + BORDER_WIDTH; - if(n == x && n == 7) - wdt = sw - BORDER_WIDTH; - if(n == x && n == 8) - wdt = 2*(sw/3) - BORDER_WIDTH; - } else - if(x >= 5) { - wdt = sw/3 - BORDER_WIDTH; - ht = sh/2 - BORDER_WIDTH; - if(n == 1 || n == 4) - xpos = 0; - if(n == 2 || n == 5) - xpos = sw/3 + BORDER_WIDTH; - if(n == 3 || n == 6) - xpos = 2*(sw/3) + BORDER_WIDTH; - if(n == 4) - y += sh/2; // + BORDER_WIDTH; - if(n == x && n == 5) - wdt = 2*(sw/3) - BORDER_WIDTH; - } else { - if(x > 2) { - if(n == 1 || n == 2) - ht = sh/2 + growth - BORDER_WIDTH; - if(n >= 3) - ht = sh/2 - growth - 2*BORDER_WIDTH; - } - else - ht = sh - BORDER_WIDTH; - if(n == 1 || n == 3) { - xpos = 0; - wdt = master_size - BORDER_WIDTH; - } - if(n == 2 || n == 4) { - xpos = master_size+BORDER_WIDTH; - wdt = sw - master_size - 2*BORDER_WIDTH; - } - if(n == 3) - y += sh/2 + growth + BORDER_WIDTH; - if(n == x && n == 3) - wdt = sw - BORDER_WIDTH; - } - XMoveResizeWindow(dis, c->win, xpos, y, wdt, ht); - } - } - break; - } - free(c); -} - -void update_current(void) { - client *c; - - for(c=head; c; c=c->next) { - if(!head->next || mode == MONOCLE) - XSetWindowBorderWidth(dis, c->win, 0); - else - XSetWindowBorderWidth(dis, c->win, BORDER_WIDTH); - - if(current == c) { /* highlight current window */ - XSetWindowBorder(dis, c->win, win_focus); - XSetInputFocus(dis, c->win, RevertToParent, CurrentTime); - XRaiseWindow(dis, c->win); - if(CLICK_TO_FOCUS) XUngrabButton(dis, AnyButton, AnyModifier, c->win); - } else { - XSetWindowBorder(dis, c->win, win_unfocus); - if(CLICK_TO_FOCUS) XGrabButton(dis, AnyButton, AnyModifier, c->win, True, - ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); - } - } - free(c); - XSync(dis, False); -} - -void switch_mode(const Arg *arg) { - if(mode == arg->i) return; - if(mode == MONOCLE) for(client *c=head; c; c=c->next) XMapWindow(dis, c->win); - mode = arg->i; - if(mode == TILE || mode == GRID) master_size = sw * MASTER_SIZE; - else if(mode == BSTACK) master_size = sh * MASTER_SIZE; - tile(); - update_current(); -} - -void resize_master(const Arg *arg) { - master_size += arg->i; - tile(); -} - -void resize_stack(const Arg *arg) { - growth += arg->i; - tile(); + if(!XAllocNamedColor(dis, map, color, &c, &c)) + die("error: cannot allocate color '%s'\n", c); + return c.pixel; } -/* -------- Keyboard Management -------- */ void grabkeys(void) { KeyCode code; @@ -516,7 +319,16 @@ void keypress(XEvent *e) { keys[i].function(&keys[i].arg); } -/* -------- Signal Management -------- */ +void killclient() { + if(!current) return; + deletewindow(current->win); + removeclient(current); +} + +void last_desktop() { + change_desktop(&(Arg){.i = previous_desktop}); +} + void maprequest(XEvent *e) { XMapRequestEvent *ev = &e->xmaprequest; static XWindowAttributes wa; @@ -560,90 +372,116 @@ void maprequest(XEvent *e) { update_current(); } -void destroynotify(XEvent *e) { - client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - int cd = current_desktop; - Bool found = False; - - save_desktop(cd); - for(int d=0; dnext) - if((found = ev->window == c->win)) { - removeclient(c); - break; - } - select_desktop(cd); +void move_down() { + if(!current || current == head || !current->next) return; + Window tmpwin = current->win; + current->win = current->next->win; + current->next->win = tmpwin; + current = current->next; + save_desktop(current_desktop); + tile(); + update_current(); } -void enternotify(XEvent *e) { - client *c; - XCrossingEvent *ev = &e->xcrossing; - - if(FOLLOW_MOUSE) { - if((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) return; - for(c=head; c; c=c->next) - if(ev->window == c->win) { - current = c; - update_current(); - return; - } - } +void move_up() { + if(!current || current == head || !current->prev) return; + Window tmpwin = current->win; + current->win = current->prev->win; + current->prev->win = tmpwin; + current = current->prev; + save_desktop(current_desktop); + tile(); + update_current(); } -void buttonpressed(XEvent *e) { - client *c; - XButtonPressedEvent *ev = &e->xbutton; +void next_win() { + if(!current || (!current->next && !current->prev)) return; + if(mode == MONOCLE) XUnmapWindow(dis, current->win); + current = (current->next) ? current->next : head; + if(mode == MONOCLE) XMapWindow(dis, current->win); + update_current(); +} - if(CLICK_TO_FOCUS && ev->window != current->win && ev->button == Button1) - for(c=head; c; c=c->next) - if(ev->window == c->win) { - current = c; - update_current(); - return; - } +void prev_win() { + if(!current || (!current->next && !current->prev)) return; + if(mode == MONOCLE) XUnmapWindow(dis, current->win); + if(current->prev) current = current->prev; + else while(current->next) current=current->next; + if(mode == MONOCLE) XMapWindow(dis, current->win); + update_current(); } -void deletewindow(Window w) { - XEvent ev; - ev.type = ClientMessage; - ev.xclient.window = w; - ev.xclient.message_type = atoms[WM_PROTOCOLS]; - ev.xclient.format = 32; - ev.xclient.data.l[0] = atoms[WM_DELETE_WINDOW]; - ev.xclient.data.l[1] = CurrentTime; - XSendEvent(dis, w, False, NoEventMask, &ev); +void quit(const Arg *arg) { + retval = arg->i; + running = False; } -unsigned long getcolor(const char* color) { - Colormap map = DefaultColormap(dis, screen); - XColor c; +void removeclient(client *c) { + if(!c->prev) { /* w is head */ + if(!c->next) { /* head is only window on screen */ + free(head); + head = NULL; + } else { /* more windows on screen */ + head->next->prev = NULL; + head = head->next; + } + current = head; + } else { /* w is on stack */ + if(!c->next) { /* w is last window on screen */ + c->prev->next = NULL; + } else { /* w is somewhere in the middle */ + c->next->prev = c->prev; + c->prev->next = c->next; + } + current = c->prev; + } - if(!XAllocNamedColor(dis, map, color, &c, &c)) - die("error: cannot allocate color '%s'\n", c); - return c.pixel; + save_desktop(current_desktop); + tile(); + if(mode == MONOCLE && current) + XMapWindow(dis, current->win); + update_current(); } -void quit(const Arg *arg) { - retval = arg->i; - running = False; +void resize_master(const Arg *arg) { + master_size += arg->i; + tile(); } -void cleanup(void) { - Window root_return; - Window parent_return; - Window *children; - unsigned int nchildren; +void resize_stack(const Arg *arg) { + growth += arg->i; + tile(); +} - XUngrabKey(dis, AnyKey, AnyModifier, root); +void rotate_desktop(const Arg *arg) { + change_desktop(&(Arg){.i = (current_desktop + DESKTOPS + arg->i) % DESKTOPS}); +} - XQueryTree(dis, root, &root_return, &parent_return, &children, &nchildren); - for(unsigned int i = 0; i < nchildren; i++) - deletewindow(children[i]); - if(children) XFree(children); +void run(void) { + XEvent ev; + while(running && !XNextEvent(dis, &ev)) + if(events[ev.type]) + events[ev.type](&ev); +} - XSync(dis, False); - XSetInputFocus(dis, PointerRoot, RevertToPointerRoot, CurrentTime); +void save_desktop(int i) { + desktops[i].master_size = master_size; + desktops[i].mode = mode; + desktops[i].growth = growth; + desktops[i].head = head; + desktops[i].current = current; + desktops[i].showpanel = showpanel; +} + +void select_desktop(int i) { + if(current_desktop == i) return; + master_size = desktops[i].master_size; + mode = desktops[i].mode; + growth = desktops[i].growth; + head = desktops[i].head; + current = desktops[i].current; + showpanel = desktops[i].showpanel; + current_desktop = i; } void setup(void) { @@ -683,25 +521,6 @@ void setup(void) { grabkeys(); } -int xerrorstart() { - die("error: another window manager is already running\n"); - return -1; -} - -/* There's no way to check accesses to destroyed windows, thus those cases are - * ignored (especially on UnmapNotify's). Other types of errors call Xlibs - * default error handler, which may call exit. */ -int xerror(Display *dis, XErrorEvent *ee) { - if(ee->error_code == BadWindow - || (ee->error_code == BadMatch && (ee->request_code == X_SetInputFocus || ee->request_code == X_ConfigureWindow)) - || (ee->error_code == BadDrawable && (ee->request_code == X_PolyText8 || ee->request_code == X_PolyFillRectangle - || ee->request_code == X_PolySegment || ee->request_code == X_CopyArea)) - || (ee->error_code == BadAccess && ee->request_code == X_GrabKey)) - return 0; - fprintf(stderr, "error: xerror: request code: %d, error code: %d\n", ee->request_code, ee->error_code); - return xerrorxlib(dis, ee); /* may call exit */ -} - void sigchld() { if(signal(SIGCHLD, sigchld) == SIG_ERR) die("error: can't install SIGCHLD handler\n"); @@ -719,19 +538,187 @@ void spawn(const Arg *arg) { } } -void run(void) { - XEvent ev; - while(running && !XNextEvent(dis, &ev)) - if(events[ev.type]) - events[ev.type](&ev); +void swap_master() { + if(!current || !head->next || mode == MONOCLE) return; + Window tmpwin = head->win; + current = (current == head) ? head->next : current; + head->win = current->win; + current->win = tmpwin; + current = head; + save_desktop(current_desktop); + tile(); + update_current(); } -void die(const char *errstr, ...) { - va_list ap; - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(EXIT_FAILURE); +void switch_mode(const Arg *arg) { + if(mode == arg->i) return; + if(mode == MONOCLE) for(client *c=head; c; c=c->next) XMapWindow(dis, c->win); + mode = arg->i; + if(mode == TILE || mode == GRID) master_size = sw * MASTER_SIZE; + else if(mode == BSTACK) master_size = sh * MASTER_SIZE; + tile(); + update_current(); +} + +void tile(void) { + if(!head) return; /* no need to arange anything */ + + client *c; + int n = 0; + int x = 0; + int panel_height = (showpanel) ? PANEL_HEIGHT : 0; + int y = (TOP_PANEL) ? panel_height : 0; + sh = XDisplayHeight(dis, screen) - panel_height - BORDER_WIDTH; + + if(!head->next) + XMoveResizeWindow(dis, head->win, 0, y, sw + 2*BORDER_WIDTH, sh + 2*BORDER_WIDTH); + else switch(mode) { + case TILE: + /* master window */ + XMoveResizeWindow(dis, head->win, 0, y, master_size - BORDER_WIDTH, sh - BORDER_WIDTH); + /* stack */ + for(n=0, c=head->next; c; c=c->next, ++n); /* count windows */ + growth = (n == 1) ? 0 : growth; /* if only one window don't care about growth */ + XMoveResizeWindow(dis, head->next->win, master_size + BORDER_WIDTH, y, sw - master_size - 2*BORDER_WIDTH, sh/n + growth - BORDER_WIDTH); + y += sh/n + growth; + for(c=head->next->next; c; c=c->next) { + XMoveResizeWindow(dis, c->win, master_size + BORDER_WIDTH, y, sw - master_size - 2*BORDER_WIDTH, sh/n - growth/(n-1) - BORDER_WIDTH); + y += sh/n - growth / (n-1); + } + break; + case MONOCLE: + for(c=head; c; c=c->next) + XMoveResizeWindow(dis, c->win, 0, y, sw + 2*BORDER_WIDTH, sh + 2*BORDER_WIDTH); + break; + case BSTACK: + /* master window */ + XMoveResizeWindow(dis, head->win, 0, y, sw - BORDER_WIDTH, master_size - BORDER_WIDTH); + /* stack */ + for(n=0, c=head->next; c; c=c->next, ++n); /* count windows */ + growth = (n == 1) ? 0 : growth; /* if only one window don't care about growth */ + XMoveResizeWindow(dis, head->next->win, 0, y + master_size + BORDER_WIDTH, sw/n + growth - BORDER_WIDTH, sh - master_size - 2*BORDER_WIDTH); + x = sw/n + growth; + for(c=head->next->next; c; c=c->next) { + XMoveResizeWindow(dis, c->win, x, y + master_size + BORDER_WIDTH, sw/n - growth/(n-1) - BORDER_WIDTH, sh-master_size - 2*BORDER_WIDTH); + x += sw/n - growth/(n-1); + } + break; + case GRID: + { + int xpos = 0; + int wdt = 0; + int ht = 0; + + for(c=head; c; c=c->next) ++x; + + for(c=head; c; c=c->next) { + ++n; + if(x >= 7) { + wdt = sw/3 - BORDER_WIDTH; + ht = sh/3 - BORDER_WIDTH; + if(n == 1 || n == 4 || n == 7) + xpos = 0; + if(n == 2 || n == 5 || n == 8) + xpos = sw/3 + BORDER_WIDTH; + if(n == 3 || n == 6 || n == 9) + xpos = 2*(sw/3) + BORDER_WIDTH; + if(n == 4 || n == 7) + y += sh/3 + BORDER_WIDTH; + if(n == x && n == 7) + wdt = sw - BORDER_WIDTH; + if(n == x && n == 8) + wdt = 2*(sw/3) - BORDER_WIDTH; + } else + if(x >= 5) { + wdt = sw/3 - BORDER_WIDTH; + ht = sh/2 - BORDER_WIDTH; + if(n == 1 || n == 4) + xpos = 0; + if(n == 2 || n == 5) + xpos = sw/3 + BORDER_WIDTH; + if(n == 3 || n == 6) + xpos = 2*(sw/3) + BORDER_WIDTH; + if(n == 4) + y += sh/2; // + BORDER_WIDTH; + if(n == x && n == 5) + wdt = 2*(sw/3) - BORDER_WIDTH; + } else { + if(x > 2) { + if(n == 1 || n == 2) + ht = sh/2 + growth - BORDER_WIDTH; + if(n >= 3) + ht = sh/2 - growth - 2*BORDER_WIDTH; + } + else + ht = sh - BORDER_WIDTH; + if(n == 1 || n == 3) { + xpos = 0; + wdt = master_size - BORDER_WIDTH; + } + if(n == 2 || n == 4) { + xpos = master_size+BORDER_WIDTH; + wdt = sw - master_size - 2*BORDER_WIDTH; + } + if(n == 3) + y += sh/2 + growth + BORDER_WIDTH; + if(n == x && n == 3) + wdt = sw - BORDER_WIDTH; + } + XMoveResizeWindow(dis, c->win, xpos, y, wdt, ht); + } + } + break; + } + free(c); +} + +void togglepanel() { + showpanel = !showpanel; + save_desktop(current_desktop); + tile(); +} + +void update_current(void) { + client *c; + + for(c=head; c; c=c->next) { + if(!head->next || mode == MONOCLE) + XSetWindowBorderWidth(dis, c->win, 0); + else + XSetWindowBorderWidth(dis, c->win, BORDER_WIDTH); + + if(current == c) { /* highlight current window */ + XSetWindowBorder(dis, c->win, win_focus); + XSetInputFocus(dis, c->win, RevertToParent, CurrentTime); + XRaiseWindow(dis, c->win); + if(CLICK_TO_FOCUS) XUngrabButton(dis, AnyButton, AnyModifier, c->win); + } else { + XSetWindowBorder(dis, c->win, win_unfocus); + if(CLICK_TO_FOCUS) XGrabButton(dis, AnyButton, AnyModifier, c->win, True, + ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); + } + } + free(c); + XSync(dis, False); +} + +/* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ +int xerror(Display *dis, XErrorEvent *ee) { + if(ee->error_code == BadWindow + || (ee->error_code == BadMatch && (ee->request_code == X_SetInputFocus || ee->request_code == X_ConfigureWindow)) + || (ee->error_code == BadDrawable && (ee->request_code == X_PolyText8 || ee->request_code == X_PolyFillRectangle + || ee->request_code == X_PolySegment || ee->request_code == X_CopyArea)) + || (ee->error_code == BadAccess && ee->request_code == X_GrabKey)) + return 0; + fprintf(stderr, "error: xerror: request code: %d, error code: %d\n", ee->request_code, ee->error_code); + return xerrorxlib(dis, ee); /* may call exit */ +} + +int xerrorstart() { + die("error: another window manager is already running\n"); + return -1; } int main(int argc, char *argv[]) { -- cgit v1.3.1