From 0a56ef356a2932b503ce1331df4fc17898de5514 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Sun, 24 Feb 2013 22:53:32 -0600 Subject: [PATCH] winemac: Handle mouse moves in -[WineApplication sendEvent:] instead of WineWindow. --- dlls/winemac.drv/cocoa_app.h | 3 +++ dlls/winemac.drv/cocoa_app.m | 44 ++++++++++++++++++++++++++++++++- dlls/winemac.drv/cocoa_window.h | 3 ++- dlls/winemac.drv/cocoa_window.m | 19 +++----------- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index 0447d47e871..32e418046ae 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -47,6 +47,9 @@ @interface WineApplication : NSApplication CGFloat primaryScreenHeight; BOOL primaryScreenHeightValid; + WineWindow* lastTargetWindow; + BOOL forceNextMouseMoveAbsolute; + NSMutableArray* orderedWineWindows; NSMutableDictionary* originalDisplayModes; diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index d22596e1cde..7e22221e8df 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -554,10 +554,40 @@ - (void) setCursorWithFrames:(NSArray*)frames */ - (void) sendEvent:(NSEvent*)anEvent { - if ([anEvent type] == NSFlagsChanged) + NSEventType type = [anEvent type]; + if (type == NSFlagsChanged) self.lastFlagsChanged = anEvent; [super sendEvent:anEvent]; + + if (type == NSMouseMoved || type == NSLeftMouseDragged || + type == NSRightMouseDragged || type == NSOtherMouseDragged) + { + WineWindow* targetWindow; + + targetWindow = (WineWindow*)[anEvent window]; + + if ([targetWindow isKindOfClass:[WineWindow class]]) + { + BOOL absolute = forceNextMouseMoveAbsolute || (targetWindow != lastTargetWindow); + forceNextMouseMoveAbsolute = FALSE; + + [targetWindow postMouseMovedEvent:anEvent absolute:absolute]; + lastTargetWindow = targetWindow; + } + else + lastTargetWindow = nil; + } + else if (type == NSLeftMouseDown || type == NSLeftMouseUp || + type == NSRightMouseDown || type == NSRightMouseUp || + type == NSOtherMouseDown || type == NSOtherMouseUp || + type == NSScrollWheel) + { + // Since mouse button and scroll wheel events deliver absolute cursor + // position, the accumulating delta from move events is invalidated. + // Make sure next mouse move event starts over from an absolute baseline. + forceNextMouseMoveAbsolute = TRUE; + } } @@ -583,12 +613,22 @@ - (void)applicationDidBecomeActive:(NSNotification *)notification // activated. This will provoke a re-synchronization of Wine's notion of // the desktop rect with the actual state. [self sendDisplaysChanged:TRUE]; + + // The cursor probably moved while we were inactive. Accumulated mouse + // movement deltas are invalidated. Make sure the next mouse move event + // starts over from an absolute baseline. + forceNextMouseMoveAbsolute = TRUE; } - (void)applicationDidChangeScreenParameters:(NSNotification *)notification { primaryScreenHeightValid = FALSE; [self sendDisplaysChanged:FALSE]; + + // When the display configuration changes, the cursor position may jump. + // Accumulated mouse movement deltas are invalidated. Make sure the next + // mouse move event starts over from an absolute baseline. + forceNextMouseMoveAbsolute = TRUE; } - (void)applicationDidResignActive:(NSNotification *)notification @@ -627,6 +667,8 @@ - (void)applicationWillFinishLaunching:(NSNotification *)notification NSWindow* window = [note object]; [keyWindows removeObjectIdenticalTo:window]; [orderedWineWindows removeObjectIdenticalTo:window]; + if (window == lastTargetWindow) + lastTargetWindow = nil; }]; [nc addObserver:self diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index 0aecf83b0b5..ea7988d1606 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -48,7 +48,6 @@ @interface WineWindow : NSPanel NSUInteger lastModifierFlags; - BOOL forceNextMouseMoveAbsolute; double mouseMoveDeltaX, mouseMoveDeltaY; NSInteger levelWhenActive; @@ -64,4 +63,6 @@ @interface WineWindow : NSPanel - (void) adjustWindowLevel; + - (void) postMouseMovedEvent:(NSEvent *)theEvent absolute:(BOOL)absolute; + @end diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index af624a710bc..b8bc79d8ffe 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -264,7 +264,6 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w if (!window) return nil; window->normalStyleMask = [window styleMask]; - window->forceNextMouseMoveAbsolute = TRUE; /* Standardize windows to eliminate differences between titled and borderless windows and between NSWindow and NSPanel. */ @@ -285,8 +284,7 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w [contentView setAutoresizesSubviews:NO]; trackingArea = [[[NSTrackingArea alloc] initWithRect:[contentView bounds] - options:(NSTrackingMouseEnteredAndExited | - NSTrackingMouseMoved | + options:(NSTrackingMouseMoved | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:window @@ -508,7 +506,6 @@ - (void) doOrderOut { self.latentParentWindow = [self parentWindow]; [latentParentWindow removeChildWindow:self]; - forceNextMouseMoveAbsolute = TRUE; [self orderOut:nil]; [NSApp wineWindow:self ordered:NSWindowOut relativeTo:nil]; [NSApp removeWindowsItem:self]; @@ -739,11 +736,11 @@ - (void) postKeyEvent:(NSEvent *)theEvent event:theEvent]; } - - (void) postMouseMovedEvent:(NSEvent *)theEvent + - (void) postMouseMovedEvent:(NSEvent *)theEvent absolute:(BOOL)absolute { macdrv_event event; - if (forceNextMouseMoveAbsolute) + if (absolute) { CGPoint point = CGEventGetLocation([theEvent CGEvent]); @@ -753,8 +750,6 @@ - (void) postMouseMovedEvent:(NSEvent *)theEvent mouseMoveDeltaX = 0; mouseMoveDeltaY = 0; - - forceNextMouseMoveAbsolute = FALSE; } else { @@ -961,14 +956,6 @@ - (void) flagsChanged:(NSEvent *)theEvent } } - - (void) mouseEntered:(NSEvent *)theEvent { forceNextMouseMoveAbsolute = TRUE; } - - (void) mouseExited:(NSEvent *)theEvent { forceNextMouseMoveAbsolute = TRUE; } - - - (void) mouseMoved:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; } - - (void) mouseDragged:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; } - - (void) rightMouseDragged:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; } - - (void) otherMouseDragged:(NSEvent *)theEvent { [self postMouseMovedEvent:theEvent]; } - - (void) scrollWheel:(NSEvent *)theEvent { CGPoint pt;