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@
This commit is contained in:
oga 2008-05-01 18:01:13 +00:00
parent 79569a4d59
commit cd0ce46817
3 changed files with 32 additions and 59 deletions

View File

@ -82,8 +82,6 @@ struct screen_ctx {
struct cycle_entry_q mruq;
struct client_ctx* cycle_client;
struct fonthash fonthash;
XftDraw *xftdraw;
XftColor xftcolor;

View File

@ -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;
struct client_ctx *oldcc = client_current(), *newcc;
struct screen_ctx *sc = screen_current();
int again = 1;
/* TODO: maybe this should just be a CIRCLEQ. */
if ((cc = client_current()) == NULL) {
if (TAILQ_EMPTY(&Clientq))
return(NULL);
cc = TAILQ_FIRST(&Clientq);
}
sc = CCTOSC(cc);
/* if altheld; then reset the iterator to the beginning */
if (!sc->altpersist || sc->cycle_client == NULL)
sc->cycle_client = TAILQ_FIRST(&sc->mruq);
if (sc->cycle_client == NULL)
/* If no windows then you cant cycle */
if (TAILQ_EMPTY(&sc->mruq))
return (NULL);
/*
* INVARIANT: as long as sc->cycle_client != NULL here, we
* won't exit with sc->cycle_client == NULL
*/
if (oldcc == NULL)
oldcc = (reverse ? TAILQ_LAST(&sc->mruq, cycle_entry_q) :
TAILQ_FIRST(&sc->mruq));
if ((sc->cycle_client = client__cycle(cc, iter)) == NULL)
sc->cycle_client = cc;
newcc = oldcc;
while (again) {
again = 0;
/* Do the actual warp. */
client_ptrsave(cc);
client_ptrwarp(sc->cycle_client);
sc->altpersist = 1; /* This is reset when alt is let go... */
newcc = (reverse ? client_mruprev(newcc) :
client_mrunext(newcc));
return (sc->cycle_client);
/* Only cycle visible windows. */
if (newcc->flags & CLIENT_HIDDEN)
again = 1;
/* Is oldcc the only non-hidden window? */
if (newcc == oldcc) {
if (again)
return (NULL); /* No windows visible. */
goto done;
}
}
done:
/* reset when alt is released. XXX I hate this hack */
sc->altpersist = 1;
client_ptrsave(oldcc);
client_ptrwarp(newcc);
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)
{

View File

@ -69,7 +69,4 @@ screen_updatestackingorder(void)
void
screen_init(void)
{
struct screen_ctx *sc = screen_current();
sc->cycle_client = NULL;
}