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

Reply via email to