This is a small patch that allows multiple window names to be specified
in conditions.  I've tried to write it with the same style used in the
rest of the code, although some variable names may be a bit terse by your
standards.  The patch keeps the window names in a linked list.  It
includes updates to the man page and ChangeLog.  The patch is against the
current CVS code.  What exactly it does is best described by the modified
portion of the man page:

--------

       In addition, the conditions may include one or  more  window  names  to
       match to.  The window names may include the wildcards '*' and '?'.  The
       window name,  icon  name,  class,  and  resource  are  considered  when
       attempting to find a match.  If more than one window name is given, the
       implicit operator is a boolean OR -- that is,  the  condition  will  be
       satisfied  if  the window has any of those names.  Each window name can
       begin with '!' which prevents command if any of the window  name,  icon
       name, class or resource match.  Mixtures of window names beginning with
       '!' and window names without '!'  are allowed.  The general rule is  as
       follows:  if  any  of the window names with '!' match, the condition is
       not satisfied; otherwise if any of the names without '!' match,  or  if
       there are no names without '!', then the condition is satisfied.

       Examples:

                 Next (Netscape konqueror Mozilla*) WarpToWindow 99 90

       This  goes to the next web browser window, no matter which of the three
       named web browsers is being used.

                 Next (XTerm !xterm3) WarpToWindow 99 90

       This goes to the next xterm window, except that the one named  "xterm3"
       (with the -name option to xterm) is excluded.

                 Next (!XTerm !rxvt !emacs !Netscape !konqueror !Mozilla* \
                      !xdvi !xpdf) WarpToWindow 99 90

       This goes to the next window which doesn't have one of the above names.

--------

I'm not subscribed to the fvwm-workers mailing list, so please forward
any comments to me as well as to the list (or yell at me to subscribe for
a while, if that would be appropriate).

Index: ChangeLog
===================================================================
RCS file: /home/cvs/fvwm/fvwm/ChangeLog,v
retrieving revision 1.2496
diff -u -u -r1.2496 ChangeLog
--- ChangeLog   31 May 2004 20:19:23 -0000      1.2496
+++ ChangeLog   1 Jun 2004 01:44:44 -0000
@@ -1,3 +1,10 @@
+2004-05-31  Norman Yarvin  <[EMAIL PROTECTED]>
+
+       * fvwm/fvwm.1.in
+       * fvmw/fvwm.h
+       * fvwm/conditional.c: modified the code for conditions so that
+       multiple window names may be specified in each condition
+
 2004-05-31  Dan Espen  <[EMAIL PROTECTED]>
 
        * fvwm/fvwm.1.in (COLORSETS): Moved FvwmTheme description of colorsets
Index: fvwm/conditional.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/conditional.c,v
retrieving revision 1.93
diff -u -u -r1.93 conditional.c
--- fvwm/conditional.c  9 May 2004 12:59:55 -0000       1.93
+++ fvwm/conditional.c  1 Jun 2004 01:44:46 -0000
@@ -382,13 +382,14 @@
  */
 void FreeConditionMask(WindowConditionMask *mask)
 {
-       if (mask->my_flags.needs_name)
-       {
-               free(mask->name);
-       }
-       else if (mask->my_flags.needs_not_name)
-       {
-               free(mask->name - 1);
+       struct namelist *p,*p2;
+
+       for (p=mask->namelist; p;)
+       { 
+               free(p->name);
+               p2=p->next;
+               free(p);
+               p=p2;
        }
 
        return;
@@ -614,21 +615,16 @@
                        }
                        mask->my_flags.needs_same_layer = on;
                }
-               else if (!mask->my_flags.needs_name &&
-                        !mask->my_flags.needs_not_name)
-               {
-                       /* only 1st name to avoid mem leak */
-                       mask->name = condition;
-                       condition = NULL;
-                       if (on == 0)
-                       {
-                               mask->my_flags.needs_not_name = 1;
-                               mask->name++;
-                       }
-                       else
-                       {
-                               mask->my_flags.needs_name = 1;
-                       }
+               else
+               { 
+                       struct namelist *p;
+
+                       p = (struct namelist *)
+                               safemalloc(sizeof(struct namelist));
+                       p->name = condition;
+                       p->next = mask->namelist;
+                       mask->namelist = p;
+                       condition = NULL; 
                }
 
                if (prev_condition)
@@ -663,6 +659,9 @@
        int is_on_page;
        int is_on_global_page;
        FvwmWindow *sf = get_focus_window();
+       struct namelist *p;
+       char *name;
+       Bool invert,tried,matched;
 
        /* match FixedSize conditional */
        /* special treatment for FixedSize, because more than just
@@ -822,27 +821,52 @@
                }
        }
 
-       /* Yes, I know this could be shorter, but it's hard to understand then
-        */
-       does_name_match = matchWildcards(mask->name, fw->name.name);
-       does_icon_name_match = matchWildcards(mask->name, fw->icon_name.name);
-       does_class_match =
-               (fw->class.res_class && matchWildcards(
-                       mask->name,fw->class.res_class));
-       does_resource_match =
-               (fw->class.res_name && matchWildcards(
-                       mask->name, fw->class.res_name));
-       does_match =
-               (does_name_match || does_icon_name_match || does_class_match ||
-                does_resource_match);
-       if (mask->my_flags.needs_name && !does_match)
-       {
-               return False;
-       }
-       if (mask->my_flags.needs_not_name && does_match)
-       {
-               return False;
-       }
+       tried = False;
+       matched = False;
+
+       for(p=mask->namelist; p; p=p->next)
+       { 
+               name = p->name;
+               invert = False;
+               if(*name == '!')
+               {
+                       name++;
+                       invert = True;
+               }
+
+               /* Yes, I know this could be shorter, but it's hard to
+                * understand then
+                */
+               does_name_match = matchWildcards(name, fw->name.name);
+               does_icon_name_match = 
+                                 matchWildcards(name, fw->icon_name.name);
+               does_class_match =                    (fw->class.res_class && 
+                                 matchWildcards(name, fw->class.res_class));
+               does_resource_match =                 (fw->class.res_name &&
+                                 matchWildcards(name, fw->class.res_name));
+               does_match =
+                       (does_name_match || does_icon_name_match ||
+                        does_class_match || does_resource_match);
+
+               if(invert && does_match)
+               {
+                       return False;           /* "!window" takes priority */
+               }
+               if(!invert && does_match)
+               {
+                       matched = True;         /* this condition satisfied */
+               }
+               if(!invert)
+               {
+                       tried = True;
+               }
+       } 
+
+       if(tried && !matched)
+       { 
+               return False; 
+       }       
+
        if (mask->layer == -1 && sf)
        {
                int is_same_layer;
Index: fvwm/fvwm.1.in
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.1.in,v
retrieving revision 1.136
diff -u -u -r1.136 fvwm.1.in
--- fvwm/fvwm.1.in      31 May 2004 20:19:23 -0000      1.136
+++ fvwm/fvwm.1.in      1 Jun 2004 01:45:00 -0000
@@ -10324,12 +10324,37 @@
 
 In addition, the
 .I conditions
-may include one window name to match to.  The window name may
-include the wildcards '*' and '?'.  The window name, icon name,
-class, and resource are considered when attempting to find a
-match.  The window name can begin with '!' which prevents
+may include one or more window names to match to.  The window
+names may include the wildcards '*' and '?'.  The window name,
+icon name, class, and resource are considered when attempting to
+find a match.  If more than one window name is given, the
+implicit operator is a boolean OR -- that is, the condition will
+be satisfied if the window has any of those names.  Each window
+name can begin with '!' which prevents
 .I command
 if any of the window name, icon name, class or resource match.
+Mixtures of window names beginning with '!' and window names
+without '!'  are allowed.  The general rule is as follows: if any
+of the window names with '!' match, the condition is not
+satisfied; otherwise if any of the names without '!' match, or if
+there are no names without '!', then the condition is satisfied.
+
+Examples:
+.EX
+       Next (Netscape konqueror Mozilla*) WarpToWindow 99 90
+.EE
+This goes to the next web browser window, no matter which of the three
+named web browsers is being used.
+.EX
+       Next (XTerm !xterm3) WarpToWindow 99 90
+.EE
+This goes to the next xterm window, except that the one named
+"xterm3" (with the -name option to xterm) is excluded.
+.EX
+       Next (!XTerm !rxvt !emacs !Netscape !konqueror !Mozilla* \\
+               !xdvi !xpdf) WarpToWindow 99 90
+.EE
+This goes to the next window which doesn't have one of the above names.
 
 Any condition can be negated by using a an exclamation mark ('!')
 directly in front of its name.
Index: fvwm/fvwm.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.h,v
retrieving revision 1.231
diff -u -u -r1.231 fvwm.h
--- fvwm/fvwm.h 30 May 2004 14:05:48 -0000      1.231
+++ fvwm/fvwm.h 1 Jun 2004 01:45:01 -0000
@@ -400,6 +400,12 @@
 } window_flags;
 
 /* Window mask for Circulate and Direction functions */
+struct namelist
+{
+       char *name;
+       struct namelist *next;
+};
+
 typedef struct WindowConditionMask
 {
        struct
@@ -419,8 +425,6 @@
 #define NEEDS_TRUE  1
 #define NEEDS_FALSE 2
                unsigned needs_focus : 2;
-               unsigned needs_name : 1;
-               unsigned needs_not_name : 1;
                unsigned needs_pointer : 2;
                unsigned needs_same_layer : 1;
                unsigned use_circulate_hit : 1;
@@ -430,7 +434,7 @@
        } my_flags;
        window_flags flags;
        window_flags flag_mask;
-       char *name;
+       struct namelist *namelist;
        int layer;
 } WindowConditionMask;
 
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [EMAIL PROTECTED]
To report problems, send mail to [EMAIL PROTECTED]

Reply via email to