[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