Hi,
The below refactors client cycling to be available from a client context
instead of limiting to a screen context; this allows bindings for the 4
related functions (window-{,r}cycle,window-{,r}cycle-ingroup) for either
key or mouse (current only available via key bindings). With the
refactor to client context a lot of the layers added over the years to
make this mimic other WM's can be simplified, I hope.
I'm posting here in case I'm missing an expected behavior, or few.
Feedback welcome.
Index: calmwm.h
===================================================================
RCS file: /home/open/cvs/xenocara/app/cwm/calmwm.h,v
retrieving revision 1.372
diff -u -p -r1.372 calmwm.h
--- calmwm.h 22 Jan 2020 19:58:35 -0000 1.372
+++ calmwm.h 28 Jan 2020 18:26:46 -0000
@@ -395,7 +395,7 @@ __dead void usage(void);
void client_applysizehints(struct client_ctx *);
void client_config(struct client_ctx *);
struct client_ctx *client_current(struct screen_ctx *);
-void client_cycle(struct screen_ctx *, int);
+void client_cycle(struct client_ctx *, int);
void client_remove(struct client_ctx *);
void client_draw_border(struct client_ctx *);
struct client_ctx *client_find(Window);
Index: client.c
===================================================================
RCS file: /home/open/cvs/xenocara/app/cwm/client.c,v
retrieving revision 1.255
diff -u -p -r1.255 client.c
--- client.c 7 Mar 2019 14:28:17 -0000 1.255
+++ client.c 28 Jan 2020 18:26:46 -0000
@@ -31,8 +31,8 @@
#include "calmwm.h"
-static struct client_ctx *client_next(struct client_ctx *);
-static struct client_ctx *client_prev(struct client_ctx *);
+static struct client_ctx *client_next(struct client_ctx *, int);
+static struct client_ctx *client_prev(struct client_ctx *, int);
static void client_placecalc(struct client_ctx *);
static void client_wm_protocols(struct client_ctx *);
static void client_mwm_hints(struct client_ctx *);
@@ -677,72 +677,58 @@ match:
}
void
-client_cycle(struct screen_ctx *sc, int flags)
+client_cycle(struct client_ctx *cc, int flags)
{
- struct client_ctx *newcc, *oldcc, *prevcc;
+ struct screen_ctx *sc = cc->sc;
+ struct client_ctx *newcc = cc;
int again = 1;
- if (TAILQ_EMPTY(&sc->clientq))
- return;
-
- prevcc = TAILQ_FIRST(&sc->clientq);
- oldcc = client_current(sc);
- if (oldcc == NULL)
- oldcc = (flags & CWM_CYCLE_REVERSE) ?
- TAILQ_LAST(&sc->clientq, client_q) :
- TAILQ_FIRST(&sc->clientq);
-
- newcc = oldcc;
while (again) {
again = 0;
+ if (flags & CWM_CYCLE_FORWARD)
+ newcc = client_next(newcc, CLIENT_SKIP_CYCLE);
+ else
+ newcc = client_prev(newcc, CLIENT_SKIP_CYCLE);
- newcc = (flags & CWM_CYCLE_REVERSE) ? client_prev(newcc) :
- client_next(newcc);
-
- /* Only cycle visible and non-ignored windows. */
- if ((newcc->flags & (CLIENT_SKIP_CYCLE)) ||
- ((flags & CWM_CYCLE_INGROUP) &&
- (newcc->gc != oldcc->gc)))
+ if ((flags & CWM_CYCLE_INGROUP) && (newcc->gc != cc->gc))
again = 1;
-
- /* Is oldcc the only non-hidden window? */
- if (newcc == oldcc) {
- if (again)
- return; /* No windows visible. */
- break;
- }
}
+ if (newcc == cc)
+ return;
- /* Reset when cycling mod is released. XXX I hate this hack */
- sc->cycling = 1;
- client_ptrsave(oldcc);
- client_raise(prevcc);
+ sc->cycling = 1; /* XXX Reset when cycling mod is released. XXX */
+ client_ptrsave(cc);
+ client_raise(cc);
client_raise(newcc);
- if (!client_inbound(newcc, newcc->ptr.x, newcc->ptr.y)) {
- newcc->ptr.x = newcc->geom.w / 2;
- newcc->ptr.y = newcc->geom.h / 2;
- }
- client_ptrwarp(newcc);
+ client_ptr_inbound(newcc, 0);
}
static struct client_ctx *
-client_next(struct client_ctx *cc)
+client_next(struct client_ctx *cc, int flags)
{
struct screen_ctx *sc = cc->sc;
- struct client_ctx *newcc;
+ struct client_ctx *nextcc;
- return(((newcc = TAILQ_NEXT(cc, entry)) != NULL) ?
- newcc : TAILQ_FIRST(&sc->clientq));
+ nextcc = TAILQ_NEXT(cc, entry);
+ if (nextcc == NULL)
+ nextcc = TAILQ_FIRST(&sc->clientq);
+ if (flags && (nextcc->flags & flags))
+ nextcc = client_next(nextcc, flags);
+ return nextcc;
}
static struct client_ctx *
-client_prev(struct client_ctx *cc)
+client_prev(struct client_ctx *cc, int flags)
{
struct screen_ctx *sc = cc->sc;
- struct client_ctx *newcc;
+ struct client_ctx *prevcc;
- return(((newcc = TAILQ_PREV(cc, client_q, entry)) != NULL) ?
- newcc : TAILQ_LAST(&sc->clientq, client_q));
+ prevcc = TAILQ_PREV(cc, client_q, entry);
+ if (prevcc == NULL)
+ prevcc = TAILQ_LAST(&sc->clientq, client_q);
+ if (flags && (prevcc->flags & flags))
+ prevcc = client_prev(prevcc, flags);
+ return prevcc;
}
static void
Index: conf.c
===================================================================
RCS file: /home/open/cvs/xenocara/app/cwm/conf.c,v
retrieving revision 1.249
diff -u -p -r1.249 conf.c
--- conf.c 7 Mar 2019 12:54:21 -0000 1.249
+++ conf.c 28 Jan 2020 18:26:46 -0000
@@ -130,11 +130,11 @@ static const struct {
{ FUNC_CC(window-resize-left-big, client_resize, (CWM_LEFT_BIG)) },
{ FUNC_CC(window-menu-label, client_menu_label, 0) },
- { FUNC_SC(window-cycle, client_cycle, (CWM_CYCLE_FORWARD)) },
- { FUNC_SC(window-rcycle, client_cycle, (CWM_CYCLE_REVERSE)) },
- { FUNC_SC(window-cycle-ingroup, client_cycle,
+ { FUNC_CC(window-cycle, client_cycle, (CWM_CYCLE_FORWARD)) },
+ { FUNC_CC(window-rcycle, client_cycle, (CWM_CYCLE_REVERSE)) },
+ { FUNC_CC(window-cycle-ingroup, client_cycle,
(CWM_CYCLE_FORWARD | CWM_CYCLE_INGROUP)) },
- { FUNC_SC(window-rcycle-ingroup, client_cycle,
+ { FUNC_CC(window-rcycle-ingroup, client_cycle,
(CWM_CYCLE_REVERSE | CWM_CYCLE_INGROUP)) },
{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
Index: kbfunc.c
===================================================================
RCS file: /home/open/cvs/xenocara/app/cwm/kbfunc.c,v
retrieving revision 1.167
diff -u -p -r1.167 kbfunc.c
--- kbfunc.c 21 Jan 2020 15:50:03 -0000 1.167
+++ kbfunc.c 28 Jan 2020 18:26:46 -0000
@@ -401,14 +401,15 @@ kbfunc_client_vtile(void *ctx, struct ca
void
kbfunc_client_cycle(void *ctx, struct cargs *cargs)
{
- struct screen_ctx *sc = ctx;
+ struct client_ctx *cc = ctx;
+ struct screen_ctx *sc = cc->sc;
/* For X apps that ignore/steal events. */
if (cargs->xev == CWM_XEV_KEY)
XGrabKeyboard(X_Dpy, sc->rootwin, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
- client_cycle(sc, cargs->flag);
+ client_cycle(cc, cargs->flag);
}
void