Find attached updated patch. Includes small performance improvement, code tidyup & bugfix to ensure bindings work in windows with dynamically changing class/resource/name values.
SCoTT. :) -- [EMAIL PROTECTED]
Index: fvwm/add_window.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/add_window.c,v retrieving revision 1.360 diff -u -r1.360 add_window.c --- fvwm/add_window.c 19 Feb 2004 09:36:01 -0000 1.360 +++ fvwm/add_window.c 2 Mar 2004 16:48:06 -0000 @@ -1441,13 +1441,11 @@ * list. */ GrabAllWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, - C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(), - True); + C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(), True); #endif GrabAllWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, - C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(), - True); + C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(), True); setup_focus_policy(fw); return; Index: fvwm/bindings.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/bindings.c,v retrieving revision 1.87 diff -u -r1.87 bindings.c --- fvwm/bindings.c 2 Nov 2003 17:04:44 -0000 1.87 +++ fvwm/bindings.c 2 Mar 2004 16:48:07 -0000 @@ -101,6 +101,11 @@ return; } +Bool bindingAppliesToFWindow (Binding *b, FvwmWindow *fw) +{ + return bindingAppliesToWindow(b, &fw->class, fw->name.name); +} + static int activate_binding(Binding *binding, binding_t type, Bool do_grab) { FvwmWindow *t; @@ -136,6 +141,13 @@ /* grab keys immediately */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { +#if 0 + if (!bindingAppliesToFWindow(binding, t)) + { + continue; + } +#endif + if (!IS_EWMH_DESKTOP(FW_W(t)) && (binding->Context & (C_WINDOW | C_DECOR)) && BIND_IS_KEY_BINDING(type)) @@ -237,8 +249,8 @@ int *nr_left_buttons, int *nr_right_buttons, unsigned short *buttons_grabbed, Bool is_silent) { - char *action, context_string[20], modifier_string[20], *ptr, *token; - char key_string[201] = ""; + char *action, context_string[80], modifier_string[20], *ptr, *token; + char key_string[201] = "", buffer[80], *windowName = NULL; int button = 0; int n1=0,n2=0,n3=0; KeySym keysym = NoSymbol; @@ -361,7 +373,34 @@ token = PeekToken(ptr, &ptr); if (token != NULL) { - n2 = sscanf(token, "%19s", context_string); + char *p = token; + if (*p == '(') + { + /* A window name has been specified for the binding. */ + strcpy(buffer, p+1); + p = buffer; + while (*p != ')') + { + if (*p == '\0') + { + if (!is_silent) + fvwm_msg(ERR, "ParseBinding", + "Syntax error in line %s - missing ')'", tline); + return 0; + } + ++p; + } + *p++ = '\0'; + windowName = buffer; + if (*p == '\0') + { + if (!is_silent) + fvwm_msg(ERR, "ParseBinding", + "Syntax error in line %s - no context specified with window", tline); + return 0; + } + } + n2 = sscanf(p, "%79s", context_string); } token = PeekToken(ptr, &action); if (token != NULL) @@ -437,7 +476,7 @@ /* BEGIN remove */ CollectBindingList( dpy, pblist, &rmlist, type, STROKE_ARG((void *)stroke) - button, keysym, modifier, context); + button, keysym, modifier, context, windowName); if (rmlist != NULL) { is_binding_removed = True; @@ -502,7 +541,7 @@ rc = AddBinding( dpy, pblist, type, STROKE_ARG((void *)stroke) button, keysym, key_string, modifier, context, (void *)action, - NULL); + NULL, windowName); return rc; } Index: fvwm/bindings.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/bindings.h,v retrieving revision 1.16 diff -u -r1.16 bindings.h --- fvwm/bindings.h 29 Jun 2003 19:53:22 -0000 1.16 +++ fvwm/bindings.h 2 Mar 2004 16:48:07 -0000 @@ -4,6 +4,8 @@ #define BINDINGS_H /* ---------------------------- included header files ---------------------- */ +#include "fvwm.h" /* FvwmWindow */ +#include "libs/Bindings.h" /* Binding */ /* ---------------------------- global definitions ------------------------- */ @@ -20,6 +22,16 @@ void update_key_bindings(void); unsigned int MaskUsedModifiers(unsigned int in_modifiers); unsigned int GetUnusedModifiers(void); +Bool bindingAppliesToFWindow (Binding *b, FvwmWindow *fw); +void grabAllFWindowKeys( + Display *dpy, Window w, Binding *blist, unsigned int contexts, + unsigned int dead_modifiers, Bool fGrab, FvwmWindow *fw); +void grabAllFWindowKeysAndButtons( + Display *dpy, Window w, Binding *blist, unsigned int contexts, + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, + FvwmWindow *fw); + + #endif /* BINDINGS_H */ Index: fvwm/builtins.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/builtins.c,v retrieving revision 1.405 diff -u -r1.405 builtins.c --- fvwm/builtins.c 19 Feb 2004 09:36:01 -0000 1.405 +++ fvwm/builtins.c 2 Mar 2004 16:48:14 -0000 @@ -2553,12 +2553,13 @@ } else if (e.type == KeyPress) { + /* TODO: should I be using <t> or <exc->w.fw>? */ + int context = GetContext(&t, t, &e, &nonewin); escape = CheckBinding( Scr.AllBindings, STROKE_ARG(0) e.xkey.keycode, e.xkey.state, - GetUnusedModifiers(), - GetContext(&t, t, &e, &nonewin), - BIND_KEYPRESS); + GetUnusedModifiers(), context, + BIND_KEYPRESS, &t->class, t->name.name); if (escape != NULL) { if (!strcasecmp(escape,"escapefunc")) @@ -4209,7 +4210,8 @@ /* check for a binding */ stroke_action = CheckBinding( Scr.AllBindings, sequence, 0, modifiers, GetUnusedModifiers(), - exc->w.wcontext, BIND_STROKE); + exc->w.wcontext, BIND_STROKE, &exc->w.fw->class, + exc->w.fw->name.name); /* execute the action */ if (stroke_action != NULL) Index: fvwm/events.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v retrieving revision 1.490 diff -u -r1.490 events.c --- fvwm/events.c 26 Feb 2004 14:40:34 -0000 1.490 +++ fvwm/events.c 2 Mar 2004 16:48:24 -0000 @@ -1461,14 +1461,18 @@ static void __handle_bpress_on_root(const exec_context_t *exc) { char *action; + XClassHint tmp; PressedW = None; __handle_bpress_stroke(); /* search for an appropriate mouse binding */ + /* exc->w.fw is always NULL, hence why we use "root". */ + tmp.res_class = tmp.res_name = "root"; action = CheckBinding( Scr.AllBindings, STROKE_ARG(0) exc->x.etrigger->xbutton.button, exc->x.etrigger->xbutton.state, GetUnusedModifiers(), C_ROOT, - BIND_BUTTONPRESS); + BIND_BUTTONPRESS, &tmp, tmp.res_class); + if (action && *action) { const exec_context_t *exc2; @@ -1541,7 +1545,7 @@ action = CheckBinding( Scr.AllBindings, STROKE_ARG(0) e->xbutton.button, e->xbutton.state, GetUnusedModifiers(), - exc->w.wcontext, BIND_BUTTONPRESS); + exc->w.wcontext, BIND_BUTTONPRESS, &fw->class, fw->name.name); if (__handle_bpress_action(exc, action)) { f.do_swallow_click = 1; @@ -1616,7 +1620,9 @@ /* need to search for an appropriate stroke binding */ action = CheckBinding( Scr.AllBindings, sequence, te->xbutton.button, real_modifier, - GetUnusedModifiers(), ea->exc->w.wcontext, BIND_STROKE); + GetUnusedModifiers(), ea->exc->w.wcontext, BIND_STROKE, + &ea->exc->w.fw->class, ea->exc->w.fw->name.name); + /* got a match, now process it */ if (action != NULL && (action[0] != 0)) { @@ -2280,45 +2286,60 @@ const XEvent *te = ea->exc->x.etrigger; const FvwmWindow * const fw = ea->exc->w.fw; Bool is_second_binding; + const XClassHint *winClass1, *winClass2; + XClassHint tmp; + char *name1, *name2; + const exec_context_t *exc; + exec_context_changes_t ecc; PressedW = None; /* Here's a real hack - some systems have two keys with the * same keysym and different keycodes. This converts all * the cases to one keycode. */ - kc = XKeysymToKeycode( - dpy, XKeycodeToKeysym(dpy, te->xkey.keycode, 0)); + kc = XKeysymToKeycode(dpy, XKeycodeToKeysym(dpy, te->xkey.keycode, 0)); /* Check if there is something bound to the key */ sf = get_focus_window(); if (sf == NULL) { + tmp.res_name = tmp.res_class = name1 = "root"; + winClass1 = &tmp; kcontext = C_ROOT; } - else if (sf == ea->exc->w.fw) + else { - kcontext = ea->exc->w.wcontext; + winClass1 = &sf->class; + name1 = sf->name.name; + kcontext = (sf == fw ? ea->exc->w.wcontext : C_WINDOW); + } + + if (fw == NULL) + { + tmp.res_name = tmp.res_class = name2 = "root"; + winClass2 = &tmp; } else { - kcontext = C_WINDOW; + winClass2 = &fw->class; + name2 = fw->name.name; } - action = CheckTwoBindings( - &is_second_binding, Scr.AllBindings, STROKE_ARG(0) kc, - te->xkey.state, GetUnusedModifiers(), kcontext, BIND_KEYPRESS, - ea->exc->w.wcontext, BIND_PKEYPRESS); + /* Searching the binding list with a different 'type' value + * (ie. BIND_KEYPRESS vs BIND_PKEYPRESS) doesn't make a difference. + * The different context value does though. */ + action = CheckTwoBindings(&is_second_binding, Scr.AllBindings, + STROKE_ARG(0) kc, te->xkey.state, GetUnusedModifiers(), kcontext, + BIND_KEYPRESS, winClass1, name1, ea->exc->w.wcontext, + BIND_PKEYPRESS, winClass2, name2); + if (action != NULL) { - const exec_context_t *exc; - exec_context_changes_t ecc; - exc = ea->exc; if (is_second_binding == False) { ecc.w.fw = sf; ecc.w.wcontext = kcontext; - exc = exc_clone_context( - ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); + exc = exc_clone_context(ea->exc, &ecc, ECC_FW | ECC_WCONTEXT); } execute_function(NULL, exc, action, 0); if (is_second_binding == False) Index: fvwm/fvwm.1.in =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/fvwm.1.in,v retrieving revision 1.123 diff -u -r1.123 fvwm.1.in --- fvwm/fvwm.1.in 19 Feb 2004 09:36:01 -0000 1.123 +++ fvwm/fvwm.1.in 2 Mar 2004 16:49:00 -0000 @@ -5753,6 +5753,26 @@ which mouse button is used to tear off menus. See the section "Tear Off Menus" for details. +By default, the binding applies to all windows. You can specify that +the binding only applies within an individual window by prefixing the +.I Context +field with a wildcard pattern (in brackets) containing the class, resource +or name of the window you want the binding to apply to. + +The following example shows how the same key-binding can be used to +perform different functions depending on the window that is focussed: +.EX +Key V (rxvt)A C Echo ctrl-V-in-RXVT +Key V (*term)A C Echo ctrl-V-in-Term +Key V A C Echo ctrl-V-elsewhere +.EE + +This example shows how to display the WindowList when Button 3 is +pressed on an rxvt window: +.EX +Mouse 3 (rxvt)A A WindowList +.EE + .I Modifiers is any combination of 'N' for no modifiers, 'C' for control, 'S' for shift, 'M' for Meta, 'L' for Caps-Lock or 'A' for any Index: fvwm/module_interface.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/module_interface.c,v retrieving revision 1.159 diff -u -r1.159 module_interface.c --- fvwm/module_interface.c 2 Mar 2004 11:19:33 -0000 1.159 +++ fvwm/module_interface.c 2 Mar 2004 16:49:11 -0000 @@ -619,7 +619,7 @@ GetContext( NULL, exc->w.fw, &tmpevent, &targetWindow), - BIND_KEYPRESS); + BIND_KEYPRESS, &exc->w.fw->class, exc->w.fw->name.name); if (escape != NULL) { if (!strcasecmp(escape,"escapefunc")) Index: libs/Bindings.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/libs/Bindings.c,v retrieving revision 1.60 diff -u -r1.60 Bindings.c --- libs/Bindings.c 17 Feb 2004 14:17:06 -0000 1.60 +++ libs/Bindings.c 2 Mar 2004 16:49:13 -0000 @@ -52,6 +52,10 @@ { free(b->Action2); } + if (b->windowName) + { + free(b->windowName); + } free(b); return; @@ -128,7 +132,7 @@ Display *dpy, Binding **pblist, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, char *key_name, int modifiers, int contexts, - void *action, void *action2) + void *action, void *action2, char *windowName) { int i; int min; @@ -250,6 +254,8 @@ (action) ? stripcpy(action) : NULL; (*pblist)->Action2 = (action2) ? stripcpy(action2) : NULL; + (*pblist)->windowName = + windowName ? stripcpy(windowName) : NULL; (*pblist)->NextBinding = temp; bound_mask |= bind_mask; count++; @@ -259,7 +265,11 @@ return count; } -static Bool AreBindingsEqual(Binding *b1, Binding *b2) +/* + * replacesBinding() - does the new binding, b1, replace a current + * binding, b2? + */ +static Bool replacesBinding(Binding *b1, Binding *b2) { if (b1->type != b2->type) { @@ -277,6 +287,24 @@ { return False; } + + /* definition: "global binding" => b->windowName == NULL + * definition: "window-specific binding" => b->windowName != NULL + */ + if (b1->windowName && b2->windowName) + { + /* Both bindings are window-specific. The existing binding, b2, + * is only replaced (by b1) if it applies to the same window */ + if (strcmp(b1->windowName, b2->windowName) != 0) + return False; + } + else if (b1->windowName || b2->windowName) + { + /* 1 binding is window-specific, the other is global - no need to + * replace this binding. */ + return False; + } + if (BIND_IS_KEY_BINDING(b1->type) || BIND_IS_MOUSE_BINDING(b1->type)) { return True; @@ -301,7 +329,7 @@ void CollectBindingList( Display *dpy, Binding **pblist_src, Binding **pblist_dest, binding_t type, STROKE_ARG(void *stroke) - int button, KeySym keysym, int modifiers, int contexts) + int button, KeySym keysym, int modifiers, int contexts, char *windowName) { Binding *tmplist = NULL; Binding *btmp; @@ -312,7 +340,7 @@ /* generate a private list of bindings to be removed */ AddBinding( dpy, &tmplist, type, STROKE_ARG(stroke) - button, keysym, NULL, modifiers, contexts, NULL, NULL); + button, keysym, NULL, modifiers, contexts, NULL, NULL, windowName); /* now find equivalent bindings in the given binding list and move * them to the new clist */ for (bold = *pblist_src, oldprev = NULL; bold != NULL; @@ -321,7 +349,7 @@ for (btmp = tmplist, tmpprev = NULL; btmp != NULL; tmpprev = btmp, btmp = btmp->NextBinding) { - if (AreBindingsEqual(btmp, bold)) + if (replacesBinding(btmp, bold)) { /* move matched binding from src list to dest * list */ @@ -342,10 +370,37 @@ return; } +/* + * bindingAppliesToWindow() + * + * The Key/Mouse/PointerKey syntax (optionally) allows a window name + * (or class or resource) to be specified with the binding, denoting + * which windows the binding can be invoked in. This function determines + * if the binding actually applies to a window based on its + * name/class/resource. + */ +Bool bindingAppliesToWindow(Binding *binding, const XClassHint *winClass, + const char *winName) +{ + /* If no window name is specified with the binding then that means + * the binding applies to ALL windows. */ + if (binding->windowName == NULL) + return True; + + if (matchWildcards(binding->windowName, winName) == TRUE || + matchWildcards(binding->windowName, winClass->res_name) == TRUE || + matchWildcards(binding->windowName, winClass->res_class) == TRUE) + { + return True; + } + return False; +} + Bool __compare_binding( Binding *b, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier, unsigned int used_modifiers, - int Context, binding_t type) + int Context, binding_t type, const XClassHint *winClass, + const char *winName) { if (b->type != type || !(b->Context & Context)) { @@ -356,24 +411,30 @@ { return False; } + if (BIND_IS_MOUSE_BINDING(type) && - (b->Button_Key == button_keycode || b->Button_Key == 0)) + (b->Button_Key != button_keycode && b->Button_Key != 0)) { - return True; + return False; } - if (BIND_IS_KEY_BINDING(type) && - b->Button_Key == button_keycode) + else if (BIND_IS_KEY_BINDING(type) && b->Button_Key != button_keycode) { - return True; + return False; } - if (0 STROKE_CODE(|| ((BIND_IS_STROKE_BINDING(type) && - (strcmp(b->Stroke_Seq,stroke) == 0) && - b->Button_Key == button_keycode)))) +#ifdef HAVE_STROKE + else if (BIND_IS_STROKE_BINDING(type) && + (strcmp(b->Stroke_Seq, stroke) != 0) && + b->Button_Key != button_keycode) { - return True; + return False; } +#endif - return False; + if (!bindingAppliesToWindow(b, winClass, winName)) + { + return False; + } + return True; } /* Check if something is bound to a key or button press and return the action @@ -381,84 +442,68 @@ void *CheckBinding( Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, - int Context, binding_t type) + int Context, binding_t type, const XClassHint *winClass, + const char *winName) { Binding *b; unsigned int used_modifiers = ~dead_modifiers; + void *action = NULL; modifier &= (used_modifiers & ALL_MODIFIERS); for (b = blist; b != NULL; b = b->NextBinding) { if (__compare_binding( - b, STROKE_ARG(stroke) button_keycode, modifier, - used_modifiers, Context, type) == True) + b, STROKE_ARG(stroke) button_keycode, modifier, + used_modifiers, Context, type, winClass, winName) == True) { - return b->Action; + action = b->Action; + /* If this is a global binding, keep searching <blist> in the + * hope of finding a window-specific binding. */ + if (b->windowName) + break; } } - return NULL; + return action; } void *CheckTwoBindings( Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, - int Context, binding_t type, int Context2, binding_t type2) + int Context, binding_t type, const XClassHint *winClass, + const char *winName, int Context2, binding_t type2, + const XClassHint *winClass2, const char *winName2) { Binding *b; unsigned int used_modifiers = ~dead_modifiers; + void *action = NULL; modifier &= (used_modifiers & ALL_MODIFIERS); for (b = blist; b != NULL; b = b->NextBinding) { if (__compare_binding( b, STROKE_ARG(stroke) button_keycode, modifier, - used_modifiers, Context, type) == True) + used_modifiers, Context, type, winClass, winName) == True) { *ret_is_second_binding = False; - return b->Action; + action = b->Action; + if (b->windowName) + break; } if (__compare_binding( b, STROKE_ARG(stroke) button_keycode, modifier, - used_modifiers, Context2, type2) == True) + used_modifiers, Context2, type2, winClass2, winName2) == True) { + if (action && !b->windowName) + continue; *ret_is_second_binding = True; - return b->Action; + action = b->Action; + if (b->windowName) + break; } } - *ret_is_second_binding = False; - return NULL; -} - -/* same as above, but only returns exactly matching bindings, i.e. wildcards for - * mouse buttons and modifiers must match exactly. */ -Bool MatchBindingExactly( - Binding *b, STROKE_ARG(void *stroke) - int button, KeyCode keycode, unsigned int modifier, int Context, - binding_t type) -{ - modifier &= ALL_MODIFIERS; - if (b->type != type || b->Context != Context || b->Modifier != modifier) - { - return False; - } - if (BIND_IS_KEY_BINDING(type) && b->Button_Key != keycode) - { - return False; - } - if (BIND_IS_MOUSE_BINDING(type) && b->Button_Key != button) - { - return False; - } - if (0 STROKE_CODE(|| ((BIND_IS_STROKE_BINDING(type) && - (b->Button_Key != button || - (strcmp(b->Stroke_Seq,stroke) != 0)))))) - { - return False; - } - - return True; + return action; } /* @@ -658,8 +703,8 @@ is_grabbing_everything = True; for ( ; blist != NULL; blist = blist->NextBinding) { - GrabWindowButton( - dpy, w, blist, contexts, dead_modifiers, cursor, fGrab); + GrabWindowButton(dpy, w, blist, contexts, dead_modifiers, + cursor, fGrab); } is_grabbing_everything = False; MyXUngrabServer(dpy); Index: libs/Bindings.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/libs/Bindings.h,v retrieving revision 1.6 diff -u -r1.6 Bindings.h --- libs/Bindings.h 5 Jul 2003 01:37:47 -0000 1.6 +++ libs/Bindings.h 2 Mar 2004 16:49:13 -0000 @@ -1,5 +1,7 @@ /* -*-c-*- */ +#include <X11/Xutil.h> /* XClassHint */ + #ifndef FVWMLIB_BINDINGS_H_H #define FVWMLIB_BINDINGS_H_H @@ -32,12 +34,14 @@ { binding_t_t type; /* Is it a mouse, key, or stroke binding */ STROKE_CODE(void *Stroke_Seq;) /* stroke sequence */ - int Button_Key; /* Mouse Button number or Keycode */ + int Button_Key; /* Mouse Button number or Keycode */ char *key_name; /* In case of keycode, give the key_name too */ int Context; /* Fvwm context, ie titlebar, frame, etc */ int Modifier; /* Modifiers for keyboard state */ void *Action; /* What to do? */ void *Action2; /* This one can be used too */ + char *windowName; /* Name of window (regex pattern) this binding + applies to. NULL means all windows. */ struct Binding *NextBinding; } Binding; @@ -46,11 +50,11 @@ void CollectBindingList( Display *dpy, Binding **pblist_src, Binding **pblist_dest, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, - int modifiers, int contexts); + int modifiers, int contexts, char *windowName); int AddBinding( Display *dpy, Binding **pblist, binding_t type, STROKE_ARG(void *stroke) int button, KeySym keysym, char *key_name, - int modifiers, int contexts, void *action, void *action2); + int modifiers, int contexts, void *action, void *action2, char *windowName); void FreeBindingStruct(Binding *b); void FreeBindingList(Binding *b); void RemoveBinding(Binding **pblist, Binding *b, Binding *prev); @@ -61,14 +65,13 @@ void *CheckBinding( Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier, unsigned int dead_modifiers, int Context, - binding_t type); + binding_t type, const XClassHint *winClass, const char *winName); void *CheckTwoBindings( Bool *ret_is_second_binding, Binding *blist, STROKE_ARG(char *stroke) int button_keycode, unsigned int modifier,unsigned int dead_modifiers, - int Context, binding_t type, int Context2, binding_t type2); -Bool MatchBindingExactly( - Binding *b, STROKE_ARG(void *stroke) int button, KeyCode keycode, - unsigned int modifier, int Context, binding_t type); + int Context, binding_t type, const XClassHint *winClass, + const char *winName, int Context2, binding_t type2, + const XClassHint *winClass2, const char *winName2); void GrabWindowKey( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab); @@ -88,5 +91,8 @@ Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); KeySym FvwmStringToKeysym(Display *dpy, char *key); +Bool bindingAppliesToWindow(Binding *binding, const XClassHint *winClass, + const char *winName); + #endif /* FVWMLIB_BINDINGS_H_H */ Index: libs/fvwmlib.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/libs/fvwmlib.h,v retrieving revision 1.119 diff -u -r1.119 fvwmlib.h --- libs/fvwmlib.h 7 Aug 2003 17:23:27 -0000 1.119 +++ libs/fvwmlib.h 2 Mar 2004 16:49:15 -0000 @@ -109,7 +109,7 @@ #include "envvar.h" #include "safemalloc.h" -int matchWildcards(char *pattern, char *string); +extern int matchWildcards(const char *pattern, const char *string); #define MAX_MODULE_INPUT_TEXT_LEN 1000 Index: libs/wild.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/libs/wild.c,v retrieving revision 1.8 diff -u -r1.8 wild.c --- libs/wild.c 29 Jun 2003 19:53:24 -0000 1.8 +++ libs/wild.c 2 Mar 2004 16:49:15 -0000 @@ -34,7 +34,7 @@ * It is public domain, no strings attached. No guarantees either. * */ -int matchWildcards(char *pattern, char *string) +int matchWildcards(const char *pattern, const char *string) { if(string == NULL) { Index: libs/wild.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/libs/wild.h,v retrieving revision 1.4 diff -u -r1.4 wild.h --- libs/wild.h 29 Jun 2003 19:53:24 -0000 1.4 +++ libs/wild.h 2 Mar 2004 16:49:15 -0000 @@ -9,4 +9,4 @@ * It is public domain, no strings attached. No guarantees either. * */ -int matchWildcards(char *pattern, char *string); +int matchWildcards(const char *pattern, const char *string); Index: modules/FvwmIconBox/FvwmIconBox.h =================================================================== RCS file: /home/cvs/fvwm/fvwm/modules/FvwmIconBox/FvwmIconBox.h,v retrieving revision 1.29 diff -u -r1.29 FvwmIconBox.h --- modules/FvwmIconBox/FvwmIconBox.h 6 Jul 2003 14:34:07 -0000 1.29 +++ modules/FvwmIconBox/FvwmIconBox.h 2 Mar 2004 16:49:16 -0000 @@ -63,7 +63,7 @@ extern Bool SortItem(struct icon_info *item); extern struct icon_info *MinItem(struct icon_info *head); extern void ExecuteKey(XEvent event); -extern int matchWildcards(char *pattern, char *string); +extern int matchWildcards(const char *pattern, const char *string); extern Bool GetBackPixmap(void); extern int LookInList(struct icon_info *item); extern char *stripcpy2(char *source); Index: modules/FvwmScript/FvwmScript.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/modules/FvwmScript/FvwmScript.c,v retrieving revision 1.70 diff -u -r1.70 FvwmScript.c --- modules/FvwmScript/FvwmScript.c 4 Jan 2004 12:39:30 -0000 1.70 +++ modules/FvwmScript/FvwmScript.c 2 Mar 2004 16:49:20 -0000 @@ -857,6 +857,7 @@ Bool find = False; char *action; int ex, ey, ex2, ey2; + XClassHint tmp; while (FEventsQueued(dpy, QueuedAfterReading)) { @@ -936,14 +937,17 @@ XKeysymToKeycode(dpy,XKeycodeToKeysym(dpy,event.xkey.keycode,0)); /* check for bindings defined by the Key instruction */ + tmp.res_class = tmp.res_name = "root"; if ((action = CheckBinding( BindingsList, STROKE_ARG(0) event.xkey.keycode, - event.xkey.state, LockMask, C_WINDOW, BIND_KEYPRESS)) != + event.xkey.state, LockMask, C_WINDOW, BIND_KEYPRESS, + &tmp, tmp.res_class)) != NULL) { SendMsgAndString(action, "CheckBinding"); break; } + if (ks == XK_Tab) { isTab = 1; if (event.xkey.state & ShiftMask) { Index: modules/FvwmScript/Instructions.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/modules/FvwmScript/Instructions.c,v retrieving revision 1.50 diff -u -r1.50 Instructions.c --- modules/FvwmScript/Instructions.c 5 Jul 2003 01:37:47 -0000 1.50 +++ modules/FvwmScript/Instructions.c 2 Mar 2004 16:49:23 -0000 @@ -1828,7 +1828,7 @@ AddBinding( dpy, &BindingsList, BIND_KEYPRESS, STROKE_ARG(0) 0, keysym, - key_string, modifier, C_WINDOW, (void *)action, NULL); + key_string, modifier, C_WINDOW, (void *)action, NULL, NULL); free(key_string); free(in_modifier); }