[PATCH xserver] XKB: Redirect actions defunct with Gtk3 (XInput?)
Peter Hutterer
peter.hutterer at who-t.net
Sun Feb 26 18:58:20 PST 2012
On Sat, Feb 25, 2012 at 08:48:17PM +0100, wettstein509 at solnet.ch wrote:
> When redirect actions are used with Gtk3, Gtk3 complained about
> events not holding a GdkDevice. This was caused by device IDs
> not being set for redirect actions.
>
> More seriously, Gtk3 did not receive state changes redirect
> actions might specify. This was because event_set_state in
> dix/inpututils.c accesses the prev_state field, but the changes
> for the redirect action were only put into the state field.
>
> Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
Thanks. I've merged this into my -next branch. With the release due this
weekend, we're down to blockers only.
Cheers,
Peter
> ---
> xkb/xkbActions.c | 28 +++++++++++++++++++++++-----
> 1 files changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
> index da0bdea..891179b 100644
> --- a/xkb/xkbActions.c
> +++ b/xkb/xkbActions.c
> @@ -795,7 +795,7 @@ _XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
> {
> DeviceEvent ev;
> int x,y;
> -XkbStateRec old;
> +XkbStateRec old, old_prev;
> unsigned mods,mask;
> xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
> ProcessInputProc backupproc;
> @@ -803,6 +803,7 @@ ProcessInputProc backupproc;
> /* never actually used uninitialised, but gcc isn't smart enough
> * to work that out. */
> memset(&old, 0, sizeof(old));
> + memset(&old_prev, 0, sizeof(old_prev));
> memset(&ev, 0, sizeof(ev));
>
> if ((filter->keycode!=0)&&(filter->keycode!=keycode))
> @@ -814,6 +815,11 @@ ProcessInputProc backupproc;
> ev.time = GetTimeInMillis();
> ev.root_x = x;
> ev.root_y = y;
> + /* redirect actions do not work across devices, therefore the following is
> + * correct: */
> + ev.deviceid = xkbi->device->id;
> + /* filter->priv must be set up by the caller for the initial press. */
> + ev.sourceid = filter->priv;
>
> if (filter->keycode==0) { /* initial press */
> if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
> @@ -823,7 +829,6 @@ ProcessInputProc backupproc;
> filter->keycode = keycode;
> filter->active = 1;
> filter->filterOthers = 0;
> - filter->priv = 0;
> filter->filter = _XkbFilterRedirectKey;
> filter->upAction = *pAction;
>
> @@ -839,6 +844,7 @@ ProcessInputProc backupproc;
>
> if ( mask || mods ) {
> old= xkbi->state;
> + old_prev= xkbi->prev_state;
> xkbi->state.base_mods&= ~mask;
> xkbi->state.base_mods|= (mods&mask);
> xkbi->state.latched_mods&= ~mask;
> @@ -846,15 +852,18 @@ ProcessInputProc backupproc;
> xkbi->state.locked_mods&= ~mask;
> xkbi->state.locked_mods|= (mods&mask);
> XkbComputeDerivedState(xkbi);
> + xkbi->prev_state= xkbi->state;
> }
>
> UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
> xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
> COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
> backupproc,xkbUnwrapProc);
> -
> - if ( mask || mods )
> +
> + if ( mask || mods ) {
> xkbi->state= old;
> + xkbi->prev_state= old_prev;
> + }
> }
> else if (filter->keycode==keycode) {
>
> @@ -870,6 +879,7 @@ ProcessInputProc backupproc;
>
> if ( mask || mods ) {
> old= xkbi->state;
> + old_prev= xkbi->prev_state;
> xkbi->state.base_mods&= ~mask;
> xkbi->state.base_mods|= (mods&mask);
> xkbi->state.latched_mods&= ~mask;
> @@ -877,6 +887,7 @@ ProcessInputProc backupproc;
> xkbi->state.locked_mods&= ~mask;
> xkbi->state.locked_mods|= (mods&mask);
> XkbComputeDerivedState(xkbi);
> + xkbi->prev_state= xkbi->state;
> }
>
> UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
> @@ -884,8 +895,10 @@ ProcessInputProc backupproc;
> COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
> backupproc,xkbUnwrapProc);
>
> - if ( mask || mods )
> + if ( mask || mods ) {
> xkbi->state= old;
> + xkbi->prev_state= old_prev;
> + }
>
> filter->keycode= 0;
> filter->active= 0;
> @@ -1155,6 +1168,11 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
> break;
> case XkbSA_RedirectKey:
> filter = _XkbNextFreeFilter(xkbi);
> + /* redirect actions must create a new DeviceEvent. The
> + * source device id for this event cannot be obtained from
> + * xkbi, so we pass it here explicitly. The field deviceid
> + * equals to xkbi->device->id. */
> + filter->priv = event->sourceid;
> sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
> break;
> case XkbSA_DeviceBtn:
> --
> 1.7.6
>
More information about the xorg-devel
mailing list