From 2eef9bac7e89bab05f32ff81d253cdebd9fe6225 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Mon, 11 Aug 2008 03:13:44 +0200 Subject: [PATCH] [wmfs.c, local.h] Add sethints function and configure request event --- config.c | 17 ++++---- local.h | 33 ++++++++------- wmfs.c | 122 ++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 119 insertions(+), 53 deletions(-) diff --git a/config.c b/config.c index 5139f29..a7157a5 100644 --- a/config.c +++ b/config.c @@ -129,7 +129,6 @@ init_conf(void) { char final_path[100]; int ret, i, j, l; - sprintf(final_path,"%s/%s",strdup(getenv("HOME")),strdup(FILE_NAME)); cfg = cfg_init(opts, CFGF_NONE); @@ -158,13 +157,13 @@ init_conf(void) { conf.ttbarheight = cfg_getint(cfg_misc, "titlebar_height"); /* colors */ - conf.bordernormal = cfg_getint(cfg_colors, "border_normal"); - conf.borderfocus = cfg_getint(cfg_colors, "border_focus"); - conf.barcolor = cfg_getint(cfg_colors, "bar"); - conf.buttoncolor = cfg_getint(cfg_colors, "button"); - conf.textcolor = cfg_getint(cfg_colors, "text"); - conf.tagselfg = cfg_getint(cfg_colors, "tag_sel_fg"); - conf.tagselbg = cfg_getint(cfg_colors, "tag_sel_bg"); + conf.colors.bordernormal = cfg_getint(cfg_colors, "border_normal"); + conf.colors.borderfocus = cfg_getint(cfg_colors, "border_focus"); + conf.colors.bar = cfg_getint(cfg_colors, "bar"); + conf.colors.button = cfg_getint(cfg_colors, "button"); + conf.colors.text = cfg_getint(cfg_colors, "text"); + conf.colors.tagselfg = cfg_getint(cfg_colors, "tag_sel_fg"); + conf.colors.tagselbg = cfg_getint(cfg_colors, "tag_sel_bg"); /* layout */ for(i=0; i < 3; ++i) @@ -176,7 +175,7 @@ init_conf(void) { conf.taglist[i] = strdup(cfg_getnstr(cfg_tag,"tag",i)); /* keybind ('tention ça rigole plus) */ - + conf.nkeybind = cfg_size(cfg_keys, "key"); for(j = 0; j < cfg_size(cfg_keys, "key"); ++j) { cfgtmp = cfg_getnsec(cfg_keys, "key", j); diff --git a/local.h b/local.h index bdc9f4f..796f4a2 100644 --- a/local.h +++ b/local.h @@ -34,9 +34,6 @@ #define LEN(x) (sizeof x / sizeof x[0]) #define Move 0 #define Resize 1 -#define Free 0 -#define Tile 1 -#define Max 2 #define MAXTAG 36 typedef struct Client Client; @@ -45,11 +42,14 @@ struct Client { int tag; /* tag num */ int x, y, w, h; /* window attribute */ int ox, oy, ow, oh; /* old window attribute */ + int basew, baseh; + int incw, inch; + int maxw, maxh, minw, minh; int border; /* border height */ Window win; /* window */ Window tbar; /* Titlebar? */ Window button; /* Close Button */ - Bool max; /* client info */ + Bool max, tile; /* client info */ int layout; Client *next; /* next client */ Client *prev; /* previous client */ @@ -63,10 +63,8 @@ typedef struct { } Key; typedef struct { - char *name; void *func; - } func_name_list_t; typedef struct { @@ -76,24 +74,28 @@ typedef struct { bool raiseswitch; int borderheight; int ttbarheight; - /* color */ - int bordernormal; - int borderfocus; - int barcolor; - int buttoncolor; - int textcolor; - int tagselfg; - int tagselbg; + struct { + int bordernormal; + int borderfocus; + int bar; + int button; + int text; + int tagselfg; + int tagselbg; + } colors; /* layout */ char *symlayout[3]; /* tag */ int ntag; char *taglist[MAXTAG]; + /* keybind */ + int nkeybind; } Conf; enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; enum { WMState, WMProtocols, WMName, WMDelete, WMLast }; enum { NetSupported, NetWMName, NetLast }; +enum { Free, Tile, Max }; /* wmfs.c */ void attach(Client *c); @@ -124,6 +126,7 @@ void moveresize(Client *c, int x, int y, int w, int h); void raiseclient(Client *c); void scan(void); void setborder(Window win, int color); +void setsizehints(Client *c); void spawn(char *cmd); void tag(char *cmd); void tagn(int tag); @@ -142,7 +145,6 @@ void wswitch(char *cmd); #define BUTH (conf.ttbarheight - 6) GC gc; -Key keys[1024]; XEvent event; Display *dpy; XFontStruct* font; @@ -151,6 +153,7 @@ int screen; Window root; Window bar; fd_set fd; +Key keys[256]; Atom wm_atom[WMLast]; Atom net_atom[NetLast]; Cursor cursor[CurLast]; diff --git a/wmfs.c b/wmfs.c index 2750330..e1be374 100644 --- a/wmfs.c +++ b/wmfs.c @@ -83,8 +83,8 @@ void focus(Client *c) { if(sel && sel != c) { grabbuttons(sel, False); - setborder(sel->win, conf.bordernormal); - setborder(sel->tbar, conf.bordernormal); + setborder(sel->win, conf.colors.bordernormal); + setborder(sel->tbar, conf.colors.bordernormal); } if(c) grabbuttons(c, True); @@ -92,8 +92,8 @@ focus(Client *c) { sel = c; if(c) { - setborder(c->win, conf.borderfocus); - setborder(sel->tbar, conf.borderfocus); + setborder(c->win, conf.colors.borderfocus); + setborder(sel->tbar, conf.colors.borderfocus); if(conf.raisefocus) raiseclient(c); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); @@ -133,6 +133,7 @@ void getevent(void) { XEvent event; XWindowAttributes at; + XWindowChanges wc; Client *c; int i; struct timeval tv; @@ -182,9 +183,22 @@ getevent(void) { c->title = NULL; updatetitle(c); } + if(event.xproperty.atom == XA_WM_NORMAL_HINTS) + setsizehints(c); } } break; + case ConfigureRequest: + wc.x = event.xconfigurerequest.x; + wc.y = event.xconfigurerequest.y; + wc.width = event.xconfigurerequest.width; + wc.height = event.xconfigurerequest.height; + wc.border_width = event.xconfigurerequest.border_width; + wc.sibling = event.xconfigurerequest.above; + wc.stack_mode = event.xconfigurerequest.detail; + XConfigureWindow(dpy, event.xconfigurerequest.window, + event.xconfigurerequest.value_mask, &wc); + break; case UnmapNotify: if((c = getclient(event.xunmap.window))) { @@ -281,7 +295,7 @@ grabkeys(void) { unsigned int i; KeyCode code; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LEN(keys); i++) { + for(i = 0; i < conf.nkeybind; i++) { code = XKeysymToKeycode(dpy, keys[i].keysym); XGrabKey(dpy, code, keys[i].mod, root, True, GrabModeAsync, GrabModeAsync); XGrabKey(dpy, code, keys[i].mod|numlockmask, root, True, GrabModeAsync, GrabModeAsync); @@ -300,9 +314,6 @@ hide(Client *c) { } } - - - void init(void) { XSetWindowAttributes at; @@ -367,7 +378,7 @@ init(void) { bar = XCreateWindow(dpy, root, 0, 0, mw, barheight, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &at); - XSetWindowBackground(dpy, bar, conf.barcolor); + XSetWindowBackground(dpy, bar, conf.colors.bar); XMapWindow(dpy, bar); /* INIT STUFF */ @@ -413,7 +424,7 @@ keypress(XEvent *e) { XKeyEvent *ev; ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for(i = 0; i < LEN(keys); i++) + for(i = 0; i < conf.nkeybind; i++) if(keysym == keys[i].keysym && (keys[i].mod & ~(numlockmask | LockMask)) == (ev->state & ~(numlockmask | LockMask)) @@ -474,6 +485,7 @@ manage(Window w, XWindowAttributes *wa) { Client *c, *t = NULL; Window trans; Status rettrans; + XWindowChanges winc; c = emallocz(sizeof(Client)); c->win = w; @@ -485,7 +497,9 @@ manage(Window w, XWindowAttributes *wa) { c->tag = seltag; c->layout = Free; - setborder(w, conf.bordernormal); + setborder(w, conf.colors.bordernormal); + + XConfigureWindow(dpy, w, CWBorderWidth, &winc); XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); @@ -498,8 +512,8 @@ manage(Window w, XWindowAttributes *wa) { c->w, conf.ttbarheight, conf.borderheight, - conf.bordernormal, - conf.barcolor); + conf.colors.bordernormal, + conf.colors.bar); XSelectInput(dpy, c->tbar, ExposureMask | EnterWindowMask); c->button = XCreateSimpleWindow(dpy,root, @@ -508,16 +522,18 @@ manage(Window w, XWindowAttributes *wa) { 5, BUTH, 1, - conf.buttoncolor, - conf.buttoncolor); + conf.colors.button, + conf.colors.button); XSelectInput(dpy, c->button, ExposureMask | EnterWindowMask); - + // confrequest(c); grabbuttons(c, False); + setsizehints(c); attach(c); XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + moveresize(c, c->x, c->y, c->w, c->h); mapclient(c); updatetitle(c); - setborder(c->tbar, conf.bordernormal); + setborder(c->tbar, conf.colors.bordernormal); focus(c); return; } @@ -570,8 +586,23 @@ mouseaction(Client *c, int x, int y, int type) { void moveresize(Client *c, int x, int y, int w, int h) { if(c) { - if(w <= 0 || h <= 0) - return; + /* Resize hints {{{ */ + + if (w < 1) w = 1; + if (h < 1) h = 1; + w -= c->basew; + h -= c->baseh; + if(c->incw) w -= w % c->incw; + if(c->inch) h -= h % c->inch; + w += c->basew; + h += c->baseh; + if(c->minw > 0 && w < c->minw) w = c->minw; + if(c->minh > 0 && h < c->minh) h = c->minh; + if(c->maxw > 0 && w > c->maxw) w = c->maxw; + if(c->maxh > 0 && h > c->maxh) h = c->maxh; + if(w <= 0 || h <= 0) return; + + /* }}} */ c->layout = Free; c->max = False; if(c->x != x || c->y != y || c->w != w || c->h != h) { @@ -632,6 +663,37 @@ setborder(Window win, int color) { return; } +void +setsizehints(Client *c) { + long msize; + XSizeHints size; + + if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) + size.flags = PSize; + if(size.flags & PBaseSize) { + c->basew = size.base_width; c->baseh = size.base_height; + } + else if(size.flags & PMinSize) { + c->basew = size.min_width; c->baseh = size.min_height; + } + else c->basew = c->baseh = 0; + if(size.flags & PResizeInc) { + c->incw = size.width_inc; c->inch = size.height_inc; + } + else c->incw = c->inch = 0; + if(size.flags & PMaxSize) { + c->maxw = size.max_width; c->maxh = size.max_height; + } + else c->maxw = c->maxh = 0; + if(size.flags & PMinSize) { + c->minw = size.min_width; c->minh = size.min_height; + } + else if(size.flags & PBaseSize) { + c->minw = size.base_width; c->minh = size.base_height; + } + else c->minw = c->minh = 0; +} + void spawn(char *cmd) { if(strlen(cmd) > 0 && !fork()) { @@ -730,15 +792,17 @@ tile(char *cmd) { for(i=0, c = clients; c; c = c->next, ++i) { if(c != sel && !ishide(c)) { moveresize(c, x, y, w, h); - if(i < i + 1) + if(i < i + 1) { y = c->y + c->h + bord + conf.ttbarheight; - c->layout = Tile; + c->layout = Tile; + } } + return; } } - return; } + void togglemax(char *cmd) { if(sel && !ishide(sel)) { @@ -811,7 +875,7 @@ updatebar(void) { lt = time(NULL); XClearWindow(dpy, bar); - XSetForeground(dpy, gc, conf.textcolor); + XSetForeground(dpy, gc, conf.colors.text); for(i=0;i< conf.ntag;++i) { /* Make the tag string */ @@ -821,23 +885,23 @@ updatebar(void) { sprintf(buf[i], "%s() ", conf.taglist[i]); taglen[i+1] = taglen[i] + 6*(strlen(conf.taglist[i]) + ((clientpertag(i+1) >= 10) ? 5 : 4)); /* Rectangle for the tag background */ - if(i+1 == seltag) XSetForeground(dpy, gc, conf.tagselbg); + if(i+1 == seltag) XSetForeground(dpy, gc, conf.colors.tagselbg); else XSetForeground(dpy, gc, 0x090909); XFillRectangle(dpy, bar, gc, taglen[i]-4, 0, strlen(buf[i])*6, barheight); /* Draw tag */ - if(i+1 == seltag) XSetForeground(dpy, gc, conf.tagselfg); - else XSetForeground(dpy, gc, conf.textcolor); + if(i+1 == seltag) XSetForeground(dpy, gc, conf.colors.tagselfg); + else XSetForeground(dpy, gc, conf.colors.text); XDrawString(dpy, bar, gc, taglen[i], fonth-1, buf[i], strlen(buf[i])); } /* Draw layout symbol */ - XSetForeground(dpy, gc, conf.tagselfg); + XSetForeground(dpy, gc, conf.colors.tagselfg); XDrawString(dpy, bar, gc, taglen[conf.ntag], fonth-1, (sel) ? conf.symlayout[sel->layout] : conf.symlayout[Free], (sel) ? strlen(conf.symlayout[sel->layout]) :strlen(conf.symlayout[Free]) ); - XSetForeground(dpy, gc, conf.textcolor); + XSetForeground(dpy, gc, conf.colors.text); XDrawLine(dpy, bar, gc, mw-slen*6-5, 0 , mw-slen*6-5 , barheight); return; } @@ -858,7 +922,7 @@ updatetitle(Client *c) { if(!c->title) c->title = strdup("WMFS"); XClearWindow(dpy, c->tbar); - XSetForeground(dpy, gc, conf.textcolor); + XSetForeground(dpy, gc, conf.colors.text); XDrawString(dpy, c->tbar, gc, 5, 10, c->title, strlen(c->title)); return; }