On Fri, Feb 13, 2004 at 03:06:06PM +1100, Scott Smedley wrote: > 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.
I'm not quite happy with this patch for several reasons. 1) Generating keyboard events out of sequence can totally confuse applications or fvwm itself. In your example, you hold down Ctrl and tap tha Tab key. The modifier mask has the bit for the Ctrl key set. Now the event is passed on, but when it is processed by fvwm or the receiving application, the real modifier mask may have already changed. This can lead to erratic behaviour. For example, an application may wait for a KeyRelease event that will never come. 2) It suffers from the same problems as the FakeClick command. Apart from #1 above, it's impossible to determine to which window the event has to be sent. There is no guarantee that the top level client window is able to handle key events. I'm not saying the patch is useless. It would be nice to further improve it to a clone of FakeClick that can replay key and modifier press and release events and send them to arbitrary windows (not just client windows). But a future FakeKey command has to be marked as a debug command to "use at own risk" like FakeClick. I'll accept a patch that duplicates the FakeClick syntax (or better: unifies both commands to use the same core loop). The application-specific-bindings problem, however, can only be solved in a different way. The binding syntax and code can be enhanced to allow window selection similar to the Style command. (Side note to Mikhael and Olivier: see why I want a unified syntax for Style + WindowStyle? If we had a single style target spec syntax, it could easily be applied to the binding commands too. Instead, we now need new commands WindowKey, WindowMouse and WindowPointerKey). > 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 */ You don't need this function and it does not copy the event you think it does. See below. > + > +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); Just make a copy of exc->x.etrigger: e = *(exc->x.etrigger); You are not really interested in the last event received by fvwm but in the event that triggered the function. I know, the whole FEvent.[ch] and execcontext.[ch] code should be documented ... > + > + 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); Use FvwmStringToKeysym() from libs/Bindings.h instead. It does some extra things to normalize the returned KeySym. > + // 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 */ Ciao Dominik ^_^ ^_^ -- Visit the official FVWM web page at <URL: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]