From 6ac51b8e41da0f47b6cf95bcb8ca58ec86378d88 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 3 Oct 2013 13:51:57 +0000 Subject: [PATCH 01/14] unify type; no change --- calmwm.h | 2 +- client.c | 2 +- group.c | 2 +- xutil.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/calmwm.h b/calmwm.h index e80f5d0..07e223c 100644 --- a/calmwm.h +++ b/calmwm.h @@ -512,7 +512,7 @@ void xev_loop(void); void xu_btn_grab(Window, int, u_int); void xu_btn_ungrab(Window, int, u_int); -int xu_getprop(Window, Atom, Atom, long, u_char **); +int xu_getprop(Window, Atom, Atom, long, unsigned char **); int xu_get_wm_state(Window, int *); int xu_getstrprop(Window, Atom, char **); void xu_key_grab(Window, u_int, KeySym); diff --git a/client.c b/client.c index 9a90588..ee069c5 100644 --- a/client.c +++ b/client.c @@ -841,7 +841,7 @@ client_getmwmhints(struct client_ctx *cc) struct mwm_hints *mwmh; if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS], cwmh[_MOTIF_WM_HINTS], - PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS) + PROP_MWM_HINTS_ELEMENTS, (unsigned char **)&mwmh) == MWM_NUMHINTS) if (mwmh->flags & MWM_HINTS_DECORATIONS && !(mwmh->decorations & MWM_DECOR_ALL) && !(mwmh->decorations & MWM_DECOR_BORDER)) diff --git a/group.c b/group.c index e025be6..9e388fd 100644 --- a/group.c +++ b/group.c @@ -419,7 +419,7 @@ group_update_names(struct screen_ctx *sc) int i = 0, j = 0, nstrings = 0, n = 0, setnames = 0; if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES], - cwmh[UTF8_STRING], 0xffffff, (u_char **)&prop_ret)) > 0) { + cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) { prop_ret[j - 1] = '\0'; /* paranoia */ while (i < j) { if (prop_ret[i++] == '\0') diff --git a/xutil.c b/xutil.c index 7912cb8..543b8b0 100644 --- a/xutil.c +++ b/xutil.c @@ -106,7 +106,7 @@ xu_key_grab(Window win, u_int mask, KeySym keysym) } int -xu_getprop(Window win, Atom atm, Atom type, long len, u_char **p) +xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p) { Atom realtype; u_long n, extra; @@ -160,7 +160,7 @@ xu_get_wm_state(Window win, int *state) long *p = NULL; if (xu_getprop(win, cwmh[WM_STATE], cwmh[WM_STATE], 2L, - (u_char **)&p) <= 0) + (unsigned char **)&p) <= 0) return (-1); *state = (int)*p; @@ -331,7 +331,7 @@ xu_ewmh_get_net_wm_state(struct client_ctx *cc, int *n) Atom *state, *p = NULL; if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L, - (u_char **)&p)) <= 0) + (unsigned char **)&p)) <= 0) return (NULL); state = xcalloc(*n, sizeof(Atom)); From bfd3f5e5e1728cacf0046e7d8e724e10b7380e7b Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 7 Oct 2013 13:40:26 +0000 Subject: [PATCH 02/14] trying parsing a XLFD string first, then by pattern --- conf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/conf.c b/conf.c index 6fe65f6..ea657f1 100644 --- a/conf.c +++ b/conf.c @@ -104,9 +104,12 @@ conf_screen(struct screen_ctx *sc) sc->gap = Conf.gap; - sc->xftfont = XftFontOpenName(X_Dpy, sc->which, Conf.font); - if (sc->xftfont == NULL) - errx(1, "XftFontOpenName"); + sc->xftfont = XftFontOpenXlfd(X_Dpy, sc->which, Conf.font); + if (sc->xftfont == NULL) { + sc->xftfont = XftFontOpenName(X_Dpy, sc->which, Conf.font); + if (sc->xftfont == NULL) + errx(1, "XftFontOpenName"); + } for (i = 0; i < nitems(color_binds); i++) { if (i == CWM_COLOR_MENU_FONT_SEL && *Conf.color[i] == '\0') { From 0d6e8a9146309f5dab93b4d15abfa91aac31ec5f Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Wed, 16 Oct 2013 23:05:51 +0200 Subject: [PATCH 03/14] Makefile: rm -f is enough --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e0abfac..d794374 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ MANPREFIX= ${PREFIX}/share/man all: ${PROG} clean: - rm -rf ${OBJS} ${PROG} y.tab.c + rm -f ${OBJS} ${PROG} y.tab.c y.tab.c: parse.y yacc parse.y From a88b8c1363bfcb9ddaf1311f6d1e43021a5ce180 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 17 Oct 2013 13:59:10 +0000 Subject: [PATCH 04/14] a few err->errx since we don't have error messages here; from Tiago Cunha --- group.c | 6 +++--- kbfunc.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/group.c b/group.c index 9e388fd..2c62ae6 100644 --- a/group.c +++ b/group.c @@ -177,7 +177,7 @@ group_movetogroup(struct client_ctx *cc, int idx) struct group_ctx *gc; if (idx < 0 || idx >= CALMWM_NGROUPS) - err(1, "group_movetogroup: index out of range (%d)", idx); + errx(1, "group_movetogroup: index out of range (%d)", idx); gc = &sc->groups[idx]; if (cc->group == gc) @@ -240,7 +240,7 @@ group_hidetoggle(struct screen_ctx *sc, int idx) struct group_ctx *gc; if (idx < 0 || idx >= CALMWM_NGROUPS) - err(1, "group_hidetoggle: index out of range (%d)", idx); + errx(1, "group_hidetoggle: index out of range (%d)", idx); gc = &sc->groups[idx]; group_fix_hidden_state(gc); @@ -261,7 +261,7 @@ group_only(struct screen_ctx *sc, int idx) int i; if (idx < 0 || idx >= CALMWM_NGROUPS) - err(1, "group_only: index out of range (%d)", idx); + errx(1, "group_only: index out of range (%d)", idx); for (i = 0; i < CALMWM_NGROUPS; i++) { if (i == idx) diff --git a/kbfunc.c b/kbfunc.c index 906ca12..4c28a2b 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -250,7 +250,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg) label = "wm"; break; default: - err(1, "kbfunc_exec: invalid cmd %d", cmd); + errx(1, "kbfunc_exec: invalid cmd %d", cmd); /*NOTREACHED*/ } @@ -305,7 +305,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg) warn("%s", mi->text); break; default: - err(1, "kb_func: egad, cmd changed value!"); + errx(1, "kb_func: egad, cmd changed value!"); break; } } From a70b2d81af54121eb080d7e9f149b892f78a0b67 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 19 Oct 2013 00:24:54 +0000 Subject: [PATCH 05/14] For clients that support WM_TAKE_FOCUS in their WM_PROTOCOLS property, send a ClientMessage event. --- client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client.c b/client.c index ee069c5..d1d6877 100644 --- a/client.c +++ b/client.c @@ -213,6 +213,8 @@ client_setactive(struct client_ctx *cc, int fg) XInstallColormap(X_Dpy, cc->colormap); XSetInputFocus(X_Dpy, cc->win, RevertToPointerRoot, CurrentTime); + if (cc->xproto & _WM_TAKE_FOCUS) + client_msg(cc, cwmh[WM_TAKE_FOCUS]); conf_grab_mouse(cc->win); /* * If we're in the middle of alt-tabbing, don't change From 083a023f2c0f36676d1015e1713ccac1b99bad59 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 19 Oct 2013 18:59:22 +0000 Subject: [PATCH 06/14] I believe we redraw the border in too many cases; likely a leftover from the cc->pwin days - don't redraw on every unhide, resize, and mouse move/resize Expose event (note, all Expose events trigger a redraw anyway). Tested with some finicky X apps I could think of, though I'm sure others will find more - if so, and they 'lose' the border, please report! --- client.c | 3 --- mousefunc.c | 10 ++-------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/client.c b/client.c index d1d6877..0733f88 100644 --- a/client.c +++ b/client.c @@ -398,8 +398,6 @@ client_resize(struct client_ctx *cc, int reset) xu_ewmh_set_net_wm_state(cc); } - client_draw_border(cc); - XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y, cc->geom.w, cc->geom.h); client_config(cc); @@ -495,7 +493,6 @@ client_unhide(struct client_ctx *cc) cc->flags &= ~CLIENT_HIDDEN; cc->state = NormalState; xu_set_wm_state(cc->win, cc->state); - client_draw_border(cc); } void diff --git a/mousefunc.c b/mousefunc.c index faf9b65..31cf951 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -88,12 +88,9 @@ mousefunc_client_resize(struct client_ctx *cc, void *arg) mousefunc_sweep_draw(cc); for (;;) { - XMaskEvent(X_Dpy, MOUSEMASK|ExposureMask, &ev); + XMaskEvent(X_Dpy, MOUSEMASK, &ev); switch (ev.type) { - case Expose: - client_draw_border(cc); - break; case MotionNotify: mousefunc_sweep_calc(cc, x, y, ev.xmotion.x_root, ev.xmotion.y_root); @@ -143,12 +140,9 @@ mousefunc_client_move(struct client_ctx *cc, void *arg) xu_ptr_getpos(cc->win, &px, &py); for (;;) { - XMaskEvent(X_Dpy, MOUSEMASK|ExposureMask, &ev); + XMaskEvent(X_Dpy, MOUSEMASK, &ev); switch (ev.type) { - case Expose: - client_draw_border(cc); - break; case MotionNotify: cc->geom.x = ev.xmotion.x_root - px - cc->bwidth; cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; From a2013ee9dd9b152c044f8120a89c3d5aa17af4ea Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 19 Oct 2013 19:39:34 +0000 Subject: [PATCH 07/14] Using xu_btn_ungrab() buttons during client_leave doesn't work (error BadValue) when the modifier is already AnyModifier . Instead alter xu_btn_ungrab() to ungrab AnyButton/AnyModifier and call it only when a client is coming into focus in client_setactive(), instead of iterating over ignore mods - matches how we handle key grabs. --- calmwm.h | 2 +- client.c | 5 ----- conf.c | 2 ++ xutil.c | 7 ++----- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/calmwm.h b/calmwm.h index 07e223c..e888bac 100644 --- a/calmwm.h +++ b/calmwm.h @@ -511,7 +511,7 @@ void conf_screen(struct screen_ctx *); void xev_loop(void); void xu_btn_grab(Window, int, u_int); -void xu_btn_ungrab(Window, int, u_int); +void xu_btn_ungrab(Window); int xu_getprop(Window, Atom, Atom, long, unsigned char **); int xu_get_wm_state(Window, int *); int xu_getstrprop(Window, Atom, char **); diff --git a/client.c b/client.c index 0733f88..cd0732f 100644 --- a/client.c +++ b/client.c @@ -186,15 +186,10 @@ client_delete(struct client_ctx *cc) void client_leave(struct client_ctx *cc) { - struct screen_ctx *sc; - if (cc == NULL) cc = client_current(); if (cc == NULL) return; - - sc = cc->sc; - xu_btn_ungrab(sc->rootwin, AnyModifier, Button1); } void diff --git a/conf.c b/conf.c index ea657f1..ce3ee1e 100644 --- a/conf.c +++ b/conf.c @@ -649,6 +649,8 @@ conf_grab_mouse(Window win) { struct mousebinding *mb; + xu_btn_ungrab(win); + TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { if (mb->flags != MOUSEBIND_CTX_WIN) continue; diff --git a/xutil.c b/xutil.c index 543b8b0..f33fa9a 100644 --- a/xutil.c +++ b/xutil.c @@ -65,12 +65,9 @@ xu_btn_grab(Window win, int mask, u_int btn) } void -xu_btn_ungrab(Window win, int mask, u_int btn) +xu_btn_ungrab(Window win) { - u_int i; - - for (i = 0; i < nitems(ign_mods); i++) - XUngrabButton(X_Dpy, btn, (mask | ign_mods[i]), win); + XUngrabButton(X_Dpy, AnyButton, AnyModifier, win); } void From 9ff288baefadb19f50def66072d1a9a765efe5b5 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 20 Oct 2013 01:35:47 +0000 Subject: [PATCH 08/14] revert 1.138 (WM_TAKE_FOCUS) for now --- client.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client.c b/client.c index cd0732f..1c41d7e 100644 --- a/client.c +++ b/client.c @@ -208,8 +208,6 @@ client_setactive(struct client_ctx *cc, int fg) XInstallColormap(X_Dpy, cc->colormap); XSetInputFocus(X_Dpy, cc->win, RevertToPointerRoot, CurrentTime); - if (cc->xproto & _WM_TAKE_FOCUS) - client_msg(cc, cwmh[WM_TAKE_FOCUS]); conf_grab_mouse(cc->win); /* * If we're in the middle of alt-tabbing, don't change From 5b733a152daa01493301333a7e756394f9b45455 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 20 Oct 2013 01:55:32 +0000 Subject: [PATCH 09/14] wrap key ungrab like btn ungrab, for it'll be used again --- calmwm.h | 1 + conf.c | 2 +- xutil.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/calmwm.h b/calmwm.h index e888bac..5a827b4 100644 --- a/calmwm.h +++ b/calmwm.h @@ -516,6 +516,7 @@ int xu_getprop(Window, Atom, Atom, long, unsigned char **); int xu_get_wm_state(Window, int *); int xu_getstrprop(Window, Atom, char **); void xu_key_grab(Window, u_int, KeySym); +void xu_key_ungrab(Window); void xu_ptr_getpos(Window, int *, int *); int xu_ptr_grab(Window, u_int, Cursor); int xu_ptr_regrab(u_int, Cursor); diff --git a/conf.c b/conf.c index ce3ee1e..68a5351 100644 --- a/conf.c +++ b/conf.c @@ -663,7 +663,7 @@ conf_grab_kbd(Window win) { struct keybinding *kb; - XUngrabKey(X_Dpy, AnyKey, AnyModifier, win); + xu_key_ungrab(win); TAILQ_FOREACH(kb, &Conf.keybindingq, entry) xu_key_grab(win, kb->modmask, kb->keysym); diff --git a/xutil.c b/xutil.c index f33fa9a..30a89f8 100644 --- a/xutil.c +++ b/xutil.c @@ -102,6 +102,12 @@ xu_key_grab(Window win, u_int mask, KeySym keysym) True, GrabModeAsync, GrabModeAsync); } +void +xu_key_ungrab(Window win) +{ + XUngrabKey(X_Dpy, AnyKey, AnyModifier, win); +} + int xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p) { From 6867821abefd761a840befcfee5a1f1f2fef9831 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 20 Oct 2013 02:00:02 +0000 Subject: [PATCH 10/14] shuffle --- xutil.c | 74 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/xutil.c b/xutil.c index 30a89f8..73dfac0 100644 --- a/xutil.c +++ b/xutil.c @@ -32,27 +32,6 @@ static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask }; -int -xu_ptr_grab(Window win, u_int mask, Cursor curs) -{ - return (XGrabPointer(X_Dpy, win, False, mask, - GrabModeAsync, GrabModeAsync, - None, curs, CurrentTime) == GrabSuccess ? 0 : -1); -} - -int -xu_ptr_regrab(u_int mask, Cursor curs) -{ - return (XChangeActivePointerGrab(X_Dpy, mask, - curs, CurrentTime) == GrabSuccess ? 0 : -1); -} - -void -xu_ptr_ungrab(void) -{ - XUngrabPointer(X_Dpy, CurrentTime); -} - void xu_btn_grab(Window win, int mask, u_int btn) { @@ -70,22 +49,6 @@ xu_btn_ungrab(Window win) XUngrabButton(X_Dpy, AnyButton, AnyModifier, win); } -void -xu_ptr_getpos(Window win, int *x, int *y) -{ - Window w0, w1; - int tmp0, tmp1; - u_int tmp2; - - XQueryPointer(X_Dpy, win, &w0, &w1, &tmp0, &tmp1, x, y, &tmp2); -} - -void -xu_ptr_setpos(Window win, int x, int y) -{ - XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y); -} - void xu_key_grab(Window win, u_int mask, KeySym keysym) { @@ -108,6 +71,43 @@ xu_key_ungrab(Window win) XUngrabKey(X_Dpy, AnyKey, AnyModifier, win); } +int +xu_ptr_grab(Window win, u_int mask, Cursor curs) +{ + return (XGrabPointer(X_Dpy, win, False, mask, + GrabModeAsync, GrabModeAsync, + None, curs, CurrentTime) == GrabSuccess ? 0 : -1); +} + +int +xu_ptr_regrab(u_int mask, Cursor curs) +{ + return (XChangeActivePointerGrab(X_Dpy, mask, + curs, CurrentTime) == GrabSuccess ? 0 : -1); +} + +void +xu_ptr_ungrab(void) +{ + XUngrabPointer(X_Dpy, CurrentTime); +} + +void +xu_ptr_getpos(Window win, int *x, int *y) +{ + Window w0, w1; + int tmp0, tmp1; + u_int tmp2; + + XQueryPointer(X_Dpy, win, &w0, &w1, &tmp0, &tmp1, x, y, &tmp2); +} + +void +xu_ptr_setpos(Window win, int x, int y) +{ + XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y); +} + int xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p) { From 6e17b41f566865629d3dd35a6a60e081e6e2b089 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 25 Oct 2013 19:46:16 +0000 Subject: [PATCH 11/14] A client_delete should behave differently depending on whether the triggering event was unmap (with pending destroy) log destroy; we only need to grab/ungrab the server lock, set WithdrawnState and XRemoveFromSaveSet clients coming from an unmap event - doing so for clients coming from destroy are already gone, hence we generate errors. --- calmwm.h | 2 +- client.c | 16 +++++++++------- xevents.c | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/calmwm.h b/calmwm.h index 5a827b4..4f20a81 100644 --- a/calmwm.h +++ b/calmwm.h @@ -373,7 +373,7 @@ struct client_ctx *client_current(void); void client_cycle(struct screen_ctx *, int); void client_cycle_leave(struct screen_ctx *, struct client_ctx *); -void client_delete(struct client_ctx *); +void client_delete(struct client_ctx *, int); void client_draw_border(struct client_ctx *); struct client_ctx *client_find(Window); void client_freeze(struct client_ctx *); diff --git a/client.c b/client.c index 1c41d7e..d9184df 100644 --- a/client.c +++ b/client.c @@ -145,17 +145,19 @@ client_init(Window win, struct screen_ctx *sc, int mapped) } void -client_delete(struct client_ctx *cc) +client_delete(struct client_ctx *cc, int destroy) { struct screen_ctx *sc = cc->sc; struct winname *wn; - XGrabServer(X_Dpy); - cc->state = WithdrawnState; - xu_set_wm_state(cc->win, cc->state); - XRemoveFromSaveSet(X_Dpy, cc->win); - XSync(X_Dpy, False); - XUngrabServer(X_Dpy); + if (destroy) { + XGrabServer(X_Dpy); + cc->state = WithdrawnState; + xu_set_wm_state(cc->win, cc->state); + XRemoveFromSaveSet(X_Dpy, cc->win); + XSync(X_Dpy, False); + XUngrabServer(X_Dpy); + } TAILQ_REMOVE(&sc->mruq, cc, mru_entry); TAILQ_REMOVE(&Clientq, cc, entry); diff --git a/xevents.c b/xevents.c index 4b6ad60..e6247ab 100644 --- a/xevents.c +++ b/xevents.c @@ -113,7 +113,7 @@ xev_handle_unmapnotify(XEvent *ee) */ if (XCheckTypedWindowEvent(X_Dpy, cc->win, DestroyNotify, &ev) || e->send_event != 0) { - client_delete(cc); + client_delete(cc, 1); } else client_hide(cc); } @@ -127,7 +127,7 @@ xev_handle_destroynotify(XEvent *ee) struct client_ctx *cc; if ((cc = client_find(e->window)) != NULL) - client_delete(cc); + client_delete(cc, 0); } static void From 06eb13dfd949199a730e9373529ef2a7e9f4b1e6 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 1 Nov 2013 14:07:19 +0000 Subject: [PATCH 12/14] re-add support for WM_TAKE_FOCUS, and additionally this time only call XSetInputFocus() for clients that have the InputHint; latter fix discovered by Valery Masiutsin with a PoC patch - solves keyboard input focus loss for java apps. --- calmwm.h | 1 + client.c | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/calmwm.h b/calmwm.h index 4f20a81..439c16f 100644 --- a/calmwm.h +++ b/calmwm.h @@ -165,6 +165,7 @@ struct client_ctx { #define CLIENT_FREEZE 0x0010 #define CLIENT_GROUP 0x0020 #define CLIENT_UNGROUP 0x0040 +#define CLIENT_INPUT 0x0080 #define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) diff --git a/client.c b/client.c index d9184df..60d9b2c 100644 --- a/client.c +++ b/client.c @@ -99,17 +99,22 @@ client_init(Window win, struct screen_ctx *sc, int mapped) cc->geom.h = wattr.height; cc->colormap = wattr.colormap; + if ((wmhints = XGetWMHints(X_Dpy, cc->win)) != NULL) { + if (wmhints->flags & InputHint) { + if (wmhints->input == 1) + cc->flags |= CLIENT_INPUT; + } + } if (wattr.map_state != IsViewable) { client_placecalc(cc); client_move(cc); - if ((wmhints = XGetWMHints(X_Dpy, cc->win)) != NULL) { - if (wmhints->flags & StateHint) { - cc->state = wmhints->initial_state; - xu_set_wm_state(cc->win, cc->state); - } - XFree(wmhints); + if ((wmhints) && (wmhints->flags & StateHint)) { + cc->state = wmhints->initial_state; + xu_set_wm_state(cc->win, cc->state); } } + if (wmhints) + XFree(wmhints); client_draw_border(cc); if (xu_get_wm_state(cc->win, &state) < 0) @@ -208,8 +213,12 @@ client_setactive(struct client_ctx *cc, int fg) if (fg) { XInstallColormap(X_Dpy, cc->colormap); - XSetInputFocus(X_Dpy, cc->win, - RevertToPointerRoot, CurrentTime); + if (cc->flags & CLIENT_INPUT) { + XSetInputFocus(X_Dpy, cc->win, + RevertToPointerRoot, CurrentTime); + } + if (cc->xproto & _WM_TAKE_FOCUS) + client_msg(cc, cwmh[WM_TAKE_FOCUS]); conf_grab_mouse(cc->win); /* * If we're in the middle of alt-tabbing, don't change From b8f53666bd3d84114c6beab636ad410c51e86c67 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 1 Nov 2013 21:54:20 +0000 Subject: [PATCH 13/14] x/y from XSizeHints are obsolete (and have been for a long time), so instead use x/y from XWindowAttributes when USPosition|PPosition are set. --- client.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/client.c b/client.c index 60d9b2c..6a75600 100644 --- a/client.c +++ b/client.c @@ -695,10 +695,8 @@ client_placecalc(struct client_ctx *cc) */ xslack = sc->view.w - cc->geom.w - cc->bwidth * 2; yslack = sc->view.h - cc->geom.h - cc->bwidth * 2; - if (cc->size->x > 0) - cc->geom.x = MIN(cc->size->x, xslack); - if (cc->size->y > 0) - cc->geom.y = MIN(cc->size->y, yslack); + cc->geom.x = MIN(cc->geom.x, xslack); + cc->geom.y = MIN(cc->geom.y, yslack); } else { struct geom xine; int xmouse, ymouse; From b5915eb9898b93d0f9eeb42df3f7a8a2bd839e49 Mon Sep 17 00:00:00 2001 From: okan Date: Sat, 2 Nov 2013 19:13:56 +0000 Subject: [PATCH 14/14] The only reason we need to keep XSizeHints in our client_ctx is for flags, so just add one to hints; consolidates sizehints and shrinks. Additionally don't abuse PSize for XGetWMNormalHints() failures. --- calmwm.h | 2 +- client.c | 67 +++++++++++++++++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/calmwm.h b/calmwm.h index 439c16f..f0361ba 100644 --- a/calmwm.h +++ b/calmwm.h @@ -137,11 +137,11 @@ struct client_ctx { TAILQ_ENTRY(client_ctx) mru_entry; struct screen_ctx *sc; Window win; - XSizeHints *size; Colormap colormap; u_int bwidth; /* border width */ struct geom geom, savegeom; struct { + long flags; /* defined hints */ int basew; /* desired width */ int baseh; /* desired height */ int minw; /* minimum width */ diff --git a/client.c b/client.c index 6a75600..74fafbc 100644 --- a/client.c +++ b/client.c @@ -73,7 +73,6 @@ client_init(Window win, struct screen_ctx *sc, int mapped) cc->state = mapped ? NormalState : IconicState; cc->sc = sc; cc->win = win; - cc->size = XAllocSizeHints(); client_getsizehints(cc); @@ -175,7 +174,6 @@ client_delete(struct client_ctx *cc, int destroy) if (cc == client_current()) client_none(sc); - XFree(cc->size); if (cc->app_name != NULL) XFree(cc->app_name); if (cc->app_class != NULL) @@ -685,7 +683,7 @@ client_placecalc(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; int xslack, yslack; - if (cc->size->flags & (USPosition|PPosition)) { + if (cc->hint.flags & (USPosition|PPosition)) { /* * Ignore XINERAMA screens, just make sure it's somewhere * in the virtual desktop. else it stops people putting xterms @@ -748,43 +746,52 @@ void client_getsizehints(struct client_ctx *cc) { long tmp; + XSizeHints *size; - if (!XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp)) - cc->size->flags = PSize; + if ((size = XAllocSizeHints()) == NULL) + warnx("XAllocSizeHints failure"); - if (cc->size->flags & PBaseSize) { - cc->hint.basew = cc->size->base_width; - cc->hint.baseh = cc->size->base_height; - } else if (cc->size->flags & PMinSize) { - cc->hint.basew = cc->size->min_width; - cc->hint.baseh = cc->size->min_height; + if (!XGetWMNormalHints(X_Dpy, cc->win, size, &tmp)) + size->flags = 0; + + cc->hint.flags = size->flags; + + if (size->flags & PBaseSize) { + cc->hint.basew = size->base_width; + cc->hint.baseh = size->base_height; + } else if (size->flags & PMinSize) { + cc->hint.basew = size->min_width; + cc->hint.baseh = size->min_height; } - if (cc->size->flags & PMinSize) { - cc->hint.minw = cc->size->min_width; - cc->hint.minh = cc->size->min_height; - } else if (cc->size->flags & PBaseSize) { - cc->hint.minw = cc->size->base_width; - cc->hint.minh = cc->size->base_height; + if (size->flags & PMinSize) { + cc->hint.minw = size->min_width; + cc->hint.minh = size->min_height; + } else if (size->flags & PBaseSize) { + cc->hint.minw = size->base_width; + cc->hint.minh = size->base_height; } - if (cc->size->flags & PMaxSize) { - cc->hint.maxw = cc->size->max_width; - cc->hint.maxh = cc->size->max_height; + if (size->flags & PMaxSize) { + cc->hint.maxw = size->max_width; + cc->hint.maxh = size->max_height; } - if (cc->size->flags & PResizeInc) { - cc->hint.incw = cc->size->width_inc; - cc->hint.inch = cc->size->height_inc; + if (size->flags & PResizeInc) { + cc->hint.incw = size->width_inc; + cc->hint.inch = size->height_inc; } 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->hint.mina = (float)cc->size->min_aspect.y / - cc->size->min_aspect.x; - if (cc->size->max_aspect.y > 0) - cc->hint.maxa = (float)cc->size->max_aspect.x / - cc->size->max_aspect.y; + if (size->flags & PAspect) { + if (size->min_aspect.x > 0) + cc->hint.mina = (float)size->min_aspect.y / + size->min_aspect.x; + if (size->max_aspect.y > 0) + cc->hint.maxa = (float)size->max_aspect.x / + size->max_aspect.y; } + + if (size) + XFree(size); } void