From f344d7a21331d42e44f8915f9d2d47509fc9cad9 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Wed, 20 Nov 2013 15:30:35 +0000 Subject: [PATCH] winemac: Update the layout list if the enabled input sources change. --- dlls/winemac.drv/cocoa_app.m | 10 ++++++++ dlls/winemac.drv/keyboard.c | 57 +++++++++++++++++++++++++++++++++++------ dlls/winemac.drv/macdrv_cocoa.h | 1 + 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index d576b81f617..284023b755f 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -411,6 +411,11 @@ int macdrv_err_on; } } + - (void) enabledKeyboardInputSourcesChanged + { + macdrv_layout_list_needs_update = TRUE; + } + - (CGFloat) primaryScreenHeight { if (!primaryScreenHeightValid) @@ -1930,6 +1935,11 @@ int macdrv_err_on; name:@"com.apple.HIToolbox.beginMenuTrackingNotification" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDrop]; + + [dnc addObserver:self + selector:@selector(enabledKeyboardInputSourcesChanged) + name:(NSString*)kTISNotifyEnabledKeyboardInputSourcesChanged + object:nil]; } - (BOOL) inputSourceIsInputMethod diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 09eff9558a4..52f97da376c 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -435,6 +435,7 @@ struct layout struct list entry; HKL hkl; TISInputSourceRef input_source; + BOOL enabled; /* is the input source enabled - ie displayed in the input source selector UI */ }; static CRITICAL_SECTION layout_list_section; @@ -446,6 +447,8 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION layout_list_section = { &critsect_debug, -1, 0, 0, 0, 0 }; +int macdrv_layout_list_needs_update = TRUE; + static DWORD get_lcid(CFStringRef lang) { CFRange range; @@ -481,10 +484,36 @@ static HKL get_hkl(CFStringRef lang, CFStringRef type) return (HKL)lcid; } +/****************************************************************** + * get_layout_from_source + * + * Must be called while holding the layout_list_section. + * Note, returned layout may not currently be enabled. + */ +static struct layout *get_layout_from_source(TISInputSourceRef input) +{ + struct layout *ret = NULL, *layout; + + LIST_FOR_EACH_ENTRY(layout, &layout_list, struct layout, entry) + { + if (CFEqual(input, layout->input_source)) + { + ret = layout; + break; + } + } + return ret; +} + /*********************************************************************** * update_layout_list * * Must be called while holding the layout_list_section + * + * If an input source has been disabled (ie. removed from the UI) its + * entry remains in the layout list but is marked as such and is not + * enumerated by GetKeyboardLayoutList. This is to ensure the + * HKL <-> input source mapping is unique. */ static void update_layout_list(void) { @@ -492,23 +521,34 @@ static void update_layout_list(void) struct layout *layout; int i; - if (!list_empty(&layout_list)) return; + if (!InterlockedExchange(&macdrv_layout_list_needs_update, FALSE)) return; sources = macdrv_create_input_source_list(); + LIST_FOR_EACH_ENTRY(layout, &layout_list, struct layout, entry) + layout->enabled = FALSE; + for (i = 0; i < CFArrayGetCount(sources); i++) { CFDictionaryRef dict = CFArrayGetValueAtIndex(sources, i); TISInputSourceRef input = (TISInputSourceRef)CFDictionaryGetValue(dict, macdrv_input_source_input_key); - CFStringRef type = CFDictionaryGetValue(dict, macdrv_input_source_type_key); - CFStringRef lang = CFDictionaryGetValue(dict, macdrv_input_source_lang_key); + layout = get_layout_from_source(input); + if (!layout) + { + CFStringRef type = CFDictionaryGetValue(dict, macdrv_input_source_type_key); + CFStringRef lang = CFDictionaryGetValue(dict, macdrv_input_source_lang_key); + + layout = HeapAlloc(GetProcessHeap(), 0, sizeof(*layout)); + layout->input_source = (TISInputSourceRef)CFRetain(input); + layout->hkl = get_hkl(lang, type); - layout = HeapAlloc(GetProcessHeap(), 0, sizeof(*layout)); - layout->input_source = (TISInputSourceRef)CFRetain(input); - layout->hkl = get_hkl(lang, type); + list_add_tail(&layout_list, &layout->entry); + TRACE("adding new layout %p\n", layout->hkl); + } + else + TRACE("enabling already existing layout %p\n", layout->hkl); - list_add_tail(&layout_list, &layout->entry); - TRACE("adding new layout %p\n", layout->hkl); + layout->enabled = TRUE; } CFRelease(sources); @@ -1322,6 +1362,7 @@ UINT CDECL macdrv_GetKeyboardLayoutList(INT size, HKL *list) LIST_FOR_EACH_ENTRY(layout, &layout_list, struct layout, entry) { + if (!layout->enabled) continue; if (list) { if (count >= size) break; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 3ce1c26e6e6..1c2277f2ba8 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -416,6 +416,7 @@ extern CFArrayRef macdrv_create_input_source_list(void) DECLSPEC_HIDDEN; extern const CFStringRef macdrv_input_source_input_key DECLSPEC_HIDDEN; extern const CFStringRef macdrv_input_source_type_key DECLSPEC_HIDDEN; extern const CFStringRef macdrv_input_source_lang_key DECLSPEC_HIDDEN; +extern int macdrv_layout_list_needs_update DECLSPEC_HIDDEN; /* clipboard */ -- 2.11.4.GIT