Hi all,

Find attached a patch to FVWM to define key-bindings on individual
windows. (Previously, a key binding had to be defined for ALL windows
or NONE.)

Example .fvwm2rc syntax:

=== BEGIN ===

AddToFunc CtrlTab
+ I Current (FvwmTabs) Function NextTab
+ I Current (!FvwmTabs) SendKeyEvent current

Key Tab A C Function CtrlTab

=== END ===

Here, Ctrl-Tab in an FvwmTabs window will perform a 'NextTab' operation
but in all other windows the Ctrl-Tab keypress is passed through untouched.
(ie. is treated as if there were no FVWM key binding for Ctrl-Tab.)

The patch involves the addition of a new keyword - SendKeyEvent
which basically allows the intercepted key event to be sent through
to a specified window. I hope to generalise SendKeyEvent to be able to
send ANY key event in the near future. (Maybe call it FakeKeypress?)

If this patch is applied I am happy to update the doco.

Comments/criticism most welcome.

SCoTTie! :)
Index: fvwm/builtins.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/builtins.c,v
retrieving revision 1.404
diff -u -r1.404 builtins.c
--- fvwm/builtins.c     24 Jan 2004 23:20:21 -0000      1.404
+++ fvwm/builtins.c     13 Feb 2004 04:00:23 -0000
@@ -4252,3 +4252,46 @@
 
        return;
 }
+
+void fev_copy_last_event(XEvent *dest); /* libs/FEvent.c */
+
+void CMD_SendKeyEvent(F_CMD_ARGS)
+{
+       char *token;
+       FvwmWindow *fw = exc->w.fw;
+       XEvent e;
+
+       if (fw == NULL)
+       {
+               fvwm_msg(ERR, "CMD_SendKeyEvent", "No window specified\n");
+               return;
+       }
+
+       fev_copy_last_event(&e);
+
+       action = GetNextToken(action, &token);
+       if (!token || StrEquals(token, "current"))
+       {
+               if (e.type != KeyPress)
+               {
+                       fvwm_msg(ERR, "CMD_SendKeyEvent", "Last event wasn't 
keypress\n");
+                       return;
+               }
+       }
+       else
+       {
+               KeySym keysym = XStringToKeysym(token);
+               // fvwm_msg(DBG, "CMD_SendKeyEvent", "keysym value: %d\n", 
keysym);
+               if (keysym == NoSymbol)
+               {
+                       fvwm_msg(ERR, "CMD_SendKeyEvent", "Unknown keysym: 
%s\n", token);
+                       return;
+               }
+               e.xkey.type = KeyPress;
+               e.xkey.state = 0;       // TODO: Ctrl/Shift/Alt/Meta etc.
+               e.xkey.keycode = XKeysymToKeycode(dpy, keysym);
+       }
+       e.xkey.window = FW_W(fw);
+       FSendEvent(dpy, e.xkey.window, False, KeyPressMask, &e);
+       return;
+}
Index: fvwm/commands.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/commands.h,v
retrieving revision 1.41
diff -u -r1.41 commands.h
--- fvwm/commands.h     16 Jul 2003 09:10:40 -0000      1.41
+++ fvwm/commands.h     13 Feb 2004 04:00:23 -0000
@@ -185,6 +185,7 @@
        F_WINDOWID,
        F_WINDOW_SHADE,
        F_WINDOW_STYLE,
+       F_SEND_KEY_EVENT,
 
        F_END_OF_LIST = 999,
 
@@ -343,6 +344,7 @@
 P(Scroll);
 P(Send_ConfigInfo);
 P(Send_WindowList);
+P(SendKeyEvent);
 P(SendToModule);
 P(set_mask);
 P(set_nograb_mask);
Index: fvwm/functable.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/functable.c,v
retrieving revision 1.29
diff -u -r1.29 functable.c
--- fvwm/functable.c    16 Jul 2003 09:10:40 -0000      1.29
+++ fvwm/functable.c    13 Feb 2004 04:00:24 -0000
@@ -516,6 +516,10 @@
                FUNC_DONT_REPEAT, 0),
        /* - Internal, used for module communication */
 
+       CMD_ENT("sendkeyevent", CMD_SendKeyEvent, F_SEND_KEY_EVENT,
+               FUNC_NEEDS_WINDOW, CRS_SELECT),
+    /* - Send a keyboard event to a window */
+
        CMD_ENT("sendtomodule", CMD_SendToModule, F_SEND_STRING,
                FUNC_DONT_REPEAT, 0),
        /* - Send a string (action) to a module */

Reply via email to