From cbe9ef77418092c9caf5628cb77016c2a2843f61 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 17 Oct 2023 09:11:21 +0700 Subject: [PATCH 1/3] added logging to learn about menu execution --- mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m | 3 +++ mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m index 1607e915e07..0e17d84c008 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m @@ -213,7 +213,10 @@ - (void)menuAction:(id)sender { } else if (itag >= 1000) { NSMenuItem *keyboards = [self.AppDelegate.menu itemWithTag:1]; + NSString *title = keyboards.title; + NSLog(@"Input Menu, selected Keyboards menu, itag: %lu, title: %@", itag, title); for (NSMenuItem *item in keyboards.submenu.itemArray) { + NSLog(@"menu item, itag: %lu, title: %@", item.tag, item.title); if (item.tag == itag) [item setState:NSOnState]; else diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 44df2ef6fa2..a7b3d69038d 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -781,6 +781,8 @@ - (void)setKeyboardsSubMenu { KVKFile *kvk = nil; BOOL didSetKeyboard = NO; NSInteger itag = 1000; + NSString *keyboardMenuName = @""; + [keyboards.submenu removeAllItems]; for (NSString *path in self.activeKeyboards) { NSDictionary *infoDict = [KMXFile keyboardInfoFromKmxFile:path]; @@ -788,6 +790,8 @@ - (void)setKeyboardsSubMenu { continue; //NSString *str = [NSString stringWithFormat:@"%@ (%@)", [infoDict objectForKey:kKMKeyboardNameKey], [infoDict objectForKey:kKMKeyboardVersionKey]]; NSString *str = [infoDict objectForKey:kKMKeyboardNameKey]; + // for debugging + keyboardMenuName = str; NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:str action:@selector(menuAction:) keyEquivalent:@""]; [item setTag:itag++]; if ([path isEqualToString:self.selectedKeyboard]) { @@ -811,6 +815,8 @@ - (void)setKeyboardsSubMenu { else [item setState:NSOffState]; + NSLog(@"*** adding item to keyboards menu, itag=%lu, keyboard=%@", itag, keyboardMenuName); + [keyboards.submenu addItem:item]; } From 6871e74d3aa2e8a46441433bc06583d6086cf047 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 19 Oct 2023 14:55:57 +0700 Subject: [PATCH 2/3] changed keyboards menu to dynamically update in Keyman section of the Input Menu and eliminated Keyboards submenu --- .../Keyman4MacIM/Base.lproj/MainMenu.xib | 17 +- .../KMConfigurationWindowController.m | 2 + .../Keyman4MacIM/KMInputController.m | 76 ++---- .../Keyman4MacIM/KMInputMethodAppDelegate.h | 17 ++ .../Keyman4MacIM/KMInputMethodAppDelegate.m | 238 ++++++++++++------ .../Keyman4MacIM/en.lproj/Localizable.strings | 2 + 6 files changed, 210 insertions(+), 142 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Base.lproj/MainMenu.xib b/mac/Keyman4MacIM/Keyman4MacIM/Base.lproj/MainMenu.xib index 4062663c00f..0696c81eba2 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/Base.lproj/MainMenu.xib +++ b/mac/Keyman4MacIM/Keyman4MacIM/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -19,19 +19,16 @@ - + + + - - - - - - + - + diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 14ee3c9c351..70937eecbf3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -364,6 +364,8 @@ - (void)checkBoxAction:(id)sender { [self saveActiveKeyboards]; } else if (checkBox.state == NSOffState) { + if ([self.AppDelegate debugMode]) + NSLog(@"Disabling active keyboard: %@", kmxFilePath); [self.activeKeyboards removeObject:kmxFilePath]; [self saveActiveKeyboards]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m index 0e17d84c008..47d2bfceb58 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputController.m @@ -183,68 +183,40 @@ - (KMXFile *)kmx { return self.AppDelegate.kmx; } - - (void)menuAction:(id)sender { NSMenuItem *mItem = [sender objectForKey:kIMKCommandMenuItemName]; NSInteger itag = mItem.tag; if ([self.AppDelegate debugMode]) NSLog(@"Keyman menu clicked - tag: %lu", itag); - if (itag == 2) { - // Using `showConfigurationWindow` instead of `showPreferences:` because `showPreferences:` is missing in - // High Sierra (10.13.1 - 10.13.3). See: https://bugreport.apple.com/web/?problemID=35422518 - // rrb: where Apple's API is broken (10.13.1-10.13.3) call our workaround, otherwise, call showPreferences - u_int16_t systemVersion = [KMOSVersion SystemVersion]; - if ([KMOSVersion Version_10_13_1] <= systemVersion && systemVersion <= [KMOSVersion Version_10_13_3]) // between 10.13.1 and 10.13.3 inclusive - { - NSLog(@"Input Menu: calling workaround instead of showPreferences (sys ver %x)", systemVersion); - [self.AppDelegate showConfigurationWindow]; // call our workaround - } - else - { - NSLog(@"Input Menu: calling Apple's showPreferences (sys ver %x)", systemVersion); - [self showPreferences:sender]; // call Apple API - } + if (itag == CONFIG_MENUITEM_TAG) { + [self showConfigurationWindow:sender]; } - else if (itag == 3) { + else if (itag == OSK_MENUITEM_TAG) { [self.AppDelegate showOSK]; } - else if (itag == 4) { + else if (itag == ABOUT_MENUITEM_TAG) { [self.AppDelegate showAboutWindow]; } - else if (itag >= 1000) { - NSMenuItem *keyboards = [self.AppDelegate.menu itemWithTag:1]; - NSString *title = keyboards.title; - NSLog(@"Input Menu, selected Keyboards menu, itag: %lu, title: %@", itag, title); - for (NSMenuItem *item in keyboards.submenu.itemArray) { - NSLog(@"menu item, itag: %lu, title: %@", item.tag, item.title); - if (item.tag == itag) - [item setState:NSOnState]; - else - [item setState:NSOffState]; - } - - NSString *path = [self.AppDelegate.activeKeyboards objectAtIndex:itag%1000]; - KMXFile *kmx = [[KMXFile alloc] initWithFilePath:path]; - [self.AppDelegate setKmx:kmx]; - KVKFile *kvk = nil; - NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:path]; - NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; - if (kvkFilename != nil) { - NSString *kvkFilePath = [self.AppDelegate kvkFilePathFromFilename:kvkFilename]; - if (kvkFilePath != nil) - kvk = [[KVKFile alloc] initWithFilePath:kvkFilePath]; - } - [self.AppDelegate setKvk:kvk]; - NSString *keyboardName = [kmxInfo objectForKey:kKMKeyboardNameKey]; - if ([self.AppDelegate debugMode]) - NSLog(@"Selected keyboard from menu: %@", keyboardName); - [self.AppDelegate setKeyboardName:keyboardName]; - [self.AppDelegate setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; - [self.AppDelegate setContextBuffer:nil]; - [self.AppDelegate setSelectedKeyboard:path]; - [self.AppDelegate loadSavedStores]; - if (kvk != nil && self.AppDelegate.alwaysShowOSK) - [self.AppDelegate showOSK]; + else if (itag >= KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG) { + [self.AppDelegate selectKeyboardFromMenu:itag]; } } + +- (void)showConfigurationWindow:(id)sender { + // Using `showConfigurationWindow` instead of `showPreferences:` because `showPreferences:` is missing in + // High Sierra (10.13.1 - 10.13.3). See: https://bugreport.apple.com/web/?problemID=35422518 + // rrb: where Apple's API is broken (10.13.1-10.13.3) call our workaround, otherwise, call showPreferences + u_int16_t systemVersion = [KMOSVersion SystemVersion]; + if ([KMOSVersion Version_10_13_1] <= systemVersion && systemVersion <= [KMOSVersion Version_10_13_3]) // between 10.13.1 and 10.13.3 inclusive + { + NSLog(@"Input Menu: calling workaround instead of showPreferences (sys ver %x)", systemVersion); + [self.AppDelegate showConfigurationWindow]; // call our workaround + } + else + { + NSLog(@"Input Menu: calling Apple's showPreferences (sys ver %x)", systemVersion); + [self showPreferences:sender]; // call Apple API + } +} + @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h index 5214faf8212..e4e53e5972f 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h @@ -38,6 +38,21 @@ typedef struct { NSString *apiKeymanCom; } KeymanVersionInfo; +// tags for default menu items, displayed whether keyboards are active or not +static const int DIVIDER_MENUITEM_TAG = -4; +static const int CONFIG_MENUITEM_TAG = -3; +static const int OSK_MENUITEM_TAG = -2; +static const int ABOUT_MENUITEM_TAG = -1; + +// the number of menu items that do not represent active keyboards +static const int DEFAULT_KEYMAN_MENU_ITEM_COUNT = 4; + +// the tag for the first keyboard dynamically added to the menu +static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG = 0; + +// the menu index for the first keyboard dynamically added to the menu +static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX = 0; + @interface KMInputMethodAppDelegate : NSObject #define USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE 1 #ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE @@ -55,6 +70,7 @@ typedef struct { @property (nonatomic, strong) NSMutableArray *kmxFileList; @property (nonatomic, strong) NSString *selectedKeyboard; @property (nonatomic, strong) NSMutableArray *activeKeyboards; +@property (assign) int numberOfKeyboardMenuItems; @property (nonatomic, strong) NSMutableString *contextBuffer; @property (nonatomic, assign) NSEventModifierFlags currentModifierFlags; @property (nonatomic, assign) CFMachPortRef lowLevelEventTap; @@ -88,6 +104,7 @@ typedef struct { - (void)showAboutWindow; - (void)showOSK; - (void)showConfigurationWindow; +- (void)selectKeyboardFromMenu:(NSInteger)tag; - (void)sleepFollowingDeactivationOfServer:(id)lastServer; - (void)wakeUpWith:(id)newServer; - (void)handleKeyEvent:(NSEvent *)event; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index a7b3d69038d..3425cf25b5c 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -700,14 +700,14 @@ - (void)saveActiveKeyboards { [userData setObject:_activeKeyboards forKey:kKMActiveKeyboardsKey]; [userData synchronize]; [self resetActiveKeyboards]; - [self setKeyboardsSubMenu]; + [self updateKeyboardMenuItems]; } - (void)clearActiveKeyboards { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; [userData setObject:nil forKey:kKMActiveKeyboardsKey]; [userData synchronize]; - [self setKeyboardsSubMenu]; + [self updateKeyboardMenuItems]; } - (void)resetActiveKeyboards { @@ -760,96 +760,174 @@ - (void)setContextBuffer:(NSMutableString *)contextBuffer { } - (void)awakeFromNib { - [self setKeyboardsSubMenu]; - - NSMenuItem *config = [self.menu itemWithTag:2]; - if (config) - [config setAction:@selector(menuAction:)]; - - NSMenuItem *osk = [self.menu itemWithTag:3]; - if (osk) - [osk setAction:@selector(menuAction:)]; + [self setDefaultKeymanMenuItems]; + [self updateKeyboardMenuItems]; +} - NSMenuItem *about = [self.menu itemWithTag:4]; - if (about) - [about setAction:@selector(menuAction:)]; +- (void)setDefaultKeymanMenuItems { + NSMenuItem *config = [self.menu itemWithTag:CONFIG_MENUITEM_TAG]; + if (config) { + [config setAction:@selector(menuAction:)]; + } + + NSMenuItem *osk = [self.menu itemWithTag:OSK_MENUITEM_TAG]; + if (osk) { + [osk setAction:@selector(menuAction:)]; + } + + NSMenuItem *about = [self.menu itemWithTag:ABOUT_MENUITEM_TAG]; + if (about) { + [about setAction:@selector(menuAction:)]; + } } -- (void)setKeyboardsSubMenu { - NSMenuItem *keyboards = [self.menu itemWithTag:1]; - if (keyboards) { - KVKFile *kvk = nil; - BOOL didSetKeyboard = NO; - NSInteger itag = 1000; - NSString *keyboardMenuName = @""; - - [keyboards.submenu removeAllItems]; - for (NSString *path in self.activeKeyboards) { - NSDictionary *infoDict = [KMXFile keyboardInfoFromKmxFile:path]; - if (!infoDict) - continue; - //NSString *str = [NSString stringWithFormat:@"%@ (%@)", [infoDict objectForKey:kKMKeyboardNameKey], [infoDict objectForKey:kKMKeyboardVersionKey]]; - NSString *str = [infoDict objectForKey:kKMKeyboardNameKey]; - // for debugging - keyboardMenuName = str; - NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:str action:@selector(menuAction:) keyEquivalent:@""]; - [item setTag:itag++]; - if ([path isEqualToString:self.selectedKeyboard]) { - [item setState:NSOnState]; - KMXFile *kmx = [[KMXFile alloc] initWithFilePath:path]; - [self setKmx:kmx]; - NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:path]; - NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; - if (kvkFilename != nil) { - NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; - if (kvkFilePath != nil) - kvk = [[KVKFile alloc] initWithFilePath:kvkFilePath]; - } - [self setKvk:kvk]; - [self setKeyboardName:[kmxInfo objectForKey:kKMKeyboardNameKey]]; - [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; - [self loadSavedStores]; +- (void)updateKeyboardMenuItems { + self.numberOfKeyboardMenuItems = [self calculateNumberOfKeyboardMenuItems]; + [self removeDynamicKeyboardMenuItems]; + [self addDynamicKeyboardMenuItems]; +} - didSetKeyboard = YES; - } - else - [item setState:NSOffState]; +- (int)calculateNumberOfKeyboardMenuItems { + if (self.activeKeyboards.count == 0) { + // if there are no active keyboards, then we will insert one placeholder menu item 'No Active Keyboards' + return 1; + } else { + return (int) self.activeKeyboards.count; + } +} - NSLog(@"*** adding item to keyboards menu, itag=%lu, keyboard=%@", itag, keyboardMenuName); +- (void)removeDynamicKeyboardMenuItems { + int numberToRemove = (int) self.menu.numberOfItems - DEFAULT_KEYMAN_MENU_ITEM_COUNT; + + if (self.debugMode) { + NSLog(@"*** removeDynamicKeyboardMenuItems, self.menu.numberOfItems = %ld, number of items to remove = %d", (long)self.menu.numberOfItems, numberToRemove); + } + + if (numberToRemove > 0) { + for (int i = 1; i <= numberToRemove; i++) { + [self.menu removeItemAtIndex:KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX]; + } + } +} - [keyboards.submenu addItem:item]; +- (void)addDynamicKeyboardMenuItems { + BOOL didSetSelectedKeyboard = NO; + NSInteger itag = KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG; + NSString *keyboardMenuName = @""; + int menuItemIndex = KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX; + + if (self.debugMode) { + NSLog(@"*** populateKeyboardMenuItems, number of active keyboards=%lu", self.activeKeyboards.count); + } + + // loop through the active keyboards list and add them to the menu + for (NSString *path in self.activeKeyboards) { + NSDictionary *infoDict = [KMXFile keyboardInfoFromKmxFile:path]; + if (!infoDict) { + continue; + } + keyboardMenuName = [infoDict objectForKey:kKMKeyboardNameKey]; + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:keyboardMenuName action:@selector(menuAction:) keyEquivalent:@""]; + [item setTag:itag++]; + + // if this is the selected keyboard, then configure it as selected + if ([path isEqualToString:self.selectedKeyboard]) { + [self setSelectedKeyboard:path inMenuItem:item]; + didSetSelectedKeyboard = YES; + } + else { + [item setState:NSOffState]; } + + [self.menu insertItem:item atIndex:menuItemIndex++]; + } + + if (self.activeKeyboards.count == 0) { + [self addKeyboardPlaceholderMenuItem]; + } else if (!didSetSelectedKeyboard) { + [self setDefaultSelectedKeyboard]; + } +} - if (keyboards.submenu.numberOfItems == 0) { - NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@"(None)" action:NULL keyEquivalent:@""]; - [keyboards.submenu addItem:item]; - [self setKmx:nil]; - [self setKvk:nil]; - [self setKeyboardName:nil]; - [self setKeyboardIcon:nil]; - [self setContextBuffer:nil]; - [self setSelectedKeyboard:nil]; +- (void) setSelectedKeyboard:(NSString*)keyboardName inMenuItem:(NSMenuItem*) menuItem { + KVKFile *kvk = nil; + + [menuItem setState:NSOnState]; + KMXFile *kmx = [[KMXFile alloc] initWithFilePath:keyboardName]; + [self setKmx:kmx]; + NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:keyboardName]; + NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; + if (kvkFilename != nil) { + NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; + if (kvkFilePath != nil) { + kvk = [[KVKFile alloc] initWithFilePath:kvkFilePath]; } - else if (!didSetKeyboard) { - [keyboards.submenu itemAtIndex:0].state = NSOnState; - NSString *path = [self.activeKeyboards objectAtIndex:0]; - KMXFile *kmx = [[KMXFile alloc] initWithFilePath:path]; - [self setKmx:kmx]; - NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:path]; - NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; - if (kvkFilename != nil) { - NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; - if (kvkFilePath != nil) - kvk = [[KVKFile alloc] initWithFilePath:kvkFilePath]; + } + [self setKvk:kvk]; + [self setKeyboardName:[kmxInfo objectForKey:kKMKeyboardNameKey]]; + [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; + [self loadSavedStores]; +} + +// defaults to the whatever keyboard happens to be first in the list +- (void) setDefaultSelectedKeyboard { + NSMenuItem* menuItem = [self.menu itemAtIndex:KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX]; + NSString *keyboardName = [self.activeKeyboards objectAtIndex:0]; + [self setSelectedKeyboard:keyboardName inMenuItem:menuItem]; + [self setSelectedKeyboard:keyboardName]; + [self setContextBuffer:nil]; +} + +- (void) addKeyboardPlaceholderMenuItem { + NSString* placeholder = NSLocalizedString(@"no-keyboard-configured-menu-placeholder", nil); + NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:placeholder action:NULL keyEquivalent:@""]; + [self.menu insertItem:item atIndex:KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX]; + [self setKmx:nil]; + [self setKvk:nil]; + [self setKeyboardName:nil]; + [self setKeyboardIcon:nil]; + [self setContextBuffer:nil]; + [self setSelectedKeyboard:nil]; +} + +- (void)selectKeyboardFromMenu:(NSInteger)tag { + NSMenuItem *menuItem = [self.menu itemWithTag:tag]; + NSString *title = menuItem.title; + NSLog(@"Input Menu, selected Keyboards menu, itag: %lu, title: %@", tag, title); + for (NSMenuItem *item in self.menu.itemArray) { + // set the state of the keyboard items in the Keyman menu based on the new selection + if (item.tag >= KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG) { + if (item.tag == tag) { + [item setState:NSOnState]; + } + else { + [item setState:NSOffState]; } - [self setKvk:kvk]; - [self setKeyboardName:[kmxInfo objectForKey:kKMKeyboardNameKey]]; - [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; - [self setContextBuffer:nil]; - [self loadSavedStores]; - [self setSelectedKeyboard:path]; } } + + NSString *path = [self.activeKeyboards objectAtIndex:tag-KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG]; + KMXFile *kmx = [[KMXFile alloc] initWithFilePath:path]; + [self setKmx:kmx]; + KVKFile *kvk = nil; + NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:path]; + NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; + if (kvkFilename != nil) { + NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; + if (kvkFilePath != nil) + kvk = [[KVKFile alloc] initWithFilePath:kvkFilePath]; + } + [self setKvk:kvk]; + NSString *keyboardName = [kmxInfo objectForKey:kKMKeyboardNameKey]; + if ([self debugMode]) + NSLog(@"Selected keyboard from menu: %@", keyboardName); + [self setKeyboardName:keyboardName]; + [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; + [self setContextBuffer:nil]; + [self setSelectedKeyboard:path]; + [self loadSavedStores]; + if (kvk != nil && self.alwaysShowOSK) + [self showOSK]; } - (NSArray *)KMXFiles { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/en.lproj/Localizable.strings b/mac/Keyman4MacIM/Keyman4MacIM/en.lproj/Localizable.strings index f14a66b0b4a..6b815a7b176 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/en.lproj/Localizable.strings +++ b/mac/Keyman4MacIM/Keyman4MacIM/en.lproj/Localizable.strings @@ -71,4 +71,6 @@ /* message displayed to alert user to need grant accessibility permission */ "privacy-alert-text" = "To function properly, Keyman requires accessibility features:\n\nGrant access in System Preferences, Security & Privacy.\nRestart your system."; +/* Text of menu item in Input Menu when no Keyboards are configured -- include parentheses */ +"no-keyboard-configured-menu-placeholder" = "(No Keyboard Configured)"; From 5d41ecf6c27f67826e837cd32581ae3065dffbfc Mon Sep 17 00:00:00 2001 From: Shawn Schantz <89134789+sgschantz@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:22:17 +0700 Subject: [PATCH 3/3] use zero-based loop when removing all keyboards from Input Menu Co-authored-by: Marc Durdin --- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 3425cf25b5c..b04236ed5b8 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -804,7 +804,7 @@ - (void)removeDynamicKeyboardMenuItems { } if (numberToRemove > 0) { - for (int i = 1; i <= numberToRemove; i++) { + for (int i = 0; i < numberToRemove; i++) { [self.menu removeItemAtIndex:KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX]; } }