[PATCH xserver] XKB: Redirect actions defunct with Gtk3 (XInput?)
wettstein509 at solnet.ch
wettstein509 at solnet.ch
Sat Feb 25 11:48:17 PST 2012
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>
---
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