aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroga2009-12-11 17:51:42 +0000
committeroga2009-12-11 17:51:42 +0000
commitb5e3cdbe512264c453033c02a088bbd72c50bf32 (patch)
tree822f8d789a51066a07ff30d05feb5188352f91a3
parent640b7c9876ce301eafc3651136e16c191f26dd4b (diff)
downloadcwm-b5e3cdbe512264c453033c02a088bbd72c50bf32.tar.gz
Implement _NET_DESKTOP_NAMES, this one was a bit tricky since thespec
says that a pager can change the property at any time (most need a clientmessage). So deal with property updates. Needed to shuffle some of the other code around since we can't just use shortcut_to_name[] everywhere now. ok okan@
-rw-r--r--calmwm.h19
-rw-r--r--conf.c3
-rw-r--r--group.c127
-rw-r--r--parse.y20
-rw-r--r--xevents.c13
-rw-r--r--xutil.c3
6 files changed, 145 insertions, 40 deletions
diff --git a/calmwm.h b/calmwm.h
index 776cb37..38b0065 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: calmwm.h,v 1.106 2009/12/10 23:21:26 oga Exp $
+ * $Id: calmwm.h,v 1.107 2009/12/11 17:51:42 oga Exp $
*/
#ifndef _CALMWM_H_
@@ -66,7 +66,6 @@ TAILQ_HEAD(client_ctx_q, client_ctx);
struct group_ctx {
TAILQ_ENTRY(group_ctx) entry;
struct client_ctx_q clients;
- const char *name;
int shortcut;
int hidden;
int nhidden;
@@ -101,6 +100,8 @@ struct screen_ctx {
struct group_ctx groups[CALMWM_NGROUPS];
int group_hideall;
struct group_ctx_q groupq;
+ char **group_names;
+ int group_nonames;
};
TAILQ_HEAD(screen_ctx_q, screen_ctx);
@@ -178,11 +179,10 @@ extern const char *shortcut_to_name[];
/* Autogroups */
struct autogroupwin {
- TAILQ_ENTRY(autogroupwin) entry;
-
- char *class;
- char *name;
- char *group;
+ TAILQ_ENTRY(autogroupwin) entry;
+ char *class;
+ char *name;
+ int num;
};
TAILQ_HEAD(autogroupwin_q, autogroupwin);
@@ -475,6 +475,8 @@ void search_match_exec(struct menu_q *, struct menu_q *,
char *);
void group_init(struct screen_ctx *);
+void group_make_autogroup(struct conf *, char *, int);
+void group_update_names(struct screen_ctx *);
void group_hidetoggle(struct screen_ctx *, int);
void group_only(struct screen_ctx *, int);
void group_cycle(struct screen_ctx *, int);
@@ -538,7 +540,8 @@ extern struct conf Conf;
#define _NET_DESKTOP_GEOMETRY cwm_atoms[15]
#define _NET_VIRTUAL_ROOTS cwm_atoms[16]
#define _NET_SHOWING_DESKTOP cwm_atoms[17]
-#define CWM_NO_ATOMS 18
+#define _NET_DESKTOP_NAMES cwm_atoms[18]
+#define CWM_NO_ATOMS 19
#define CWM_NETWM_START 7
extern Atom cwm_atoms[CWM_NO_ATOMS];
diff --git a/conf.c b/conf.c
index b07a3de..cc3a03e 100644
--- a/conf.c
+++ b/conf.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: conf.c,v 1.72 2009/12/08 16:52:17 okan Exp $
+ * $Id: conf.c,v 1.73 2009/12/11 17:51:42 oga Exp $
*/
#include "headers.h"
@@ -225,7 +225,6 @@ conf_clear(struct conf *c)
xfree(ag->class);
if (ag->name)
xfree(ag->name);
- xfree(ag->group);
xfree(ag);
}
diff --git a/group.c b/group.c
index 021e485..af7226a 100644
--- a/group.c
+++ b/group.c
@@ -16,7 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: group.c,v 1.36 2009/12/10 23:21:26 oga Exp $
+ * $Id: group.c,v 1.37 2009/12/11 17:51:42 oga Exp $
*/
#include "headers.h"
@@ -28,6 +28,7 @@ static void group_hide(struct screen_ctx *, struct group_ctx *);
static void group_show(struct screen_ctx *, struct group_ctx *);
static void group_fix_hidden_state(struct group_ctx *);
static void group_setactive(struct screen_ctx *, int);
+static void group_set_names(struct screen_ctx *);
const char *shortcut_to_name[] = {
"nogroup", "one", "two", "three", "four", "five", "six",
@@ -47,7 +48,8 @@ group_add(struct group_ctx *gc, struct client_ctx *cc)
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING,
- 8, PropModeReplace, gc->name, strlen(gc->name));
+ 8, PropModeReplace, shortcut_to_name[gc->shortcut],
+ strlen(shortcut_to_name[gc->shortcut]));
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
cc->group = gc;
@@ -131,12 +133,15 @@ group_init(struct screen_ctx *sc)
TAILQ_INIT(&sc->groupq);
sc->group_hideall = 0;
+ /* see if any group names have already been set and update the property
+ * with ours if they'll have changed.
+ */
+ group_update_names(sc);
for (i = 0; i < CALMWM_NGROUPS; i++) {
TAILQ_INIT(&sc->groups[i].clients);
sc->groups[i].hidden = 0;
sc->groups[i].shortcut = i + 1;
- sc->groups[i].name = shortcut_to_name[sc->groups[i].shortcut];
TAILQ_INSERT_TAIL(&sc->groupq, &sc->groups[i], entry);
}
@@ -160,6 +165,28 @@ group_init(struct screen_ctx *sc)
group_setactive(sc, 0);
}
+void
+group_make_autogroup(struct conf *conf, char *class, int no)
+{
+ struct autogroupwin *aw;
+ char *p;
+
+ aw = xcalloc(1, sizeof(*aw));
+
+ if ((p = strchr(class, ',')) == NULL) {
+ aw->name = NULL;
+ aw->class = xstrdup(class);
+ } else {
+ *(p++) = '\0';
+ aw->name = xstrdup(class);
+ aw->class = xstrdup(p);
+ }
+ aw->num = no;
+
+ TAILQ_INSERT_TAIL(&conf->autogroupq, aw, entry);
+
+}
+
static void
group_setactive(struct screen_ctx *sc, int idx)
{
@@ -334,10 +361,10 @@ group_menu(XButtonEvent *e)
mi = xcalloc(1, sizeof(*mi));
if (gc->hidden)
snprintf(mi->text, sizeof(mi->text), "%d: [%s]",
- gc->shortcut, shortcut_to_name[gc->shortcut]);
+ gc->shortcut, sc->group_names[i]);
else
snprintf(mi->text, sizeof(mi->text), "%d: %s",
- gc->shortcut, shortcut_to_name[gc->shortcut]);
+ gc->shortcut, sc->group_names[i]);
mi->ctx = gc;
TAILQ_INSERT_TAIL(&menuq, mi, entry);
}
@@ -382,31 +409,36 @@ group_autogroup(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc;
struct autogroupwin *aw;
struct group_ctx *gc;
+ int no = -1, i;
unsigned char *grpstr = NULL;
- char group[CALMWM_MAXNAMELEN];
if (cc->app_class == NULL || cc->app_name == NULL)
return;
if (xu_getprop(cc, _CWM_GRP, XA_STRING,
(CALMWM_MAXNAMELEN - 1)/sizeof(long), &grpstr) > 0) {
- strlcpy(group, grpstr, sizeof(group));
+ for (i = 0; i < sizeof(shortcut_to_name) /
+ sizeof(shortcut_to_name[0]); i++) {
+ if (strcmp(shortcut_to_name[i], grpstr) == 0)
+ no = i;
+ }
XFree(grpstr);
} else {
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
if (strcmp(aw->class, cc->app_class) == 0 &&
(aw->name == NULL ||
strcmp(aw->name, cc->app_name) == 0)) {
- strlcpy(group, aw->group, sizeof(group));
+ no = aw->num;
break;
}
}
}
- if (strncmp("nogroup", group, 7) == 0)
+ /* no group please */
+ if (no == 0)
return;
TAILQ_FOREACH(gc, &sc->groupq, entry) {
- if (strcmp(shortcut_to_name[gc->shortcut], group) == 0) {
+ if (gc->shortcut == no) {
group_add(gc, cc);
return;
}
@@ -416,3 +448,78 @@ group_autogroup(struct client_ctx *cc)
group_add(sc->group_active, cc);
}
+
+void
+group_update_names(struct screen_ctx *sc)
+{
+ char **strings, *p;
+ unsigned char *prop_ret;
+ Atom type_ret;
+ int format_ret, i = 0, nstrings = 0, n, setnames = 0;
+ unsigned long bytes_after, num_ret;
+
+ if (XGetWindowProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES, 0,
+ 0xffffff, False, UTF8_STRING, &type_ret, &format_ret,
+ &num_ret, &bytes_after, &prop_ret) == Success &&
+ prop_ret != NULL && format_ret == 8) {
+ /* failure, just set defaults */
+ prop_ret[num_ret - 1] = '\0'; /* paranoia */
+ while (i < num_ret) {
+ if (prop_ret[i++] == '\0')
+ nstrings++;
+ }
+ }
+
+ strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
+ nstrings) * sizeof(*strings));
+
+ i = n = 0;
+ p = prop_ret;
+ while (n < nstrings) {
+ strings[n++] = xstrdup(p);
+ p += strlen(p) + 1;
+ }
+ /*
+ * make sure we always set our defaults if nothing is there to
+ * replace them.
+ */
+ if (n < CALMWM_NGROUPS) {
+ setnames = 1;
+ i = 1;
+ while (n < CALMWM_NGROUPS)
+ strings[n++] = xstrdup(shortcut_to_name[i++]);
+ }
+
+ if (prop_ret != NULL)
+ XFree(prop_ret);
+ if (sc->group_nonames != 0)
+ free(sc->group_names);
+
+ sc->group_names = strings;
+ sc->group_nonames = n;
+ if (setnames)
+ group_set_names(sc);
+}
+
+static void
+group_set_names(struct screen_ctx *sc)
+{
+ unsigned char *p, *q;
+ size_t len = 0, tlen, slen;
+ int i;
+
+ for (i = 0; i < sc->group_nonames; i++)
+ len += strlen(sc->group_names[i]) + 1;
+ q = p = xcalloc(len, sizeof(*p));
+
+ tlen = len;
+ for (i = 0; i < sc->group_nonames; i++) {
+ slen = strlen(sc->group_names[i]) + 1;
+ strlcpy(q, sc->group_names[i], tlen);
+ tlen -= slen;
+ q += slen;
+ }
+
+ XChangeProperty(X_Dpy, sc->rootwin, _NET_DESKTOP_NAMES,
+ UTF8_STRING, 8, PropModeReplace, p, len);
+}
diff --git a/parse.y b/parse.y
index 9c501bc..337be45 100644
--- a/parse.y
+++ b/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.21 2009/06/20 00:22:39 okan Exp $ */
+/* $OpenBSD: parse.y,v 1.22 2009/12/11 17:51:42 oga Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -123,29 +123,13 @@ main : FONTNAME STRING {
free($3);
}
| AUTOGROUP NUMBER STRING {
- struct autogroupwin *aw;
- char *p;
-
if ($2 < 0 || $2 > 9) {
free($3);
yyerror("autogroup number out of range: %d", $2);
YYERROR;
}
- aw = xcalloc(1, sizeof(*aw));
-
- if ((p = strchr($3, ',')) == NULL) {
- aw->name = NULL;
- aw->class = xstrdup($3);
- } else {
- *(p++) = '\0';
- aw->name = xstrdup($3);
- aw->class = xstrdup(p);
- }
- aw->group = xstrdup(shortcut_to_name[$2]);
-
- TAILQ_INSERT_TAIL(&conf->autogroupq, aw, entry);
-
+ group_make_autogroup(conf, $3, $2);
free($3);
}
| IGNORE STRING {
diff --git a/xevents.c b/xevents.c
index 69bbec4..fb2a136 100644
--- a/xevents.c
+++ b/xevents.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: xevents.c,v 1.46 2009/12/10 23:14:58 oga Exp $
+ * $Id: xevents.c,v 1.47 2009/12/11 17:51:42 oga Exp $
*/
/*
@@ -170,6 +170,7 @@ static void
xev_handle_propertynotify(XEvent *ee)
{
XPropertyEvent *e = &ee->xproperty;
+ struct screen_ctx *sc;
struct client_ctx *cc;
if ((cc = client_find(e->window)) != NULL) {
@@ -184,7 +185,17 @@ xev_handle_propertynotify(XEvent *ee)
/* do nothing */
break;
}
+ } else {
+ TAILQ_FOREACH(sc, &Screenq, entry)
+ if (sc->rootwin == e->window)
+ goto test;
+ return;
+
+test:
+ if (e->atom == _NET_DESKTOP_NAMES)
+ group_update_names(sc);
}
+
}
void
diff --git a/xutil.c b/xutil.c
index b8001ca..da94d30 100644
--- a/xutil.c
+++ b/xutil.c
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: xutil.c,v 1.23 2009/12/10 23:21:26 oga Exp $
+ * $Id: xutil.c,v 1.24 2009/12/11 17:51:42 oga Exp $
*/
#include "headers.h"
@@ -189,6 +189,7 @@ char *atoms[CWM_NO_ATOMS] = {
"_NET_DESKTOP_GEOMETRY",
"_NET_VIRTUAL_ROOTS",
"_NET_SHOWING_DESKTOP",
+ "_NET_DESKTOP_NAMES",
};
void