From 9471c8095373df357d2a4185ca8de26290faa72c Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Fri, 25 Nov 2011 17:57:17 +0200 Subject: move everything to top level --- dminiwm.c | 1011 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1011 insertions(+) create mode 100644 dminiwm.c (limited to 'dminiwm.c') diff --git a/dminiwm.c b/dminiwm.c new file mode 100644 index 0000000..1c1b0ff --- /dev/null +++ b/dminiwm.c @@ -0,0 +1,1011 @@ +/* dminiwm.c [ 0.1.7 ] +* +* I started this from catwm 31/12/10 +* Bad window error checking and numlock checking used from +* 2wm at http://hg.suckless.org/2wm/ +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TABLENGTH(X) (sizeof(X)/sizeof(*X)) + +typedef union { + const char** com; + const int i; +} Arg; + +// Structs +typedef struct { + unsigned int mod; + KeySym keysym; + void (*function)(const Arg arg); + const Arg arg; +} key; + +typedef struct client client; +struct client{ + // Prev and next client + client *next; + client *prev; + + // The window + Window win; +}; + +typedef struct desktop desktop; +struct desktop{ + int master_size; + int mode; + int growth; + client *head; + client *current; +}; + +typedef struct { + const char *class; + int preferredd; + int followwin; +} Convenience; + +typedef enum { + ATOM_NET_WM_WINDOW_TYPE, + ATOM_NET_WM_WINDOW_TYPE_UTILITY, + ATOM_NET_WM_WINDOW_TYPE_DOCK, + ATOM_NET_WM_WINDOW_TYPE_SPLASH, + ATOM_NET_WM_WINDOW_TYPE_DIALOG, + ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION, + ATOM_COUNT +} AtomType; + +typedef struct { + Atom *atom; + const char *name; +} AtomNode; + +Atom atoms[ATOM_COUNT]; + +static const AtomNode atomList[] = { + { &atoms[ATOM_NET_WM_WINDOW_TYPE], "_NET_WM_WINDOW_TYPE" }, + { &atoms[ATOM_NET_WM_WINDOW_TYPE_UTILITY], "_NET_WM_WINDOW_TYPE_UTILITY" }, + { &atoms[ATOM_NET_WM_WINDOW_TYPE_DOCK], "_NET_WM_WINDOW_TYPE_DOCK" }, + { &atoms[ATOM_NET_WM_WINDOW_TYPE_SPLASH], "_NET_WM_WINDOW_TYPE_SPLASH" }, + { &atoms[ATOM_NET_WM_WINDOW_TYPE_DIALOG], "_NET_WM_WINDOW_TYPE_DIALOG" }, + { &atoms[ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION], "_NET_WM_WINDOW_TYPE_NOTIFICATION"}, +}; + +// Functions +static void add_window(Window w); +static void change_desktop(const Arg arg); +static void client_to_desktop(const Arg arg); +static void configurenotify(XEvent *e); +static void configurerequest(XEvent *e); +static void destroynotify(XEvent *e); +static void enternotify(XEvent *e); +static void logger(const char* e); +static unsigned long getcolor(const char* color); +static void grabkeys(); +static void keypress(XEvent *e); +static void kill_client(); +static void maprequest(XEvent *e); +static void move_down(); +static void move_up(); +static void next_desktop(); +static void next_win(); +static void prev_desktop(); +static void prev_win(); +static void quit(); +static void remove_window(Window w); +static void resize_master(const Arg arg); +static void resize_stack(const Arg arg); +static void save_desktop(int i); +static void select_desktop(int i); +static void send_kill_signal(Window w); +static void setup(); +static void sigchld(int unused); +static void spawn(const Arg arg); +static void start(); +static void swap_master(); +static void tile(); +static void switch_fullscreen(); +static void switch_grid(); +static void switch_horizontal(); +static void switch_vertical(); +static void update_current(); + +// Include configuration file (need struct key) +#include "config.h" + +// Variable +static Display *dis; +static int bool_quit; +static int current_desktop; +static int growth; +static int master_size; +static int mode; +static int sh; +static int sw; +static int screen; +static int xerror(Display *dis, XErrorEvent *ee); +static int (*xerrorxlib)(Display *, XErrorEvent *); +static unsigned int win_focus; +static unsigned int win_unfocus; +unsigned int numlockmask; /* dynamic key lock mask */ +static Window root; +static client *head; +static client *current; + +// Events array +static void (*events[LASTEvent])(XEvent *e) = { + [KeyPress] = keypress, + [MapRequest] = maprequest, + [EnterNotify] = enternotify, + [DestroyNotify] = destroynotify, + [ConfigureNotify] = configurenotify, + [ConfigureRequest] = configurerequest +}; + +// Desktop array +static desktop desktops[DESKTOPS]; + +/* ***************************** Window Management ******************************* */ +void add_window(Window w) { + client *c,*t; + + if(!(c = (client *)calloc(1,sizeof(client)))) { + logger("\033[0;31mError calloc!"); + exit(1); + } + + if(head == NULL) { + c->next = NULL; + c->prev = NULL; + c->win = w; + head = c; + } + else { + if(ATTACH_ASIDE == 0) { + for(t=head;t->next;t=t->next); + + c->next = NULL; + c->prev = t; + c->win = w; + + t->next = c; + } + else { + for(t=head;t->prev;t=t->prev); + + c->prev = NULL; + c->next = t; + c->win = w; + + t->prev = c; + + head = c; + } + } + + current = c; + save_desktop(current_desktop); + // for folow mouse + if(FOLLOW_MOUSE == 0) + XSelectInput(dis, c->win, EnterWindowMask); +} + +void remove_window(Window w) { + client *c; + + // CHANGE THIS UGLY CODE + for(c=head;c;c=c->next) { + + if(c->win == w) { + if(c->prev == NULL && c->next == NULL) { + free(head); + head = NULL; + current = NULL; + save_desktop(current_desktop); + return; + } + + if(c->prev == NULL) { + head = c->next; + c->next->prev = NULL; + current = c->next; + } + else if(c->next == NULL) { + c->prev->next = NULL; + current = c->prev; + } + else { + c->prev->next = c->next; + c->next->prev = c->prev; + current = c->prev; + } + + free(c); + save_desktop(current_desktop); + tile(); + update_current(); + return; + } + } +} + +void kill_client() { + if(current != NULL) { + //send delete signal to window + XEvent ke; + ke.type = ClientMessage; + ke.xclient.window = current->win; + ke.xclient.message_type = XInternAtom(dis, "WM_PROTOCOLS", True); + ke.xclient.format = 32; + ke.xclient.data.l[0] = XInternAtom(dis, "WM_DELETE_WINDOW", True); + ke.xclient.data.l[1] = CurrentTime; + XSendEvent(dis, current->win, False, NoEventMask, &ke); + send_kill_signal(current->win); + remove_window(current->win); + } +} + +void next_win() { + client *c; + + if(current != NULL && head != NULL) { + if(current->next == NULL) + c = head; + else + c = current->next; + + current = c; + if(mode == 1) + tile(); + update_current(); + } +} + +void prev_win() { + client *c; + + if(current != NULL && head != NULL) { + if(current->prev == NULL) + for(c=head;c->next;c=c->next); + else + c = current->prev; + + current = c; + if(mode == 1) + tile(); + update_current(); + } +} + +void move_down() { + Window tmp; + if(current == NULL || current->next == NULL || current->win == head->win || current->prev == NULL) + return; + + tmp = current->win; + current->win = current->next->win; + current->next->win = tmp; + //keep the moved window activated + next_win(); + save_desktop(current_desktop); + tile(); +} + +void move_up() { + Window tmp; + if(current == NULL || current->prev == head || current->win == head->win) { + return; + } + tmp = current->win; + current->win = current->prev->win; + current->prev->win = tmp; + prev_win(); + save_desktop(current_desktop); + tile(); +} + +void swap_master() { + Window tmp; + + if(head->next != NULL && current != NULL && mode != 1) { + if(current == head) { + tmp = head->next->win; + head->next->win = head->win; + head->win = tmp; + } else { + tmp = head->win; + head->win = current->win; + current->win = tmp; + current = head; + } + save_desktop(current_desktop); + tile(); + update_current(); + } +} + +/* **************************** Desktop Management ************************************* */ +void change_desktop(const Arg arg) { + client *c; + + if(arg.i == current_desktop) + return; + + // Save current "properties" + save_desktop(current_desktop); + + // Unmap all window + if(head != NULL) + for(c=head;c;c=c->next) + XUnmapWindow(dis,c->win); + + // Take "properties" from the new desktop + select_desktop(arg.i); + + // Map all windows + if(head != NULL) + for(c=head;c;c=c->next) + XMapWindow(dis,c->win); + + tile(); + update_current(); +} + +void next_desktop() { + int tmp = current_desktop; + if(tmp == TABLENGTH(desktops)-1) + tmp = 0; + else + tmp++; + + Arg a = {.i = tmp}; + change_desktop(a); +} + +void prev_desktop() { + int tmp = current_desktop; + if(tmp == 0) + tmp = TABLENGTH(desktops)-1; + else + tmp--; + + Arg a = {.i = tmp}; + change_desktop(a); +} + +void client_to_desktop(const Arg arg) { + client *tmp = current; + int tmp2 = current_desktop; + + if(arg.i == current_desktop || current == NULL) + return; + + // Add client to desktop + select_desktop(arg.i); + add_window(tmp->win); + save_desktop(arg.i); + + // Remove client from current desktop + select_desktop(tmp2); + XUnmapWindow(dis,tmp->win); + remove_window(tmp->win); + save_desktop(tmp2); + tile(); + update_current(); + if(FOLLOW_WINDOW == 0) + 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; +} + +void select_desktop(int i) { + master_size = desktops[i].master_size; + mode = desktops[i].mode; + growth = desktops[i].growth; + head = desktops[i].head; + current = desktops[i].current; + current_desktop = i; +} + +void tile() { + client *c; + int n = 0; + int x = 0; + int y = 0; + + // For a top panel + if(TOP_PANEL == 0) + y = PANEL_HEIGHT; + + // If only one window + if(head != NULL && head->next == NULL) { + XMoveResizeWindow(dis,head->win,0,y,sw+2*BORDER_WIDTH,sh+2*BORDER_WIDTH); + } + else if(head != NULL) { + switch(mode) { + case 0: /* Vertical */ + // Master window + XMoveResizeWindow(dis,head->win,0,y,master_size - BORDER_WIDTH,sh - BORDER_WIDTH); + + // Stack + for(c=head->next;c;c=c->next) ++n; + if(n == 1) growth = 0; + 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 1: /* Fullscreen */ + for(c=head;c;c=c->next) { + XMoveResizeWindow(dis,c->win,0,y,sw+2*BORDER_WIDTH,sh+2*BORDER_WIDTH); + } + break; + case 2: /* Horizontal */ + // Master window + XMoveResizeWindow(dis,head->win,0,y,sw-BORDER_WIDTH,master_size - BORDER_WIDTH); + + // Stack + for(c=head->next;c;c=c->next) ++n; + if(n == 1) growth = 0; + 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 3: { // 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; + default: + break; + } + } +} + +void update_current() { + client *c; + + for(c=head;c;c=c->next) { + if((head->next == NULL) || (mode == 1)) + XSetWindowBorderWidth(dis,c->win,0); + else + XSetWindowBorderWidth(dis,c->win,BORDER_WIDTH); + + if(current == c) { + // "Enable" current window + XSetWindowBorder(dis,c->win,win_focus); + XSetInputFocus(dis,c->win,RevertToParent,CurrentTime); + XRaiseWindow(dis,c->win); + } + else + XSetWindowBorder(dis,c->win,win_unfocus); + } + XSync(dis, False); +} + +void switch_vertical() { + if(mode != 0) { + mode = 0; + master_size = sw * MASTER_SIZE; + tile(); + update_current(); + } +} + +void switch_fullscreen() { + if(mode != 1) { + mode = 1; + tile(); + update_current(); + } +} + +void switch_horizontal() { + if(mode != 2) { + mode = 2; + master_size = sh * MASTER_SIZE; + tile(); + update_current(); + } +} + +void switch_grid() { + if(mode != 3) { + mode = 3; + master_size = sw * 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(); +} + +/* ********************** Keyboard Management ********************** */ +void grabkeys() { + int i; + KeyCode code; + + XUngrabKey(dis, AnyKey, AnyModifier, root); + // For each shortcuts + for(i=0;ixkey; + + keysym = XKeycodeToKeysym(dis, (KeyCode)ev->keycode, 0); + for(i = 0; i < len; i++) { + if(keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)) { + if(keys[i].function) + keys[i].function(keys[i].arg); + } + } +} + +void configurenotify(XEvent *e) { + // Do nothing for the moment +} + +/* ********************** Signal Management ************************** */ +void configurerequest(XEvent *e) { + // Paste from DWM, thx again \o/ + XConfigureRequestEvent *ev = &e->xconfigurerequest; + XWindowChanges wc; + + wc.x = ev->x; + wc.y = ev->y; + if(ev->width < sw-BORDER_WIDTH) + wc.width = ev->width; + else + wc.width = sw-BORDER_WIDTH; + if(ev->height < sh-BORDER_WIDTH) + wc.height = ev->height; + else + wc.height = sh-BORDER_WIDTH; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(dis, ev->window, ev->value_mask, &wc); + XSync(dis, False); +} + +void maprequest(XEvent *e) { + XMapRequestEvent *ev = &e->xmaprequest; + + // For fullscreen mplayer (and maybe some other program) + client *c; + + for(c=head;c;c=c->next) + if(ev->window == c->win) { + XMapWindow(dis,ev->window); + XMoveResizeWindow(dis,c->win,-BORDER_WIDTH,-BORDER_WIDTH,sw+BORDER_WIDTH,sh+BORDER_WIDTH); + return; + } + + Window trans = None; + if (XGetTransientForHint(dis, ev->window, &trans) && trans != None) { + add_window(ev->window); + XMapWindow(dis, ev->window); + XSetInputFocus(dis,ev->window,RevertToParent,CurrentTime); + XRaiseWindow(dis,ev->window); + return; + } + + unsigned long count, j, extra; + Atom realType; + int realFormat; + unsigned char *temp; + Atom *type; + + if(XGetWindowProperty(dis, ev->window, atoms[ATOM_NET_WM_WINDOW_TYPE], 0, 32, False, XA_ATOM, &realType, &realFormat, &count, &extra, &temp) == Success) { + if(count > 0) { + type = (unsigned long*)temp; + for(j=0; jwindow); + XMapWindow(dis, ev->window); + XSetInputFocus(dis,ev->window,RevertToParent,CurrentTime); + XRaiseWindow(dis,ev->window); + return; + } + } + } + if(temp) + XFree(temp); + } + + XClassHint ch = {0}; + static unsigned int len = sizeof convenience / sizeof convenience[0]; + int i = 0; + int tmp = current_desktop; + if(XGetClassHint(dis, ev->window, &ch)) + for(i=0;iwindow); + if(tmp == convenience[i].preferredd-1) { + XMapWindow(dis, ev->window); + tile(); + update_current(); + } else { + select_desktop(tmp); + } + if(convenience[i].followwin != 0) { + Arg a = {.i = convenience[i].preferredd-1}; + change_desktop(a); + } + if(ch.res_class) + XFree(ch.res_class); + if(ch.res_name) + XFree(ch.res_name); + return; + } + + add_window(ev->window); + XMapWindow(dis,ev->window); + tile(); + update_current(); +} + +void destroynotify(XEvent *e) { + int i = 0; + int j = 0; + int tmp = current_desktop; + client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + + save_desktop(tmp); + for(j=0;jnext) + if(ev->window == c->win) + i++; + + if(i != 0) { + remove_window(ev->window); + select_desktop(tmp); + return; + } + + i = 0; + } + select_desktop(tmp); +} + +void enternotify(XEvent *e) { + client *c; + XCrossingEvent *ev = &e->xcrossing; + + if(FOLLOW_MOUSE == 0) { + 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 send_kill_signal(Window w) { + XEvent ke; + ke.type = ClientMessage; + ke.xclient.window = w; + ke.xclient.message_type = XInternAtom(dis, "WM_PROTOCOLS", True); + ke.xclient.format = 32; + ke.xclient.data.l[0] = XInternAtom(dis, "WM_DELETE_WINDOW", True); + ke.xclient.data.l[1] = CurrentTime; + XSendEvent(dis, w, False, NoEventMask, &ke); +} + +unsigned long getcolor(const char* color) { + XColor c; + Colormap map = DefaultColormap(dis,screen); + + if(!XAllocNamedColor(dis,map,color,&c,&c)) { + logger("\033[0;31mError parsing color!"); + exit(1); + } + return c.pixel; +} + +void quit() { + Window root_return, parent; + Window *children; + int i; + unsigned int nchildren; + XEvent ev; + + /* + * if a client refuses to terminate itself, + * we kill every window remaining the brutal way. + * Since we're stuck in the while(nchildren > 0) { ... } loop + * we can't exit through the main method. + * This all happens if MOD+q is pushed a second time. + */ + if(bool_quit == 1) { + XUngrabKey(dis, AnyKey, AnyModifier, root); + XDestroySubwindows(dis, root); + logger(" \033[0;33mThanks for using!"); + XCloseDisplay(dis); + logger("\033[0;31mforced shutdown"); + } + + bool_quit = 1; + XQueryTree(dis, root, &root_return, &parent, &children, &nchildren); + for(i = 0; i < nchildren; i++) { + send_kill_signal(children[i]); + } + //keep alive until all windows are killed + while(nchildren > 0) { + XQueryTree(dis, root, &root_return, &parent, &children, &nchildren); + XNextEvent(dis,&ev); + if(events[ev.type]) + events[ev.type](&ev); + } + + XUngrabKey(dis,AnyKey,AnyModifier,root); + logger("\033[0;34mYou Quit : Thanks for using!"); +} + +void logger(const char* e) { + fprintf(stdout,"\n\033[0;34m:: dminiwm : %s \033[0;m\n", e); +} + +void setup() { + // Install a signal + sigchld(0); + + // Screen and root window + screen = DefaultScreen(dis); + root = RootWindow(dis,screen); + + // Screen width and height + sw = XDisplayWidth(dis,screen) - BORDER_WIDTH; + sh = (XDisplayHeight(dis,screen) - PANEL_HEIGHT) - BORDER_WIDTH; + + // Colors + win_focus = getcolor(FOCUS); + win_unfocus = getcolor(UNFOCUS); + + // numlock workaround + int j, k; + XModifierKeymap *modmap; + numlockmask = 0; + modmap = XGetModifierMapping(dis); + for (k = 0; k < 8; k++) { + for (j = 0; j < modmap->max_keypermod; j++) { + if(modmap->modifiermap[k * modmap->max_keypermod + j] == XKeysymToKeycode(dis, XK_Num_Lock)) + numlockmask = (1 << k); + } + } + XFreeModifiermap(modmap); + + // Shortcuts + grabkeys(); + + // Default stack + mode = DEFAULT_MODE; + growth = 0; + + // For exiting + bool_quit = 0; + + // List of client + head = NULL; + current = NULL; + + // Master size + if(mode == 2) + master_size = sh*MASTER_SIZE; + else + master_size = sw*MASTER_SIZE; + + // Set up all desktop + int i; + for(i=0;ierror_code == BadWindow + || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) + || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) + || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) + || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) + || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) + || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) + || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) + return 0; + logger("\033[0;31mBad Window Error!"); + return xerrorxlib(dis, ee); /* may call exit */ +} + +void start() { + XEvent ev; + + // Main loop, just dispatch events (thx to dwm ;) + while(!bool_quit && !XNextEvent(dis,&ev)) { + if(events[ev.type]) + events[ev.type](&ev); + } +} + + +int main(int argc, char **argv) { + // Open display + if(!(dis = XOpenDisplay(NULL))) { + logger("\033[0;31mCannot open display!"); + exit(1); + } + + // Setup env + setup(); + + // Start wm + start(); + + // Close display + XCloseDisplay(dis); + + return 0; +} -- cgit v1.3.1