A long time ago sent Dimitris Papastamos a patch to misc which let one send X clients to corners.[0]
I think it is useful so thank you Dimitris! With some minor editing it still builds on current. I have no use of window-move-{up,down,right,left}{,-big} but X client corner warping is done on a regular basis. At the time it did not receive the attention it (IMO) deserves. Maybe was it because "feature" was written on the first line? ;) I know featuritis is considered a disease around here and I'm happy it is but here is an updated version anyway. This version lacks the keybindings from the initial patch, it also lacks for now a change in the man pages. I use it with the following in ~/.cwmrc: bind-key 4S-Left window-movebottomleft bind-key 4S-Right window-movebottomright bind-key 4S-XF86Back window-movetopleft bind-key 4S-XF86Forward window-movetopright I know these are not standards keys found on every keyboard, but Thinkpads are not exotic beasts in this land so it might be an helpful start to some of you and every declinaison of h j k l was already in use in the default config. OK? [0] https://marc.info/?l=openbsd-misc&m=140344759017419&w=2 Index: calmwm.h =================================================================== RCS file: /cvs/xenocara/app/cwm/calmwm.h,v retrieving revision 1.341 diff -u -p -r1.341 calmwm.h --- calmwm.h 14 Jul 2017 17:23:38 -0000 1.341 +++ calmwm.h 22 Nov 2017 19:21:47 -0000 @@ -54,6 +54,10 @@ #define CWM_DOWN 0x0002 #define CWM_LEFT 0x0004 #define CWM_RIGHT 0x0008 +#define CWM_TOP_LEFT 0x0100 +#define CWM_BOTTOM_LEFT 0x0200 +#define CWM_TOP_RIGHT 0x0400 +#define CWM_BOTTOM_RIGHT 0x0800 #define CWM_BIGAMOUNT 0x0010 #define DIRECTIONMASK (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT) @@ -476,6 +480,7 @@ void kbfunc_client_toggle_hmaximize(v void kbfunc_client_toggle_vmaximize(void *, struct cargs *); void kbfunc_client_htile(void *, struct cargs *); void kbfunc_client_vtile(void *, struct cargs *); +void kbfunc_client_move_edge(void *, struct cargs *); void kbfunc_client_cycle(void *, struct cargs *); void kbfunc_client_toggle_group(void *, struct cargs *); void kbfunc_client_movetogroup(void *, struct cargs *); Index: conf.c =================================================================== RCS file: /cvs/xenocara/app/cwm/conf.c,v retrieving revision 1.233 diff -u -p -r1.233 conf.c --- conf.c 14 Jul 2017 17:23:38 -0000 1.233 +++ conf.c 22 Nov 2017 19:21:48 -0000 @@ -67,6 +67,14 @@ static const struct { { "window-delete", kbfunc_client_delete, CWM_CONTEXT_CC, 0 }, { "window-htile", kbfunc_client_htile, CWM_CONTEXT_CC, 0 }, { "window-vtile", kbfunc_client_vtile, CWM_CONTEXT_CC, 0 }, + { "window-movetopleft", kbfunc_client_move_edge, CWM_CONTEXT_CC, + (CWM_TOP_LEFT) }, + { "window-movebottomleft", kbfunc_client_move_edge, CWM_CONTEXT_CC, + (CWM_BOTTOM_LEFT) }, + { "window-movetopright", kbfunc_client_move_edge, CWM_CONTEXT_CC, + (CWM_TOP_RIGHT) }, + { "window-movebottomright", kbfunc_client_move_edge, CWM_CONTEXT_CC, + (CWM_BOTTOM_RIGHT) }, { "window-stick", kbfunc_client_toggle_sticky, CWM_CONTEXT_CC, 0 }, { "window-fullscreen", kbfunc_client_toggle_fullscreen, CWM_CONTEXT_CC, 0 }, { "window-maximize", kbfunc_client_toggle_maximize, CWM_CONTEXT_CC, 0 }, @@ -666,6 +674,51 @@ conf_grab_mouse(Window win) BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); } + } +} + +void +kbfunc_client_move_edge(void *ctx, struct cargs *cargs) +{ + struct client_ctx *cc = ctx; + struct screen_ctx *sc = cc->sc; + struct geom xine; + int flags; + + /* + * 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_area(sc, + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2, CWM_GAP); + + flags = cargs->flag; + + switch (flags) { + case CWM_TOP_LEFT: + cc->geom.x = xine.x; + cc->geom.y = xine.y; + client_move(cc); + break; + case CWM_BOTTOM_LEFT: + cc->geom.x = xine.x; + cc->geom.y = xine.y + xine.h - cc->geom.h - cc->bwidth * 2; + client_move(cc); + break; + case CWM_TOP_RIGHT: + cc->geom.x = xine.x + xine.w - cc->geom.w - cc->bwidth * 2; + cc->geom.y = xine.y; + client_move(cc); + break; + case CWM_BOTTOM_RIGHT: + cc->geom.x = xine.x + xine.w - cc->geom.w - cc->bwidth * 2; + cc->geom.y = xine.y + xine.h - cc->geom.h - cc->bwidth * 2; + client_move(cc); + break; + default: + warnx("invalid flags passed to kbfunc_client_move_edge"); } }