From 364d64981549544213e2bca8de6ff8a5b2b5a69e Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 30 Oct 2018 18:43:51 +0100 Subject: [PATCH] dix: do not send focus event when grab actually does not change c67f2eac5651 ("dix: always send focus event on grab change") made dix always sent events when it's a NotifyGrab or NotifyUngrab, even if from == to, because 'from' can just come from a previous XSetInputFocus call. However, when an application calls XGrabKeyboard several times on the same window, we are now sending spurious FocusOut+FocusIn with NotifyGrab, even if the grab does not actually change. This makes screen readers for blind people spuriously emit activity events which disturb screen reading workflow when e.g. switching between menus. This commit avoids calling DoFocusEvents in that precise case, i.e. when oldWin is a previous grab and the new grab is the same window. Signed-off-by: Samuel Thibault Reviewed-by: Adam Jackson --- dix/events.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dix/events.c b/dix/events.c index b12d731dd..98ea15b5b 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1530,7 +1530,9 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, mouse->spriteInfo->sprite->hotPhys.y = 0; ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); } - DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); + if (! (grabinfo->grab && oldWin == grabinfo->grab->window + && oldWin == grab->window)) + DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); mouse->valuator->motionHintWindow = NullWindow; if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time; @@ -1640,7 +1642,9 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, oldWin = keybd->focus->win; if (keybd->valuator) keybd->valuator->motionHintWindow = NullWindow; - if (oldWin) + if (oldWin && + ! (grabinfo->grab && oldWin == grabinfo->grab->window + && oldWin == grab->window)) DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); if (syncEvents.playingEvents) grabinfo->grabTime = syncEvents.time;