index

sawfish: How to read all necessary key events, and nothing more

Original (and messy) text was sent to the sawfish ML. Here much improved.

How to grab (keys)

passive grabs cannot be asynchronous (in general):

This gives little control in case the invoked command decides to grab actively; it may be too late, because other key events have already been distributed to the focused window.

neither synchro passive grabs are enough.

the grab ends with the release of the grabbed key. That means that if we grab H-i, this sequence (which might occur if i type quickly) Hyper-press, i-press, Hyper-Release, e-Press, i-Release will deliver the "e-press" to the grabber. This is undesired! But it can occur by mistake (wrong synchronization of fingers).

I think, that this is a non-intended feature, but i don't know of any proposal for different behaviour.

SUMMARY: we have to grab passively synchro, and once the

passive grab activates, we have to ungrab explicitely, in case we don't need/want more key events, otherwise we have to grab actively.

How to allow-events (i.e. request more key events)

If the lisp code has a possibility to grab-keyboard, it seems plausible, that the C code should not disregard it, and should not run `allow-events' `ungrab-keyboard' without precise rules.

We must use only synchronous allow-events.

When the C part composes a path in a keymap (to find which command to invoke), we should not read more events, so we proceed 1 by 1.

C part must coordinate with lisp on reading next event:

lisp part decides and instructs the C part whether other key events are needed to complete a command/action.

OTOH, i want to isolate the lisp code from some boring tasks:

C might take care about skipping over modifier events, key-releases. C is told what to do through keymaps, 2 variables eval-key-release-events and eval_modifier_events and the unbound-key-hook.

My reasoning is this: If lisp requests more key events, and eval-key-release-events or eval-modifier-events indicate that lisp is not interested in an arrived event (because it is a modifier, or a keyRelease), the C code should request the next event.

Summary: Lisp defines what considers an event, and

the C part issues XallowEvent appropriately, without reading anything else, i.e. all synchronously.

note: there is currently no way to grab keyboard and prevent C from calling any XAllowEvent. There is code for it, and once I used it (to freeze the keyboard for some time), but since then i changed the lisp--C synchronization and didn't update this feature.

When to ungrab?

As i explained above, we have to ungrab explicitely, instead of using "passive" key grab. Also, ungrabbing has to be synchronized with change of focused window: we ungrab "into" a certain window. We don't want any following key-events to be delivered to the previously focused window, or any other random window.

So the (possible) XSetInputFocus must be issued before XUngrabKeyboard. And since C postpones the XSetInputFocus, the lisp code must delegate the C part for (postponed) ungrabbing as well.

I added another variable: grab-counter

It's a counter, like one used for "reference counting". the C code starts with 0, which means that Lisp is not requiring anything, and C can ungrab. Any "subsystem" in Lisp should raise this counter when it (still) needs the keyboard.

ungrab_into_focused_window

high level lisp api:

All these function are ready to be used from repl.

Please note, that when entering (recursive-edit) you have to (allow-events 'sync-keyboard) before, from lisp! The usual C part does not follow! This needs fix.

links:

http://incise.org/index.cgi/XlibKeyPassing still incorrect approach?

http://www.std.org/~msm/common/protocol.pdf

Key-processor

new feature to have a look on key events before C processes them.