Re: PATCH: window-specific key/mouse bindings
Final patch - removes some unused code I left lying around. It's 4am - time for bed! SCoTT. :) -- [EMAIL PROTECTED] 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 - 1.87 +++ fvwm/bindings.c 2 Mar 2004 17:08:19 - @@ -237,8 +237,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 +361,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 +464,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 +529,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/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 - 1.405 +++ fvwm/builtins.c 2 Mar 2004 17:08:26 - @@ -2553,12 +2553,13 @@ } else if (e.type == KeyPress) { + /* TODO: should I be using or 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 - 1.490 +++ fvwm/events.c
Re: PATCH: window-specific key/mouse bindings
Hi Dominik, > > I assume you're talking about grabbing the X server whenever a new > > window is created to GrabWindowKey() for each applicable binding? > > No, I mean the underlying calls to XGrabKey()/XUngrabKey() in > libs/bindings.c. Yeah, that's what I meant. > If you have lots of bindings that change and/or an application with a > frequently changing title, this can be a problem. I can see why this could be a problem for bindings that change, but I don't see what that has to do with windows that frequently change their title. > Hm? Earlier you wrote: > > > > The patch handles windows that dynamically change name/class/resource. > > > I just wrote a small Perl/Tk app to change the window name at the > > > click of a button ($mw->configure(-title => ...)) to confirm this. > > So I assumed that it reacts to name/class/resource changes. Doing > so requires redoing the grabs. Nah. All bindings are grabbed for all windows. But a binding is only _activated_ if it's resource/class/name matches. (See my last patch - just posted - which fixes a bug. Previously this wasn't strictly true.) And we lookup the resource/class/name just before we search the binding list. Find attached a very simple Perl/Tk app to test this functionality. Setup a couple of window-specific bindings like so: Key G (Abc)A C Echo ABC Key G (Something)A C Echo SOMETHING Click the 2 buttons ('Something' & 'Abc') to change the title & then press Ctrl-G in the window. SCoTT. :) -- [EMAIL PROTECTED] #!/usr/local/bin/perl -w use strict; use Tk; my $main = new MainWindow(-class => 'Scott', -title => 'Abc'); $main->Button(-text => 'Something', -command => sub { $main->configure(-title => 'Something'); } )->pack(-expand => 1, -fill => 'x'); $main->Button(-text => 'Abc', -command => sub { $main->configure(-title => 'Abc'); } )->pack(-expand => 1, -fill => 'x'); $main->Button(-text => 'Quit', -command => sub{exit} )->pack(-expand => 1, -fill => 'x'); MainLoop;
Re: PATCH: window-specific key/mouse bindings
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 - 1.360 +++ fvwm/add_window.c 2 Mar 2004 16:48:06 - @@ -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 - 1.87 +++ fvwm/bindings.c 2 Mar 2004 16:48:07 - @@ -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
Re: PATCH: window-specific key/mouse bindings
Dominik Vogt writes: > On Wed, Mar 03, 2004 at 01:03:03AM +1100, scott wrote: > > Hi Dominik, > > > > > ... and possibly people connected to the X server by a phone line. > > > What I'm worried about is the latency by grabbing or ungrabbing > > > bindings over a slow connection. > > > > I assume you're talking about grabbing the X server whenever a new > > window is created to GrabWindowKey() for each applicable binding? > > No, I mean the underlying calls to XGrabKey()/XUngrabKey() in > libs/bindings.c. These calls require contacting the X server. If > you have lots of bindings that change and/or an application with a > frequently changing title, this can be a problem. I vaguely > remember an old bug in that area that slowed down startup > dramatically because of unnecessary grabs. I believe that was around the time IgnoreModifiers was invented. I was running Fvwm remotely over dialup with lots of key bindings in my .fvwm2rc. -- Dan Espen E-mail: [EMAIL PROTECTED] -- Visit the official FVWM web page at 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]
Re: PATCH: window-specific key/mouse bindings
On Wed, Mar 03, 2004 at 01:03:03AM +1100, scott wrote: > Hi Dominik, > > > ... and possibly people connected to the X server by a phone line. > > What I'm worried about is the latency by grabbing or ungrabbing > > bindings over a slow connection. > > I assume you're talking about grabbing the X server whenever a new > window is created to GrabWindowKey() for each applicable binding? No, I mean the underlying calls to XGrabKey()/XUngrabKey() in libs/bindings.c. These calls require contacting the X server. If you have lots of bindings that change and/or an application with a frequently changing title, this can be a problem. I vaguely remember an old bug in that area that slowed down startup dramatically because of unnecessary grabs. See below. > Well the latency is increased by 3 matchWildcards() calls for > each window-specific binding. (global bindings have negligible > overhead.) Not much for an irregular event such as the creation of > a toplevel window. > > > Some applications change their > > name very often (e.g. some clocks). > > Yes. How does this relate to my patch? The binding list is > searched when a key/mouse event occurs - not when the window > class/resource/name changes. Hm? Earlier you wrote: > > The patch handles windows that dynamically change name/class/resource. > > I just wrote a small Perl/Tk app to change the window name at the > > click of a button ($mw->configure(-title => ...)) to confirm this. So I assumed that it reacts to name/class/resource changes. Doing so requires redoing the grabs. > And this doesn't require an X server grab. > > > By the way, how does the patch handle PointerKey bindings? > > The CheckTwoBindings() call tries to match bindings on the > window with the focus & the window that the pointer is in. > My patch just extends the check to include the resource/class/name > of both windows. Ciao Dominik ^_^ ^_^ -- Visit the official FVWM web page at 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]
Re: PATCH: window-specific key/mouse bindings
Hi Dominik, > ... and possibly people connected to the X server by a phone line. > What I'm worried about is the latency by grabbing or ungrabbing > bindings over a slow connection. I assume you're talking about grabbing the X server whenever a new window is created to GrabWindowKey() for each applicable binding? Well the latency is increased by 3 matchWildcards() calls for each window-specific binding. (global bindings have negligible overhead.) Not much for an irregular event such as the creation of a toplevel window. > Some applications change their > name very often (e.g. some clocks). Yes. How does this relate to my patch? The binding list is searched when a key/mouse event occurs - not when the window class/resource/name changes. And this doesn't require an X server grab. > By the way, how does the patch handle PointerKey bindings? The CheckTwoBindings() call tries to match bindings on the window with the focus & the window that the pointer is in. My patch just extends the check to include the resource/class/name of both windows. > > > - I'd rather see the four name strings put into a structure (to > > > reduce the number arguments passed to the functions). I think I'll pass an XClassHint* to reduce the number of additional parameters to 2. Creating a new struct to hold resource/class/name will create lots more code & get a bit messy. SCoTT. :) -- [EMAIL PROTECTED] -- Visit the official FVWM web page at 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]
Re: PATCH: window-specific key/mouse bindings
On Tue, Mar 02, 2004 at 11:43:26PM +1100, scott wrote: > Hi Dominik, > > > The only problem I see is how > > predictable program behaviour is. Does the patch re-grab window > > bindings when the name/class/resource of the window changes? If > > so, it may be a performance hog, if not, it may confuse the user. > > I don't see a good way to handle both problems at the same time. > > The patch handles windows that dynamically change name/class/resource. > I just wrote a small Perl/Tk app to change the window name at the > click of a button ($mw->configure(-title => ...)) to confirm this. > > As for performance, it should be pretty good. Looking up a > window-specific binding should take about the same amount of time, > but looking up a global binding will be (on average) about twice > as long. This is because in CheckBinding() we search the whole > binding list in the hope of finding a window-specific binding. > Previously, when searching the binding list we would stop as soon > as we found a matching binding (as we do now for window-specific > bindings). > > Anyway, only bean-counters will be unhappy with the performance > change. (I tried to make it as efficient as possible.) ... and possibly people connected to the X server by a phone line. What I'm worried about is the latency by grabbing or ungrabbing bindings over a slow connection. Some applications change their name very often (e.g. some clocks). By the way, how does the patch handle PointerKey bindings? > As for confusing the user - yes I agree. Most apps won't change > their class/resource name, however, & a decent wildcard pattern > for window names should avoid most problems. > > - The reference to regular expressions is wrong. Wildcard > > matching in fvwm has nothing to do with regular expressions > > Ah yes. Well spotted. > > > - I'd rather see the four name strings put into a structure (to > > reduce the number arguments passed to the functions). > > A good idea. A shame the XClassHint structure only holds the > class & resource names. > > "four name string" - I thought only 3? Right, three. > > - Is there a specific reason why the patch handles only key > > bindings? It should be trivial to extend it to handle mouse and > > stroke bindings too. > > I've always said the patch supports both key & mouse bindings. > (The fvwm man page gives an example of how to use both.) I've never > used stroke bindings - I'll have a look. Hm, I must have missed that. Ciao Dominik ^_^ ^_^ -- Visit the official FVWM web page at 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]
Re: PATCH: window-specific key/mouse bindings
Hi Dominik, > The only problem I see is how > predictable program behaviour is. Does the patch re-grab window > bindings when the name/class/resource of the window changes? If > so, it may be a performance hog, if not, it may confuse the user. > I don't see a good way to handle both problems at the same time. The patch handles windows that dynamically change name/class/resource. I just wrote a small Perl/Tk app to change the window name at the click of a button ($mw->configure(-title => ...)) to confirm this. As for performance, it should be pretty good. Looking up a window-specific binding should take about the same amount of time, but looking up a global binding will be (on average) about twice as long. This is because in CheckBinding() we search the whole binding list in the hope of finding a window-specific binding. Previously, when searching the binding list we would stop as soon as we found a matching binding (as we do now for window-specific bindings). Anyway, only bean-counters will be unhappy with the performance change. (I tried to make it as efficient as possible.) As for confusing the user - yes I agree. Most apps won't change their class/resource name, however, & a decent wildcard pattern for window names should avoid most problems. > - The reference to regular expressions is wrong. Wildcard > matching in fvwm has nothing to do with regular expressions Ah yes. Well spotted. > - I'd rather see the four name strings put into a structure (to > reduce the number arguments passed to the functions). A good idea. A shame the XClassHint structure only holds the class & resource names. "four name string" - I thought only 3? > - Is there a specific reason why the patch handles only key > bindings? It should be trivial to extend it to handle mouse and > stroke bindings too. I've always said the patch supports both key & mouse bindings. (The fvwm man page gives an example of how to use both.) I've never used stroke bindings - I'll have a look. SCoTT. :) -- [EMAIL PROTECTED] -- Visit the official FVWM web page at 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]
Re: PATCH: window-specific key/mouse bindings
On Tue, Mar 02, 2004 at 04:34:52PM +1100, Scott Smedley wrote: > Hi all, > > Find attached my final patch to bind key &/or mouse events to > individual windows. Thanks for your work, Scott. The only problem I see is how predictable program behaviour is. Does the patch re-grab window bindings when the name/class/resource of the window changes? If so, it may be a performance hog, if not, it may confuse the user. I don't see a good way to handle both problems at the same time. Anyway, I think I will try this patch with some cosmetic changes. Some other comments: - The reference to regular expressions is wrong. Wildcard matching in fvwm has nothing to do with regular expressions (although it were nice if it had). - I'd rather see the four name strings put into a structure (to reduce the number arguments passed to the functions). - Is there a specific reason why the patch handles only key bindings? It should be trivial to extend it to handle mouse and stroke bindings too. Ciao Dominik ^_^ ^_^ -- Visit the official FVWM web page at 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]
PATCH: window-specific key/mouse bindings
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 - 1.360 +++ fvwm/add_window.c 2 Mar 2004 05:25:14 - @@ -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 - 1.87 +++ fvwm/bindings.c 2 Mar 2004 05:25:14 - @@ -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; +} +