From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/event.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 5018a8f8223..79b5cbe501b 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -348,6 +348,24 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE } #endif
+/* merge ConfigureNotify events to reduce the chances of window resize feedback loops */ +static BOOL merge_configure_events( Display *display, XEvent *prev, XEvent *next ) +{ + BOOL queued = FALSE; + + /* allow merging ConfigureNotify across Expose and PropertyNotify events */ + if (next->type == Expose || next->type == PropertyNotify) return FALSE; + if (next->type != ConfigureNotify) return handle_delayed_event( display, prev ); + + if (!prev->type || prev->xany.window != next->xany.window) queued |= handle_delayed_event( display, prev ); + else WARN( "discarding duplicate ConfigureNotify for window %lx\n", next->xany.window ); + + TRACE( "delaying ConfigureNotify for window %lx for merging\n", next->xany.window ); + *prev = *next; + next->type = 0; + return queued; +} + /*********************************************************************** * merge_events * @@ -357,21 +375,6 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) { switch (prev->type) { - case ConfigureNotify: - switch (next->type) - { - case ConfigureNotify: - if (prev->xany.window == next->xany.window) - { - TRACE( "discarding duplicate ConfigureNotify for window %lx\n", prev->xany.window ); - return MERGE_DISCARD; - } - break; - case Expose: - case PropertyNotify: - return MERGE_KEEP; - } - break; case MotionNotify: switch (next->type) { @@ -413,7 +416,7 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) */ BOOL X11DRV_ProcessEvents( DWORD mask ) { - XEvent event, prev_event; + XEvent event, prev_configure = {0}, prev_event; struct x11drv_thread_data *thread_data; Display *display; int count = 0; @@ -459,7 +462,9 @@ BOOL X11DRV_ProcessEvents( DWORD mask ) continue; /* filtered, ignore it */ } get_event_data( &event ); - if (prev_event.type) action = merge_events( &prev_event, &event ); + queued |= merge_configure_events( display, &prev_configure, &event ); + if (!event.type) action = MERGE_IGNORE; + else if (prev_event.type) action = merge_events( &prev_event, &event ); switch( action ) { case MERGE_HANDLE: /* handle prev, keep new */ @@ -478,6 +483,7 @@ BOOL X11DRV_ProcessEvents( DWORD mask ) break; } } + queued |= handle_delayed_event( display, &prev_configure ); queued |= handle_delayed_event( display, &prev_event ); XFlush( gdi_display ); if (count) TRACE( "processed %d events, returning %d\n", count, queued );