About a month ago, I sent in a patch to allow multiple window names in conditions. It was developed for my own use, but since I am a lazy guy, I was hoping the fvwm workers would pick it up, so I wouldn't have to keep maintaining it. That doesn't seem to have happened. Perhaps I should have mentioned that the patch is backward-compatible with old fvwm2rc files. It is mildly half-assed in the sense that it doesn't implement a full boolean expression parser, but in exchange it is small and simple. It assumes that the boolean operator the user wants is "OR", or in the case of a window name prefixed with '!', "AND NOT". The following is a rehash of the patch against the current CVS tree. ChangeLog and man page updates are included. If something's wrong with it, I'd appreciate hearing what.
Index: ChangeLog =================================================================== RCS file: /home/cvs/fvwm/fvwm/ChangeLog,v retrieving revision 1.2512 diff -u -u -r1.2512 ChangeLog --- ChangeLog 1 Jul 2004 14:34:22 -0000 1.2512 +++ ChangeLog 4 Jul 2004 19:23:31 -0000 @@ -1,3 +1,11 @@ +2004-07-04 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-07-01 Dominik Vogt <[EMAIL PROTECTED]> * fvwm/move_resize.c (GetResizeArguments): 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 4 Jul 2004 19:23:33 -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.141 diff -u -u -r1.141 fvwm.1.in --- fvwm/fvwm.1.in 1 Jul 2004 14:34:23 -0000 1.141 +++ fvwm/fvwm.1.in 4 Jul 2004 19:23:46 -0000 @@ -10366,15 +10366,42 @@ 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. Window names +to avoid may also be specified: each window +name can begin with '!' which prevents .I command if any of the window name, icon name, class or resource match. +If a mixture of names beginning with '!' and names +without '!' is specified, then the implicit operator is an OR +on the names without '!' and an AND NOT on the names with '!'; +that is, the condition is satisfied if none of the names with '!' +match, and if one or more of the names without '!' match. -Any condition can be negated by using a an exclamation mark ('!') -directly in front of its name. +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 (!Netscape !konqueror !Mozilla*) WarpToWindow 99 90 +.EE +This goes to the next non-browser window; if the above two commands are +bound to two different keys, the first key pages through browser windows +and the second through non-browser windows. +.EX + Next (XTerm !console) WarpToWindow 99 90 +.EE +This goes to the next xterm window, except that the one named +"console" (with the -name option to xterm) is excluded. + +Any of the other conditions, which follow, can also be negated by using a +an exclamation mark ('!') directly in front of its name. .IR AcceptsFocus , .IR CirculateHit , 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 4 Jul 2004 19:23:47 -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]