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]