Ken Thomases : winemac: Handle mouse moves in -[WineApplication sendEvent:] instead of WineWindow.

Alexandre Julliard julliard at winehq.org
Mon Feb 25 14:33:46 CST 2013


Module: wine
Branch: master
Commit: 0a56ef356a2932b503ce1331df4fc17898de5514
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0a56ef356a2932b503ce1331df4fc17898de5514

Author: Ken Thomases <ken at codeweavers.com>
Date:   Sun Feb 24 22:53:32 2013 -0600

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 0447d47..32e4180 100644
--- a/dlls/winemac.drv/cocoa_app.h
+++ b/dlls/winemac.drv/cocoa_app.h
@@ -47,6 +47,9 @@
     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 d22596e..7e22221 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -554,10 +554,40 @@ int macdrv_err_on;
      */
     - (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 @@ int macdrv_err_on;
         // 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 @@ int macdrv_err_on;
             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 0aecf83..ea7988d 100644
--- a/dlls/winemac.drv/cocoa_window.h
+++ b/dlls/winemac.drv/cocoa_window.h
@@ -48,7 +48,6 @@
 
     NSUInteger lastModifierFlags;
 
-    BOOL forceNextMouseMoveAbsolute;
     double mouseMoveDeltaX, mouseMoveDeltaY;
 
     NSInteger levelWhenActive;
@@ -64,4 +63,6 @@
 
     - (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 af624a7..b8bc79d 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -264,7 +264,6 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
 
         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 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         [contentView setAutoresizesSubviews:NO];
 
         trackingArea = [[[NSTrackingArea alloc] initWithRect:[contentView bounds]
-                                                     options:(NSTrackingMouseEnteredAndExited |
-                                                              NSTrackingMouseMoved |
+                                                     options:(NSTrackingMouseMoved |
                                                               NSTrackingActiveAlways |
                                                               NSTrackingInVisibleRect)
                                                        owner:window
@@ -508,7 +506,6 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
     {
         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 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
                 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 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
 
             mouseMoveDeltaX = 0;
             mouseMoveDeltaY = 0;
-
-            forceNextMouseMoveAbsolute = FALSE;
         }
         else
         {
@@ -961,14 +956,6 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         }
     }
 
-    - (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;




More information about the wine-cvs mailing list