From 2dc8df110c738f4bcbe300a5ec1dec1f555765e7 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 22 Aug 2011 16:18:05 +0000 Subject: [PATCH 01/13] revert r1.11 of parse.y and create logic in conf_setup instead to deal with the various scenarios of when to attempt a parse of the config, load defaults, and when to warn and/or exit. triggered by bogus warning first noticed by sobrado@. ok oga@ --- conf.c | 22 ++++++++++++++-------- parse.y | 2 -- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/conf.c b/conf.c index ecdc578..8473033 100644 --- a/conf.c +++ b/conf.c @@ -265,26 +265,32 @@ conf_clear(struct conf *c) void conf_setup(struct conf *c, const char *conf_file) { + char *home; struct stat sb; + int parse = 0; + + conf_init(c); if (conf_file == NULL) { - char *home = getenv("HOME"); - - if (home == NULL) + if ((home = getenv("HOME")) == NULL) errx(1, "No HOME directory."); (void)snprintf(c->conf_path, sizeof(c->conf_path), "%s/%s", home, CONFFILE); - } else + + if (stat(c->conf_path, &sb) == 0 && (sb.st_mode & S_IFREG)) + parse = 1; + } else { if (stat(conf_file, &sb) == -1 || !(sb.st_mode & S_IFREG)) errx(1, "%s: %s", conf_file, strerror(errno)); - else + else { (void)strlcpy(c->conf_path, conf_file, sizeof(c->conf_path)); + parse = 1; + } + } - conf_init(c); - - if (parse_config(c->conf_path, c) == -1) + if (parse && (parse_config(c->conf_path, c) == -1)) warnx("config file %s has errors, not loading", c->conf_path); } diff --git a/parse.y b/parse.y index a31a6c2..1b55f08 100644 --- a/parse.y +++ b/parse.y @@ -462,8 +462,6 @@ pushfile(const char *name) nfile->name = xstrdup(name); if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { - if (errno != ENOENT) - warn("%s", nfile->name); free(nfile->name); free(nfile); return (NULL); From be3b8a0748f7470ed4a6e8bc51fe7622c93c6707 Mon Sep 17 00:00:00 2001 From: oga Date: Mon, 22 Aug 2011 16:34:34 +0000 Subject: [PATCH 02/13] A while ago I wrote some code to not warp to ignored windows on map (rev 1.52), not realising that the previous (less efficient) fix had already been commited (rev 1.50). Had this in my tree for ages to remove the previous code. Effectively reverts rev 1.50. ok okan@ --- xevents.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/xevents.c b/xevents.c index 438b700..34dd051 100644 --- a/xevents.c +++ b/xevents.c @@ -76,7 +76,6 @@ xev_handle_maprequest(XEvent *ee) XMapRequestEvent *e = &ee->xmaprequest; struct client_ctx *cc = NULL, *old_cc; XWindowAttributes xattr; - struct winmatch *wm; if ((old_cc = client_current()) != NULL) client_ptrsave(old_cc); @@ -86,10 +85,6 @@ xev_handle_maprequest(XEvent *ee) cc = client_new(e->window, screen_fromroot(xattr.root), 1); } - TAILQ_FOREACH(wm, &Conf.ignoreq, entry) { - if (strncasecmp(wm->title, cc->name, strlen(wm->title)) == 0) - return; - } if ((cc->flags & CLIENT_IGNORE) == 0) client_ptrwarp(cc); } From 0dcf7efb8eef706b36af4197514671e524482b43 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 29 Aug 2011 09:09:45 +0000 Subject: [PATCH 03/13] restore mouse move via the keyboard, noticed by todd@. while the check for cc was wrong due to the fact that cc->sc is always filled in during the event, we don't even need it - just operate on the focused screen's root window regardless. ok todd@ oga@ --- kbfunc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/kbfunc.c b/kbfunc.c index 69b8d5e..fbb603d 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -129,13 +129,8 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) client_ptrwarp(cc); break; case CWM_PTRMOVE: - if (cc) { - xu_ptr_getpos(cc->win, &x, &y); - xu_ptr_setpos(cc->win, x + mx, y + my); - } else { - xu_ptr_getpos(sc->rootwin, &x, &y); - xu_ptr_setpos(sc->rootwin, x + mx, y + my); - } + xu_ptr_getpos(sc->rootwin, &x, &y); + xu_ptr_setpos(sc->rootwin, x + mx, y + my); break; default: warnx("invalid flags passed to kbfunc_client_moveresize"); From a4683b55f8cdac9c0884f44896ed972864b81f78 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 29 Aug 2011 09:10:49 +0000 Subject: [PATCH 04/13] zap unused macro. ok oga@ --- conf.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/conf.c b/conf.c index 8473033..f8b306c 100644 --- a/conf.c +++ b/conf.c @@ -31,13 +31,6 @@ #include "calmwm.h" -#ifndef timespeccmp -#define timespeccmp(tsp, usp, cmp) \ - (((tsp)->tv_sec == (usp)->tv_sec) ? \ - ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ - ((tsp)->tv_sec cmp (usp)->tv_sec)) -#endif - static void conf_mouseunbind(struct conf *, struct mousebinding *); static void conf_unbind(struct conf *, struct keybinding *); From b51f8e6a990c3462464b3830e51b54605e2ade6a Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 3 Sep 2011 09:17:16 +0000 Subject: [PATCH 05/13] "defaultfont" is unclear (and confusing while reading code) when it also applies to the user supplied font, so rename. ok oga@ --- calmwm.h | 4 ++-- conf.c | 6 +++--- parse.y | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/calmwm.h b/calmwm.h index fb77499..631aaff 100644 --- a/calmwm.h +++ b/calmwm.h @@ -285,8 +285,8 @@ struct conf { struct color color[CWM_COLOR_MAX]; char termpath[MAXPATHLEN]; char lockpath[MAXPATHLEN]; -#define DEFAULTFONTNAME "sans-serif:pixelsize=14:bold" - char *DefaultFontName; +#define CONF_FONT "sans-serif:pixelsize=14:bold" + char *font; }; /* MWM hints */ diff --git a/conf.c b/conf.c index f8b306c..9f19ae2 100644 --- a/conf.c +++ b/conf.c @@ -62,7 +62,7 @@ conf_gap(struct conf *c, struct screen_ctx *sc) void conf_font(struct conf *c, struct screen_ctx *sc) { - sc->font = font_make(sc, c->DefaultFontName); + sc->font = font_make(sc, c->font); } void @@ -208,7 +208,7 @@ conf_init(struct conf *c) c->color[CWM_COLOR_BG_MENU].name = xstrdup(CONF_COLOR_MENUBG); - c->DefaultFontName = xstrdup(DEFAULTFONTNAME); + c->font = xstrdup(CONF_FONT); } void @@ -252,7 +252,7 @@ conf_clear(struct conf *c) for (i = 0; i < CWM_COLOR_MAX; i++) xfree(c->color[i].name); - xfree(c->DefaultFontName); + xfree(c->font); } void diff --git a/parse.y b/parse.y index 1b55f08..1b291ca 100644 --- a/parse.y +++ b/parse.y @@ -105,8 +105,8 @@ yesno : YES { $$ = 1; } ; main : FONTNAME STRING { - free(conf->DefaultFontName); - conf->DefaultFontName = $2; + free(conf->font); + conf->font = $2; } | STICKY yesno { if ($2 == 0) @@ -561,7 +561,7 @@ parse_config(const char *filename, struct conf *xconf) for (i = 0; i < CWM_COLOR_MAX; i++) xconf->color[i].name = conf->color[i].name; - xconf->DefaultFontName = conf->DefaultFontName; + xconf->font = conf->font; } free(conf); From 142a36a0c0448ef9c9f7eb36068d45dce09839a9 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 3 Sep 2011 09:20:58 +0000 Subject: [PATCH 06/13] Add {r,}cycleingroup to cycle through clients belonging to the same group as the active client (as opposed to all unhidden clients); from Alexander Polakov, with a tiny tweak requested by oga. ok oga@ --- calmwm.h | 5 +++-- client.c | 9 +++++---- conf.c | 2 ++ cwmrc.5 | 6 +++++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/calmwm.h b/calmwm.h index 631aaff..cbf58a2 100644 --- a/calmwm.h +++ b/calmwm.h @@ -68,8 +68,9 @@ #define CWM_EXEC_WM 0x0002 /* cycle */ -#define CWM_CYCLE 0 -#define CWM_RCYCLE 1 +#define CWM_CYCLE 0x0001 +#define CWM_RCYCLE 0x0002 +#define CWM_INGROUP 0x0004 #define KBTOGROUP(X) ((X) - 1) diff --git a/client.c b/client.c index a55bd42..7a0fbc6 100644 --- a/client.c +++ b/client.c @@ -567,7 +567,7 @@ match: } void -client_cycle(struct screen_ctx *sc, int reverse) +client_cycle(struct screen_ctx *sc, int flags) { struct client_ctx *oldcc, *newcc; int again = 1; @@ -579,18 +579,19 @@ client_cycle(struct screen_ctx *sc, int reverse) return; if (oldcc == NULL) - oldcc = (reverse ? TAILQ_LAST(&sc->mruq, cycle_entry_q) : + oldcc = (flags & CWM_RCYCLE ? TAILQ_LAST(&sc->mruq, cycle_entry_q) : TAILQ_FIRST(&sc->mruq)); newcc = oldcc; while (again) { again = 0; - newcc = (reverse ? client_mruprev(newcc) : + newcc = (flags & CWM_RCYCLE ? client_mruprev(newcc) : client_mrunext(newcc)); /* Only cycle visible and non-ignored windows. */ - if (newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE)) + if ((newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE)) + || ((flags & CWM_INGROUP) && (newcc->group != oldcc->group))) again = 1; /* Is oldcc the only non-hidden window? */ diff --git a/conf.c b/conf.c index 9f19ae2..f44113a 100644 --- a/conf.c +++ b/conf.c @@ -359,6 +359,8 @@ static struct { { "nogroup", kbfunc_client_nogroup, 0, {0} }, { "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} }, { "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} }, + { "cycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_CYCLE|CWM_INGROUP} }, + { "rcycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_RCYCLE|CWM_INGROUP} }, { "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}}, { "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} }, { "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} }, diff --git a/cwmrc.5 b/cwmrc.5 index c7dbf7f..86aa0d8 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 24 2011 $ +.Dd $Mdocdate: June 25 2011 $ .Dt CWMRC 5 .Os .Sh NAME @@ -289,6 +289,10 @@ Reverse cycle through groups. Forward cycle through windows. .It rcycle Reverse cycle through windows. +.It cycleingroup +Forward cycle through windows in current group. +.It rcycleingroup +Reverse cycle through windows in current group. .It snapdist Minimum distance to snap-to adjacent edge. .It delete From 325129c6baa2aca0cadbdb965fcdb520fc7d3912 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 3 Sep 2011 09:25:39 +0000 Subject: [PATCH 07/13] simplify color initialization. ok oga@ --- calmwm.h | 8 +------- conf.c | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/calmwm.h b/calmwm.h index cbf58a2..1256437 100644 --- a/calmwm.h +++ b/calmwm.h @@ -90,8 +90,8 @@ enum cwmcolor { }; struct color { - unsigned long pixel; char *name; + unsigned long pixel; }; struct gap { @@ -277,12 +277,6 @@ struct conf { #define CONF_SNAPDIST 0 int snapdist; struct gap gap; -#define CONF_COLOR_ACTIVEBORDER "#CCCCCC" -#define CONF_COLOR_INACTIVEBORDER "#666666" -#define CONF_COLOR_GROUPBORDER "blue" -#define CONF_COLOR_UNGROUPBORDER "red" -#define CONF_COLOR_MENUFG "black" -#define CONF_COLOR_MENUBG "white" struct color color[CWM_COLOR_MAX]; char termpath[MAXPATHLEN]; char lockpath[MAXPATHLEN]; diff --git a/conf.c b/conf.c index f44113a..5c921a4 100644 --- a/conf.c +++ b/conf.c @@ -65,6 +65,15 @@ conf_font(struct conf *c, struct screen_ctx *sc) sc->font = font_make(sc, c->font); } +static struct color color_binds[] = { + { "#CCCCCC", 0 }, /* CWM_COLOR_BORDOR_ACTIVE */ + { "#666666", 0 }, /* CWM_COLOR_BORDOR_INACTIVE */ + { "blue", 0 }, /* CWM_COLOR_BORDOR_GROUP */ + { "red", 0 }, /* CWM_COLOR_BORDOR_UNGROUP */ + { "black", 0 }, /* CWM_COLOR_FG_MENU */ + { "white", 0 }, /* CWM_COLOR_BG_MENU */ +}; + void conf_color(struct conf *c, struct screen_ctx *sc) { @@ -191,23 +200,13 @@ conf_init(struct conf *c) for (i = 0; i < nitems(m_binds); i++) conf_mousebind(c, m_binds[i].key, m_binds[i].func); + for (i = 0; i < nitems(color_binds); i++) + c->color[i].name = xstrdup(color_binds[i].name); + /* Default term/lock */ (void)strlcpy(c->termpath, "xterm", sizeof(c->termpath)); (void)strlcpy(c->lockpath, "xlock", sizeof(c->lockpath)); - c->color[CWM_COLOR_BORDER_ACTIVE].name = - xstrdup(CONF_COLOR_ACTIVEBORDER); - c->color[CWM_COLOR_BORDER_INACTIVE].name = - xstrdup(CONF_COLOR_INACTIVEBORDER); - c->color[CWM_COLOR_BORDER_GROUP].name = - xstrdup(CONF_COLOR_GROUPBORDER); - c->color[CWM_COLOR_BORDER_UNGROUP].name = - xstrdup(CONF_COLOR_UNGROUPBORDER); - c->color[CWM_COLOR_FG_MENU].name = - xstrdup(CONF_COLOR_MENUFG); - c->color[CWM_COLOR_BG_MENU].name = - xstrdup(CONF_COLOR_MENUBG); - c->font = xstrdup(CONF_FONT); } From b852a73a60f96b45ae93ab5c7ea23a68743eaf04 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 3 Sep 2011 09:42:33 +0000 Subject: [PATCH 08/13] split off window hints from geometry so we don't need to carry them all around when dealing with {,h,v}max. same idea from oga. --- calmwm.h | 4 ++- client.c | 74 ++++++++++++++++++++++++++--------------------------- mousefunc.c | 4 +-- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/calmwm.h b/calmwm.h index 1256437..7ffd157 100644 --- a/calmwm.h +++ b/calmwm.h @@ -121,6 +121,8 @@ struct client_ctx { int y; /* y position */ int width; /* width */ int height;/* height */ + } geom, savegeom; + struct { int basew; /* desired width */ int baseh; /* desired height */ int minw; /* minimum width */ @@ -131,7 +133,7 @@ struct client_ctx { int inch; /* height increment progression */ float mina; /* minimum aspect ratio */ float maxa; /* maximum aspect ratio */ - } geom, savegeom; + } hint; struct { int x; /* x position */ int y; /* y position */ diff --git a/client.c b/client.c index 7a0fbc6..a3c4ddb 100644 --- a/client.c +++ b/client.c @@ -725,36 +725,36 @@ client_getsizehints(struct client_ctx *cc) cc->size->flags = PSize; if (cc->size->flags & PBaseSize) { - cc->geom.basew = cc->size->base_width; - cc->geom.baseh = cc->size->base_height; + cc->hint.basew = cc->size->base_width; + cc->hint.baseh = cc->size->base_height; } else if (cc->size->flags & PMinSize) { - cc->geom.basew = cc->size->min_width; - cc->geom.baseh = cc->size->min_height; + cc->hint.basew = cc->size->min_width; + cc->hint.baseh = cc->size->min_height; } if (cc->size->flags & PMinSize) { - cc->geom.minw = cc->size->min_width; - cc->geom.minh = cc->size->min_height; + cc->hint.minw = cc->size->min_width; + cc->hint.minh = cc->size->min_height; } else if (cc->size->flags & PBaseSize) { - cc->geom.minw = cc->size->base_width; - cc->geom.minh = cc->size->base_height; + cc->hint.minw = cc->size->base_width; + cc->hint.minh = cc->size->base_height; } if (cc->size->flags & PMaxSize) { - cc->geom.maxw = cc->size->max_width; - cc->geom.maxh = cc->size->max_height; + cc->hint.maxw = cc->size->max_width; + cc->hint.maxh = cc->size->max_height; } if (cc->size->flags & PResizeInc) { - cc->geom.incw = cc->size->width_inc; - cc->geom.inch = cc->size->height_inc; + cc->hint.incw = cc->size->width_inc; + cc->hint.inch = cc->size->height_inc; } - cc->geom.incw = MAX(1, cc->geom.incw); - cc->geom.inch = MAX(1, cc->geom.inch); + cc->hint.incw = MAX(1, cc->hint.incw); + cc->hint.inch = MAX(1, cc->hint.inch); if (cc->size->flags & PAspect) { if (cc->size->min_aspect.x > 0) - cc->geom.mina = (float)cc->size->min_aspect.y / + cc->hint.mina = (float)cc->size->min_aspect.y / cc->size->min_aspect.x; if (cc->size->max_aspect.y > 0) - cc->geom.maxa = (float)cc->size->max_aspect.x / + cc->hint.maxa = (float)cc->size->max_aspect.x / cc->size->max_aspect.y; } } @@ -763,48 +763,48 @@ client_applysizehints(struct client_ctx *cc) { Bool baseismin; - baseismin = (cc->geom.basew == cc->geom.minw) && - (cc->geom.baseh == cc->geom.minh); + baseismin = (cc->hint.basew == cc->hint.minw) && + (cc->hint.baseh == cc->hint.minh); /* temporarily remove base dimensions, ICCCM 4.1.2.3 */ if (!baseismin) { - cc->geom.width -= cc->geom.basew; - cc->geom.height -= cc->geom.baseh; + cc->geom.width -= cc->hint.basew; + cc->geom.height -= cc->hint.baseh; } /* adjust for aspect limits */ - if (cc->geom.mina > 0 && cc->geom.maxa > 0) { - if (cc->geom.maxa < + if (cc->hint.mina > 0 && cc->hint.maxa > 0) { + if (cc->hint.maxa < (float)cc->geom.width / cc->geom.height) - cc->geom.width = cc->geom.height * cc->geom.maxa; - else if (cc->geom.mina < + cc->geom.width = cc->geom.height * cc->hint.maxa; + else if (cc->hint.mina < (float)cc->geom.height / cc->geom.width) - cc->geom.height = cc->geom.width * cc->geom.mina; + cc->geom.height = cc->geom.width * cc->hint.mina; } /* remove base dimensions for increment */ if (baseismin) { - cc->geom.width -= cc->geom.basew; - cc->geom.height -= cc->geom.baseh; + cc->geom.width -= cc->hint.basew; + cc->geom.height -= cc->hint.baseh; } /* adjust for increment value */ - cc->geom.width -= cc->geom.width % cc->geom.incw; - cc->geom.height -= cc->geom.height % cc->geom.inch; + cc->geom.width -= cc->geom.width % cc->hint.incw; + cc->geom.height -= cc->geom.height % cc->hint.inch; /* restore base dimensions */ - cc->geom.width += cc->geom.basew; - cc->geom.height += cc->geom.baseh; + cc->geom.width += cc->hint.basew; + cc->geom.height += cc->hint.baseh; /* adjust for min width/height */ - cc->geom.width = MAX(cc->geom.width, cc->geom.minw); - cc->geom.height = MAX(cc->geom.height, cc->geom.minh); + cc->geom.width = MAX(cc->geom.width, cc->hint.minw); + cc->geom.height = MAX(cc->geom.height, cc->hint.minh); /* adjust for max width/height */ - if (cc->geom.maxw) - cc->geom.width = MIN(cc->geom.width, cc->geom.maxw); - if (cc->geom.maxh) - cc->geom.height = MIN(cc->geom.height, cc->geom.maxh); + if (cc->hint.maxw) + cc->geom.width = MIN(cc->geom.width, cc->hint.maxw); + if (cc->hint.maxh) + cc->geom.height = MIN(cc->geom.height, cc->hint.maxh); } static void diff --git a/mousefunc.c b/mousefunc.c index 6e697de..ddbcff1 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -58,8 +58,8 @@ mousefunc_sweep_draw(struct client_ctx *cc) int width, width_size, width_name; (void)snprintf(asize, sizeof(asize), "%dx%d", - (cc->geom.width - cc->geom.basew) / cc->geom.incw, - (cc->geom.height - cc->geom.baseh) / cc->geom.inch); + (cc->geom.width - cc->hint.basew) / cc->hint.incw, + (cc->geom.height - cc->hint.baseh) / cc->hint.inch); width_size = font_width(sc, asize, strlen(asize)) + 4; width_name = font_width(sc, cc->name, strlen(cc->name)) + 4; width = MAX(width_size, width_name); From 44d8b1d3ace79e2c648e859f931f76a027f51ff0 Mon Sep 17 00:00:00 2001 From: oga Date: Sun, 4 Sep 2011 16:59:31 +0000 Subject: [PATCH 09/13] Make flavours of maximisation additive. i.e. horiz-max + vertmax = full maximisation. full - horiz = vertmax. etc. Martynas wrote something like this once, so I did okan, this version seems to finally deal with the corner cases. ok okan@. --- calmwm.h | 10 ++-- client.c | 158 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 99 insertions(+), 69 deletions(-) diff --git a/calmwm.h b/calmwm.h index 7ffd157..0d035d9 100644 --- a/calmwm.h +++ b/calmwm.h @@ -143,10 +143,12 @@ struct client_ctx { int xproto; #define CLIENT_HIDDEN 0x0001 #define CLIENT_IGNORE 0x0002 -#define CLIENT_MAXIMIZED 0x0004 -#define CLIENT_VMAXIMIZED 0x0008 -#define CLIENT_HMAXIMIZED 0x0010 -#define CLIENT_FREEZE 0x0020 +#define CLIENT_VMAXIMIZED 0x0004 +#define CLIENT_HMAXIMIZED 0x0008 +#define CLIENT_FREEZE 0x0010 + +#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) +#define CLIENT_MAXIMIZED (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) int flags; int state; int active; diff --git a/client.c b/client.c index a3c4ddb..b46dede 100644 --- a/client.c +++ b/client.c @@ -281,39 +281,46 @@ client_maximize(struct client_ctx *cc) if (cc->flags & CLIENT_FREEZE) return; - if (cc->flags & CLIENT_MAXIMIZED) { + if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED) { + cc->flags &= ~CLIENT_MAXIMIZED; cc->geom = cc->savegeom; cc->bwidth = Conf.bwidth; - cc->flags &= ~CLIENT_MAXIMIZED; - } else { - if (!(cc->flags & (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED))) - cc->savegeom = cc->geom; - if (HasXinerama) { - XineramaScreenInfo *xine; - /* - * pick screen that the middle of the window is on. - * that's probably more fair than if just the origin of - * a window is poking over a boundary - */ - xine = screen_find_xinerama(sc, - cc->geom.x + cc->geom.width / 2, - cc->geom.y + cc->geom.height / 2); - if (xine == NULL) - goto calc; - x_org = xine->x_org; - y_org = xine->y_org; - xmax = xine->width; - ymax = xine->height; - } -calc: - cc->geom.x = x_org + sc->gap.left; - cc->geom.y = y_org + sc->gap.top; - cc->geom.height = ymax - (sc->gap.top + sc->gap.bottom); - cc->geom.width = xmax - (sc->gap.left + sc->gap.right); - cc->bwidth = 0; - cc->flags |= CLIENT_MAXIMIZED; + goto resize; } + if ((cc->flags & CLIENT_VMAXIMIZED) == 0) { + cc->savegeom.height = cc->geom.height; + cc->savegeom.y = cc->geom.y; + } + + if ((cc->flags & CLIENT_HMAXIMIZED) == 0) { + cc->savegeom.width = cc->geom.width; + cc->savegeom.x = cc->geom.x; + } + + if (HasXinerama) { + XineramaScreenInfo *xine; + /* * that's probably more fair than if just the origin of * a window is poking over a boundary + */ + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.width / 2, + cc->geom.y + cc->geom.height / 2); + if (xine == NULL) + goto calc; + x_org = xine->x_org; + y_org = xine->y_org; + xmax = xine->width; + ymax = xine->height; + } +calc: + cc->geom.x = x_org + sc->gap.left; + cc->geom.y = y_org + sc->gap.top; + cc->geom.height = ymax - (sc->gap.top + sc->gap.bottom); + cc->geom.width = xmax - (sc->gap.left + sc->gap.right); + cc->bwidth = 0; + cc->flags |= CLIENT_MAXIMIZED; + +resize: client_resize(cc); } @@ -330,27 +337,38 @@ client_vertmaximize(struct client_ctx *cc) cc->geom.y = cc->savegeom.y; cc->geom.height = cc->savegeom.height; cc->bwidth = Conf.bwidth; + if (cc->flags & CLIENT_HMAXIMIZED) + cc->geom.width -= cc->bwidth * 2; cc->flags &= ~CLIENT_VMAXIMIZED; - } else { - if (!(cc->flags & (CLIENT_MAXIMIZED | CLIENT_HMAXIMIZED))) - cc->savegeom = cc->geom; - if (HasXinerama) { - XineramaScreenInfo *xine; - xine = screen_find_xinerama(sc, - cc->geom.x + cc->geom.width / 2, - cc->geom.y + cc->geom.height / 2); - if (xine == NULL) - goto calc; - y_org = xine->y_org; - ymax = xine->height; - } -calc: - cc->geom.y = y_org + sc->gap.top; - cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top + - sc->gap.bottom); - cc->flags |= CLIENT_VMAXIMIZED; + goto resize; } + cc->savegeom.y = cc->geom.y; + cc->savegeom.height = cc->geom.height; + + /* if this will make us fully maximized then remove boundary */ + if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) { + cc->geom.width += Conf.bwidth * 2; + cc->bwidth = 0; + } + + if (HasXinerama) { + XineramaScreenInfo *xine; + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.width / 2, + cc->geom.y + cc->geom.height / 2); + if (xine == NULL) + goto calc; + y_org = xine->y_org; + ymax = xine->height; + } +calc: + cc->geom.y = y_org + sc->gap.top; + cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top + + sc->gap.bottom); + cc->flags |= CLIENT_VMAXIMIZED; + +resize: client_resize(cc); } @@ -367,27 +385,37 @@ client_horizmaximize(struct client_ctx *cc) cc->geom.x = cc->savegeom.x; cc->geom.width = cc->savegeom.width; cc->bwidth = Conf.bwidth; + if (cc->flags & CLIENT_VMAXIMIZED) + cc->geom.height -= cc->bwidth * 2; cc->flags &= ~CLIENT_HMAXIMIZED; - } else { - if (!(cc->flags & (CLIENT_MAXIMIZED | CLIENT_VMAXIMIZED))) - cc->savegeom = cc->geom; - if (HasXinerama) { - XineramaScreenInfo *xine; - xine = screen_find_xinerama(sc, - cc->geom.x + cc->geom.width / 2, - cc->geom.y + cc->geom.height / 2); - if (xine == NULL) - goto calc; - x_org = xine->x_org; - xmax = xine->width; - } -calc: - cc->geom.x = x_org + sc->gap.left; - cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left + - sc->gap.right); - cc->flags |= CLIENT_HMAXIMIZED; + goto resize; + } + + cc->savegeom.x = cc->geom.x; + cc->savegeom.width = cc->geom.width; + + if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) { + cc->geom.height += cc->bwidth * 2; + cc->bwidth = 0; } + if (HasXinerama) { + XineramaScreenInfo *xine; + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.width / 2, + cc->geom.y + cc->geom.height / 2); + if (xine == NULL) + goto calc; + x_org = xine->x_org; + xmax = xine->width; + } +calc: + cc->geom.x = x_org + sc->gap.left; + cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left + + sc->gap.right); + cc->flags |= CLIENT_HMAXIMIZED; + +resize: client_resize(cc); } From d85b3adc0c77fb932927671cd0a473885a975c3e Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 5 Sep 2011 07:37:55 +0000 Subject: [PATCH 10/13] restore a comment and add another for clarity. --- client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client.c b/client.c index b46dede..e7783a4 100644 --- a/client.c +++ b/client.c @@ -300,7 +300,10 @@ client_maximize(struct client_ctx *cc) if (HasXinerama) { XineramaScreenInfo *xine; - /* * that's probably more fair than if just the origin of * a window is poking over a boundary + /* + * pick screen that the middle of the window is on. + * that's probably more fair than if just the origin of + * a window is poking over a boundary */ xine = screen_find_xinerama(sc, cc->geom.x + cc->geom.width / 2, @@ -394,6 +397,7 @@ client_horizmaximize(struct client_ctx *cc) cc->savegeom.x = cc->geom.x; cc->savegeom.width = cc->geom.width; + /* if this will make us fully maximized then remove boundary */ if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) { cc->geom.height += cc->bwidth * 2; cc->bwidth = 0; From 840323558d6b6e2b32df27232a0ebe66c45d6952 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 8 Sep 2011 12:00:49 +0000 Subject: [PATCH 11/13] reinit menu on reload; from Alexander Polakov. needed for catching upcoming menu config changes. ok oga@ --- conf.c | 1 + menu.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/conf.c b/conf.c index 5c921a4..e2263b0 100644 --- a/conf.c +++ b/conf.c @@ -100,6 +100,7 @@ conf_reload(struct conf *c) conf_gap(c, sc); conf_color(c, sc); conf_font(c, sc); + menu_init(sc); } TAILQ_FOREACH(cc, &Clientq, entry) client_draw_border(cc); diff --git a/menu.c b/menu.c index 072da10..fdeeee4 100644 --- a/menu.c +++ b/menu.c @@ -76,6 +76,8 @@ menu_init(struct screen_ctx *sc) { XGCValues gv; + if (sc->menuwin) + XDestroyWindow(X_Dpy, sc->menuwin); sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, Conf.bwidth, sc->color[CWM_COLOR_FG_MENU].pixel, @@ -86,6 +88,8 @@ menu_init(struct screen_ctx *sc) gv.background = sc->color[CWM_COLOR_BG_MENU].pixel; gv.function = GXxor; + if (sc->gc) + XFreeGC(X_Dpy, sc->gc); sc->gc = XCreateGC(X_Dpy, sc->menuwin, GCForeground|GCBackground|GCFunction, &gv); } From a262f8e80cb02238e7b01fde8faf4085115acd1c Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 8 Sep 2011 12:07:03 +0000 Subject: [PATCH 12/13] allow menufg/menubg to be configurable; from Alexander Polakov. ok oga@ --- cwmrc.5 | 8 +++++++- parse.y | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cwmrc.5 b/cwmrc.5 index 86aa0d8..3f9a09c 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 25 2011 $ +.Dd $Mdocdate: September 3 2011 $ .Dt CWMRC 5 .Os .Sh NAME @@ -105,6 +105,12 @@ Set the color of the border while grouping a window. .It Ic color inactiveborder Ar color Set the color of the inactive border. .Pp +.It Ic color menubg Ar color +Set menu background color. +.Pp +.It Ic color menufg Ar color +Set menu foreground color. +.Pp .It Ic color ungroupborder Ar color Set the color of the border while ungrouping a window. .Pp diff --git a/parse.y b/parse.y index 1b291ca..43c687e 100644 --- a/parse.y +++ b/parse.y @@ -73,6 +73,7 @@ typedef struct { %token COLOR SNAPDIST %token ACTIVEBORDER INACTIVEBORDER %token GROUPBORDER UNGROUPBORDER +%token MENUBG MENUFG %token ERROR %token STRING %token NUMBER @@ -184,6 +185,14 @@ colors : ACTIVEBORDER STRING { free(conf->color[CWM_COLOR_BORDER_UNGROUP].name); conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2; } + | MENUBG STRING { + free(conf->color[CWM_COLOR_BG_MENU].name); + conf->color[CWM_COLOR_BG_MENU].name = $2; + } + | MENUFG STRING { + free(conf->color[CWM_COLOR_FG_MENU].name); + conf->color[CWM_COLOR_FG_MENU].name = $2; + } ; %% @@ -228,6 +237,8 @@ lookup(char *s) { "groupborder", GROUPBORDER}, { "ignore", IGNORE}, { "inactiveborder", INACTIVEBORDER}, + { "menubg", MENUBG}, + { "menufg", MENUFG}, { "mousebind", MOUSEBIND}, { "moveamount", MOVEAMOUNT}, { "no", NO}, From 82d31aec1d380bc53a1ccfdabe81e37d9b7213c2 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 8 Sep 2011 12:35:33 +0000 Subject: [PATCH 13/13] allow configurable menu font color; from Alexander Polakov with a tweak from me. ok oga@ --- calmwm.c | 1 - calmwm.h | 3 ++- conf.c | 2 ++ cwmrc.5 | 5 ++++- font.c | 9 +++++++-- parse.y | 7 ++++++- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/calmwm.c b/calmwm.c index 8bfdff3..611ae37 100644 --- a/calmwm.c +++ b/calmwm.c @@ -169,7 +169,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which) conf_color(&Conf, sc); group_init(sc); - font_init(sc); conf_font(&Conf, sc); TAILQ_INIT(&sc->mruq); diff --git a/calmwm.h b/calmwm.h index 0d035d9..2f1c6c2 100644 --- a/calmwm.h +++ b/calmwm.h @@ -86,6 +86,7 @@ enum cwmcolor { CWM_COLOR_BORDER_UNGROUP, CWM_COLOR_FG_MENU, CWM_COLOR_BG_MENU, + CWM_COLOR_FONT, CWM_COLOR_MAX }; @@ -435,7 +436,7 @@ int font_descent(struct screen_ctx *); void font_draw(struct screen_ctx *, const char *, int, Drawable, int, int); u_int font_height(struct screen_ctx *); -void font_init(struct screen_ctx *); +void font_init(struct screen_ctx *, const char *); int font_width(struct screen_ctx *, const char *, int); XftFont *font_make(struct screen_ctx *, const char *); diff --git a/conf.c b/conf.c index e2263b0..e8cd157 100644 --- a/conf.c +++ b/conf.c @@ -62,6 +62,7 @@ conf_gap(struct conf *c, struct screen_ctx *sc) void conf_font(struct conf *c, struct screen_ctx *sc) { + font_init(sc, c->color[CWM_COLOR_FONT].name); sc->font = font_make(sc, c->font); } @@ -72,6 +73,7 @@ static struct color color_binds[] = { { "red", 0 }, /* CWM_COLOR_BORDOR_UNGROUP */ { "black", 0 }, /* CWM_COLOR_FG_MENU */ { "white", 0 }, /* CWM_COLOR_BG_MENU */ + { "black", 0 }, /* CWM_COLOR_FONT */ }; void diff --git a/cwmrc.5 b/cwmrc.5 index 3f9a09c..ebae713 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 3 2011 $ +.Dd $Mdocdate: September 8 2011 $ .Dt CWMRC 5 .Os .Sh NAME @@ -99,6 +99,9 @@ Set the window border width to .It Ic color activeborder Ar color Set the color of the active border. .Pp +.It Ic color font Ar color +Set menu font color. +.Pp .It Ic color groupborder Ar color Set the color of the border while grouping a window. .Pp diff --git a/font.c b/font.c index cc24eaf..54c878e 100644 --- a/font.c +++ b/font.c @@ -49,15 +49,20 @@ font_height(struct screen_ctx *sc) } void -font_init(struct screen_ctx *sc) +font_init(struct screen_ctx *sc, const char *color) { + if (sc->xftdraw) + XftDrawDestroy(sc->xftdraw); sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin, DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which)); if (sc->xftdraw == NULL) errx(1, "XftDrawCreate"); + if (sc->xftcolor.pixel) + XftColorFree(X_Dpy, DefaultVisual(X_Dpy, sc->which), + DefaultColormap(X_Dpy, sc->which), &sc->xftcolor); if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which), - DefaultColormap(X_Dpy, sc->which), "black", &sc->xftcolor)) + DefaultColormap(X_Dpy, sc->which), color, &sc->xftcolor)) errx(1, "XftColorAllocName"); } diff --git a/parse.y b/parse.y index 43c687e..1b1a249 100644 --- a/parse.y +++ b/parse.y @@ -73,7 +73,7 @@ typedef struct { %token COLOR SNAPDIST %token ACTIVEBORDER INACTIVEBORDER %token GROUPBORDER UNGROUPBORDER -%token MENUBG MENUFG +%token MENUBG MENUFG FONTCOLOR %token ERROR %token STRING %token NUMBER @@ -193,6 +193,10 @@ colors : ACTIVEBORDER STRING { free(conf->color[CWM_COLOR_FG_MENU].name); conf->color[CWM_COLOR_FG_MENU].name = $2; } + | FONTCOLOR STRING { + free(conf->color[CWM_COLOR_FONT].name); + conf->color[CWM_COLOR_FONT].name = $2; + } ; %% @@ -232,6 +236,7 @@ lookup(char *s) { "borderwidth", BORDERWIDTH}, { "color", COLOR}, { "command", COMMAND}, + { "font", FONTCOLOR}, { "fontname", FONTNAME}, { "gap", GAP}, { "groupborder", GROUPBORDER},