Index: calmwm.h =================================================================== RCS file: /cvs/xenocara/app/cwm/calmwm.h,v retrieving revision 1.311 diff -u -r1.311 calmwm.h --- calmwm.h 12 Nov 2015 21:28:03 -0000 1.311 +++ calmwm.h 18 Jul 2016 20:40:12 -0000 @@ -141,6 +141,7 @@ TAILQ_ENTRY(client_ctx) entry; TAILQ_ENTRY(client_ctx) group_entry; struct screen_ctx *sc; + struct region_ctx *rc; struct group_ctx *gc; Window win; Colormap colormap; @@ -218,9 +219,7 @@ struct region_ctx { TAILQ_ENTRY(region_ctx) entry; int num; - struct geom area; struct geom view; /* viewable area */ - struct geom work; /* workable area, gap-applied */ }; TAILQ_HEAD(region_ctx_q, region_ctx); @@ -394,8 +393,11 @@ void client_getsizehints(struct client_ctx *); void client_hide(struct client_ctx *); void client_htile(struct client_ctx *); +int client_keep_visible(struct client_ctx *); void client_lower(struct client_ctx *); void client_map(struct client_ctx *); +void client_migrate_region(struct client_ctx *, + struct region_ctx *); void client_msg(struct client_ctx *, Atom, Time); void client_move(struct client_ctx *); struct client_ctx *client_init(Window, struct screen_ctx *); @@ -408,6 +410,7 @@ void client_setactive(struct client_ctx *); void client_setname(struct client_ctx *); int client_snapcalc(int, int, int, int, int); +struct geom client_region_area(struct client_ctx *, int); void client_toggle_freeze(struct client_ctx *); void client_toggle_fullscreen(struct client_ctx *); void client_toggle_hidden(struct client_ctx *); @@ -453,7 +456,7 @@ void search_print_cmd(struct menu *, int); void search_print_group(struct menu *, int); -struct region_ctx *region_find(struct screen_ctx *, int, int); +struct region_ctx *region_find(struct screen_ctx *, struct geom); struct geom screen_apply_gap(struct screen_ctx *, struct geom); struct screen_ctx *screen_find(Window); struct geom screen_area(struct screen_ctx *, int, int, int); @@ -468,11 +471,12 @@ void kbfunc_client_hide(struct client_ctx *, union arg *); void kbfunc_client_label(struct client_ctx *, union arg *); void kbfunc_client_lower(struct client_ctx *, union arg *); +void kbfunc_client_migrateregion(struct client_ctx *, + union arg *); void kbfunc_client_move(struct client_ctx *, union arg *); void kbfunc_client_movetogroup(struct client_ctx *, union arg *); void kbfunc_client_raise(struct client_ctx *, union arg *); -void kbfunc_client_rcycle(struct client_ctx *, union arg *); void kbfunc_client_resize(struct client_ctx *, union arg *); void kbfunc_client_tile(struct client_ctx *, union arg *); void kbfunc_client_toggle_freeze(struct client_ctx *, Index: client.c =================================================================== RCS file: /cvs/xenocara/app/cwm/client.c,v retrieving revision 1.214 diff -u -r1.214 client.c --- client.c 12 Nov 2015 18:33:30 -0000 1.214 +++ client.c 15 Aug 2016 19:51:00 -0000 @@ -101,6 +101,7 @@ if ((cc->wmh) && (cc->wmh->flags & StateHint)) client_set_wm_state(cc, cc->wmh->initial_state); } else { + cc->rc = region_find(sc, cc->geom); if ((XQueryPointer(X_Dpy, cc->win, &rwin, &cwin, &x, &y, &wx, &wy, &mask)) && (cwin != None)) activate = 1; @@ -250,6 +251,16 @@ return(curcc); } +struct geom +client_region_area(struct client_ctx *cc, int flags) +{ + struct geom area = cc->rc->view; + + if (flags & CWM_GAP) + area = screen_apply_gap(cc->sc, area); + return(area); +} + void client_toggle_freeze(struct client_ctx *cc) { @@ -289,8 +300,7 @@ void client_toggle_fullscreen(struct client_ctx *cc) { - struct screen_ctx *sc = cc->sc; - struct geom area; + struct geom area; if ((cc->flags & CLIENT_FREEZE) && !(cc->flags & CLIENT_FULLSCREEN)) @@ -305,9 +315,7 @@ cc->fullgeom = cc->geom; - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_NOGAP); + area = client_region_area(cc, CWM_NOGAP); cc->bwidth = 0; cc->geom = area; @@ -321,8 +329,7 @@ void client_toggle_maximize(struct client_ctx *cc) { - struct screen_ctx *sc = cc->sc; - struct geom area; + struct geom area; if (cc->flags & CLIENT_FREEZE) return; @@ -343,14 +350,7 @@ cc->savegeom.x = cc->geom.x; } - /* - * 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 - */ - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); cc->geom.x = area.x; cc->geom.y = area.y; @@ -366,8 +366,7 @@ void client_toggle_vmaximize(struct client_ctx *cc) { - struct screen_ctx *sc = cc->sc; - struct geom area; + struct geom area; if (cc->flags & CLIENT_FREEZE) return; @@ -382,9 +381,7 @@ cc->savegeom.y = cc->geom.y; cc->savegeom.h = cc->geom.h; - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); cc->geom.y = area.y; cc->geom.h = area.h - (cc->bwidth * 2); @@ -398,8 +395,7 @@ void client_toggle_hmaximize(struct client_ctx *cc) { - struct screen_ctx *sc = cc->sc; - struct geom area; + struct geom area; if (cc->flags & CLIENT_FREEZE) return; @@ -414,9 +410,7 @@ cc->savegeom.x = cc->geom.x; cc->savegeom.w = cc->geom.w; - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); cc->geom.x = area.x; cc->geom.w = area.w - (cc->bwidth * 2); @@ -442,6 +436,32 @@ client_config(cc); } +int +client_keep_visible(struct client_ctx *cc) +{ + struct region_ctx *rc; + int changed = 0; + + /* Recalculate region for the client */ + cc->rc = region_find(cc->sc, cc->geom); + rc = cc->rc; + if (cc->geom.x + cc->geom.w + (int)(cc->bwidth * 2) <= rc->view.x) { + cc->geom.x = rc->view.x - (cc->geom.w + (cc->bwidth * 2) - 1); + changed = 1; + } else if (cc->geom.x >= (rc->view.x + rc->view.w)) { + cc->geom.x = rc->view.x + rc->view.w - 1; + changed = 1; + } + if (cc->geom.y + cc->geom.h + (int)(cc->bwidth * 2) <= rc->view.y) { + cc->geom.y = rc->view.y - (cc->geom.h + (cc->bwidth * 2) - 1); + changed = 1; + } else if (cc->geom.y >= (rc->view.y + rc->view.h)) { + cc->geom.y = rc->view.y + rc->view.h - 1; + changed = 1; + } + return(changed); +} + void client_move(struct client_ctx *cc) { @@ -749,6 +769,7 @@ client_placecalc(struct client_ctx *cc) { struct screen_ctx *sc = cc->sc; + struct geom area; int xslack, yslack; if (cc->hint.flags & (USPosition | PPosition)) { @@ -759,40 +780,29 @@ * XRandR bits mean that {x,y}max shouldn't be outside what's * currently there. */ - xslack = sc->view.w - cc->geom.w - cc->bwidth * 2; - yslack = sc->view.h - cc->geom.h - cc->bwidth * 2; - cc->geom.x = MIN(cc->geom.x, xslack); - cc->geom.y = MIN(cc->geom.y, yslack); + cc->rc = region_find(sc, cc->geom); + area = client_region_area(cc, CWM_NOGAP); } else { - struct geom area; + struct geom point; int xmouse, ymouse; xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse); - area = screen_area(sc, xmouse, ymouse, CWM_GAP); - area.w += area.x; - area.h += area.y; - xmouse = MAX(xmouse, area.x) - cc->geom.w / 2; - ymouse = MAX(ymouse, area.y) - cc->geom.h / 2; - - xmouse = MAX(xmouse, area.x); - ymouse = MAX(ymouse, area.y); - - xslack = area.w - cc->geom.w - cc->bwidth * 2; - yslack = area.h - cc->geom.h - cc->bwidth * 2; - - if (xslack >= area.x) { - cc->geom.x = MAX(MIN(xmouse, xslack), area.x); - } else { - cc->geom.x = area.x; - cc->geom.w = area.w; - } - if (yslack >= area.y) { - cc->geom.y = MAX(MIN(ymouse, yslack), area.y); - } else { - cc->geom.y = area.y; - cc->geom.h = area.h; + point = (struct geom){ xmouse, ymouse, 0, 0 }; + cc->rc = region_find(sc, point); + area = client_region_area(cc, CWM_GAP); + + if (!(cc->hint.flags & (USSize | PSize))) { + cc->geom.w = MIN(cc->geom.w, area.w - cc->bwidth * 2); + cc->geom.h = MIN(cc->geom.h, area.h - cc->bwidth * 2); + client_applysizehints(cc); } + cc->geom.x = xmouse - cc->geom.w / 2 - cc->bwidth; + cc->geom.y = ymouse - cc->geom.h / 2 - cc->bwidth; } + xslack = area.x + area.w - cc->geom.w - cc->bwidth * 2; + yslack = area.y + area.h - cc->geom.h - cc->bwidth * 2; + cc->geom.x = MAX(MIN(cc->geom.x, xslack), area.x); + cc->geom.y = MAX(MIN(cc->geom.y, yslack), area.y); } static void @@ -974,7 +984,6 @@ { struct client_ctx *ci; struct group_ctx *gc = cc->gc; - struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mh, x, h, w; @@ -983,17 +992,15 @@ i = n = 0; TAILQ_FOREACH(ci, &gc->clientq, group_entry) { - if (ci->flags & CLIENT_HIDDEN || - ci->flags & CLIENT_IGNORE || (ci == cc)) + if ((ci->flags & (CLIENT_HIDDEN | CLIENT_IGNORE)) || + (ci == cc) || (ci->rc != cc->rc)) continue; n++; } if (n == 0) return; - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); if (cc->flags & CLIENT_VMAXIMIZED || cc->geom.h + (cc->bwidth * 2) >= area.h) @@ -1011,8 +1018,8 @@ w = area.w / n; h = area.h - mh; TAILQ_FOREACH(ci, &gc->clientq, group_entry) { - if (ci->flags & CLIENT_HIDDEN || - ci->flags & CLIENT_IGNORE || (ci == cc)) + if ((ci->flags & (CLIENT_HIDDEN | CLIENT_IGNORE)) || + (ci == cc) || (ci->rc != cc->rc)) continue; ci->bwidth = Conf.bwidth; ci->geom.y = area.y + mh; @@ -1033,7 +1040,6 @@ { struct client_ctx *ci; struct group_ctx *gc = cc->gc; - struct screen_ctx *sc = cc->sc; struct geom area; int i, n, mw, y, h, w; @@ -1042,17 +1048,15 @@ i = n = 0; TAILQ_FOREACH(ci, &gc->clientq, group_entry) { - if (ci->flags & CLIENT_HIDDEN || - ci->flags & CLIENT_IGNORE || (ci == cc)) + if ((ci->flags & (CLIENT_HIDDEN | CLIENT_IGNORE)) || + (ci == cc) || (ci->rc != cc->rc)) continue; n++; } if (n == 0) return; - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); if (cc->flags & CLIENT_HMAXIMIZED || cc->geom.w + (cc->bwidth * 2) >= area.w) @@ -1070,8 +1074,8 @@ h = area.h / n; w = area.w - mw; TAILQ_FOREACH(ci, &gc->clientq, group_entry) { - if (ci->flags & CLIENT_HIDDEN || - ci->flags & CLIENT_IGNORE || (ci == cc)) + if ((ci->flags & (CLIENT_HIDDEN | CLIENT_IGNORE)) || + (ci == cc) || (ci->rc != cc->rc)) continue; ci->bwidth = Conf.bwidth; ci->geom.y = y; @@ -1087,6 +1091,51 @@ } } +static void +client_migrate_area(struct geom *geom, struct geom *newarea, + struct geom *oldarea) +{ + int oldslack, newslack; + + oldslack = oldarea->w - geom->w - (Conf.bwidth * 2); + newslack = newarea->w - geom->w - (Conf.bwidth * 2); + geom->x -= oldarea->x; + if (oldslack != 0 && newslack != oldslack) + geom->x = (long long)geom->x * newslack / oldslack; + geom->x += newarea->x; + + oldslack = oldarea->h - geom->h - (Conf.bwidth * 2); + newslack = newarea->h - geom->h - (Conf.bwidth * 2); + geom->y -= oldarea->y; + if (oldslack != 0 && newslack != oldslack) + geom->y = (long long)geom->y * newslack / oldslack; + geom->y += newarea->y; +} + +void +client_migrate_region(struct client_ctx *cc, struct region_ctx *rc) +{ + struct screen_ctx *sc = cc->sc; + struct geom oldarea, newarea; + + oldarea = screen_apply_gap(sc, cc->rc->view); + newarea = screen_apply_gap(sc, rc->view); + client_migrate_area(&cc->savegeom, &newarea, &oldarea); + client_migrate_area(&cc->fullgeom, &newarea, &oldarea); + if (cc->flags & CLIENT_FULLSCREEN) + cc->geom = rc->view; + else { + client_migrate_area(&cc->geom, &newarea, &oldarea); + if (cc->flags & CLIENT_HMAXIMIZED) + cc->geom.w = newarea.w - (cc->bwidth * 2); + if (cc->flags & CLIENT_VMAXIMIZED) + cc->geom.h = newarea.h - (cc->bwidth * 2); + client_keep_visible(cc); + } + cc->rc = rc; + client_resize(cc, 0); +} + long client_get_wm_state(struct client_ctx *cc) { @@ -1108,4 +1157,3 @@ XChangeProperty(X_Dpy, cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 32, PropModeReplace, (unsigned char *)data, 2); } - Index: conf.c =================================================================== RCS file: /cvs/xenocara/app/cwm/conf.c,v retrieving revision 1.204 diff -u -r1.204 conf.c --- conf.c 13 Aug 2016 09:59:48 -0000 1.204 +++ conf.c 18 Jul 2016 20:40:12 -0000 @@ -406,6 +406,10 @@ {.i = (CWM_CLIENT_CYCLE | CWM_CLIENT_CYCLE_INGRP)} }, { "rcycleingroup", kbfunc_client_cycle, CWM_CONTEXT_CLIENT, {.i = (CWM_CLIENT_RCYCLE | CWM_CLIENT_CYCLE_INGRP)} }, + { "migrateregion", kbfunc_client_migrateregion, CWM_CONTEXT_CLIENT, + {.i = CWM_CLIENT_CYCLE} }, + { "rmigrateregion", kbfunc_client_migrateregion, CWM_CONTEXT_CLIENT, + {.i = CWM_CLIENT_RCYCLE} }, { "grouptoggle", kbfunc_client_grouptoggle, CWM_CONTEXT_CLIENT, {.i = CWM_KBD}}, { "sticky", kbfunc_client_toggle_sticky, CWM_CONTEXT_CLIENT, {0} }, Index: cwmrc.5 =================================================================== RCS file: /cvs/xenocara/app/cwm/cwmrc.5,v retrieving revision 1.61 diff -u -r1.61 cwmrc.5 --- cwmrc.5 12 Jul 2015 14:31:47 -0000 1.61 +++ cwmrc.5 18 Jul 2016 20:40:12 -0000 @@ -289,6 +289,10 @@ Forward cycle through windows in current group. .It rcycleingroup Reverse cycle through windows in current group. +.It migrateregion +Migrate current window to next region (XRandR monitor). +.It rmigrateregion +Migrate current window to previous region (XRandR monitor). .It delete Delete current window. .It hide Index: kbfunc.c =================================================================== RCS file: /cvs/xenocara/app/cwm/kbfunc.c,v retrieving revision 1.126 diff -u -r1.126 kbfunc.c --- kbfunc.c 17 Nov 2015 14:32:38 -0000 1.126 +++ kbfunc.c 18 Jul 2016 20:40:12 -0000 @@ -104,19 +104,10 @@ kbfunc_amount(arg->i, Conf.mamount, &mx, &my); cc->geom.x += mx; - 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.y += my; - 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; - - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + client_keep_visible(cc); + + area = client_region_area(cc, CWM_GAP); cc->geom.x += client_snapcalc(cc->geom.x, cc->geom.x + cc->geom.w + (cc->bwidth * 2), area.x, area.x + area.w, sc->snapdist); @@ -149,6 +140,7 @@ cc->geom.w = cc->hint.minw; if ((cc->geom.h += my * cc->hint.inch) < cc->hint.minh) cc->geom.h = cc->hint.minh; + client_keep_visible(cc); client_resize(cc, 1); /* Make sure the pointer stays within the window. */ @@ -491,6 +483,24 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg) { group_movetogroup(cc, arg->i); +} + +void +kbfunc_client_migrateregion(struct client_ctx *cc, union arg *arg) +{ + struct screen_ctx *sc = cc->sc; + struct region_ctx *rc; + + if (arg->i == CWM_CLIENT_RCYCLE) { + if ((rc = TAILQ_PREV(cc->rc, region_ctx_q, entry)) == NULL) + rc = TAILQ_LAST(&sc->regionq, region_ctx_q); + } else { + if ((rc = TAILQ_NEXT(cc->rc, entry)) == NULL) + rc = TAILQ_FIRST(&sc->regionq); + } + client_ptrsave(cc); + client_migrate_region(cc, rc); + client_ptrwarp(cc); } void Index: mousefunc.c =================================================================== RCS file: /cvs/xenocara/app/cwm/mousefunc.c,v retrieving revision 1.103 diff -u -r1.103 mousefunc.c --- mousefunc.c 17 Nov 2015 14:31:28 -0000 1.103 +++ mousefunc.c 18 Jul 2016 20:40:12 -0000 @@ -140,10 +140,14 @@ cc->geom.x = ev.xmotion.x_root - px - cc->bwidth; cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; + if (client_keep_visible(cc)) { + px = ev.xmotion.x_root - cc->geom.x - + cc->bwidth; + py = ev.xmotion.y_root - cc->geom.y - + cc->bwidth; + } - area = screen_area(sc, - cc->geom.x + cc->geom.w / 2, - cc->geom.y + cc->geom.h / 2, CWM_GAP); + area = client_region_area(cc, CWM_GAP); cc->geom.x += client_snapcalc(cc->geom.x, cc->geom.x + cc->geom.w + (cc->bwidth * 2), area.x, area.x + area.w, sc->snapdist); Index: screen.c =================================================================== RCS file: /cvs/xenocara/app/cwm/screen.c,v retrieving revision 1.79 diff -u -r1.79 screen.c --- screen.c 11 Nov 2015 14:22:01 -0000 1.79 +++ screen.c 18 Jul 2016 20:40:12 -0000 @@ -125,32 +125,67 @@ } struct region_ctx * -region_find(struct screen_ctx *sc, int x, int y) +region_find(struct screen_ctx *sc, struct geom area) { struct region_ctx *rc; + struct region_ctx *best = NULL; + long long overlap = 0; + int cx, cy, distance = -1; + cx = area.x + area.w / 2; + cy = area.y + area.h / 2; TAILQ_FOREACH(rc, &sc->regionq, entry) { - if ((x >= rc->view.x) && (x < (rc->view.x + rc->view.w)) && - (y >= rc->view.y) && (y < (rc->view.y + rc->view.h))) { - break; + if ((cx >= rc->view.x) && (cx < (rc->view.x + rc->view.w)) && + (cy >= rc->view.y) && (cy < (rc->view.y + rc->view.h))) { + /* Centre of area is within region, we're done */ + return(rc); + } + if ((area.x < (rc->view.x + rc->view.w)) && + (rc->view.x < (area.x + area.w)) && + (area.y < (rc->view.y + rc->view.h)) && + (rc->view.y < (area.y + area.h))) { + /* Region overlaps with area; find largest overlap */ + int w, h; + + w = MIN(area.x + area.w, rc->view.x + rc->view.w) - + MAX(area.x, rc->view.x); + h = MIN(area.y + area.h, rc->view.y + rc->view.h) - + MAX(area.y, rc->view.y); + if ((long long)w * h > overlap) { + overlap = (long long)w * h; + best = rc; + } + } else if (!overlap) { + /* Lacking overlaps, find region with shortest + * Manhattan distance from area */ + int d = 0; + + if ((area.x + area.w) <= rc->view.x) + d += rc->view.x - (area.x + area.w - 1); + else if ((rc->view.x + rc->view.w) <= area.x) + d += area.x - (rc->view.x + rc->view.w - 1); + if ((area.y + area.h) <= rc->view.y) + d += rc->view.y - (area.y + area.h - 1); + else if ((rc->view.y + rc->view.h) <= area.y) + d += area.y - (rc->view.y + rc->view.h - 1); + + if (distance == -1 || d < distance) { + distance = d; + best = rc; + } } } - return(rc); + return(best); } struct geom screen_area(struct screen_ctx *sc, int x, int y, int flags) { struct region_ctx *rc; - struct geom area = sc->work; + struct geom area, point = { x, y, 0, 0 }; - TAILQ_FOREACH(rc, &sc->regionq, entry) { - if ((x >= rc->area.x) && (x < (rc->area.x + rc->area.w)) && - (y >= rc->area.y) && (y < (rc->area.y + rc->area.h))) { - area = rc->area; - break; - } - } + rc = region_find(sc, point); + area = rc->view; if (flags & CWM_GAP) area = screen_apply_gap(sc, area); return(area); @@ -159,7 +194,9 @@ void screen_update_geometry(struct screen_ctx *sc) { - struct region_ctx *rc; + struct region_ctx_q oldregionq; + struct region_ctx *oldrc, *rc; + struct client_ctx *cc; sc->view.x = 0; sc->view.y = 0; @@ -167,9 +204,10 @@ sc->view.h = DisplayHeight(X_Dpy, sc->which); sc->work = screen_apply_gap(sc, sc->view); + TAILQ_INIT(&oldregionq); while ((rc = TAILQ_FIRST(&sc->regionq)) != NULL) { TAILQ_REMOVE(&sc->regionq, rc, entry); - free(rc); + TAILQ_INSERT_TAIL(&oldregionq, rc, entry); } if (HasRandr) { @@ -189,15 +227,10 @@ rc = xmalloc(sizeof(*rc)); rc->num = i; - rc->area.x = ci->x; - rc->area.y = ci->y; - rc->area.w = ci->width; - rc->area.h = ci->height; rc->view.x = ci->x; rc->view.y = ci->y; rc->view.w = ci->width; rc->view.h = ci->height; - rc->work = screen_apply_gap(sc, rc->view); TAILQ_INSERT_TAIL(&sc->regionq, rc, entry); XRRFreeCrtcInfo(ci); @@ -210,8 +243,18 @@ rc->view.y = 0; rc->view.w = DisplayWidth(X_Dpy, sc->which); rc->view.h = DisplayHeight(X_Dpy, sc->which); - rc->work = screen_apply_gap(sc, rc->view); TAILQ_INSERT_TAIL(&sc->regionq, rc, entry); + } + + while ((oldrc = TAILQ_FIRST(&oldregionq)) != NULL) { + rc = region_find(sc, oldrc->view); + TAILQ_FOREACH(cc, &sc->clientq, entry) { + if (cc->rc != oldrc) + continue; + client_migrate_region(cc, rc); + } + TAILQ_REMOVE(&oldregionq, oldrc, entry); + free(oldrc); } xu_ewmh_net_desktop_geometry(sc); Index: xevents.c =================================================================== RCS file: /cvs/xenocara/app/cwm/xevents.c,v retrieving revision 1.120 diff -u -r1.120 xevents.c --- xevents.c 10 Nov 2015 20:05:33 -0000 1.120 +++ xevents.c 18 Jul 2016 20:40:12 -0000 @@ -139,6 +139,8 @@ if (e->value_mask & CWStackMode) wc.stack_mode = e->detail; + client_keep_visible(cc); + if (cc->geom.x == 0 && cc->geom.w >= sc->view.w) cc->geom.x -= cc->bwidth;