From f98e123bfccf2ededa1cd22dbf88bedc5e4a2ccf Mon Sep 17 00:00:00 2001 From: okan Date: Tue, 3 Jul 2012 13:49:03 +0000 Subject: [PATCH 01/17] re-implement atom handing; makes for a normalized and more consistent separation between cwm and ewmh. seen by a few. --- calmwm.h | 74 ++++++++++++-------- client.c | 46 ++++-------- group.c | 55 +++++---------- screen.c | 22 ++---- xevents.c | 2 +- xutil.c | 206 +++++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 247 insertions(+), 158 deletions(-) diff --git a/calmwm.h b/calmwm.h index 29d1019..2d2064e 100644 --- a/calmwm.h +++ b/calmwm.h @@ -466,6 +466,19 @@ void xu_setstate(struct client_ctx *, int); void xu_ewmh_net_supported(struct screen_ctx *); void xu_ewmh_net_supported_wm_check(struct screen_ctx *); +void xu_ewmh_net_desktop_geometry(struct screen_ctx *); +void xu_ewmh_net_workarea(struct screen_ctx *); +void xu_ewmh_net_client_list(struct screen_ctx *); +void xu_ewmh_net_active_window(struct screen_ctx *, Window); +void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *); +void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *); +void xu_ewmh_net_showing_desktop(struct screen_ctx *); +void xu_ewmh_net_virtual_roots(struct screen_ctx *); +void xu_ewmh_net_current_desktop(struct screen_ctx *, long); +void xu_ewmh_net_desktop_names(struct screen_ctx *, unsigned char *, int); + +void xu_ewmh_net_wm_desktop(struct client_ctx *); + void u_exec(char *); void u_spawn(char *); @@ -490,34 +503,37 @@ extern struct conf Conf; extern int HasXinerama, HasRandr, Randr_ev; -#define WM_STATE cwm_atoms[0] -#define WM_DELETE_WINDOW cwm_atoms[1] -#define WM_TAKE_FOCUS cwm_atoms[2] -#define WM_PROTOCOLS cwm_atoms[3] -#define _MOTIF_WM_HINTS cwm_atoms[4] -#define UTF8_STRING cwm_atoms[5] -/* - * please make all hints below this point netwm hints, starting with - * _NET_SUPPORTED. If you change other hints make sure you update - * CWM_NETWM_START - */ -#define _NET_SUPPORTED cwm_atoms[6] -#define _NET_SUPPORTING_WM_CHECK cwm_atoms[7] -#define _NET_WM_NAME cwm_atoms[8] -#define _NET_ACTIVE_WINDOW cwm_atoms[9] -#define _NET_CLIENT_LIST cwm_atoms[10] -#define _NET_NUMBER_OF_DESKTOPS cwm_atoms[11] -#define _NET_CURRENT_DESKTOP cwm_atoms[12] -#define _NET_DESKTOP_VIEWPORT cwm_atoms[13] -#define _NET_DESKTOP_GEOMETRY cwm_atoms[14] -#define _NET_VIRTUAL_ROOTS cwm_atoms[15] -#define _NET_SHOWING_DESKTOP cwm_atoms[16] -#define _NET_DESKTOP_NAMES cwm_atoms[17] -#define _NET_WM_DESKTOP cwm_atoms[18] -#define _NET_WORKAREA cwm_atoms[19] -#define CWM_NO_ATOMS 20 -#define CWM_NETWM_START 6 - -extern Atom cwm_atoms[CWM_NO_ATOMS]; +enum { + WM_STATE, + WM_DELETE_WINDOW, + WM_TAKE_FOCUS, + WM_PROTOCOLS, + _MOTIF_WM_HINTS, + UTF8_STRING, + CWMH_NITEMS +}; +enum { + _NET_SUPPORTED, + _NET_SUPPORTING_WM_CHECK, + _NET_ACTIVE_WINDOW, + _NET_CLIENT_LIST, + _NET_NUMBER_OF_DESKTOPS, + _NET_CURRENT_DESKTOP, + _NET_DESKTOP_VIEWPORT, + _NET_DESKTOP_GEOMETRY, + _NET_VIRTUAL_ROOTS, + _NET_SHOWING_DESKTOP, + _NET_DESKTOP_NAMES, + _NET_WORKAREA, + _NET_WM_NAME, + _NET_WM_DESKTOP, + EWMH_NITEMS +}; +struct atom_ctx { + char *name; + Atom atom; +}; +extern struct atom_ctx cwmh[CWMH_NITEMS]; +extern struct atom_ctx ewmh[EWMH_NITEMS]; #endif /* _CALMWM_H_ */ diff --git a/client.c b/client.c index 5fe7aaf..991b841 100644 --- a/client.c +++ b/client.c @@ -126,9 +126,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped) TAILQ_INSERT_TAIL(&sc->mruq, cc, mru_entry); TAILQ_INSERT_TAIL(&Clientq, cc, entry); - /* append to the client list */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST, XA_WINDOW, 32, - PropModeAppend, (unsigned char *)&cc->win, 1); + + xu_ewmh_net_client_list(sc); client_gethints(cc); client_update(cc); @@ -143,10 +142,7 @@ void client_delete(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - struct client_ctx *tcc; struct winname *wn; - Window *winlist; - int i, j; group_client_delete(cc); @@ -159,23 +155,8 @@ client_delete(struct client_ctx *cc) TAILQ_REMOVE(&sc->mruq, cc, mru_entry); TAILQ_REMOVE(&Clientq, cc, entry); - /* - * Sadly we can't remove just one entry from a property, so we must - * redo the whole thing from scratch. this is the stupid way, the other - * way incurs many roundtrips to the server. - */ - i = j = 0; - TAILQ_FOREACH(tcc, &Clientq, entry) - i++; - if (i > 0) { - winlist = xmalloc(i * sizeof(*winlist)); - TAILQ_FOREACH(tcc, &Clientq, entry) - winlist[j++] = tcc->win; - XChangeProperty(X_Dpy, sc->rootwin, _NET_CLIENT_LIST, - XA_WINDOW, 32, PropModeReplace, - (unsigned char *)winlist, i); - xfree(winlist); - } + + xu_ewmh_net_client_list(sc); if (_curcc == cc) client_none(sc); @@ -236,9 +217,7 @@ client_setactive(struct client_ctx *cc, int fg) if (fg && _curcc != cc) { client_setactive(NULL, 0); _curcc = cc; - XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW, - XA_WINDOW, 32, PropModeReplace, - (unsigned char *)&cc->win, 1); + xu_ewmh_net_active_window(sc, cc->win); } cc->active = fg; @@ -253,8 +232,8 @@ client_none(struct screen_ctx *sc) { Window none = None; - XChangeProperty(X_Dpy, sc->rootwin, _NET_ACTIVE_WINDOW, - XA_WINDOW, 32, PropModeReplace, (unsigned char *)&none, 1); + xu_ewmh_net_active_window(sc, none); + _curcc = NULL; } @@ -545,9 +524,9 @@ client_update(struct client_ctx *cc) return; for (i = 0; i < n; i++) - if (p[i] == WM_DELETE_WINDOW) + if (p[i] == cwmh[WM_DELETE_WINDOW].atom) cc->xproto |= CLIENT_PROTO_DELETE; - else if (p[i] == WM_TAKE_FOCUS) + else if (p[i] == cwmh[WM_TAKE_FOCUS].atom) cc->xproto |= CLIENT_PROTO_TAKEFOCUS; XFree(p); @@ -557,7 +536,8 @@ void client_send_delete(struct client_ctx *cc) { if (cc->xproto & CLIENT_PROTO_DELETE) - xu_sendmsg(cc->win, WM_PROTOCOLS, WM_DELETE_WINDOW); + xu_sendmsg(cc->win, + cwmh[WM_PROTOCOLS].atom, cwmh[WM_DELETE_WINDOW].atom); else XKillClient(X_Dpy, cc->win); } @@ -568,7 +548,7 @@ client_setname(struct client_ctx *cc) struct winname *wn; char *newname; - if (!xu_getstrprop(cc->win, _NET_WM_NAME, &newname)) + if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME].atom, &newname)) if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname)) newname = emptystring; @@ -868,7 +848,7 @@ client_gethints(struct client_ctx *cc) cc->app_class = xch.res_class; } - if (xu_getprop(cc->win, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, + if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS].atom, _MOTIF_WM_HINTS, PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS) if (mwmh->flags & MWM_HINTS_DECORATIONS && !(mwmh->decorations & MWM_DECOR_ALL) && diff --git a/group.c b/group.c index 85a0e67..71ea3d0 100644 --- a/group.c +++ b/group.c @@ -48,38 +48,31 @@ const char *shortcut_to_name[] = { static void group_add(struct group_ctx *gc, struct client_ctx *cc) { - long no; if (cc == NULL || gc == NULL) errx(1, "group_add: a ctx is NULL"); - no = gc->shortcut - 1; - if (cc->group == gc) return; if (cc->group != NULL) TAILQ_REMOVE(&cc->group->clients, cc, group_entry); - XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&no, 1); - TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry); cc->group = gc; + + xu_ewmh_net_wm_desktop(cc); } static void group_remove(struct client_ctx *cc) { - long no = 0xffffffff; - if (cc == NULL || cc->group == NULL) errx(1, "group_remove: a ctx is NULL"); - XChangeProperty(X_Dpy, cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *)&no, 1); - TAILQ_REMOVE(&cc->group->clients, cc, group_entry); cc->group = NULL; + + xu_ewmh_net_wm_desktop(cc); } static void @@ -146,8 +139,6 @@ void group_init(struct screen_ctx *sc) { int i; - long viewports[2] = {0, 0}; - long ndesks = CALMWM_NGROUPS, zero = 0; TAILQ_INIT(&sc->groupq); sc->group_hideall = 0; @@ -164,23 +155,11 @@ group_init(struct screen_ctx *sc) TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry); } - /* we don't support large desktops, so this is always (0, 0) */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_VIEWPORT, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); - XChangeProperty(X_Dpy, sc->rootwin, _NET_NUMBER_OF_DESKTOPS, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1); - /* - * we don't use virtual roots, so make sure it's not there from a - * previous wm. - */ - XDeleteProperty(X_Dpy, sc->rootwin, _NET_VIRTUAL_ROOTS); - /* - * We don't really have a ``showing desktop'' mode, so this is zero - * always. XXX Note that when we hide all groups, or when all groups - * are hidden we could technically set this later on. - */ - XChangeProperty(X_Dpy, sc->rootwin, _NET_SHOWING_DESKTOP, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1); + xu_ewmh_net_wm_desktop_viewport(sc); + xu_ewmh_net_wm_number_of_desktops(sc); + xu_ewmh_net_showing_desktop(sc); + xu_ewmh_net_virtual_roots(sc); + group_setactive(sc, 0); } @@ -209,8 +188,8 @@ static void group_setactive(struct screen_ctx *sc, long idx) { sc->group_active = &sc->groups[idx]; - XChangeProperty(X_Dpy, sc->rootwin, _NET_CURRENT_DESKTOP, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1); + + xu_ewmh_net_current_desktop(sc, idx); } void @@ -439,8 +418,8 @@ group_autogroup(struct client_ctx *cc) if (cc->app_class == NULL || cc->app_name == NULL) return; - if (xu_getprop(cc->win, _NET_WM_DESKTOP, XA_CARDINAL, - 1, (unsigned char **)&grpno) > 0) { + if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP].atom, + XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) { if (*grpno == 0xffffffff) no = 0; else if (*grpno > CALMWM_NGROUPS || *grpno < 0) @@ -483,8 +462,9 @@ group_update_names(struct screen_ctx *sc) int format_ret, i = 0, nstrings = 0, n, setnames = 0; unsigned long bytes_after, num_ret; - if (XGetWindowProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, 0, - 0xffffff, False, UTF8_STRING, &type_ret, &format_ret, + if (XGetWindowProperty(X_Dpy, sc->rootwin, + ewmh[_NET_DESKTOP_NAMES].atom, 0, 0xffffff, False, + cwmh[UTF8_STRING].atom, &type_ret, &format_ret, &num_ret, &bytes_after, &prop_ret) == Success && prop_ret != NULL && format_ret == 8) { /* failure, just set defaults */ @@ -545,6 +525,5 @@ group_set_names(struct screen_ctx *sc) q += slen; } - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, - UTF8_STRING, 8, PropModeReplace, p, len); + xu_ewmh_net_desktop_names(sc, p, len); } diff --git a/screen.c b/screen.c index ecd8104..6711073 100644 --- a/screen.c +++ b/screen.c @@ -111,23 +111,9 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) void screen_update_geometry(struct screen_ctx *sc, int width, int height) { - long geom[2], workareas[CALMWM_NGROUPS][4]; - int i; + sc->xmax = width; + sc->ymax = height; - sc->xmax = geom[0] = width; - sc->ymax = geom[1] = height; - XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_GEOMETRY, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); - - /* x, y, width, height. */ - for (i = 0; i < CALMWM_NGROUPS; i++) { - workareas[i][0] = sc->gap.left; - workareas[i][1] = sc->gap.top; - workareas[i][2] = width - (sc->gap.left + sc->gap.right); - workareas[i][3] = height - (sc->gap.top + sc->gap.bottom); - } - - XChangeProperty(X_Dpy, sc->rootwin, _NET_WORKAREA, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)workareas, CALMWM_NGROUPS * 4); + xu_ewmh_net_desktop_geometry(sc); + xu_ewmh_net_workarea(sc); } diff --git a/xevents.c b/xevents.c index f64adb8..db6450e 100644 --- a/xevents.c +++ b/xevents.c @@ -207,7 +207,7 @@ xev_handle_propertynotify(XEvent *ee) goto test; return; test: - if (e->atom == _NET_DESKTOP_NAMES) + if (e->atom == ewmh[_NET_DESKTOP_NAMES].atom) group_update_names(sc); } } diff --git a/xutil.c b/xutil.c index 030584b..7f0c4c4 100644 --- a/xutil.c +++ b/xutil.c @@ -207,7 +207,8 @@ xu_getstate(struct client_ctx *cc, int *state) { long *p = NULL; - if (xu_getprop(cc->win, WM_STATE, WM_STATE, 2L, (u_char **)&p) <= 0) + if (xu_getprop(cc->win, cwmh[WM_STATE].atom, WM_STATE, 2L, + (u_char **)&p) <= 0) return (-1); *state = (int)*p; @@ -225,67 +226,194 @@ xu_setstate(struct client_ctx *cc, int state) dat[1] = None; cc->state = state; - XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32, + XChangeProperty(X_Dpy, cc->win, + cwmh[WM_STATE].atom, WM_STATE, 32, PropModeReplace, (unsigned char *)dat, 2); } -Atom cwm_atoms[CWM_NO_ATOMS]; -char *atoms[CWM_NO_ATOMS] = { - "WM_STATE", - "WM_DELETE_WINDOW", - "WM_TAKE_FOCUS", - "WM_PROTOCOLS", - "_MOTIF_WM_HINTS", - "UTF8_STRING", - "_NET_SUPPORTED", - "_NET_SUPPORTING_WM_CHECK", - "_NET_WM_NAME", - "_NET_ACTIVE_WINDOW", - "_NET_CLIENT_LIST", - "_NET_NUMBER_OF_DESKTOPS", - "_NET_CURRENT_DESKTOP", - "_NET_DESKTOP_VIEWPORT", - "_NET_DESKTOP_GEOMETRY", - "_NET_VIRTUAL_ROOTS", - "_NET_SHOWING_DESKTOP", - "_NET_DESKTOP_NAMES", - "_NET_WM_DESKTOP", - "_NET_WORKAREA", +struct atom_ctx cwmh[CWMH_NITEMS] = { + {"WM_STATE", None}, + {"WM_DELETE_WINDOW", None}, + {"WM_TAKE_FOCUS", None}, + {"WM_PROTOCOLS", None}, + {"_MOTIF_WM_HINTS", None}, + {"UTF8_STRING", None}, +}; +struct atom_ctx ewmh[EWMH_NITEMS] = { + {"_NET_SUPPORTED", None}, + {"_NET_SUPPORTING_WM_CHECK", None}, + {"_NET_ACTIVE_WINDOW", None}, + {"_NET_CLIENT_LIST", None}, + {"_NET_NUMBER_OF_DESKTOPS", None}, + {"_NET_CURRENT_DESKTOP", None}, + {"_NET_DESKTOP_VIEWPORT", None}, + {"_NET_DESKTOP_GEOMETRY", None}, + {"_NET_VIRTUAL_ROOTS", None}, + {"_NET_SHOWING_DESKTOP", None}, + {"_NET_DESKTOP_NAMES", None}, + {"_NET_WORKAREA", None}, + {"_NET_WM_NAME", None}, + {"_NET_WM_DESKTOP", None}, }; void xu_getatoms(void) { - XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms); + int i; + + for (i = 0; i < nitems(cwmh); i++) + cwmh[i].atom = XInternAtom(X_Dpy, cwmh[i].name, False); + for (i = 0; i < nitems(ewmh); i++) + ewmh[i].atom = XInternAtom(X_Dpy, ewmh[i].name, False); } +/* Root Window Properties */ void xu_ewmh_net_supported(struct screen_ctx *sc) { - XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTED, XA_ATOM, 32, - PropModeReplace, (unsigned char *)&_NET_SUPPORTED, - CWM_NO_ATOMS - CWM_NETWM_START); + Atom atom[EWMH_NITEMS]; + int i; + + for (i = 0; i < nitems(ewmh); i++) + atom[i] = ewmh[i].atom; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTED].atom, + XA_ATOM, 32, PropModeReplace, (unsigned char *)atom, EWMH_NITEMS); } -/* - * The netwm spec says that to prove that the hint is not stale, one - * must provide _NET_SUPPORTING_WM_CHECK containing a window created by - * the root window. The property must be set on the root window and the - * window itself. This child window also must have _NET_WM_NAME set with - * the window manager name. - */ void xu_ewmh_net_supported_wm_check(struct screen_ctx *sc) { Window w; w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0); - XChangeProperty(X_Dpy, sc->rootwin, _NET_SUPPORTING_WM_CHECK, + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); - XChangeProperty(X_Dpy, w, _NET_SUPPORTING_WM_CHECK, + XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); - XChangeProperty(X_Dpy, w, _NET_WM_NAME, UTF8_STRING, - 8, PropModeReplace, WMNAME, strlen(WMNAME)); + XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom, + XA_WM_NAME, 8, PropModeReplace, WMNAME, strlen(WMNAME)); +} + +void +xu_ewmh_net_desktop_geometry(struct screen_ctx *sc) +{ + long geom[2] = { sc->xmax, sc->ymax }; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); +} + +void +xu_ewmh_net_workarea(struct screen_ctx *sc) +{ + long workareas[CALMWM_NGROUPS][4]; + int i; + + for (i = 0; i < CALMWM_NGROUPS; i++) { + workareas[i][0] = sc->gap.left; + workareas[i][1] = sc->gap.top; + workareas[i][2] = sc->xmax - (sc->gap.left + sc->gap.right); + workareas[i][3] = sc->ymax - (sc->gap.top + sc->gap.bottom); + } + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)workareas, + CALMWM_NGROUPS * 4); +} + +void +xu_ewmh_net_client_list(struct screen_ctx *sc) +{ + struct client_ctx *cc; + Window *winlist; + int i = 0, j = 0; + + TAILQ_FOREACH(cc, &Clientq, entry) + i++; + if (i == 0) + return; + + winlist = xmalloc(i * sizeof(*winlist)); + TAILQ_FOREACH(cc, &Clientq, entry) + winlist[j++] = cc->win; + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom, + XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i); + xfree(winlist); +} + +void +xu_ewmh_net_active_window(struct screen_ctx *sc, Window w) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_ACTIVE_WINDOW].atom, + XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); +} + +void +xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *sc) +{ + long viewports[2] = {0, 0}; + + /* We don't support large desktops, so this is (0, 0). */ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); +} + +void +xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc) +{ + long ndesks = CALMWM_NGROUPS; + + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_NUMBER_OF_DESKTOPS].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1); +} + +void +xu_ewmh_net_showing_desktop(struct screen_ctx *sc) +{ + long zero = 0; + + /* We don't support `showing desktop' mode, so this is zero. + * Note that when we hide all groups, or when all groups are + * hidden we could technically set this later on. + */ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SHOWING_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1); +} + +void +xu_ewmh_net_virtual_roots(struct screen_ctx *sc) +{ + /* We don't support virtual roots, so delete if set by previous wm. */ + XDeleteProperty(X_Dpy, sc->rootwin, ewmh[_NET_VIRTUAL_ROOTS].atom); +} + +void +xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CURRENT_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1); +} + +void +xu_ewmh_net_desktop_names(struct screen_ctx *sc, unsigned char *data, int n) +{ + XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom, + cwmh[UTF8_STRING].atom, 8, PropModeReplace, data, n); +} + +/* Application Window Properties */ +void +xu_ewmh_net_wm_desktop(struct client_ctx *cc) +{ + struct group_ctx *gc = cc->group; + long no = 0xffffffff; + + if (gc) + no = gc->shortcut - 1; + + XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP].atom, + XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1); } unsigned long From 8c7964468fe82bfd557165f7b42874933fc2a586 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 4 Jul 2012 18:00:13 +0000 Subject: [PATCH 02/17] fix missing atom (WM_PROTOCOLS) wrt new style handing; without this, the window manager didn't know if a client supported CLIENT_PROTO_DELETE and thus used a hammer, XKillClient. behaviour reported by Tim van der Molen. --- client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client.c b/client.c index 991b841..c993af7 100644 --- a/client.c +++ b/client.c @@ -519,7 +519,7 @@ client_update(struct client_ctx *cc) int i; long n; - if ((n = xu_getprop(cc->win, WM_PROTOCOLS, + if ((n = xu_getprop(cc->win, cwmh[WM_PROTOCOLS].atom, XA_ATOM, 20L, (u_char **)&p)) <= 0) return; From 3681b26914c3097295c37027bbf7eede76e308bf Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 4 Jul 2012 18:07:12 +0000 Subject: [PATCH 03/17] use the screen ctx since we already have it assigned. --- kbfunc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kbfunc.c b/kbfunc.c index fbb603d..b739aec 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -91,20 +91,20 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) cc->geom.y += my; if (cc->geom.y + cc->geom.height < 0) cc->geom.y = -cc->geom.height; - if (cc->geom.y > cc->sc->ymax - 1) - cc->geom.y = cc->sc->ymax - 1; + if (cc->geom.y > sc->ymax - 1) + cc->geom.y = sc->ymax - 1; cc->geom.x += mx; if (cc->geom.x + cc->geom.width < 0) cc->geom.x = -cc->geom.width; - if (cc->geom.x > cc->sc->xmax - 1) - cc->geom.x = cc->sc->xmax - 1; + if (cc->geom.x > sc->xmax - 1) + cc->geom.x = sc->xmax - 1; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, cc->sc->xmax, + cc->geom.width, sc->xmax, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, cc->sc->ymax, + cc->geom.height, sc->ymax, cc->bwidth, Conf.snapdist); client_move(cc); From 287a5b2aad2fb54fbe7016fc90f8a62b1433547b Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 4 Jul 2012 23:42:03 +0000 Subject: [PATCH 04/17] assign and use screen ctx where appropriate and consistently. --- kbfunc.c | 20 ++++++-------------- mousefunc.c | 12 +++++------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/kbfunc.c b/kbfunc.c index b739aec..bcebd76 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -54,14 +54,13 @@ kbfunc_client_raise(struct client_ctx *cc, union arg *arg) void kbfunc_moveresize(struct client_ctx *cc, union arg *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; int x, y, flags, amt; u_int mx, my; if (cc->flags & CLIENT_FREEZE) return; - sc = cc->sc; mx = my = 0; flags = arg->i; @@ -140,12 +139,11 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) void kbfunc_client_search(struct client_ctx *cc, union arg *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; struct client_ctx *old_cc; struct menu *mi; struct menu_q menuq; - sc = cc->sc; old_cc = client_current(); TAILQ_INIT(&menuq); @@ -177,12 +175,11 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg) void kbfunc_menu_search(struct client_ctx *cc, union arg *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; struct cmd *cmd; struct menu *mi; struct menu_q menuq; - sc = cc->sc; TAILQ_INIT(&menuq); TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { @@ -205,9 +202,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg) void kbfunc_client_cycle(struct client_ctx *cc, union arg *arg) { - struct screen_ctx *sc; - - sc = cc->sc; + struct screen_ctx *sc = cc->sc; /* XXX for X apps that ignore events */ XGrabKeyboard(X_Dpy, sc->rootwin, True, @@ -244,7 +239,7 @@ void kbfunc_exec(struct client_ctx *cc, union arg *arg) { #define NPATHS 256 - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; char **ap, *paths[NPATHS], *path, *pathcpy, *label; char tpath[MAXPATHLEN]; DIR *dirp; @@ -253,7 +248,6 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg) struct menu_q menuq; int l, i, cmd = arg->i; - sc = cc->sc; switch (cmd) { case CWM_EXEC_PROGRAM: label = "exec"; @@ -332,7 +326,7 @@ out: void kbfunc_ssh(struct client_ctx *cc, union arg *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; struct menu *mi; struct menu_q menuq; FILE *fp; @@ -342,8 +336,6 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg) int l; size_t len; - sc = cc->sc; - if ((home = getenv("HOME")) == NULL) return; diff --git a/mousefunc.c b/mousefunc.c index c165977..713b3bc 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -137,6 +137,7 @@ mousefunc_window_move(struct client_ctx *cc, void *arg) { XEvent ev; Time ltime = 0; + struct screen_ctx *sc = cc->sc; int px, py; client_raise(cc); @@ -161,10 +162,10 @@ mousefunc_window_move(struct client_ctx *cc, void *arg) cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, cc->sc->xmax, + cc->geom.width, sc->xmax, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, cc->sc->ymax, + cc->geom.height, sc->ymax, cc->bwidth, Conf.snapdist); /* don't move more than 60 times / second */ @@ -217,13 +218,12 @@ mousefunc_menu_group(struct client_ctx *cc, void *arg) void mousefunc_menu_unhide(struct client_ctx *cc, void *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; struct client_ctx *old_cc; struct menu *mi; struct menu_q menuq; char *wname; - sc = cc->sc; old_cc = client_current(); TAILQ_INIT(&menuq); @@ -261,13 +261,11 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg) void mousefunc_menu_cmd(struct client_ctx *cc, void *arg) { - struct screen_ctx *sc; + struct screen_ctx *sc = cc->sc; struct menu *mi; struct menu_q menuq; struct cmd *cmd; - sc = cc->sc; - TAILQ_INIT(&menuq); TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { mi = xcalloc(1, sizeof(*mi)); From 1124ee5cc1342d62ccdcb6d163809434184b9301 Mon Sep 17 00:00:00 2001 From: okan Date: Thu, 5 Jul 2012 17:35:13 +0000 Subject: [PATCH 05/17] the display's width and height are updated after an XRandR event so we don't need to pass down the new values to screen_update_geometry(); so just read the width/height values directly for both uses of screen_update_geometry(). prep for further changes in this area. --- calmwm.c | 4 ++-- calmwm.h | 2 +- screen.c | 6 +++--- xevents.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/calmwm.c b/calmwm.c index 2a52f6a..6254781 100644 --- a/calmwm.c +++ b/calmwm.c @@ -167,8 +167,8 @@ x_setupscreen(struct screen_ctx *sc, u_int which) xu_ewmh_net_supported_wm_check(sc); conf_gap(&Conf, sc); - screen_update_geometry(sc, DisplayWidth(X_Dpy, sc->which), - DisplayHeight(X_Dpy, sc->which)); + + screen_update_geometry(sc); conf_color(&Conf, sc); diff --git a/calmwm.h b/calmwm.h index 2d2064e..301f21f 100644 --- a/calmwm.h +++ b/calmwm.h @@ -361,7 +361,7 @@ void search_print_client(struct menu *, int); XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int); struct screen_ctx *screen_fromroot(Window); void screen_init_xinerama(struct screen_ctx *); -void screen_update_geometry(struct screen_ctx *, int, int); +void screen_update_geometry(struct screen_ctx *); void screen_updatestackingorder(struct screen_ctx *); void kbfunc_client_cycle(struct client_ctx *, union arg *); diff --git a/screen.c b/screen.c index 6711073..2285257 100644 --- a/screen.c +++ b/screen.c @@ -109,10 +109,10 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) } void -screen_update_geometry(struct screen_ctx *sc, int width, int height) +screen_update_geometry(struct screen_ctx *sc) { - sc->xmax = width; - sc->ymax = height; + sc->xmax = DisplayWidth(X_Dpy, sc->which); + sc->ymax = DisplayHeight(X_Dpy, sc->which); xu_ewmh_net_desktop_geometry(sc); xu_ewmh_net_workarea(sc); diff --git a/xevents.c b/xevents.c index db6450e..57983cd 100644 --- a/xevents.c +++ b/xevents.c @@ -365,7 +365,7 @@ xev_handle_randr(XEvent *ee) TAILQ_FOREACH(sc, &Screenq, entry) { if (sc->which == (u_int)i) { XRRUpdateConfiguration(ee); - screen_update_geometry(sc, rev->width, rev->height); + screen_update_geometry(sc); screen_init_xinerama(sc); } } From 315f25f7aba3eb416757465a55b487289d8f8c27 Mon Sep 17 00:00:00 2001 From: dcoppa Date: Fri, 6 Jul 2012 08:41:29 +0000 Subject: [PATCH 06/17] Add a couple examples of keybindings using keysyms, as discussed with okan@ and sthen@. OK okan@, sthen@ --- cwmrc.5 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cwmrc.5 b/cwmrc.5 index 2bb1d53..e09e35b 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 8 2011 $ +.Dd $Mdocdate: November 6 2011 $ .Dt CWMRC 5 .Os .Sh NAME @@ -244,6 +244,10 @@ ignore xclock bind CM-r label bind CS-Return "xterm -e top" bind 4-o unmap +bind CM-equal unmap +bind CMS-equal unmap +bind C4-equal vmaximize +bind C4S-equal hmaximize bind M-1 grouponly1 bind M-2 grouponly2 bind M-3 grouponly3 From cb893d0aa96e0a3e86cbd1094206871b10d92cd0 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 6 Jul 2012 14:18:00 +0000 Subject: [PATCH 07/17] querying for Xinerama should be done per display, not per screen, so move chuck to display init; allows some shuffling to occur limiting screen_init_xinerama()'s scope while keeping order intact. --- calmwm.c | 15 ++++----------- calmwm.h | 1 - screen.c | 8 ++++++++ xevents.c | 1 - 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/calmwm.c b/calmwm.c index 6254781..4ee7253 100644 --- a/calmwm.c +++ b/calmwm.c @@ -97,7 +97,7 @@ main(int argc, char **argv) static void dpy_init(const char *dpyname) { - int i; + int i, fake; XSetErrorHandler(x_errorhandler); @@ -110,6 +110,9 @@ dpy_init(const char *dpyname) XSync(X_Dpy, False); XSetErrorHandler(x_errorhandler); + if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 && + ((HasXinerama = XineramaIsActive(X_Dpy)) == 1)) + HasXinerama = 1; HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i); } @@ -157,7 +160,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which) Window *wins, w0, w1; XWindowAttributes winattr; XSetWindowAttributes rootattr; - int fake; u_int nwins, i; sc->which = which; @@ -201,17 +203,8 @@ x_setupscreen(struct screen_ctx *sc, u_int which) screen_updatestackingorder(sc); - if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 && - ((HasXinerama = XineramaIsActive(X_Dpy)) == 1)) - HasXinerama = 1; if (HasRandr) XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask); - /* - * initial setup of xinerama screens, if we're using RandR then we'll - * redo this whenever the screen changes since a CTRC may have been - * added or removed - */ - screen_init_xinerama(sc); XSync(X_Dpy, False); } diff --git a/calmwm.h b/calmwm.h index 301f21f..3ef5260 100644 --- a/calmwm.h +++ b/calmwm.h @@ -360,7 +360,6 @@ void search_print_client(struct menu *, int); XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int); struct screen_ctx *screen_fromroot(Window); -void screen_init_xinerama(struct screen_ctx *); void screen_update_geometry(struct screen_ctx *); void screen_updatestackingorder(struct screen_ctx *); diff --git a/screen.c b/screen.c index 2285257..dd7eb0e 100644 --- a/screen.c +++ b/screen.c @@ -30,6 +30,8 @@ #include "calmwm.h" +static void screen_init_xinerama(struct screen_ctx *); + struct screen_ctx * screen_fromroot(Window rootwin) { @@ -65,6 +67,10 @@ screen_updatestackingorder(struct screen_ctx *sc) XFree(wins); } +/* + * If we're using RandR then we'll redo this whenever the screen + * changes since a CTRC may have been added or removed + */ void screen_init_xinerama(struct screen_ctx *sc) { @@ -114,6 +120,8 @@ screen_update_geometry(struct screen_ctx *sc) sc->xmax = DisplayWidth(X_Dpy, sc->which); sc->ymax = DisplayHeight(X_Dpy, sc->which); + screen_init_xinerama(sc); + xu_ewmh_net_desktop_geometry(sc); xu_ewmh_net_workarea(sc); } diff --git a/xevents.c b/xevents.c index 57983cd..9478505 100644 --- a/xevents.c +++ b/xevents.c @@ -366,7 +366,6 @@ xev_handle_randr(XEvent *ee) if (sc->which == (u_int)i) { XRRUpdateConfiguration(ee); screen_update_geometry(sc); - screen_init_xinerama(sc); } } } From c8a17ef5364a1ed43e709da40f1f4715e2852e3c Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 8 Jul 2012 01:00:24 +0000 Subject: [PATCH 08/17] remove a redundant assignment and another one up. --- group.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/group.c b/group.c index 71ea3d0..f28640c 100644 --- a/group.c +++ b/group.c @@ -459,7 +459,7 @@ group_update_names(struct screen_ctx *sc) char **strings, *p; unsigned char *prop_ret; Atom type_ret; - int format_ret, i = 0, nstrings = 0, n, setnames = 0; + int format_ret, i = 0, nstrings = 0, n = 0, setnames = 0; unsigned long bytes_after, num_ret; if (XGetWindowProperty(X_Dpy, sc->rootwin, @@ -478,7 +478,6 @@ group_update_names(struct screen_ctx *sc) strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS : nstrings) * sizeof(*strings)); - i = n = 0; p = prop_ret; while (n < nstrings) { strings[n++] = xstrdup(p); From 6faef40c55bdf81ed638085f224cda8b9001fb85 Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 8 Jul 2012 02:50:41 +0000 Subject: [PATCH 09/17] fix atom for retrieving WM_STATE between re-exec's. --- xutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xutil.c b/xutil.c index 7f0c4c4..2a7d089 100644 --- a/xutil.c +++ b/xutil.c @@ -207,7 +207,7 @@ xu_getstate(struct client_ctx *cc, int *state) { long *p = NULL; - if (xu_getprop(cc->win, cwmh[WM_STATE].atom, WM_STATE, 2L, + if (xu_getprop(cc->win, cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 2L, (u_char **)&p) <= 0) return (-1); From 2450e309ea6b0666606adcd93146687ece13c11e Mon Sep 17 00:00:00 2001 From: okan Date: Sun, 8 Jul 2012 02:55:01 +0000 Subject: [PATCH 10/17] fix atom for setting WM_STATE. --- xutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xutil.c b/xutil.c index 2a7d089..1158a05 100644 --- a/xutil.c +++ b/xutil.c @@ -227,7 +227,7 @@ xu_setstate(struct client_ctx *cc, int state) cc->state = state; XChangeProperty(X_Dpy, cc->win, - cwmh[WM_STATE].atom, WM_STATE, 32, + cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 32, PropModeReplace, (unsigned char *)dat, 2); } From cc08aef0df6236f794fb1d5dfcef265dba9da228 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 13 Jul 2012 14:18:04 +0000 Subject: [PATCH 11/17] introduce screen "view" area and "work" area (gap applied) to simplify various blocks that require understanding the screen geometry. --- calmwm.h | 9 +++++++++ screen.c | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/calmwm.h b/calmwm.h index 3ef5260..4eee07b 100644 --- a/calmwm.h +++ b/calmwm.h @@ -96,6 +96,13 @@ struct color { unsigned long pixel; }; +struct geom { + int x; + int y; + int w; + int h; +}; + struct gap { int top; int bottom; @@ -206,6 +213,8 @@ struct screen_ctx { int cycling; int xmax; int ymax; + struct geom view; /* viewable area */ + struct geom work; /* workable area, gap-applied */ struct gap gap; struct cycle_entry_q mruq; XftColor xftcolor; diff --git a/screen.c b/screen.c index dd7eb0e..72468c2 100644 --- a/screen.c +++ b/screen.c @@ -120,6 +120,16 @@ screen_update_geometry(struct screen_ctx *sc) sc->xmax = DisplayWidth(X_Dpy, sc->which); sc->ymax = DisplayHeight(X_Dpy, sc->which); + sc->view.x = 0; + sc->view.y = 0; + sc->view.w = DisplayWidth(X_Dpy, sc->which); + sc->view.h = DisplayHeight(X_Dpy, sc->which); + + sc->work.x = sc->view.x + sc->gap.left; + sc->work.y = sc->view.y + sc->gap.top; + sc->work.w = sc->view.w - (sc->gap.left + sc->gap.right); + sc->work.h = sc->view.h - (sc->gap.top + sc->gap.bottom); + screen_init_xinerama(sc); xu_ewmh_net_desktop_geometry(sc); From 186a78ff1e8f19155b337b68586cebc7495fcdf9 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 13 Jul 2012 15:21:35 +0000 Subject: [PATCH 12/17] convert xmax/ymax uses to view geometry. --- calmwm.h | 2 -- client.c | 14 +++++++------- kbfunc.c | 12 ++++++------ menu.c | 4 ++-- mousefunc.c | 4 ++-- screen.c | 3 --- xevents.c | 4 ++-- xutil.c | 10 +++++----- 8 files changed, 24 insertions(+), 29 deletions(-) diff --git a/calmwm.h b/calmwm.h index 4eee07b..4271421 100644 --- a/calmwm.h +++ b/calmwm.h @@ -211,8 +211,6 @@ struct screen_ctx { struct color color[CWM_COLOR_MAX]; GC gc; int cycling; - int xmax; - int ymax; struct geom view; /* viewable area */ struct geom work; /* workable area, gap-applied */ struct gap gap; diff --git a/client.c b/client.c index c993af7..cd50290 100644 --- a/client.c +++ b/client.c @@ -256,7 +256,7 @@ void client_maximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int xmax = sc->xmax, ymax = sc->ymax; + int xmax = sc->view.w, ymax = sc->view.h; int x_org = 0, y_org = 0; if (cc->flags & CLIENT_FREEZE) @@ -312,7 +312,7 @@ void client_vertmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int y_org = 0, ymax = sc->ymax; + int y_org = 0, ymax = sc->view.h; if (cc->flags & CLIENT_FREEZE) return; @@ -360,7 +360,7 @@ void client_horizmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int x_org = 0, xmax = sc->xmax; + int x_org = 0, xmax = sc->view.w; if (cc->flags & CLIENT_FREEZE) return; @@ -670,8 +670,8 @@ client_placecalc(struct client_ctx *cc) * XRandR bits mean that {x,y}max shouldn't be outside what's * currently there. */ - xslack = sc->xmax - cc->geom.width - cc->bwidth * 2; - yslack = sc->ymax - cc->geom.height - cc->bwidth * 2; + xslack = sc->view.w - cc->geom.width - cc->bwidth * 2; + yslack = sc->view.h - cc->geom.height - cc->bwidth * 2; if (cc->size->x > 0) cc->geom.x = MIN(cc->size->x, xslack); if (cc->size->y > 0) @@ -693,8 +693,8 @@ client_placecalc(struct client_ctx *cc) } else { noxine: xorig = yorig = 0; - xmax = sc->xmax; - ymax = sc->ymax; + xmax = sc->view.w; + ymax = sc->view.h; } xmouse = MAX(xmouse, xorig) - cc->geom.width / 2; ymouse = MAX(ymouse, yorig) - cc->geom.height / 2; diff --git a/kbfunc.c b/kbfunc.c index bcebd76..4c02610 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -90,20 +90,20 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) cc->geom.y += my; if (cc->geom.y + cc->geom.height < 0) cc->geom.y = -cc->geom.height; - if (cc->geom.y > sc->ymax - 1) - cc->geom.y = sc->ymax - 1; + if (cc->geom.y > sc->view.h - 1) + cc->geom.y = sc->view.h - 1; cc->geom.x += mx; if (cc->geom.x + cc->geom.width < 0) cc->geom.x = -cc->geom.width; - if (cc->geom.x > sc->xmax - 1) - cc->geom.x = sc->xmax - 1; + if (cc->geom.x > sc->view.w - 1) + cc->geom.x = sc->view.w - 1; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, sc->xmax, + cc->geom.width, sc->view.w, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, sc->ymax, + cc->geom.height, sc->view.h, cc->bwidth, Conf.snapdist); client_move(cc); diff --git a/menu.c b/menu.c index 17c665a..58ed618 100644 --- a/menu.c +++ b/menu.c @@ -349,8 +349,8 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq, ymax = xine->y_org + xine->height; } else { xmin = ymin = 0; - xmax = sc->xmax; - ymax = sc->ymax; + xmax = sc->view.w; + ymax = sc->view.h; } xsave = mc->x; diff --git a/mousefunc.c b/mousefunc.c index 713b3bc..d404a18 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -162,10 +162,10 @@ mousefunc_window_move(struct client_ctx *cc, void *arg) cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, sc->xmax, + cc->geom.width, sc->view.w, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, sc->ymax, + cc->geom.height, sc->view.h, cc->bwidth, Conf.snapdist); /* don't move more than 60 times / second */ diff --git a/screen.c b/screen.c index 72468c2..07f1731 100644 --- a/screen.c +++ b/screen.c @@ -117,9 +117,6 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) void screen_update_geometry(struct screen_ctx *sc) { - sc->xmax = DisplayWidth(X_Dpy, sc->which); - sc->ymax = DisplayHeight(X_Dpy, sc->which); - sc->view.x = 0; sc->view.y = 0; sc->view.w = DisplayWidth(X_Dpy, sc->which); diff --git a/xevents.c b/xevents.c index 9478505..fad3cd1 100644 --- a/xevents.c +++ b/xevents.c @@ -151,10 +151,10 @@ xev_handle_configurerequest(XEvent *ee) if (e->value_mask & CWBorderWidth) wc.border_width = e->border_width; - if (cc->geom.x == 0 && cc->geom.width >= sc->xmax) + if (cc->geom.x == 0 && cc->geom.width >= sc->view.w) cc->geom.x -= cc->bwidth; - if (cc->geom.y == 0 && cc->geom.height >= sc->ymax) + if (cc->geom.y == 0 && cc->geom.height >= sc->view.h) cc->geom.y -= cc->bwidth; wc.x = cc->geom.x; diff --git a/xutil.c b/xutil.c index 1158a05..c0c35e5 100644 --- a/xutil.c +++ b/xutil.c @@ -298,7 +298,7 @@ xu_ewmh_net_supported_wm_check(struct screen_ctx *sc) void xu_ewmh_net_desktop_geometry(struct screen_ctx *sc) { - long geom[2] = { sc->xmax, sc->ymax }; + long geom[2] = { sc->view.w, sc->view.h }; XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY].atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); @@ -311,10 +311,10 @@ xu_ewmh_net_workarea(struct screen_ctx *sc) int i; for (i = 0; i < CALMWM_NGROUPS; i++) { - workareas[i][0] = sc->gap.left; - workareas[i][1] = sc->gap.top; - workareas[i][2] = sc->xmax - (sc->gap.left + sc->gap.right); - workareas[i][3] = sc->ymax - (sc->gap.top + sc->gap.bottom); + workareas[i][0] = sc->work.x; + workareas[i][1] = sc->work.y; + workareas[i][2] = sc->work.w; + workareas[i][3] = sc->work.h; } XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA].atom, From 0e8815dfb02f38a622d71ea3eb5644e6d5b8fb90 Mon Sep 17 00:00:00 2001 From: okan Date: Fri, 13 Jul 2012 17:01:04 +0000 Subject: [PATCH 13/17] re-use geom struct in client_ctx (saved)geometry. --- calmwm.h | 7 +--- client.c | 102 ++++++++++++++++++++++++++-------------------------- kbfunc.c | 28 +++++++-------- mousefunc.c | 30 ++++++++-------- xevents.c | 12 +++---- xutil.c | 4 +-- 6 files changed, 89 insertions(+), 94 deletions(-) diff --git a/calmwm.h b/calmwm.h index 4271421..849a945 100644 --- a/calmwm.h +++ b/calmwm.h @@ -125,12 +125,7 @@ struct client_ctx { XSizeHints *size; Colormap cmap; u_int bwidth; /* border width */ - struct { - int x; /* x position */ - int y; /* y position */ - int width; /* width */ - int height;/* height */ - } geom, savegeom; + struct geom geom, savegeom; struct { int basew; /* desired width */ int baseh; /* desired height */ diff --git a/client.c b/client.c index cd50290..57807e3 100644 --- a/client.c +++ b/client.c @@ -89,8 +89,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped) XGetWindowAttributes(X_Dpy, cc->win, &wattr); cc->geom.x = wattr.x; cc->geom.y = wattr.y; - cc->geom.width = wattr.width; - cc->geom.height = wattr.height; + cc->geom.w = wattr.width; + cc->geom.h = wattr.height; cc->cmap = wattr.colormap; if (wattr.map_state != IsViewable) { @@ -270,12 +270,12 @@ client_maximize(struct client_ctx *cc) } if ((cc->flags & CLIENT_VMAXIMIZED) == 0) { - cc->savegeom.height = cc->geom.height; + cc->savegeom.h = cc->geom.h; cc->savegeom.y = cc->geom.y; } if ((cc->flags & CLIENT_HMAXIMIZED) == 0) { - cc->savegeom.width = cc->geom.width; + cc->savegeom.w = cc->geom.w; cc->savegeom.x = cc->geom.x; } @@ -287,8 +287,8 @@ client_maximize(struct client_ctx *cc) * 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); + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2); if (xine == NULL) goto calc; x_org = xine->x_org; @@ -299,8 +299,8 @@ client_maximize(struct client_ctx *cc) 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->geom.h = ymax - (sc->gap.top + sc->gap.bottom); + cc->geom.w = xmax - (sc->gap.left + sc->gap.right); cc->bwidth = 0; cc->flags |= CLIENT_MAXIMIZED; @@ -319,28 +319,28 @@ client_vertmaximize(struct client_ctx *cc) if (cc->flags & CLIENT_VMAXIMIZED) { cc->geom.y = cc->savegeom.y; - cc->geom.height = cc->savegeom.height; + cc->geom.h = cc->savegeom.h; cc->bwidth = Conf.bwidth; if (cc->flags & CLIENT_HMAXIMIZED) - cc->geom.width -= cc->bwidth * 2; + cc->geom.w -= cc->bwidth * 2; cc->flags &= ~CLIENT_VMAXIMIZED; goto resize; } cc->savegeom.y = cc->geom.y; - cc->savegeom.height = cc->geom.height; + cc->savegeom.h = cc->geom.h; /* if this will make us fully maximized then remove boundary */ if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) { - cc->geom.width += Conf.bwidth * 2; + cc->geom.w += 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); + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2); if (xine == NULL) goto calc; y_org = xine->y_org; @@ -348,7 +348,7 @@ client_vertmaximize(struct client_ctx *cc) } calc: cc->geom.y = y_org + sc->gap.top; - cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top + + cc->geom.h = ymax - (cc->bwidth * 2) - (sc->gap.top + sc->gap.bottom); cc->flags |= CLIENT_VMAXIMIZED; @@ -367,28 +367,28 @@ client_horizmaximize(struct client_ctx *cc) if (cc->flags & CLIENT_HMAXIMIZED) { cc->geom.x = cc->savegeom.x; - cc->geom.width = cc->savegeom.width; + cc->geom.w = cc->savegeom.w; cc->bwidth = Conf.bwidth; if (cc->flags & CLIENT_VMAXIMIZED) - cc->geom.height -= cc->bwidth * 2; + cc->geom.h -= cc->bwidth * 2; cc->flags &= ~CLIENT_HMAXIMIZED; goto resize; } cc->savegeom.x = cc->geom.x; - cc->savegeom.width = cc->geom.width; + cc->savegeom.w = cc->geom.w; /* if this will make us fully maximized then remove boundary */ if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) { - cc->geom.height += cc->bwidth * 2; + cc->geom.h += 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); + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2); if (xine == NULL) goto calc; x_org = xine->x_org; @@ -396,7 +396,7 @@ client_horizmaximize(struct client_ctx *cc) } calc: cc->geom.x = x_org + sc->gap.left; - cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left + + cc->geom.w = xmax - (cc->bwidth * 2) - (sc->gap.left + sc->gap.right); cc->flags |= CLIENT_HMAXIMIZED; @@ -410,7 +410,7 @@ client_resize(struct client_ctx *cc) client_draw_border(cc); XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x, - cc->geom.y, cc->geom.width, cc->geom.height); + cc->geom.y, cc->geom.w, cc->geom.h); xu_configure(cc); } @@ -439,8 +439,8 @@ client_ptrwarp(struct client_ctx *cc) int x = cc->ptr.x, y = cc->ptr.y; if (x == -1 || y == -1) { - x = cc->geom.width / 2; - y = cc->geom.height / 2; + x = cc->geom.w / 2; + y = cc->geom.h / 2; } (cc->state == IconicState) ? client_unhide(cc) : client_raise(cc); @@ -670,8 +670,8 @@ client_placecalc(struct client_ctx *cc) * XRandR bits mean that {x,y}max shouldn't be outside what's * currently there. */ - xslack = sc->view.w - cc->geom.width - cc->bwidth * 2; - yslack = sc->view.h - cc->geom.height - cc->bwidth * 2; + 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) @@ -696,14 +696,14 @@ noxine: xmax = sc->view.w; ymax = sc->view.h; } - xmouse = MAX(xmouse, xorig) - cc->geom.width / 2; - ymouse = MAX(ymouse, yorig) - cc->geom.height / 2; + xmouse = MAX(xmouse, xorig) - cc->geom.w / 2; + ymouse = MAX(ymouse, yorig) - cc->geom.h / 2; xmouse = MAX(xmouse, xorig); ymouse = MAX(ymouse, yorig); - xslack = xmax - cc->geom.width - cc->bwidth * 2; - yslack = ymax - cc->geom.height - cc->bwidth * 2; + xslack = xmax - cc->geom.w - cc->bwidth * 2; + yslack = ymax - cc->geom.h - cc->bwidth * 2; if (xslack >= xorig) { cc->geom.x = MAX(MIN(xmouse, xslack), @@ -712,7 +712,7 @@ noxine: cc->geom.x -= sc->gap.right; } else { cc->geom.x = xorig + sc->gap.left; - cc->geom.width = xmax - sc->gap.left; + cc->geom.w = xmax - sc->gap.left; } if (yslack >= yorig) { cc->geom.y = MAX(MIN(ymouse, yslack), @@ -721,7 +721,7 @@ noxine: cc->geom.y -= sc->gap.bottom; } else { cc->geom.y = yorig + sc->gap.top; - cc->geom.height = ymax - sc->gap.top; + cc->geom.h = ymax - sc->gap.top; } } } @@ -796,43 +796,43 @@ client_applysizehints(struct client_ctx *cc) /* temporarily remove base dimensions, ICCCM 4.1.2.3 */ if (!baseismin) { - cc->geom.width -= cc->hint.basew; - cc->geom.height -= cc->hint.baseh; + cc->geom.w -= cc->hint.basew; + cc->geom.h -= cc->hint.baseh; } /* adjust for aspect limits */ 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->hint.maxa; + (float)cc->geom.w / cc->geom.h) + cc->geom.w = cc->geom.h * cc->hint.maxa; else if (cc->hint.mina < - (float)cc->geom.height / cc->geom.width) - cc->geom.height = cc->geom.width * cc->hint.mina; + (float)cc->geom.h / cc->geom.w) + cc->geom.h = cc->geom.w * cc->hint.mina; } /* remove base dimensions for increment */ if (baseismin) { - cc->geom.width -= cc->hint.basew; - cc->geom.height -= cc->hint.baseh; + cc->geom.w -= cc->hint.basew; + cc->geom.h -= cc->hint.baseh; } /* adjust for increment value */ - cc->geom.width -= cc->geom.width % cc->hint.incw; - cc->geom.height -= cc->geom.height % cc->hint.inch; + cc->geom.w -= cc->geom.w % cc->hint.incw; + cc->geom.h -= cc->geom.h % cc->hint.inch; /* restore base dimensions */ - cc->geom.width += cc->hint.basew; - cc->geom.height += cc->hint.baseh; + cc->geom.w += cc->hint.basew; + cc->geom.h += cc->hint.baseh; /* adjust for min width/height */ - cc->geom.width = MAX(cc->geom.width, cc->hint.minw); - cc->geom.height = MAX(cc->geom.height, cc->hint.minh); + cc->geom.w = MAX(cc->geom.w, cc->hint.minw); + cc->geom.h = MAX(cc->geom.h, cc->hint.minh); /* adjust for max width/height */ if (cc->hint.maxw) - cc->geom.width = MIN(cc->geom.width, cc->hint.maxw); + cc->geom.w = MIN(cc->geom.w, cc->hint.maxw); if (cc->hint.maxh) - cc->geom.height = MIN(cc->geom.height, cc->hint.maxh); + cc->geom.h = MIN(cc->geom.h, cc->hint.maxh); } static void @@ -883,8 +883,8 @@ client_transient(struct client_ctx *cc) static int client_inbound(struct client_ctx *cc, int x, int y) { - return (x < cc->geom.width && x >= 0 && - y < cc->geom.height && y >= 0); + return (x < cc->geom.w && x >= 0 && + y < cc->geom.h && y >= 0); } int diff --git a/kbfunc.c b/kbfunc.c index 4c02610..0f95df4 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -88,22 +88,22 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) switch (flags & TYPEMASK) { case CWM_MOVE: cc->geom.y += my; - if (cc->geom.y + cc->geom.height < 0) - cc->geom.y = -cc->geom.height; + if (cc->geom.y + cc->geom.h < 0) + cc->geom.y = -cc->geom.h; if (cc->geom.y > sc->view.h - 1) cc->geom.y = sc->view.h - 1; cc->geom.x += mx; - if (cc->geom.x + cc->geom.width < 0) - cc->geom.x = -cc->geom.width; + if (cc->geom.x + cc->geom.w < 0) + cc->geom.x = -cc->geom.w; if (cc->geom.x > sc->view.w - 1) cc->geom.x = sc->view.w - 1; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, sc->view.w, + cc->geom.w, sc->view.w, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, sc->view.h, + cc->geom.h, sc->view.h, cc->bwidth, Conf.snapdist); client_move(cc); @@ -113,18 +113,18 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg) client_ptrwarp(cc); break; case CWM_RESIZE: - if ((cc->geom.height += my) < 1) - cc->geom.height = 1; - if ((cc->geom.width += mx) < 1) - cc->geom.width = 1; + if ((cc->geom.h += my) < 1) + cc->geom.h = 1; + if ((cc->geom.w += mx) < 1) + cc->geom.w = 1; client_resize(cc); /* Make sure the pointer stays within the window. */ xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y); - if (cc->ptr.x > cc->geom.width) - cc->ptr.x = cc->geom.width - cc->bwidth; - if (cc->ptr.y > cc->geom.height) - cc->ptr.y = cc->geom.height - cc->bwidth; + if (cc->ptr.x > cc->geom.w) + cc->ptr.x = cc->geom.w - cc->bwidth; + if (cc->ptr.y > cc->geom.h) + cc->ptr.y = cc->geom.h - cc->bwidth; client_ptrwarp(cc); break; case CWM_PTRMOVE: diff --git a/mousefunc.c b/mousefunc.c index d404a18..b0bd40f 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -37,17 +37,17 @@ static void mousefunc_sweep_draw(struct client_ctx *); static int mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my) { - int width = cc->geom.width, height = cc->geom.height; + int width = cc->geom.w, height = cc->geom.h; - cc->geom.width = abs(x - mx) - cc->bwidth; - cc->geom.height = abs(y - my) - cc->bwidth; + cc->geom.w = abs(x - mx) - cc->bwidth; + cc->geom.h = abs(y - my) - cc->bwidth; client_applysizehints(cc); - cc->geom.x = x <= mx ? x : x - cc->geom.width; - cc->geom.y = y <= my ? y : y - cc->geom.height; + cc->geom.x = x <= mx ? x : x - cc->geom.w; + cc->geom.y = y <= my ? y : y - cc->geom.h; - return (width != cc->geom.width || height != cc->geom.height); + return (width != cc->geom.w || height != cc->geom.h); } static void @@ -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->hint.basew) / cc->hint.incw, - (cc->geom.height - cc->hint.baseh) / cc->hint.inch); + (cc->geom.w - cc->hint.basew) / cc->hint.incw, + (cc->geom.h - 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); @@ -91,7 +91,7 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg) if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_resize) < 0) return; - xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height); + xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h); mousefunc_sweep_draw(cc); for (;;) { @@ -121,10 +121,10 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg) xu_ptr_ungrab(); /* Make sure the pointer stays within the window. */ - if (cc->ptr.x > cc->geom.width) - cc->ptr.x = cc->geom.width - cc->bwidth; - if (cc->ptr.y > cc->geom.height) - cc->ptr.y = cc->geom.height - cc->bwidth; + if (cc->ptr.x > cc->geom.w) + cc->ptr.x = cc->geom.w - cc->bwidth; + if (cc->ptr.y > cc->geom.h) + cc->ptr.y = cc->geom.h - cc->bwidth; client_ptrwarp(cc); return; } @@ -162,10 +162,10 @@ mousefunc_window_move(struct client_ctx *cc, void *arg) cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; cc->geom.x += client_snapcalc(cc->geom.x, - cc->geom.width, sc->view.w, + cc->geom.w, sc->view.w, cc->bwidth, Conf.snapdist); cc->geom.y += client_snapcalc(cc->geom.y, - cc->geom.height, sc->view.h, + cc->geom.h, sc->view.h, cc->bwidth, Conf.snapdist); /* don't move more than 60 times / second */ diff --git a/xevents.c b/xevents.c index fad3cd1..eddf4fe 100644 --- a/xevents.c +++ b/xevents.c @@ -141,9 +141,9 @@ xev_handle_configurerequest(XEvent *ee) sc = cc->sc; if (e->value_mask & CWWidth) - cc->geom.width = e->width; + cc->geom.w = e->width; if (e->value_mask & CWHeight) - cc->geom.height = e->height; + cc->geom.h = e->height; if (e->value_mask & CWX) cc->geom.x = e->x; if (e->value_mask & CWY) @@ -151,16 +151,16 @@ xev_handle_configurerequest(XEvent *ee) if (e->value_mask & CWBorderWidth) wc.border_width = e->border_width; - if (cc->geom.x == 0 && cc->geom.width >= sc->view.w) + if (cc->geom.x == 0 && cc->geom.w >= sc->view.w) cc->geom.x -= cc->bwidth; - if (cc->geom.y == 0 && cc->geom.height >= sc->view.h) + if (cc->geom.y == 0 && cc->geom.h >= sc->view.h) cc->geom.y -= cc->bwidth; wc.x = cc->geom.x; wc.y = cc->geom.y; - wc.width = cc->geom.width; - wc.height = cc->geom.height; + wc.width = cc->geom.w; + wc.height = cc->geom.h; wc.border_width = cc->bwidth; XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc); diff --git a/xutil.c b/xutil.c index c0c35e5..d3f7978 100644 --- a/xutil.c +++ b/xutil.c @@ -128,8 +128,8 @@ xu_configure(struct client_ctx *cc) ce.window = cc->win; ce.x = cc->geom.x; ce.y = cc->geom.y; - ce.width = cc->geom.width; - ce.height = cc->geom.height; + ce.width = cc->geom.w; + ce.height = cc->geom.h; ce.border_width = cc->bwidth; ce.above = None; ce.override_redirect = 0; From e42d1c7f01e06665a3e6e763685e47b965e7b0ae Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 16 Jul 2012 01:36:30 +0000 Subject: [PATCH 14/17] move the HasXinerama check into screen_find_xinerama and simplify logic; moves closer to logic in menu code. --- client.c | 59 ++++++++++++++++++++++++-------------------------------- screen.c | 3 +++ 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/client.c b/client.c index 57807e3..c101c5e 100644 --- a/client.c +++ b/client.c @@ -258,6 +258,7 @@ client_maximize(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; int xmax = sc->view.w, ymax = sc->view.h; int x_org = 0, y_org = 0; + XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) return; @@ -279,24 +280,21 @@ client_maximize(struct client_ctx *cc) cc->savegeom.x = cc->geom.x; } - 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.w / 2, - cc->geom.y + cc->geom.h / 2); - if (xine == NULL) - goto calc; + /* + * 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.w / 2, + cc->geom.y + cc->geom.h / 2); + if (xine) { 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.h = ymax - (sc->gap.top + sc->gap.bottom); @@ -313,6 +311,7 @@ client_vertmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; int y_org = 0, ymax = sc->view.h; + XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) return; @@ -336,17 +335,14 @@ client_vertmaximize(struct client_ctx *cc) cc->bwidth = 0; } - if (HasXinerama) { - XineramaScreenInfo *xine; - xine = screen_find_xinerama(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2); - if (xine == NULL) - goto calc; + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2); + if (xine) { y_org = xine->y_org; ymax = xine->height; } -calc: + cc->geom.y = y_org + sc->gap.top; cc->geom.h = ymax - (cc->bwidth * 2) - (sc->gap.top + sc->gap.bottom); @@ -361,6 +357,7 @@ client_horizmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; int x_org = 0, xmax = sc->view.w; + XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) return; @@ -384,17 +381,14 @@ client_horizmaximize(struct client_ctx *cc) cc->bwidth = 0; } - if (HasXinerama) { - XineramaScreenInfo *xine; - xine = screen_find_xinerama(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2); - if (xine == NULL) - goto calc; + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2); + if (xine) { x_org = xine->x_org; xmax = xine->width; } -calc: + cc->geom.x = x_org + sc->gap.left; cc->geom.w = xmax - (cc->bwidth * 2) - (sc->gap.left + sc->gap.right); @@ -682,16 +676,13 @@ client_placecalc(struct client_ctx *cc) int xmax, ymax; xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse); - if (HasXinerama) { - info = screen_find_xinerama(sc, xmouse, ymouse); - if (info == NULL) - goto noxine; + info = screen_find_xinerama(sc, xmouse, ymouse); + if (info) { xorig = info->x_org; yorig = info->y_org; xmax = xorig + info->width; ymax = yorig + info->height; } else { -noxine: xorig = yorig = 0; xmax = sc->view.w; ymax = sc->view.h; diff --git a/screen.c b/screen.c index 07f1731..29d720e 100644 --- a/screen.c +++ b/screen.c @@ -105,6 +105,9 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) XineramaScreenInfo *info; int i; + if (HasXinerama = 0) + return (NULL); + for (i = 0; i < sc->xinerama_no; i++) { info = &sc->xinerama[i]; if (x >= info->x_org && x < info->x_org + info->width && From 57af364a2188e90c68b14852c85f26aba04be334 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 16 Jul 2012 01:42:00 +0000 Subject: [PATCH 15/17] check value --- screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/screen.c b/screen.c index 29d720e..768b495 100644 --- a/screen.c +++ b/screen.c @@ -105,7 +105,7 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) XineramaScreenInfo *info; int i; - if (HasXinerama = 0) + if (HasXinerama == 0) return (NULL); for (i = 0; i < sc->xinerama_no; i++) { From 3f956098d9e8382d27a81aedd1e77220dff4865f Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 16 Jul 2012 01:53:14 +0000 Subject: [PATCH 16/17] unify various max routines to match client placement and partially menu ones when calculating screen dimensions. --- client.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/client.c b/client.c index c101c5e..15052eb 100644 --- a/client.c +++ b/client.c @@ -256,8 +256,7 @@ void client_maximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int xmax = sc->view.w, ymax = sc->view.h; - int x_org = 0, y_org = 0; + int x_org, y_org, xmax, ymax; XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) @@ -293,6 +292,10 @@ client_maximize(struct client_ctx *cc) y_org = xine->y_org; xmax = xine->width; ymax = xine->height; + } else { + x_org = y_org = 0; + xmax = sc->view.w; + ymax = sc->view.h; } cc->geom.x = x_org + sc->gap.left; @@ -310,7 +313,7 @@ void client_vertmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int y_org = 0, ymax = sc->view.h; + int y_org, ymax; XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) @@ -341,6 +344,9 @@ client_vertmaximize(struct client_ctx *cc) if (xine) { y_org = xine->y_org; ymax = xine->height; + } else { + y_org = 0; + ymax = sc->view.h; } cc->geom.y = y_org + sc->gap.top; @@ -356,7 +362,7 @@ void client_horizmaximize(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; - int x_org = 0, xmax = sc->view.w; + int x_org, xmax; XineramaScreenInfo *xine; if (cc->flags & CLIENT_FREEZE) @@ -387,6 +393,9 @@ client_horizmaximize(struct client_ctx *cc) if (xine) { x_org = xine->x_org; xmax = xine->width; + } else { + x_org = 0; + xmax = sc->view.w; } cc->geom.x = x_org + sc->gap.left; From 013497c79cdb17d8a40f53d5535b4ba8362f0ef5 Mon Sep 17 00:00:00 2001 From: okan Date: Wed, 18 Jul 2012 21:53:22 +0000 Subject: [PATCH 17/17] Further simplify Xinerama init and re-init on XRR events. While testing for Xinerama during setup was done display-wide, each time XineramaQueryScreens() is called either in start-up or due to an XRR event, the library re-tests for the Xinerama extension anyway before moving on; so the initial test is redundant and allows another global to go away with one other change: always fill in sc->xinerama (and _no), regardless of the success of malloc in XineramaQueryScreens(), and use it to see if Xinerama dimensions exist when asked by client and/or menu code. --- calmwm.c | 7 ++----- screen.c | 20 +++++--------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/calmwm.c b/calmwm.c index 4ee7253..911c280 100644 --- a/calmwm.c +++ b/calmwm.c @@ -44,7 +44,7 @@ Cursor Cursor_resize; struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq); struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq); -int HasXinerama, HasRandr, Randr_ev; +int HasRandr, Randr_ev; struct conf Conf; static void sigchld_cb(int); @@ -97,7 +97,7 @@ main(int argc, char **argv) static void dpy_init(const char *dpyname) { - int i, fake; + int i; XSetErrorHandler(x_errorhandler); @@ -110,9 +110,6 @@ dpy_init(const char *dpyname) XSync(X_Dpy, False); XSetErrorHandler(x_errorhandler); - if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 && - ((HasXinerama = XineramaIsActive(X_Dpy)) == 1)) - HasXinerama = 1; HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i); } diff --git a/screen.c b/screen.c index 768b495..69a638a 100644 --- a/screen.c +++ b/screen.c @@ -74,21 +74,11 @@ screen_updatestackingorder(struct screen_ctx *sc) void screen_init_xinerama(struct screen_ctx *sc) { - XineramaScreenInfo *info; - int no; + XineramaScreenInfo *info = NULL; + int no = 0; - if (HasXinerama == 0 || XineramaIsActive(X_Dpy) == 0) { - HasXinerama = 0; - sc->xinerama_no = 0; - } - - info = XineramaQueryScreens(X_Dpy, &no); - if (info == NULL) { - /* Is xinerama actually off, instead of a malloc failure? */ - if (sc->xinerama == NULL) - HasXinerama = 0; - return; - } + if (XineramaIsActive(X_Dpy)) + info = XineramaQueryScreens(X_Dpy, &no); if (sc->xinerama != NULL) XFree(sc->xinerama); @@ -105,7 +95,7 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y) XineramaScreenInfo *info; int i; - if (HasXinerama == 0) + if (sc->xinerama == NULL) return (NULL); for (i = 0; i < sc->xinerama_no; i++) {