Ken Thomases : winemac: Dispatch key-up events directly to window to be sure to get them.

Alexandre Julliard julliard at winehq.org
Tue Jul 9 15:58:10 CDT 2013


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

Author: Ken Thomases <ken at codeweavers.com>
Date:   Tue Jul  9 02:49:59 2013 -0500

winemac: Dispatch key-up events directly to window to be sure to get them.

For keys pressed in combination with Command, -[NSApplication sendEvent:]
simply doesn't pass the key-up event through to the window.  We have to
track which keys we've told Wine are pressed because Cocoa may consume
key-downs that trigger menus or system behaviors.

---

 dlls/winemac.drv/cocoa_app.h    |    2 ++
 dlls/winemac.drv/cocoa_app.m    |   30 ++++++++++++++++++++++++++++++
 dlls/winemac.drv/cocoa_window.h |    2 ++
 dlls/winemac.drv/cocoa_window.m |    3 ++-
 4 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h
index 0614c76..25f60f6 100644
--- a/dlls/winemac.drv/cocoa_app.h
+++ b/dlls/winemac.drv/cocoa_app.h
@@ -54,6 +54,7 @@ enum {
     NSEvent* lastFlagsChanged;
     BOOL inputSourceIsInputMethod;
     BOOL inputSourceIsInputMethodValid;
+    uint32_t pressedKeyCodes[128 / 32];
 
     CGFloat primaryScreenHeight;
     BOOL primaryScreenHeightValid;
@@ -105,6 +106,7 @@ enum {
     - (BOOL) waitUntilQueryDone:(int*)done timeout:(NSDate*)timeout processEvents:(BOOL)processEvents;
 
     - (void) keyboardSelectionDidChange;
+    - (void) noteKey:(uint16_t)keyCode pressed:(BOOL)pressed;
 
     - (void) flipRect:(NSRect*)rect;
 
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m
index 25081db..8de68bb 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -1280,6 +1280,25 @@ int macdrv_err_on;
         return TRUE;
     }
 
+    - (BOOL) isKeyPressed:(uint16_t)keyCode
+    {
+        int bits = sizeof(pressedKeyCodes[0]) * 8;
+        int index = keyCode / bits;
+        uint32_t mask = 1 << (keyCode % bits);
+        return (pressedKeyCodes[index] & mask) != 0;
+    }
+
+    - (void) noteKey:(uint16_t)keyCode pressed:(BOOL)pressed
+    {
+        int bits = sizeof(pressedKeyCodes[0]) * 8;
+        int index = keyCode / bits;
+        uint32_t mask = 1 << (keyCode % bits);
+        if (pressed)
+            pressedKeyCodes[index] |= mask;
+        else
+            pressedKeyCodes[index] &= ~mask;
+    }
+
     - (void) handleMouseMove:(NSEvent*)anEvent
     {
         WineWindow* targetWindow;
@@ -1692,6 +1711,17 @@ int macdrv_err_on;
             [self handleScrollWheel:anEvent];
             ret = mouseCaptureWindow != nil;
         }
+        else if (type == NSKeyUp)
+        {
+            uint16_t keyCode = [anEvent keyCode];
+            if ([self isKeyPressed:keyCode])
+            {
+                WineWindow* window = (WineWindow*)[anEvent window];
+                [self noteKey:keyCode pressed:FALSE];
+                if ([window isKindOfClass:[WineWindow class]])
+                    [window postKeyEvent:anEvent];
+            }
+        }
 
         return ret;
     }
diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h
index c5a630f..e0e581b 100644
--- a/dlls/winemac.drv/cocoa_window.h
+++ b/dlls/winemac.drv/cocoa_window.h
@@ -68,4 +68,6 @@
     - (NSInteger) minimumLevelForActive:(BOOL)active;
     - (void) updateFullscreen;
 
+    - (void) postKeyEvent:(NSEvent *)theEvent;
+
 @end
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index e88a854..4a0a945 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -1117,6 +1117,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         [queue postEvent:event];
 
         macdrv_release_event(event);
+
+        [controller noteKey:keyCode pressed:pressed];
     }
 
     - (void) postKeyEvent:(NSEvent *)theEvent
@@ -1243,7 +1245,6 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
      * ---------- NSResponder method overrides ----------
      */
     - (void) keyDown:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; }
-    - (void) keyUp:(NSEvent *)theEvent   { [self postKeyEvent:theEvent]; }
 
     - (void) flagsChanged:(NSEvent *)theEvent
     {




More information about the wine-cvs mailing list