[PATCH v3 01/10] winex11.drv: Make it possible to merge events across process_events calls.
Rémi Bernon
rbernon at codeweavers.com
Mon Oct 7 08:02:07 CDT 2019
We will have to wait for several process_events calls while delaying
FocusIn events.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winex11.drv/event.c | 73 +++++++++++++++++++++++++--------------
dlls/winex11.drv/x11drv.h | 1 +
2 files changed, 48 insertions(+), 26 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 25730192d3d..32fdf23bf35 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -404,22 +404,50 @@ static inline BOOL call_event_handler( Display *display, XEvent *event )
return ret;
}
+static inline BOOL merge_and_handle_events( Display *display, XEvent *prev, XEvent *next )
+{
+ enum event_merge_action action = MERGE_DISCARD;
+ BOOL queued = FALSE;
+
+ if (prev->type) action = merge_events( prev, next );
+ switch( action )
+ {
+ case MERGE_HANDLE: /* handle prev, keep new */
+ queued |= call_event_handler( display, prev );
+ /* fall through */
+ case MERGE_DISCARD: /* discard prev, keep new */
+ free_event_data( prev );
+ *prev = *next;
+ break;
+ case MERGE_KEEP: /* handle new, keep prev for future merging */
+ if (!next->type) break;
+ queued |= call_event_handler( display, next );
+ /* fall through */
+ case MERGE_IGNORE: /* ignore new, keep prev for future merging */
+ free_event_data( next );
+ break;
+ }
+
+ return queued;
+}
/***********************************************************************
* process_events
*/
static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,XPointer), ULONG_PTR arg )
{
- XEvent event, prev_event;
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+ XEvent event, *next = &event, *prev = &thread_data->prev_event;
int count = 0;
BOOL queued = FALSE;
- enum event_merge_action action = MERGE_DISCARD;
- prev_event.type = 0;
- while (XCheckIfEvent( display, &event, filter, (char *)arg ))
+ next->type = 0;
+ if (prev->type) get_event_data( prev );
+
+ while (XCheckIfEvent( display, next, filter, (char *)arg ))
{
count++;
- if (XFilterEvent( &event, None ))
+ if (XFilterEvent( next, None ))
{
/*
* SCIM on linux filters key events strangely. It does not filter the
@@ -433,7 +461,7 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
if (event.type == KeyRelease)
{
KeySym keysym = 0;
- XKeyEvent *keyevent = &event.xkey;
+ XKeyEvent *keyevent = &next->xkey;
XLookupString(keyevent, NULL, 0, &keysym, NULL);
if (!(keysym == XK_Shift_L ||
@@ -449,27 +477,20 @@ static BOOL process_events( Display *display, Bool (*filter)(Display*, XEvent*,X
else
continue; /* filtered, ignore it */
}
- get_event_data( &event );
- if (prev_event.type) action = merge_events( &prev_event, &event );
- switch( action )
- {
- case MERGE_HANDLE: /* handle prev, keep new */
- queued |= call_event_handler( display, &prev_event );
- /* fall through */
- case MERGE_DISCARD: /* discard prev, keep new */
- free_event_data( &prev_event );
- prev_event = event;
- break;
- case MERGE_KEEP: /* handle new, keep prev for future merging */
- queued |= call_event_handler( display, &event );
- /* fall through */
- case MERGE_IGNORE: /* ignore new, keep prev for future merging */
- free_event_data( &event );
- break;
- }
+ get_event_data( next );
+ queued |= merge_and_handle_events( display, prev, next );
}
- if (prev_event.type) queued |= call_event_handler( display, &prev_event );
- free_event_data( &prev_event );
+
+ if (prev->type && !thread_data->current_event)
+ {
+ next->type = 0;
+ queued |= merge_and_handle_events( display, prev, next );
+ free_event_data( prev );
+
+ /* retry handling prev next time */
+ if (prev->type) queued |= 1;
+ }
+
XFlush( gdi_display );
if (count) TRACE( "processed %d events, returning %d\n", count, queued );
return queued;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 135faa8989b..e44239d834f 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -323,6 +323,7 @@ struct x11drv_valuator_data
struct x11drv_thread_data
{
Display *display;
+ XEvent prev_event; /* event to be eventually merged */
XEvent *current_event; /* event currently being processed */
HWND grab_hwnd; /* window that currently grabs the mouse */
HWND last_focus; /* last window that had focus */
--
2.23.0
More information about the wine-devel
mailing list