key handling in 1.4.1-mmc



Let me explain one of the new features: the precise handling of
keyboard events:


How to manage the key grabs, and request more key events.


* How to grab (keys)

** passive grabs cannot be asynchronous:

This gives little control, if we wanted to grab actively, it may
be too late (i.e. other key events already were distributed).


** neither synchro passive grabs are not 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 regrab and later ungrab
explicitely.





* 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
run `allow-events' `ungrab-keyboard' w/o 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, the C code should
request the next event.


*** Summary: Lisp defines what considers an event, and
the C part issues XallowEvent appropriately, w/o 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. when we release the keyboard.


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 needs the keyboard.


** high level lisp api:

-  grab-keyboard-soft
increments the counter. Moreover, it issues grab-keyboard. This is
for the situation, when you try a function from repl. This might
be avoided probably.
                                 
-  ungrab-keyboard-soft          decrements the counter.

-  call-with-keyboard-grabbed-soft thunk
                          protects thunk w/ counter increased

-  call-with-keyboard-grabbed-synchro thunk
                                 same, but assures that the grab
                                 is synchro

All these function are ready to be used from repl.


- obsolete:  call-with-keyboard-grabbed

- read-event is ok now.

Please note, that when entering (recursive-edit) you have to
(allow-events 'sync-keyboard) before, from lisp.



* notes:

I had tried several versions, and the C code remained cluttered.
Lisp code also, but less.



I also simplified and _corrected_ the code and you can get a new 
version here:

http://maruska.dyndns.org/comp/packages/sawfish-1.4.1-mmc.tar.gz 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]