On Mon, Nov 24, 2014 at 10:17:33PM +, Daniel Stone wrote:
> KeyFocusIn is used to notify the server that it has entered focus with a
> key held down, so should be used to update the internal state (including
> modifiers), but perform any actions such as sending key events to the
> client, switching VTs, etc.
typo: "not perform any actions"
> This is intended to be used for FocusIn/KeymapNotify when running nested
> servers such as Xephyr, as well as a wl_keyboard::enter event from
> XWayland.
>
> Running the currently-pressed keys through the entire XKB event
> mechanism is quite fragile, and will produce incorrect results in some
> cases, e.g. entering with Shift+AltGr pressed when Shift→AltGr will
> produce different results to AltGr→Shift. In this case, we need to lift
> the _actual_ modifier state from the parent server, however this is a
> much larger job.
>
> Signed-off-by: Daniel Stone
> Tested-by: Giulio Camuffo
> ---
> Xi/exevents.c | 8 +++-
> dix/events.c | 5 +++--
> dix/getevents.c| 7 ++-
> dix/inpututils.c | 3 ++-
> include/eventstr.h | 1 +
> xkb/xkbActions.c | 38 ++
> xkb/xkbPrKeyEv.c | 8 +---
> 7 files changed, 58 insertions(+), 12 deletions(-)
>
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index b0bc47e..cd2924a 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -810,6 +810,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent *event)
> case ET_ButtonPress:
> case ET_ButtonRelease:
> case ET_KeyPress:
> +case ET_KeyFocusIn:
I would honestly prefer some different name. We do real focus in events, I'd
like to avoid potential confusion here. How about ET_ServerFocusIn?
but see my reply to 3/3, an extra field in the ET_KeyPress event should
serve us just fine here too.
> case ET_KeyRelease:
> case ET_ProximityIn:
> case ET_ProximityOut:
> @@ -854,7 +855,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent *event)
> v->axisVal[i] = event->valuators.data[i];
> }
>
> -if (event->type == ET_KeyPress) {
> +if (event->type == ET_KeyPress || event->type == ET_KeyFocusIn) {
> if (!k)
> return DONT_PROCESS;
>
> @@ -1715,6 +1716,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr
> device)
> case ET_ButtonPress:
> case ET_ButtonRelease:
> case ET_KeyPress:
> +case ET_KeyFocusIn:
> case ET_KeyRelease:
> case ET_ProximityIn:
> case ET_ProximityOut:
> @@ -1749,6 +1751,10 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr
> device)
> if (!grab && CheckDeviceGrabs(device, event, 0))
> return;
> break;
> +case ET_KeyFocusIn:
> + /* FocusIn events are just for internal state management, and do not
> + * get posted to clients. */
> + return;
you need to run a tab vs space replace on this patch (and maybe the other
two patches as well).
> case ET_KeyRelease:
> if (grab && device->deviceGrab.fromPassiveGrab &&
> (key == device->deviceGrab.activatingKey) &&
> diff --git a/dix/events.c b/dix/events.c
> index b8c67fd..49f21d1 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -4308,10 +4308,11 @@ FixKeyState(DeviceEvent *event, DeviceIntPtr keybd)
>
> if (event->type == ET_KeyPress) {
> DebugF("FixKeyState: Key %d %s\n", key,
> - ((event->type == ET_KeyPress) ? "down" : "up"));
> + ((event->type == ET_KeyPress) ? "down" :
> + ((event->type == ET_KeyFocusIn) ? "down (focus)" : "up")));
> }
>
> -if (event->type == ET_KeyPress)
> +if (event->type == ET_KeyPress || event->type == ET_KeyFocusIn)
> set_key_down(keybd, key, KEY_PROCESSED);
> else if (event->type == ET_KeyRelease)
> set_key_up(keybd, key, KEY_PROCESSED);
> diff --git a/dix/getevents.c b/dix/getevents.c
> index dd96265..c2248fb 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -1120,7 +1120,8 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr
> pDev, int type,
> UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT,
> &num_events);
>
> /* Handle core repeating, via press/release/press/release. */
> -if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
> +if ((type == KeyPress || type == KeymapNotify) &&
> +key_is_down(pDev, key_code, KEY_POSTED)) {
> /* If autorepeating is disabled either globally or just for that key,
> * or we have a modifier, don't generate a repeat event. */
> if (!pDev->kbdfeed->ctrl.autoRepeat ||
> @@ -1152,6 +1153,10 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr
> pDev, int type,
> event->type = ET_KeyPress;
> set_key_down(pDev, key_code, KEY_POSTED);
> }
> +else if (type == KeymapNotify) {
> + event->type = ET_KeyFocusIn;
> + set_key_down(pDev, key_code, KEY_POSTED);
> +}
> else if (