From a39b02c3e77cf2082c548c65958fd56d0897c1fc Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Tue, 9 Jul 2013 02:49:59 -0500 Subject: [PATCH] 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 deletion(-) diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index 0614c76c440..25f60f69f51 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -54,6 +54,7 @@ @interface WineApplicationController : NSObject NSEvent* lastFlagsChanged; BOOL inputSourceIsInputMethod; BOOL inputSourceIsInputMethodValid; + uint32_t pressedKeyCodes[128 / 32]; CGFloat primaryScreenHeight; BOOL primaryScreenHeightValid; @@ -105,6 +106,7 @@ - (void) windowGotFocus:(WineWindow*)window; - (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 25081db2892..8de68bb1618 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -1280,6 +1280,25 @@ - (BOOL) stopClippingCursor 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 @@ - (BOOL) handleEvent:(NSEvent*)anEvent [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 c5a630f7f29..e0e581ba2c9 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -68,4 +68,6 @@ @interface WineWindow : NSPanel - (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 e88a8541142..4a0a9452654 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -1117,6 +1117,8 @@ - (void) postKey:(uint16_t)keyCode [queue postEvent:event]; macdrv_release_event(event); + + [controller noteKey:keyCode pressed:pressed]; } - (void) postKeyEvent:(NSEvent *)theEvent @@ -1243,7 +1245,6 @@ - (void) updateColorSpace * ---------- NSResponder method overrides ---------- */ - (void) keyDown:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; } - - (void) keyUp:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; } - (void) flagsChanged:(NSEvent *)theEvent {