Module: wine Branch: master Commit: d81c4ce1ba700cca040afcf89c75c683b23e531d URL: https://gitlab.winehq.org/wine/wine/-/commit/d81c4ce1ba700cca040afcf89c75c68...
Author: Tim Clem tclem@codeweavers.com Date: Tue Jan 23 10:33:10 2024 -0800
winemac.drv: Detect active handwriting and panel IMEs.
Allows such IMEs that process keyboard input to do so. For instance, fixes backspace and escape for handwriting methods.
---
dlls/winemac.drv/cocoa_app.h | 1 - dlls/winemac.drv/cocoa_app.m | 68 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index c4c8bbd16f2..b2b8187e0b4 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -92,7 +92,6 @@ enum { CGEventSourceKeyboardType keyboardType; NSEvent* lastFlagsChanged; BOOL inputSourceIsInputMethod; - BOOL inputSourceIsInputMethodValid; uint32_t pressedKeyCodes[128 / 32];
CGFloat primaryScreenHeight; diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index 4e26bf1e122..de3a23a5d2d 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -478,8 +478,6 @@ static NSString* WineLocalizedString(unsigned int stringID) CFRelease(lastKeyboardLayoutInputSource); lastKeyboardLayoutInputSource = inputSourceLayout;
- inputSourceIsInputMethodValid = FALSE; - if (inputSourceLayout) { CFDataRef uchr; @@ -2064,24 +2062,68 @@ static NSString* WineLocalizedString(unsigned int stringID) [NSApp activate]; }
+ static BOOL InputSourceShouldBeIgnored(TISInputSourceRef inputSource) + { + /* Certain system utilities are technically input sources, but we + shouldn't consider them as such for our purposes. + Dictation is its own source too (com.apple.inputmethod.ironwood), but + it should receive keypresses; it cancels input on escape. */ + static CFStringRef ignoredIDs[] = { + /* The "Emoji & Symbols" palette. */ + CFSTR("com.apple.CharacterPaletteIM"), + /* The on-screen keyboard and accessibility panel. */ + CFSTR("com.apple.inputmethod.AssistiveControl"), + /* The popup for accented characters when you hold down a key. */ + CFSTR("com.apple.PressAndHold"), + }; + + CFStringRef sourceID = TISGetInputSourceProperty(inputSource, kTISPropertyInputSourceID); + for (int i = 0; i < sizeof(ignoredIDs) / sizeof(CFStringRef); i++) + { + if (CFEqual(sourceID, ignoredIDs[i])) + return YES; + } + + return NO; + } + - (BOOL) inputSourceIsInputMethod { - if (!inputSourceIsInputMethodValid) + static dispatch_once_t onceToken; + static CFDictionaryRef filterDict; + CFArrayRef enabledSources; + CFIndex i; + BOOL ret = NO; + + /* There may be multiple active ("selected") input sources, but there is + always exactly one selected keyboard input source. For instance, + handwriting methods are active simultaneously with a keyboard source. + As the name implies, TISCopyCurrentKeyboardInputSource only returns + the keyboard source, so it's not sufficient for our needs. We use + TISCreateInputSourceList instead to find all selected sources. */ + dispatch_once(&onceToken, ^{ + filterDict = CFDictionaryCreate(NULL, (const void **)&kTISPropertyInputSourceIsSelected, (const void **)&kCFBooleanTrue, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + }); + enabledSources = TISCreateInputSourceList(filterDict, false); + for (i = 0; i < CFArrayGetCount(enabledSources); i++) { - TISInputSourceRef inputSource = TISCopyCurrentKeyboardInputSource(); - if (inputSource) + TISInputSourceRef source = (TISInputSourceRef)CFArrayGetValueAtIndex(enabledSources, i); + CFStringRef type = TISGetInputSourceProperty(source, kTISPropertyInputSourceType); + + /* kTISTypeKeyboardLayout is for physical keyboards. Any type other + than that is an IME. */ + if (!CFEqual(type, kTISTypeKeyboardLayout) && !InputSourceShouldBeIgnored(source)) { - CFStringRef type = TISGetInputSourceProperty(inputSource, kTISPropertyInputSourceType); - inputSourceIsInputMethod = !CFEqual(type, kTISTypeKeyboardLayout); - CFRelease(inputSource); + ret = YES; + break; } - else - inputSourceIsInputMethod = FALSE; - inputSourceIsInputMethodValid = TRUE; }
- return inputSourceIsInputMethod; - } + CFRelease(enabledSources); + return ret; + }
- (void) releaseMouseCapture {