--- b/Xi/exevents.c 2013-12-27 19:38:52.000000000 +0200 +++ a/Xi/exevents.c 2014-03-04 19:44:15.228721619 +0200 @@ -665,7 +665,8 @@ DeepCopyFeedbackClasses(from, to); if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) - DeepCopyKeyboardClasses(from, to); + /* We need to copy to MASTER_KEYBOARD. Didn't worked with 'to'. */ + DeepCopyKeyboardClasses(from, GetMaster(from, MASTER_KEYBOARD)); if ((dce->flags & DEVCHANGE_POINTER_EVENT)) DeepCopyPointerClasses(from, to); } --- b/dix/getevents.c 2013-12-27 19:38:52.000000000 +0200 +++ a/dix/getevents.c 2014-03-04 19:46:50.126336327 +0200 @@ -706,12 +706,19 @@ { DeviceIntPtr master; - master = - GetMaster(dev, - (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : - MASTER_KEYBOARD); + /* Don't guess the master upon the event type. Use MASTER_ATTACHED, + * otherwise we'll never get a DeviceChangedEvent(reason:SlaveSwith). */ + master = GetMaster(dev, MASTER_ATTACHED); + /* Need to track the slave event type. Other we'le never get a + * DeviceChangedEvent(reason:SlaveSwith) for the 'keyboard' if the + * 'pointer' has been touched before. */ + int slave_type = (type & DEVCHANGE_KEYBOARD_EVENT) | + (type & DEVCHANGE_POINTER_EVENT); - if (master && master->last.slave != dev) { + if (master && + ((master->last.slave != dev) || + (master->last.slave == dev && master->last.slave_type != slave_type))) { + master->last.slave_type = slave_type; CreateClassesChangedEvent(events, master, dev, type | DEVCHANGE_SLAVE_SWITCH); if (IsPointerDevice(master)) { --- b/include/inputstr.h 2013-12-27 19:38:52.000000000 +0200 +++ a/include/inputstr.h 2014-03-04 19:47:28.074051116 +0200 @@ -577,6 +577,7 @@ double valuators[MAX_VALUATORS]; int numValuators; DeviceIntPtr slave; + int slave_type; ValuatorMask *scroll; int num_touches; /* size of the touches array */ DDXTouchPointInfoPtr touches;