From 4f9de6bcdf1722a258413ce99c26f2ee5b36dbf2 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Tue, 31 Dec 2013 01:05:18 -0600 Subject: [PATCH] winemac: More thoroughly discard events which have been obsoleted by subsequent Wine- or program-driven changes. Among other things, this fixes Syberia 2. That game shows, hides, and then shows its window. Hiding it caused a WINDOW_LOST_FOCUS event to be queued. By the time it was processed, the window was the foreground window again. In response to being told it had lost focus, the game minimized its window. Hiding the window should have prevented or discarded the WINDOW_LOST_FOCUS event since the change was driven from Wine and the Win32 foreground/active window state would already be correct. In addition, when the program re-showed its window and made it foreground, that should have discarded the event as being out of date. Now they do. --- dlls/winemac.drv/cocoa_app.m | 2 ++ dlls/winemac.drv/cocoa_event.m | 3 +++ dlls/winemac.drv/cocoa_window.m | 34 +++++++++++++++++++++++++-------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index 17644d0d331..fea30e36a8c 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -2515,6 +2515,8 @@ void macdrv_set_mouse_capture_window(macdrv_window window) { WineWindow* w = (WineWindow*)window; + [w.queue discardEventsMatchingMask:event_mask_for_type(RELEASE_CAPTURE) forWindow:w]; + OnMainThread(^{ [[WineApplicationController sharedController] setMouseCaptureWindow:w]; }); diff --git a/dlls/winemac.drv/cocoa_event.m b/dlls/winemac.drv/cocoa_event.m index 00f6f8e6fb3..85cac5f4996 100644 --- a/dlls/winemac.drv/cocoa_event.m +++ b/dlls/winemac.drv/cocoa_event.m @@ -269,6 +269,7 @@ - (MacDrvEvent*) getEventMatchingMask:(macdrv_event_mask)mask - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSIndexSet* indexes; [eventsLock lock]; @@ -282,6 +283,8 @@ - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*) [events removeObjectsAtIndexes:indexes]; [eventsLock unlock]; + + [pool release]; } - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvents:(BOOL)processEvents diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 07abbcaab3d..54cb8db6ec9 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -838,7 +838,7 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state if (state->minimized_valid) { - BOOL discardUnminimize = TRUE; + macdrv_event_mask discard = event_mask_for_type(WINDOW_DID_UNMINIMIZE); pendingMinimize = FALSE; if (state->minimized && ![self isMiniaturized]) @@ -848,10 +848,15 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state if ([self styleMask] & NSFullScreenWindowMask) { [self postDidUnminimizeEvent]; - discardUnminimize = FALSE; + discard &= ~event_mask_for_type(WINDOW_DID_UNMINIMIZE); } else + { [super miniaturize:nil]; + discard |= event_mask_for_type(WINDOW_BROUGHT_FORWARD) | + event_mask_for_type(WINDOW_GOT_FOCUS) | + event_mask_for_type(WINDOW_LOST_FOCUS); + } } else pendingMinimize = TRUE; @@ -860,14 +865,11 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state { ignore_windowDeminiaturize = TRUE; [self deminiaturize:nil]; + discard |= event_mask_for_type(WINDOW_LOST_FOCUS); } - if (discardUnminimize) - { - /* Whatever events regarding minimization might have been in the queue are now stale. */ - [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_DID_UNMINIMIZE) - forWindow:self]; - } + if (discard) + [queue discardEventsMatchingMask:discard forWindow:self]; } if (state->maximized != maximized) @@ -1221,6 +1223,14 @@ - (void) doOrderOut [controller updateFullscreenWindows]; [controller adjustWindowLevels]; [NSApp removeWindowsItem:self]; + + [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD) | + event_mask_for_type(WINDOW_GOT_FOCUS) | + event_mask_for_type(WINDOW_LOST_FOCUS) | + event_mask_for_type(WINDOW_MAXIMIZE_REQUESTED) | + event_mask_for_type(WINDOW_MINIMIZE_REQUESTED) | + event_mask_for_type(WINDOW_RESTORE_REQUESTED) + forWindow:self]; } - (void) updateFullscreen @@ -1399,6 +1409,10 @@ - (void) makeFocused:(BOOL)activate causing_becomeKeyWindow = self; [self makeKeyWindow]; causing_becomeKeyWindow = nil; + + [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_GOT_FOCUS) | + event_mask_for_type(WINDOW_LOST_FOCUS) + forWindow:self]; } - (void) postKey:(uint16_t)keyCode @@ -2168,6 +2182,10 @@ void macdrv_order_cocoa_window(macdrv_window w, macdrv_window p, orAbove:next activate:activate]; }); + [window.queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD) + forWindow:window]; + [next.queue discardEventsMatchingMask:event_mask_for_type(WINDOW_BROUGHT_FORWARD) + forWindow:next]; } /***********************************************************************