Record: Avoid duplicates from replaying frozen events

Reintroduce a check which used to be there in the old
ProcessKeyboardEvent/ProcessPointerEvent codepath, which avoids us
recording events subject to a grab twice: once when it's first processed
in EnqueueEvent, and then again when it's thawed and being replayed.

This required a tiny amount of code motion to expose syncEvents.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
(cherry picked from commit a2ea8c2f2c)

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Daniel Stone 2010-03-11 14:19:04 +02:00 committed by Peter Hutterer
parent 2086e4920a
commit a69c7a4c53
3 changed files with 32 additions and 28 deletions

View File

@ -1051,7 +1051,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
break;
}
if (DeviceEventCallback) {
if (DeviceEventCallback && !syncEvents.playingEvents) {
DeviceEventInfoRec eventinfo;
SpritePtr pSprite = device->spriteInfo->sprite;

View File

@ -253,33 +253,7 @@ extern BOOL EventIsKeyRepeat(xEvent *event);
*/
InputInfo inputInfo;
/**
* syncEvents is the global structure for queued events.
*
* Devices can be frozen through GrabModeSync pointer grabs. If this is the
* case, events from these devices are added to "pending" instead of being
* processed normally. When the device is unfrozen, events in "pending" are
* replayed and processed as if they would come from the device directly.
*/
static struct {
QdEventPtr pending, /**< list of queued events */
*pendtail; /**< last event in list */
/** The device to replay events for. Only set in AllowEvents(), in which
* case it is set to the device specified in the request. */
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
/**
* The window the events are supposed to be replayed on.
* This window may be set to the grab's window (but only when
* Replay{Pointer|Keyboard} is given in the XAllowEvents()
* request. */
WindowPtr replayWin; /* ComputeFreezes */
/**
* Flag to indicate whether we're in the process of
* replaying events. Only set in ComputeFreezes(). */
Bool playingEvents;
TimeStamp time;
} syncEvents;
EventSyncInfoRec syncEvents;
/**
* The root window the given device is currently on.

View File

@ -557,4 +557,34 @@ typedef struct _QdEvent {
InternalEvent *event;
} QdEventRec;
/**
* syncEvents is the global structure for queued events.
*
* Devices can be frozen through GrabModeSync pointer grabs. If this is the
* case, events from these devices are added to "pending" instead of being
* processed normally. When the device is unfrozen, events in "pending" are
* replayed and processed as if they would come from the device directly.
*/
typedef struct _EventSyncInfo {
QdEventPtr pending, /**< list of queued events */
*pendtail; /**< last event in list */
/** The device to replay events for. Only set in AllowEvents(), in which
* case it is set to the device specified in the request. */
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
/**
* The window the events are supposed to be replayed on.
* This window may be set to the grab's window (but only when
* Replay{Pointer|Keyboard} is given in the XAllowEvents()
* request. */
WindowPtr replayWin; /* ComputeFreezes */
/**
* Flag to indicate whether we're in the process of
* replaying events. Only set in ComputeFreezes(). */
Bool playingEvents;
TimeStamp time;
} EventSyncInfoRec, *EventSyncInfoPtr;
extern EventSyncInfoRec syncEvents;
#endif /* INPUTSTRUCT_H */