summary refs log tree commit diff
diff options
context:
space:
mode:
authoroga <oga>2008-05-01 18:01:13 +0000
committeroga <oga>2008-05-01 18:01:13 +0000
commitcd0ce468175113c2bd7fdae285a7fe508151fc5b (patch)
treedfbbf298b6b76de0c14ae782186147cda470f248
parent79569a4d5963e27f9e3180b9249ceba32be8ac99 (diff)
downloadcwm-cd0ce468175113c2bd7fdae285a7fe508151fc5b.tar.gz
cwm-cd0ce468175113c2bd7fdae285a7fe508151fc5b.tar.xz
cwm-cd0ce468175113c2bd7fdae285a7fe508151fc5b.zip
Rework the alt-tabbing code to be a lot simpler.
Diff mostly from Edd Barrett, with some minor changes from me.
Unfortunately the issue where apps like gvim and xpdf are stealing
keyrelease events causing the ordering to be messed up, but this is a
lot better. A fix for the aforementioned issue shall be forthcoming,
once a good one's been found.

ok okan@, also tested by todd@
-rw-r--r--calmwm.h2
-rw-r--r--client.c82
-rw-r--r--screen.c3
3 files changed, 30 insertions, 57 deletions
diff --git a/calmwm.h b/calmwm.h
index 71018b5..5fdf989 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -82,8 +82,6 @@ struct screen_ctx {
 
 	struct cycle_entry_q mruq;
 
-	struct client_ctx* cycle_client;
-
 	struct fonthash	 fonthash;
 	XftDraw		*xftdraw;
 	XftColor	 xftcolor;
diff --git a/client.c b/client.c
index 77efde3..89be1fa 100644
--- a/client.c
+++ b/client.c
@@ -21,8 +21,6 @@
 #include "headers.h"
 #include "calmwm.h"
 
-static struct client_ctx *client__cycle(struct client_ctx *cc,
-    struct client_ctx *(*iter)(struct client_ctx *));
 int	_inwindowbounds(struct client_ctx *, int, int);
 
 static char		 emptystring[] = "";
@@ -231,9 +229,6 @@ client_delete(struct client_ctx *cc, int sendevent, int ignorewindow)
 	if (_curcc == cc)
 		_curcc = NULL;
 
-	if (sc->cycle_client == cc)
-		sc->cycle_client = NULL;
-
 	XFree(cc->size);
 
 	while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
@@ -595,50 +590,47 @@ match:
 	return;
 }
 
-/*
- * TODO: seems to have some issues still on the first invocation
- * (globally the first)
- */
-
 struct client_ctx *
 client_cyclenext(int reverse)
 {
-	struct screen_ctx *sc;
-	struct client_ctx *cc;
-	struct client_ctx *(*iter)(struct client_ctx *) =
-	    reverse ? &client_mruprev : &client_mrunext;
-
-	/* TODO: maybe this should just be a CIRCLEQ. */
+	struct client_ctx	*oldcc = client_current(), *newcc;
+	struct screen_ctx	*sc = screen_current();
+	int			 again = 1;
 
-	if ((cc = client_current()) == NULL) {
-		if (TAILQ_EMPTY(&Clientq))
-			return(NULL);
-		cc = TAILQ_FIRST(&Clientq);
-	}
+	/* If no windows then you cant cycle */
+	if (TAILQ_EMPTY(&sc->mruq))
+		return (NULL);
 
-	sc = CCTOSC(cc);
+	if (oldcc == NULL)
+		oldcc = (reverse ? TAILQ_LAST(&sc->mruq, cycle_entry_q) :
+		    TAILQ_FIRST(&sc->mruq));
 
-	/* if altheld; then reset the iterator to the beginning */
-	if (!sc->altpersist || sc->cycle_client == NULL)
-		sc->cycle_client = TAILQ_FIRST(&sc->mruq);
+	newcc = oldcc;
+	while (again) {
+		again = 0;
 
-	if (sc->cycle_client == NULL)
-		return (NULL);
+		newcc = (reverse ? client_mruprev(newcc) :
+		    client_mrunext(newcc));
 
-	/*
-	 * INVARIANT: as long as sc->cycle_client != NULL here, we
-	 * won't exit with sc->cycle_client == NULL
-	 */
+		/* Only cycle visible windows. */
+		if (newcc->flags & CLIENT_HIDDEN)
+			again = 1;
 
-	if ((sc->cycle_client = client__cycle(cc, iter)) == NULL)
-		sc->cycle_client = cc;
+		/* Is oldcc the only non-hidden window? */
+		if (newcc == oldcc) {
+			if (again)
+				return (NULL);	/* No windows visible. */
 
-	/* Do the actual warp. */
-	client_ptrsave(cc);
-	client_ptrwarp(sc->cycle_client);
-	sc->altpersist = 1; /* This is reset when alt is let go... */
+			goto done;
+		}
+	}
+done:
+	/* reset when alt is released. XXX I hate this hack */
+	sc->altpersist = 1;
+	client_ptrsave(oldcc);
+	client_ptrwarp(newcc);
 
-	return (sc->cycle_client);
+	return (newcc);
 }
 
 struct client_ctx *
@@ -661,20 +653,6 @@ client_mruprev(struct client_ctx *cc)
 	    ccc : TAILQ_LAST(&sc->mruq, cycle_entry_q));
 }
 
-static struct client_ctx *
-client__cycle(struct client_ctx *cc,
-    struct client_ctx *(*iter)(struct client_ctx *))
-{
-	struct client_ctx *save = cc;
-
-	do {
-		if (!((cc = (*iter)(cc))->flags & CLIENT_HIDDEN))
-			break;
-	} while (cc != save);
-
-	return (cc != save ? cc : NULL);
-}
-
 void
 client_placecalc(struct client_ctx *cc)
 {
diff --git a/screen.c b/screen.c
index 78344af..02d92b2 100644
--- a/screen.c
+++ b/screen.c
@@ -69,7 +69,4 @@ screen_updatestackingorder(void)
 void
 screen_init(void)
 {
-	struct screen_ctx *sc = screen_current();
-
-	sc->cycle_client = NULL;
 }