Hey, dude-

> > Below is a new diff which only sets no if class matches and name is NULL or
> > if class and name both match.
> > 
> > Since we must explicitly check for name == NULL I decided to also go ahead
> > and skip setting no if any previous class-only matches were found.
> 
> It's too bad the explicit class+name match is backwards in the config
> grammar;  I suppose we could reverse it and may make more sense going
> generic to specific matches...but that's another topic.

Hrmmm...  Well, it's not backwards compared to the way xprop(1) displays
WM_CLASS (see my latest diff in the other thread ;-)).  But I agree with
you that going from generic to specific makes a lot of sense.

How about this (while here also fix the grammar so quotes are optional around
the "name,class" syntax unless either value contains a space)?


Index: calmwm.h
===================================================================
RCS file: /cvs/xenocara/app/cwm/calmwm.h,v
retrieving revision 1.153
diff -p -u -r1.153 calmwm.h
--- calmwm.h    9 Sep 2012 19:47:47 -0000       1.153
+++ calmwm.h    30 Oct 2012 05:57:08 -0000
@@ -343,7 +343,7 @@ void                         group_client_delete(struct 
clien
 void                    group_cycle(struct screen_ctx *, int);
 void                    group_hidetoggle(struct screen_ctx *, int);
 void                    group_init(struct screen_ctx *);
-void                    group_make_autogroup(struct conf *, char *, int);
+void                    group_make_autogroup(struct conf *, int, char *, char 
*);
 void                    group_menu(XButtonEvent *);
 void                    group_movetogroup(struct client_ctx *, int);
 void                    group_only(struct screen_ctx *, int);
Index: cwmrc.5
===================================================================
RCS file: /cvs/xenocara/app/cwm/cwmrc.5,v
retrieving revision 1.44
diff -p -u -r1.44 cwmrc.5
--- cwmrc.5     28 Oct 2012 20:13:02 -0000      1.44
+++ cwmrc.5     30 Oct 2012 05:57:08 -0000
@@ -40,6 +40,7 @@ The following options are accepted:
 .Pp
 .Bl -tag -width Ds -compact
 .It Ic autogroup Ar group windowclass
+.It Ic autogroup Ar group windowclass windowname
 .It Ic autogroup Ar group windowname,windowclass
 Automatically add new windows to
 .Ar group
Index: group.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/group.c,v
retrieving revision 1.60
diff -p -u -r1.60 group.c
--- group.c     9 Sep 2012 20:52:57 -0000       1.60
+++ group.c     30 Oct 2012 05:57:08 -0000
@@ -164,19 +164,34 @@ group_init(struct screen_ctx *sc)
 }
 
 void
-group_make_autogroup(struct conf *conf, char *val, int no)
+group_make_autogroup(struct conf *conf, int no, char *class, char *name)
 {
        struct autogroupwin     *aw;
-       char                    *p;
+       char                    *p, *tmp;
 
        aw = xcalloc(1, sizeof(*aw));
 
-       if ((p = strchr(val, ',')) == NULL) {
-               aw->name = NULL;
-               aw->class = xstrdup(val);
+       if ((p = strchr(class, ',')) == NULL) {
+               if (name == NULL)
+                       aw->name = NULL;
+               else
+                       aw->name = xstrdup(name);
+
+               aw->class = xstrdup(class);
        } else {
+               /*
+                * Avoid the awkwardness of aw->name = xstrdup(class)
+                * below.
+                */
+               tmp = class;
+
                *(p++) = '\0';
-               aw->name = xstrdup(val);
+
+               if (name == NULL)
+                       aw->name = xstrdup(tmp);
+               else
+                       aw->name = xstrdup(name);
+
                aw->class = xstrdup(p);
        }
        aw->num = no;
Index: parse.y
===================================================================
RCS file: /cvs/xenocara/app/cwm/parse.y,v
retrieving revision 1.33
diff -p -u -r1.33 parse.y
--- parse.y     8 Sep 2011 12:35:33 -0000       1.33
+++ parse.y     30 Oct 2012 05:57:08 -0000
@@ -129,15 +129,45 @@ main              : FONTNAME STRING               {
                        free($2);
                        free($3);
                }
-               | AUTOGROUP NUMBER STRING       {
+               | AUTOGROUP NUMBER STRING               {
                        if ($2 < 0 || $2 > 9) {
                                free($3);
                                yyerror("autogroup number out of range: %d", 
$2);
                                YYERROR;
                        }
 
-                       group_make_autogroup(conf, $3, $2);
+                       group_make_autogroup(conf, $2, $3, NULL);
                        free($3);
+               }
+               | AUTOGROUP NUMBER STRING STRING        {
+                       char    *p;
+
+                       if ($2 < 0 || $2 > 9) {
+                               free($3);
+                               yyerror("autogroup number out of range: %d", 
$2);
+                               YYERROR;
+                       }
+
+                       if ((p = strchr($3, ',')) != NULL) {
+                               warnx("%s:%d: ambiguous autogroup 
configuration, "
+                                   "will use class=%s, name=%s", file->name,
+                                   yylval.lineno, ++p, $4);
+                       }
+
+                       group_make_autogroup(conf, $2, $3, $4);
+                       free($3);
+                       free($4);
+               }
+               | AUTOGROUP NUMBER STRING ',' STRING    {
+                       if ($2 < 0 || $2 > 9) {
+                               free($3);
+                               yyerror("autogroup number out of range: %d", 
$2);
+                               YYERROR;
+                       }
+
+                       group_make_autogroup(conf, $2, $5, $3);
+                       free($3);
+                       free($5);
                }
                | IGNORE STRING {
                        struct winmatch *wm;


> However, in general, I do prefer last matching when it comes to the
> matching options in the config.  So the below allows for specific
> matches of class+name or just class matches, but last matching in both
> cases.

I'm fine with last match.  I only kept the first match to preserve
existing behavior.  However, I also think it's idiomatic to prefer more
specific matches, and in the case of window classes and names there's
clearly a hierarchy.  So, I'd prefer to do both.  What do you think of
this addition to your diff (independent of the diff above)?


Index: cwmrc.5
===================================================================
RCS file: /cvs/xenocara/app/cwm/cwmrc.5,v
retrieving revision 1.44
diff -N -p -u cwmrc.5
--- cwmrc.5     28 Oct 2012 20:13:02 -0000      1.44
+++ cwmrc.5     30 Oct 2012 06:41:48 -0000
@@ -58,8 +59,21 @@ is 0, matching windows will not be added to any group;
 used to override
 .Dq sticky group mode .
 .Pp
+If a window matches more than one
+.Dq autogroup
+the last defined
+.Dq autogroup
+that matches both class and name wins.
+If no
+.Dq autogroup
+matches both then the last defined
+.Dq autogroup
+that matches only class wins.
+.Pp
 The name and class values for existing windows may be obtained using
 .Xr xprop 1 .
 .Pp
Index: group.c
===================================================================
RCS file: /cvs/xenocara/app/cwm/group.c,v
retrieving revision 1.60
diff -N -p -u group.c
--- group.c     9 Sep 2012 20:52:57 -0000       1.60
+++ group.c     30 Oct 2012 06:41:48 -0000
@@ -412,7 +427,7 @@ group_autogroup(struct client_ctx *cc)
        struct screen_ctx       *sc = cc->sc;
        struct autogroupwin     *aw;
        struct group_ctx        *gc;
-       int                      no = -1;
+       int                      both_match = 0, no = -1;
        long                    *grpno;
 
        if (cc->app_class == NULL || cc->app_name == NULL)
@@ -429,11 +444,13 @@ group_autogroup(struct client_ctx *cc)
                XFree(grpno);
        } 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)) {
-                               no = aw->num;
-                               break;
+                       if (strcmp(aw->class, cc->app_class) == 0) {
+                               if ((aw->name != NULL) &&
+                                   (strcmp(aw->name, cc->app_name) == 0)) {
+                                       no = aw->num;
+                                       both_match = 1;
+                               } else if (aw->name == NULL && !both_match)
+                                       no = aw->num;
                        }
                }
        }


Thanks again!

Best,
Kent

Reply via email to