mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
cvsimport
* refs/heads/master: (21 commits) Lost fix from r1.112; add comment. Mechanical change: group->gc Add consistent checks against NULL. Move client cycle grab/ungrab into a more relevant place; while here, update comments about why we need to grab/ungrab the keyboard. Re-add lost chunk in group_cycle from r1.113. Further simplify _NET_WM_DESKTOP handling using new group_assign(). oops; remove left over debug print Allowing sending a valid 'nogroup' (0) group_ctx to group_assign() (since we init all groups), though assigning the client's group to NULL for 'sticky'; use this simplification in a few places (others to follow). Split out sticky mode checks and the restoring of a client's group and _NET_WM_DESKTOP from the config-based auto-grouping; no (intentional) behavior changes. Needed for further work in cleaning up this area. Implement _NET_CLIENT_LIST_STACKING (from Thomas Admin), but bottom-to-top order, as per spec (notified Thomas as well). Don't allow freeze operations on fullscreen (consistent with what fullscreen does). Sort _NET_WM_STATE Atoms like the spec. Move CLIENT_STICKY logic from client hide/unhide to group hide/unhide; rationale being that clients should be able to hide/unhide independently of group switching. Add Xkb modifier to ignore mask; from Alexander Polakov. Fix whitespace. Add client freeze extension to _NET_WM_STATE Atom, allowing flag to persist. As usual with new Atoms, requires X restart. _NET_WM_STATE_STICKY implies only sticky at the group/desktop level, not position and size; based on discussion with a few. Instead of special casing the 'term' and 'lock' commands, go back to keeping them hidden; showing them has apparently caused confusion/angst. Leave command list order from .cwmrc alone; remove sort. Bring group and client cycle closer together. ...
This commit is contained in:
150
group.c
150
group.c
@ -32,7 +32,8 @@
|
||||
|
||||
#include "calmwm.h"
|
||||
|
||||
static void group_assign(struct group_ctx *, struct client_ctx *);
|
||||
static struct group_ctx *group_next(struct group_ctx *);
|
||||
static struct group_ctx *group_prev(struct group_ctx *);
|
||||
static void group_restack(struct group_ctx *);
|
||||
static void group_setactive(struct group_ctx *);
|
||||
|
||||
@ -41,15 +42,18 @@ const char *num_to_name[] = {
|
||||
"seven", "eight", "nine"
|
||||
};
|
||||
|
||||
static void
|
||||
void
|
||||
group_assign(struct group_ctx *gc, struct client_ctx *cc)
|
||||
{
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clientq, cc, group_entry);
|
||||
if (cc->gc != NULL)
|
||||
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
|
||||
|
||||
cc->group = gc;
|
||||
if ((gc != NULL) && (gc->num == 0))
|
||||
gc = NULL;
|
||||
|
||||
if (cc->group != NULL)
|
||||
cc->gc = gc;
|
||||
|
||||
if (cc->gc != NULL)
|
||||
TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry);
|
||||
|
||||
xu_ewmh_net_wm_desktop(cc);
|
||||
@ -62,8 +66,10 @@ group_hide(struct group_ctx *gc)
|
||||
|
||||
screen_updatestackingorder(gc->sc);
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
|
||||
client_hide(cc);
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
||||
if (!(cc->flags & CLIENT_STICKY))
|
||||
client_hide(cc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -71,8 +77,10 @@ group_show(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
|
||||
client_unhide(cc);
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
||||
if (!(cc->flags & CLIENT_STICKY))
|
||||
client_unhide(cc);
|
||||
}
|
||||
|
||||
group_restack(gc);
|
||||
group_setactive(gc);
|
||||
@ -154,7 +162,7 @@ group_movetogroup(struct client_ctx *cc, int idx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc->group == gc)
|
||||
if (cc->gc == gc)
|
||||
return;
|
||||
if (group_holds_only_hidden(gc))
|
||||
client_hide(cc);
|
||||
@ -167,7 +175,7 @@ group_toggle_membership_enter(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct group_ctx *gc = sc->group_active;
|
||||
|
||||
if (gc == cc->group) {
|
||||
if (gc == cc->gc) {
|
||||
group_assign(NULL, cc);
|
||||
cc->flags |= CLIENT_UNGROUP;
|
||||
} else {
|
||||
@ -255,36 +263,31 @@ group_only(struct screen_ctx *sc, int idx)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cycle through active groups. If none exist, then just stay put.
|
||||
*/
|
||||
void
|
||||
group_cycle(struct screen_ctx *sc, int flags)
|
||||
{
|
||||
struct group_ctx *gc, *showgroup = NULL;
|
||||
struct group_ctx *newgc, *oldgc, *showgroup = NULL;
|
||||
|
||||
if (((gc = sc->group_active)) == NULL)
|
||||
errx(1, "group_cycle: no active group");
|
||||
oldgc = sc->group_active;
|
||||
|
||||
newgc = oldgc;
|
||||
for (;;) {
|
||||
gc = (flags & CWM_RCYCLE) ? TAILQ_PREV(gc, group_ctx_q,
|
||||
entry) : TAILQ_NEXT(gc, entry);
|
||||
if (gc == NULL)
|
||||
gc = (flags & CWM_RCYCLE) ? TAILQ_LAST(&sc->groupq,
|
||||
group_ctx_q) : TAILQ_FIRST(&sc->groupq);
|
||||
if (gc == sc->group_active)
|
||||
newgc = (flags & CWM_RCYCLE) ? group_prev(newgc) :
|
||||
group_next(newgc);
|
||||
|
||||
if (newgc == oldgc)
|
||||
break;
|
||||
|
||||
if (!group_holds_only_sticky(gc) && showgroup == NULL)
|
||||
showgroup = gc;
|
||||
else if (!group_holds_only_hidden(gc))
|
||||
group_hide(gc);
|
||||
if (!group_holds_only_sticky(newgc) && showgroup == NULL)
|
||||
showgroup = newgc;
|
||||
else if (!group_holds_only_hidden(newgc))
|
||||
group_hide(newgc);
|
||||
}
|
||||
|
||||
if (showgroup == NULL)
|
||||
return;
|
||||
|
||||
group_hide(sc->group_active);
|
||||
group_hide(oldgc);
|
||||
|
||||
if (group_holds_only_hidden(showgroup))
|
||||
group_show(showgroup);
|
||||
@ -292,6 +295,26 @@ group_cycle(struct screen_ctx *sc, int flags)
|
||||
group_setactive(showgroup);
|
||||
}
|
||||
|
||||
static struct group_ctx *
|
||||
group_next(struct group_ctx *gc)
|
||||
{
|
||||
struct screen_ctx *sc = gc->sc;
|
||||
struct group_ctx *newgc;
|
||||
|
||||
return(((newgc = TAILQ_NEXT(gc, entry)) != NULL) ?
|
||||
newgc : TAILQ_FIRST(&sc->groupq));
|
||||
}
|
||||
|
||||
static struct group_ctx *
|
||||
group_prev(struct group_ctx *gc)
|
||||
{
|
||||
struct screen_ctx *sc = gc->sc;
|
||||
struct group_ctx *newgc;
|
||||
|
||||
return(((newgc = TAILQ_PREV(gc, group_ctx_q, entry)) != NULL) ?
|
||||
newgc : TAILQ_LAST(&sc->groupq, group_ctx_q));
|
||||
}
|
||||
|
||||
void
|
||||
group_alltoggle(struct screen_ctx *sc)
|
||||
{
|
||||
@ -306,51 +329,58 @@ group_alltoggle(struct screen_ctx *sc)
|
||||
sc->hideall = !sc->hideall;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
group_restore(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct group_ctx *gc;
|
||||
int num;
|
||||
long *grpnum;
|
||||
|
||||
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L,
|
||||
(unsigned char **)&grpnum) <= 0)
|
||||
return(0);
|
||||
|
||||
num = (*grpnum == -1) ? 0 : *grpnum;
|
||||
num = MIN(num, (CALMWM_NGROUPS - 1));
|
||||
XFree(grpnum);
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
group_autogroup(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct autogroupwin *aw;
|
||||
struct group_ctx *gc;
|
||||
int num = -2, both_match = 0;
|
||||
long *grpnum;
|
||||
int num = -1, both_match = 0;
|
||||
|
||||
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
|
||||
return;
|
||||
return(0);
|
||||
|
||||
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP],
|
||||
XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) {
|
||||
num = *grpnum;
|
||||
if (num > CALMWM_NGROUPS || num < -1)
|
||||
num = CALMWM_NGROUPS - 1;
|
||||
XFree(grpnum);
|
||||
} else {
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
if (strcmp(aw->class, cc->ch.res_class) == 0) {
|
||||
if ((aw->name != NULL) &&
|
||||
(strcmp(aw->name, cc->ch.res_name) == 0)) {
|
||||
num = aw->num;
|
||||
both_match = 1;
|
||||
} else if (aw->name == NULL && !both_match)
|
||||
num = aw->num;
|
||||
}
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
if (strcmp(aw->class, cc->ch.res_class) == 0) {
|
||||
if ((aw->name != NULL) &&
|
||||
(strcmp(aw->name, cc->ch.res_name) == 0)) {
|
||||
num = aw->num;
|
||||
both_match = 1;
|
||||
} else if (aw->name == NULL && !both_match)
|
||||
num = aw->num;
|
||||
}
|
||||
}
|
||||
|
||||
if ((num == -1) || (num == 0)) {
|
||||
group_assign(NULL, cc);
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Conf.flags & CONF_STICKY_GROUPS)
|
||||
group_assign(sc->group_active, cc);
|
||||
else
|
||||
group_assign(NULL, cc);
|
||||
return(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user