Hi all, Find attached my final patch to bind key &/or mouse events to individual windows.
SCoTT. :)
? fvwm/.fvwm.1.in.swo ? fvwm/.fvwm.1.in.swp ? modules/FvwmScript/.FvwmScript.c.swp ? modules/FvwmScript/.Instructions.c.swp 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 05:25:14 -0000 @@ -1439,15 +1439,15 @@ * the other contexts, new windows have problems when bindings are * removed. Therefore, grab all keys in a single pass through the * list. */ - GrabAllWindowKeys( + grabAllFWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, C_WINDOW|C_TITLE|C_RALL|C_LALL|C_SIDEBAR, GetUnusedModifiers(), - True); + True, fw); #endif - GrabAllWindowKeys( + grabAllFWindowKeys( dpy, FW_W_FRAME(fw), Scr.AllBindings, C_TITLE|C_RALL|C_LALL|C_SIDEBAR|C_WINDOW, GetUnusedModifiers(), - True); + True, fw); 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 05:25:14 -0000 @@ -101,6 +101,12 @@ return; } +Bool bindingAppliesToFWindow (Binding *b, FvwmWindow *fw) +{ + return bindingAppliesToWindow(b, fw->class.res_class, + fw->class.res_name, fw->name.name); +} + static int activate_binding(Binding *binding, binding_t type, Bool do_grab) { FvwmWindow *t; @@ -136,6 +142,11 @@ /* grab keys immediately */ for (t = Scr.FvwmRoot.next; t != NULL; t = t->next) { + if (!bindingAppliesToFWindow(binding, t)) + { + continue; + } + if (!IS_EWMH_DESKTOP(FW_W(t)) && (binding->Context & (C_WINDOW | C_DECOR)) && BIND_IS_KEY_BINDING(type)) @@ -237,8 +248,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 +372,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 +475,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 +540,7 @@ rc = AddBinding( dpy, pblist, type, STROKE_ARG((void *)stroke) button, keysym, key_string, modifier, context, (void *)action, - NULL); + NULL, windowName); return rc; } @@ -604,4 +642,23 @@ } return; +} + +void grabAllFWindowKeys( + Display *dpy, Window w, Binding *blist, unsigned int contexts, + unsigned int dead_modifiers, Bool fGrab, FvwmWindow *fw) +{ + GrabAllWindowKeys( + dpy, w, blist, contexts, dead_modifiers, fGrab, + fw->class.res_class, fw->class.res_name, fw->name.name); +} + +void grabAllFWindowKeysAndButtons( + Display *dpy, Window w, Binding *blist, unsigned int contexts, + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, + FvwmWindow *fw) +{ + GrabAllWindowKeysAndButtons( + dpy, w, blist, contexts, dead_modifiers, cursor, fGrab, + fw->class.res_class, fw->class.res_name, fw->name.name); } 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 05:25:14 -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 05:25:14 -0000 @@ -2553,12 +2553,14 @@ } 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.res_class, + t->class.res_name, t->name.name); if (escape != NULL) { if (!strcasecmp(escape,"escapefunc")) @@ -4209,7 +4211,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.res_class, + exc->w.fw->class.res_name, 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 05:25:15 -0000 @@ -1465,10 +1465,12 @@ PressedW = None; __handle_bpress_stroke(); /* search for an appropriate mouse binding */ + /* exc->w.fw is always NULL, hence why we use "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, "root", "root", "root"); + if (action && *action) { const exec_context_t *exc2; @@ -1541,7 +1543,8 @@ 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.res_class, + fw->class.res_name, fw->name.name); if (__handle_bpress_action(exc, action)) { f.do_swallow_click = 1; @@ -2280,45 +2283,56 @@ const XEvent *te = ea->exc->x.etrigger; const FvwmWindow * const fw = ea->exc->w.fw; Bool is_second_binding; + char *resource1, *class1, *name1, *resource2, *class2, *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) { + resource1 = class1 = name1 = "root"; kcontext = C_ROOT; } - else if (sf == ea->exc->w.fw) + else { - kcontext = ea->exc->w.wcontext; + resource1 = sf->class.res_class; + class1 = sf->class.res_name; + name1 = sf->name.name; + kcontext = (sf == fw ? ea->exc->w.wcontext : C_WINDOW); } + + if (fw == NULL) + resource2 = class2 = name2 = "root"; else { - kcontext = C_WINDOW; - } - action = CheckTwoBindings( - &is_second_binding, Scr.AllBindings, STROKE_ARG(0) kc, - te->xkey.state, GetUnusedModifiers(), kcontext, BIND_KEYPRESS, - ea->exc->w.wcontext, BIND_PKEYPRESS); + resource2 = fw->class.res_class; + class2 = fw->class.res_name; + name2 = fw->name.name; + } + /* 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, class1, resource1, name1, ea->exc->w.wcontext, + BIND_PKEYPRESS, class2, resource2, 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 05:25:17 -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 regex-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/icons.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/icons.c,v retrieving revision 1.231 diff -u -r1.231 icons.c --- fvwm/icons.c 5 Jul 2003 01:37:47 -0000 1.231 +++ fvwm/icons.c 2 Mar 2004 05:25:18 -0000 @@ -783,10 +783,10 @@ dpy, FW_W_ICON_TITLE(fw), FvwmContext, (caddr_t)fw); XDefineCursor( dpy, FW_W_ICON_TITLE(fw), Scr.FvwmCursors[CRS_DEFAULT]); - GrabAllWindowKeysAndButtons( + grabAllFWindowKeysAndButtons( dpy, FW_W_ICON_TITLE(fw), Scr.AllBindings, C_ICON, GetUnusedModifiers(), Scr.FvwmCursors[CRS_DEFAULT], - True); + True, fw); xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; XConfigureWindow( @@ -800,10 +800,10 @@ XDefineCursor( dpy, FW_W_ICON_PIXMAP(fw), Scr.FvwmCursors[CRS_DEFAULT]); - GrabAllWindowKeysAndButtons( + grabAllFWindowKeysAndButtons( dpy, FW_W_ICON_PIXMAP(fw), Scr.AllBindings, C_ICON, GetUnusedModifiers(), Scr.FvwmCursors[CRS_DEFAULT], - True); + True, fw); xwc.sibling = FW_W_FRAME(fw); xwc.stack_mode = Below; XConfigureWindow( Index: fvwm/module_interface.c =================================================================== RCS file: /home/cvs/fvwm/fvwm/fvwm/module_interface.c,v retrieving revision 1.158 diff -u -r1.158 module_interface.c --- fvwm/module_interface.c 29 Jul 2003 15:42:01 -0000 1.158 +++ fvwm/module_interface.c 2 Mar 2004 05:25:18 -0000 @@ -619,7 +619,8 @@ GetContext( NULL, exc->w.fw, &tmpevent, &targetWindow), - BIND_KEYPRESS); + BIND_KEYPRESS, exc->w.fw->class.res_class, + exc->w.fw->class.res_name, 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 05:25:18 -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, char *winClass, + char *winResource, 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, winClass) == TRUE || + matchWildcards(binding->windowName, winResource) == TRUE || + matchWildcards(binding->windowName, winName) == 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, char *winClass, char *winResource, + char *winName) { if (b->type != type || !(b->Context & Context)) { @@ -356,6 +411,10 @@ { return False; } + if (!bindingAppliesToWindow(b, winClass, winResource, winName)) + { + return False; + } if (BIND_IS_MOUSE_BINDING(type) && (b->Button_Key == button_keycode || b->Button_Key == 0)) { @@ -381,56 +440,74 @@ 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, char *winClass, char *winResource, + 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) - { - return b->Action; + b, STROKE_ARG(stroke) button_keycode, modifier, + used_modifiers, Context, type, winClass, winResource, + winName) == True) + { + 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, char *winClass, char *winResource, + char *winName, int Context2, binding_t type2, char *winClass2, + char *winResource2, 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, winResource, + 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, winResource2, + 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; + return action; } +#if 0 /* same as above, but only returns exactly matching bindings, i.e. wildcards for * mouse buttons and modifiers must match exactly. */ Bool MatchBindingExactly( @@ -460,6 +537,7 @@ return True; } +#endif /* * GrabWindowKey - grab needed keys for the window for one binding @@ -545,12 +623,17 @@ void GrabAllWindowKeys( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Bool fGrab) + unsigned int dead_modifiers, Bool fGrab, char *winClass, + char *winResource, char *winName) { MyXGrabServer(dpy); is_grabbing_everything = True; for ( ; blist != NULL; blist = blist->NextBinding) { + if (!bindingAppliesToWindow(blist, winClass, winResource, winName)) + { + continue; + } GrabWindowKey(dpy, w, blist, contexts, dead_modifiers, fGrab); } is_grabbing_everything = False; @@ -652,7 +735,8 @@ void GrabAllWindowButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Cursor cursor, Bool fGrab) + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, char *winClass, + char *winResource, char *winName) { MyXGrabServer(dpy); is_grabbing_everything = True; @@ -669,7 +753,8 @@ void GrabAllWindowKeysAndButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Cursor cursor, Bool fGrab) + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, char *winClass, + char *winResource, char *winName) { MyXGrabServer(dpy); is_grabbing_everything = True; 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 05:25:18 -0000 @@ -32,12 +32,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 +48,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,32 +63,37 @@ 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, char *winClass, char *winResource, 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, char *winClass, char *winResource, + char *winName, int Context2, binding_t type2, char *winClass2, + char *winResource2, char *winName2); void GrabWindowKey( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Bool fGrab); void GrabAllWindowKeys( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Bool fGrab); + unsigned int dead_modifiers, Bool fGrab, char *winClass, + char *winResource, char *winName); void GrabWindowButton( Display *dpy, Window w, Binding *binding, unsigned int contexts, unsigned int dead_modifiers, Cursor cursor, Bool fGrab); void GrabAllWindowButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Cursor cursor, Bool fGrab); + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, char *winClass, + char *winResource, char *winName); void GrabAllWindowKeysAndButtons( Display *dpy, Window w, Binding *blist, unsigned int contexts, - unsigned int dead_modifiers, Cursor cursor, Bool fGrab); + unsigned int dead_modifiers, Cursor cursor, Bool fGrab, char *winClass, + char *winResource, char *winName); void GrabWindowKeyOrButton( 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, char *winClass, + char *winResource, char *winName); + #endif /* FVWMLIB_BINDINGS_H_H */ 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 05:25:19 -0000 @@ -938,12 +938,14 @@ /* check for bindings defined by the Key instruction */ 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, + "none", "none", "none")) != 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 05:25:19 -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); }