XKB: Redirect actions defunct with Gtk3 (XInput?)
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@solnet.ch> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
ab3a815a75
commit
9e017cf0cf
|
@ -799,7 +799,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
{
|
{
|
||||||
DeviceEvent ev;
|
DeviceEvent ev;
|
||||||
int x, y;
|
int x, y;
|
||||||
XkbStateRec old;
|
XkbStateRec old, old_prev;
|
||||||
unsigned mods, mask;
|
unsigned mods, mask;
|
||||||
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
|
xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
|
||||||
ProcessInputProc backupproc;
|
ProcessInputProc backupproc;
|
||||||
|
@ -807,6 +807,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
/* never actually used uninitialised, but gcc isn't smart enough
|
/* never actually used uninitialised, but gcc isn't smart enough
|
||||||
* to work that out. */
|
* to work that out. */
|
||||||
memset(&old, 0, sizeof(old));
|
memset(&old, 0, sizeof(old));
|
||||||
|
memset(&old_prev, 0, sizeof(old_prev));
|
||||||
memset(&ev, 0, sizeof(ev));
|
memset(&ev, 0, sizeof(ev));
|
||||||
|
|
||||||
if ((filter->keycode != 0) && (filter->keycode != keycode))
|
if ((filter->keycode != 0) && (filter->keycode != keycode))
|
||||||
|
@ -818,6 +819,11 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
ev.time = GetTimeInMillis();
|
ev.time = GetTimeInMillis();
|
||||||
ev.root_x = x;
|
ev.root_x = x;
|
||||||
ev.root_y = y;
|
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 (filter->keycode == 0) { /* initial press */
|
||||||
if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
|
if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
|
||||||
|
@ -827,7 +833,6 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
filter->keycode = keycode;
|
filter->keycode = keycode;
|
||||||
filter->active = 1;
|
filter->active = 1;
|
||||||
filter->filterOthers = 0;
|
filter->filterOthers = 0;
|
||||||
filter->priv = 0;
|
|
||||||
filter->filter = _XkbFilterRedirectKey;
|
filter->filter = _XkbFilterRedirectKey;
|
||||||
filter->upAction = *pAction;
|
filter->upAction = *pAction;
|
||||||
|
|
||||||
|
@ -845,6 +850,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
|
|
||||||
if (mask || mods) {
|
if (mask || mods) {
|
||||||
old = xkbi->state;
|
old = xkbi->state;
|
||||||
|
old_prev = xkbi->prev_state;
|
||||||
xkbi->state.base_mods &= ~mask;
|
xkbi->state.base_mods &= ~mask;
|
||||||
xkbi->state.base_mods |= (mods & mask);
|
xkbi->state.base_mods |= (mods & mask);
|
||||||
xkbi->state.latched_mods &= ~mask;
|
xkbi->state.latched_mods &= ~mask;
|
||||||
|
@ -852,6 +858,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
xkbi->state.locked_mods &= ~mask;
|
xkbi->state.locked_mods &= ~mask;
|
||||||
xkbi->state.locked_mods |= (mods & mask);
|
xkbi->state.locked_mods |= (mods & mask);
|
||||||
XkbComputeDerivedState(xkbi);
|
XkbComputeDerivedState(xkbi);
|
||||||
|
xkbi->prev_state = xkbi->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
|
UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
|
||||||
|
@ -860,8 +867,10 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
|
COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
|
||||||
xkbUnwrapProc);
|
xkbUnwrapProc);
|
||||||
|
|
||||||
if (mask || mods)
|
if (mask || mods) {
|
||||||
xkbi->state = old;
|
xkbi->state = old;
|
||||||
|
xkbi->prev_state = old_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (filter->keycode == keycode) {
|
else if (filter->keycode == keycode) {
|
||||||
|
|
||||||
|
@ -879,6 +888,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
|
|
||||||
if (mask || mods) {
|
if (mask || mods) {
|
||||||
old = xkbi->state;
|
old = xkbi->state;
|
||||||
|
old_prev = xkbi->prev_state;
|
||||||
xkbi->state.base_mods &= ~mask;
|
xkbi->state.base_mods &= ~mask;
|
||||||
xkbi->state.base_mods |= (mods & mask);
|
xkbi->state.base_mods |= (mods & mask);
|
||||||
xkbi->state.latched_mods &= ~mask;
|
xkbi->state.latched_mods &= ~mask;
|
||||||
|
@ -886,6 +896,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
xkbi->state.locked_mods &= ~mask;
|
xkbi->state.locked_mods &= ~mask;
|
||||||
xkbi->state.locked_mods |= (mods & mask);
|
xkbi->state.locked_mods |= (mods & mask);
|
||||||
XkbComputeDerivedState(xkbi);
|
XkbComputeDerivedState(xkbi);
|
||||||
|
xkbi->prev_state = xkbi->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
|
UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
|
||||||
|
@ -894,8 +905,10 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
|
||||||
COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
|
COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
|
||||||
xkbUnwrapProc);
|
xkbUnwrapProc);
|
||||||
|
|
||||||
if (mask || mods)
|
if (mask || mods) {
|
||||||
xkbi->state = old;
|
xkbi->state = old;
|
||||||
|
xkbi->prev_state = old_prev;
|
||||||
|
}
|
||||||
|
|
||||||
filter->keycode = 0;
|
filter->keycode = 0;
|
||||||
filter->active = 0;
|
filter->active = 0;
|
||||||
|
@ -1165,6 +1178,11 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
|
||||||
break;
|
break;
|
||||||
case XkbSA_RedirectKey:
|
case XkbSA_RedirectKey:
|
||||||
filter = _XkbNextFreeFilter(xkbi);
|
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);
|
sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
|
||||||
break;
|
break;
|
||||||
case XkbSA_DeviceBtn:
|
case XkbSA_DeviceBtn:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user