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:
okan
2015-08-28 12:07:28 +00:00
11 changed files with 254 additions and 184 deletions

150
group.c
View File

@ -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);
}