Re: PATCH: window-specific key/mouse bindings

2004-03-02 Thread scott
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

2004-03-02 Thread scott
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

2004-03-02 Thread scott
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

2004-03-02 Thread Dan Espen
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

2004-03-02 Thread Dominik Vogt
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

2004-03-02 Thread scott
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

2004-03-02 Thread Dominik Vogt
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

2004-03-02 Thread scott
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

2004-03-02 Thread Dominik Vogt
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

2004-03-01 Thread Scott Smedley
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;
+}
+