summary refs log tree commit diff
path: root/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'group.c')
-rw-r--r--group.c106
1 files changed, 65 insertions, 41 deletions
diff --git a/group.c b/group.c
index cdc5912..1cae681 100644
--- a/group.c
+++ b/group.c
@@ -33,7 +33,7 @@
 #include "calmwm.h"
 
 static void		 group_assign(struct group_ctx *, struct client_ctx *);
-static void		 group_restack(struct screen_ctx *, struct group_ctx *);
+static void		 group_restack(struct group_ctx *);
 static void		 group_setactive(struct screen_ctx *, long);
 
 const char *num_to_name[] = {
@@ -45,55 +45,55 @@ static void
 group_assign(struct group_ctx *gc, struct client_ctx *cc)
 {
 	if (cc->group != NULL)
-		TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
+		TAILQ_REMOVE(&cc->group->clientq, cc, group_entry);
 
 	cc->group = gc;
 
 	if (cc->group != NULL)
-		TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
+		TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry);
 
 	xu_ewmh_net_wm_desktop(cc);
 }
 
 void
-group_hide(struct screen_ctx *sc, struct group_ctx *gc)
+group_hide(struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 
-	screen_updatestackingorder(sc);
+	screen_updatestackingorder(gc->sc);
 
-	TAILQ_FOREACH(cc, &gc->clients, group_entry)
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry)
 		client_hide(cc);
 }
 
 void
-group_show(struct screen_ctx *sc, struct group_ctx *gc)
+group_show(struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 
-	TAILQ_FOREACH(cc, &gc->clients, group_entry)
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry)
 		client_unhide(cc);
 
-	group_restack(sc, gc);
-	group_setactive(sc, gc->num);
+	group_restack(gc);
+	group_setactive(gc->sc, gc->num);
 }
 
 static void
-group_restack(struct screen_ctx *sc, struct group_ctx *gc)
+group_restack(struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 	Window			*winlist;
 	int			 i, lastempty = -1;
 	int			 nwins = 0, highstack = 0;
 
-	TAILQ_FOREACH(cc, &gc->clients, group_entry) {
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
 		if (cc->stackingorder > highstack)
 			highstack = cc->stackingorder;
 	}
 	winlist = xcalloc((highstack + 1), sizeof(*winlist));
 
 	/* Invert the stacking order for XRestackWindows(). */
-	TAILQ_FOREACH(cc, &gc->clients, group_entry) {
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
 		winlist[highstack - cc->stackingorder] = cc->win;
 		nwins++;
 	}
@@ -116,16 +116,19 @@ group_restack(struct screen_ctx *sc, struct group_ctx *gc)
 void
 group_init(struct screen_ctx *sc)
 {
-	int	 i;
+	struct group_ctx	*gc;
+	int			 i;
 
 	TAILQ_INIT(&sc->groupq);
 	sc->group_hideall = 0;
 
 	for (i = 0; i < CALMWM_NGROUPS; i++) {
-		TAILQ_INIT(&sc->groups[i].clients);
-		sc->groups[i].name = xstrdup(num_to_name[i]);
-		sc->groups[i].num = i;
-		TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
+		gc = xcalloc(1, sizeof(*gc));
+		gc->sc = sc;
+		TAILQ_INIT(&gc->clientq);
+		gc->name = xstrdup(num_to_name[i]);
+		gc->num = i;
+		TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
 	}
 
 	xu_ewmh_net_desktop_names(sc);
@@ -140,7 +143,13 @@ group_init(struct screen_ctx *sc)
 static void
 group_setactive(struct screen_ctx *sc, long idx)
 {
-	sc->group_active = &sc->groups[idx];
+	struct group_ctx	*gc;
+
+	TAILQ_FOREACH(gc, &sc->groupq, entry) {
+		if (gc->num == idx)
+			break;
+	}
+	sc->group_active = gc;
 
 	xu_ewmh_net_current_desktop(sc, idx);
 }
@@ -154,11 +163,14 @@ group_movetogroup(struct client_ctx *cc, int idx)
 	if (idx < 0 || idx >= CALMWM_NGROUPS)
 		errx(1, "group_movetogroup: index out of range (%d)", idx);
 
-	gc = &sc->groups[idx];
+	TAILQ_FOREACH(gc, &sc->groupq, entry) {
+		if (gc->num == idx)
+			break;
+	}
 
 	if (cc->group == gc)
 		return;
-	if (group_hidden_state(gc))
+	if (group_holds_only_hidden(gc))
 		client_hide(cc);
 	group_assign(gc, cc);
 }
@@ -190,16 +202,25 @@ group_sticky_toggle_exit(struct client_ctx *cc)
 	client_draw_border(cc);
 }
 
-/*
- * If all clients in a group are hidden, then the group state is hidden.
- */
 int
-group_hidden_state(struct group_ctx *gc)
+group_holds_only_sticky(struct group_ctx *gc)
+{
+	struct client_ctx	*cc;
+
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
+		if (!(cc->flags & CLIENT_STICKY))
+			return(0);
+	}
+	return(1);
+}
+
+int
+group_holds_only_hidden(struct group_ctx *gc)
 {
 	struct client_ctx	*cc;
 	int			 hidden = 0, same = 0;
 
-	TAILQ_FOREACH(cc, &gc->clients, group_entry) {
+	TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
 		if (cc->flags & CLIENT_STICKY)
 			continue;
 		if (hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0))
@@ -220,14 +241,17 @@ group_hidetoggle(struct screen_ctx *sc, int idx)
 	if (idx < 0 || idx >= CALMWM_NGROUPS)
 		errx(1, "group_hidetoggle: index out of range (%d)", idx);
 
-	gc = &sc->groups[idx];
+	TAILQ_FOREACH(gc, &sc->groupq, entry) {
+		if (gc->num == idx)
+			break;
+	}
 
-	if (group_hidden_state(gc))
-		group_show(sc, gc);
+	if (group_holds_only_hidden(gc))
+		group_show(gc);
 	else {
-		group_hide(sc, gc);
+		group_hide(gc);
 		/* make clients stick to empty group */
-		if (TAILQ_EMPTY(&gc->clients))
+		if (TAILQ_EMPTY(&gc->clientq))
 			group_setactive(sc, idx);
 	}
 }
@@ -242,9 +266,9 @@ group_only(struct screen_ctx *sc, int idx)
 
 	TAILQ_FOREACH(gc, &sc->groupq, entry) {
 		if (gc->num == idx)
-			group_show(sc, gc);
+			group_show(gc);
 		else
-			group_hide(sc, gc);
+			group_hide(gc);
 	}
 }
 
@@ -268,19 +292,19 @@ group_cycle(struct screen_ctx *sc, int flags)
 		if (gc == sc->group_active)
 			break;
 
-		if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL)
+		if (!group_holds_only_sticky(gc) && showgroup == NULL)
 			showgroup = gc;
-		else if (!group_hidden_state(gc))
-			group_hide(sc, gc);
+		else if (!group_holds_only_hidden(gc))
+			group_hide(gc);
 	}
 
 	if (showgroup == NULL)
 		return;
 
-	group_hide(sc, sc->group_active);
+	group_hide(sc->group_active);
 
-	if (group_hidden_state(showgroup))
-		group_show(sc, showgroup);
+	if (group_holds_only_hidden(showgroup))
+		group_show(showgroup);
 	else
 		group_setactive(sc, showgroup->num);
 }
@@ -292,9 +316,9 @@ group_alltoggle(struct screen_ctx *sc)
 
 	TAILQ_FOREACH(gc, &sc->groupq, entry) {
 		if (sc->group_hideall)
-			group_show(sc, gc);
+			group_show(gc);
 		else
-			group_hide(sc, gc);
+			group_hide(gc);
 	}
 	sc->group_hideall = !sc->group_hideall;
 }