From 5488e32be28ab06b83db45ec3f6ea7c960ff4b98 Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Mon, 29 Jul 2024 16:01:58 +0700 Subject: [PATCH 001/127] change(mac): add class to encapsulate settings --- .../Keyman4MacIM.xcodeproj/project.pbxproj | 6 ++ .../Keyman4MacIM/KMInputMethodAppDelegate.m | 18 +++++- .../Keyman4MacIM/KMInputMethodEventHandler.m | 16 +++++- .../Keyman4MacIM/KMSettingsRepository.h | 20 +++++++ .../Keyman4MacIM/KMSettingsRepository.m | 57 +++++++++++++++++++ 5 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 8e0b973442e..46b7f70e24b 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -72,6 +72,7 @@ 98FE10631B4DEE5600525F54 /* KMInfoWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 98FE10611B4DEE5600525F54 /* KMInfoWindowController.m */; }; 9A3D6C5D221531B0008785A3 /* KMOSVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A3D6C5C221531B0008785A3 /* KMOSVersion.m */; }; B90818AF7ED302187DE0E026 /* Pods_Keyman.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B644E63217FFE54B91C71C94 /* Pods_Keyman.framework */; }; + D861B03F2C5747F70003675E /* KMSettingsRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = D861B03E2C5747F70003675E /* KMSettingsRepository.m */; }; E211769D20E182DD00F8065D /* NoContextTestClient.m in Sources */ = {isa = PBXBuildFile; fileRef = E211769C20E182DD00F8065D /* NoContextTestClient.m */; }; E21176A020E18C5200F8065D /* AppleCompliantTestClient.m in Sources */ = {isa = PBXBuildFile; fileRef = E211769F20E18C5200F8065D /* AppleCompliantTestClient.m */; }; E211CCF620B600A500505C36 /* KeymanEngine4Mac.framework.dSYM in CopyFiles */ = {isa = PBXBuildFile; fileRef = E211CCF520B600A500505C36 /* KeymanEngine4Mac.framework.dSYM */; }; @@ -350,6 +351,8 @@ CEFFECDB2A417FEC00D58C36 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/KMKeyboardHelpWindowController.strings; sourceTree = ""; }; CEFFECDC2A417FEC00D58C36 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MainMenu.strings; sourceTree = ""; }; CEFFECDD2A4180FD00D58C36 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + D861B03D2C5747F70003675E /* KMSettingsRepository.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KMSettingsRepository.h; sourceTree = ""; }; + D861B03E2C5747F70003675E /* KMSettingsRepository.m */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = KMSettingsRepository.m; sourceTree = ""; tabWidth = 2; }; E211769B20E1826800F8065D /* NoContextTestClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NoContextTestClient.h; sourceTree = ""; }; E211769C20E182DD00F8065D /* NoContextTestClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NoContextTestClient.m; sourceTree = ""; }; E211769E20E18C0B00F8065D /* AppleCompliantTestClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleCompliantTestClient.h; sourceTree = ""; }; @@ -548,6 +551,8 @@ 29B4A0D32BF7675A00682049 /* KMLogs.m */, 299ABD6F29ECE75B00AA5948 /* KeySender.m */, 299ABD7029ECE75B00AA5948 /* KeySender.h */, + D861B03D2C5747F70003675E /* KMSettingsRepository.h */, + D861B03E2C5747F70003675E /* KMSettingsRepository.m */, 297A501128DF4D360074EB1B /* Privacy */, 98FE105B1B4DE86300525F54 /* Categories */, 98D6DA791A799EE700B09822 /* Frameworks */, @@ -974,6 +979,7 @@ 29B4A0D52BF7675A00682049 /* KMLogs.m in Sources */, 98BF924F1BF02DC20002126A /* KMBarView.m in Sources */, E240F599202DED740000067D /* KMPackage.m in Sources */, + D861B03F2C5747F70003675E /* KMSettingsRepository.m in Sources */, 984B8F441AF1C3D900E096A8 /* OSKWindowController.m in Sources */, 9836B3711AE5F11D00780482 /* mztools.c in Sources */, 9836B3701AE5F11D00780482 /* ioapi.c in Sources */, diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 0675a78adec..b7acec58e83 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -16,6 +16,7 @@ // Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (sessionFinished) block performed very slowly (0.00 secs) #import "KMInputMethodAppDelegate.h" +#import "KMSettingsRepository.h" #import "KMConfigurationWindowController.h" #import "KMDownloadKBWindowController.h" #import "ZipArchive.h" @@ -509,7 +510,9 @@ - (NSString *)keymanDataPath { if(_keymanDataPath == nil) { NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; _keymanDataPath = [documentDirPath stringByAppendingPathComponent:@"Keyman-Keyboards"]; - + + os_log_debug([KMLogs dataLog], "creating keymanDataPath, %{public}@", _keymanDataPath); + NSFileManager *fm = [NSFileManager defaultManager]; if (![fm fileExistsAtPath:_keymanDataPath]) { [fm createDirectoryAtPath:_keymanDataPath withIntermediateDirectories:YES attributes:nil error:nil]; @@ -531,6 +534,7 @@ - (NSString *)keyboardsPath { } - (NSArray *)kmxFileList { + os_log_debug([KMLogs dataLog], "kmxFileList"); if (_kmxFileList == nil) { NSArray *kmxFiles = [self KMXFiles]; _kmxFileList = [[NSMutableArray alloc] initWithCapacity:0]; @@ -650,6 +654,7 @@ - (NSString *)packageNameFromPackageInfo:(NSString *)packageFolder { } - (NSArray *)keyboardNamesFromFolder:(NSString *)packageFolder { + os_log_debug([KMLogs dataLog], "keyboardNamesFromFolder, folder = %{public}@", packageFolder); NSMutableArray *kbNames = [[NSMutableArray alloc] initWithCapacity:0];; for (NSString *kmxFile in [self KMXFilesAtPath:packageFolder]) { NSDictionary * infoDict = [KMXFile keyboardInfoFromKmxFile:kmxFile]; @@ -756,6 +761,12 @@ - (void)setContextBuffer:(NSMutableString *)contextBuffer { } - (void)awakeFromNib { + if ([KMSettingsRepository.shared keyboardsMigrationNeeded]) { + os_log_info([KMLogs startupLog], "keyboards migration needed"); + } else { + os_log_info([KMLogs startupLog], "keyboards migration not needed"); + } + [self setDefaultKeymanMenuItems]; [self updateKeyboardMenuItems]; } @@ -928,13 +939,16 @@ - (NSArray *)KMXFiles { } - (NSArray *)KMXFilesAtPath:(NSString *)path { + os_log_debug([KMLogs dataLog], "Reading KMXFiles at path %{public}@", path); NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:path]; NSMutableArray *kmxFiles = [[NSMutableArray alloc] initWithCapacity:0]; NSString *filePath; while (filePath = (NSString *)[dirEnum nextObject]) { NSString *extension = [[filePath pathExtension] lowercaseString]; - if ([extension isEqualToString:@"kmx"]) + if ([extension isEqualToString:@"kmx"]) { [kmxFiles addObject:[path stringByAppendingPathComponent:filePath]]; + os_log_debug([KMLogs dataLog], "file = %{public}@", filePath); + } } return kmxFiles; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index fa912ca67d5..cf9eea07024 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -10,6 +10,7 @@ #import /* For kVK_ constants. */ #import "KeySender.h" #import "TextApiCompliance.h" +#import "KMSettingsRepository.h" #import "KMLogs.h" @import Sentry; @@ -238,6 +239,17 @@ - (BOOL)handleEvent:(NSEvent *)event client:(id)sender { // return NO to pass through to client app return NO; } + + // TODO: remove test code + /* + if (event.keyCode == kVK_ANSI_Slash) { + if ([KMSettingsRepository.shared keyboardsMigrationNeeded]) { + os_log_info([KMLogs startupLog], "keyboards migration needed"); + } else { + os_log_info([KMLogs startupLog], "keyboards migration not needed"); + } + } + */ } if (event.type == NSEventTypeFlagsChanged) { @@ -412,11 +424,11 @@ -(void) persistOptions:(NSDictionary*)options{ for(NSString *key in options) { NSString *value = [options objectForKey:key]; if(key && value) { - os_log_debug([KMLogs keyLog], "applyNonTextualOutput calling writePersistedOptions, key: %{public}@, value: %{public}@", key, value); + os_log_debug([KMLogs keyLog], "persistOptions, key: %{public}@, value: %{public}@", key, value); [self.appDelegate writePersistedOptions:key withValue:value]; } else { - os_log_debug([KMLogs keyLog], "applyNonTextualOutput, invalid values in optionsToPersist, not writing to UserDefaults, key: %{public}@, value: %{public}@", key, value); + os_log_debug([KMLogs keyLog], "invalid values in persistOptions, not writing to UserDefaults, key: %{public}@, value: %{public}@", key, value); } } } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h new file mode 100644 index 00000000000..e4b9f1c158a --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h @@ -0,0 +1,20 @@ +/** + * Keyman is copyright (C) SIL International. MIT License. + * + * KMSettingsRepository.h + * Keyman + * + * Created by Shawn Schantz on 2024-07-29. + * + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KMSettingsRepository : NSObject ++ (KMSettingsRepository *)shared; +- (BOOL)keyboardsMigrationNeeded; +@end + +NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m new file mode 100644 index 00000000000..d5a26cccac7 --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -0,0 +1,57 @@ +/** + * Keyman is copyright (C) SIL International. MIT License. + * + * KMSettingsRepository.h + * Keyman + * + * Created by Shawn Schantz on 2024-07-29. + * + * Singleton object for reading and writing Keyman application settings. + * Serves as an abstraction to StandardUserDefaults which is currently used to persist application settings. + */ + +#import "KMSettingsRepository.h" +#import "KMLogs.h" + +NSString *const kStoreKeyboardsInLibraryKey = @"KMStoreKeyboardsInLibraryKey"; +NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; + +@implementation KMSettingsRepository + ++ (KMSettingsRepository *)shared +{ + static KMSettingsRepository *shared = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shared = [[KMSettingsRepository alloc] init]; + }); + return shared; +} + +- (BOOL)settingsExist +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:kActiveKeyboardsKey] != nil; +} + +- (BOOL)keyboardsStoredInLibraryFolder +{ + return [[NSUserDefaults standardUserDefaults] boolForKey:kStoreKeyboardsInLibraryKey]; +} + +/** + * Determines whether the keyboards data needs to be moved from the old location in the Documents folder to the new location under /username/Library... + * This is true if + * 1) the UserDefaults exist (indicating that this is not a new installation of Keyman) and + * 2) the value for KMStoreKeyboardsInLibraryKey is not set to true + */ +- (BOOL)keyboardsMigrationNeeded { + BOOL keyboardSettingsExist = [self settingsExist]; + os_log([KMLogs startupLog], " keyboard settings exist: %@", keyboardSettingsExist ? @"YES" : @"NO" ); + + BOOL keyboardsInLibrary = [self keyboardsStoredInLibraryFolder]; + os_log([KMLogs startupLog], " keyboards stored in Library: %@", keyboardsInLibrary ? @"YES" : @"NO" ); + + return !(keyboardSettingsExist && keyboardsInLibrary); +} + +@end From 37dcacc0cb092201edea1e00905ec40961fb9dd0 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 30 Jul 2024 16:08:34 +0700 Subject: [PATCH 002/127] change(mac): add KMDataRepository class to handle data (keyboards) migration --- .../Keyman4MacIM.xcodeproj/project.pbxproj | 6 ++ .../Keyman4MacIM/KMDataRepository.h | 21 +++++ .../Keyman4MacIM/KMDataRepository.m | 85 +++++++++++++++++++ .../Keyman4MacIM/KMInputMethodAppDelegate.m | 3 + 4 files changed, 115 insertions(+) create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h create mode 100644 mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 46b7f70e24b..9d63aac4685 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 29015ABD2C58D86F00CCBB94 /* KMDataRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */; }; 290BC680274B9DB1005CD1C3 /* KMPackageInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 290BC67F274B9DB1005CD1C3 /* KMPackageInfo.m */; }; 290BC75E274F3FD7005CD1C3 /* KMKeyboardInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 290BC75D274F3FD7005CD1C3 /* KMKeyboardInfo.m */; }; 2915DC512BFE35DB0051FC52 /* KMLogs.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B4A0D32BF7675A00682049 /* KMLogs.m */; }; @@ -136,6 +137,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 29015ABB2C58D86F00CCBB94 /* KMDataRepository.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KMDataRepository.h; sourceTree = ""; }; + 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KMDataRepository.m; sourceTree = ""; }; 2901BA8A292332B3009903EC /* ff-NG */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ff-NG"; path = "ff-NG.lproj/KMAboutWindowController.strings"; sourceTree = ""; }; 2901BA8B292332B3009903EC /* ff-NG */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ff-NG"; path = "ff-NG.lproj/preferences.strings"; sourceTree = ""; }; 2901BA8C292332B3009903EC /* ff-NG */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ff-NG"; path = "ff-NG.lproj/KMInfoWindowController.strings"; sourceTree = ""; }; @@ -553,6 +556,8 @@ 299ABD7029ECE75B00AA5948 /* KeySender.h */, D861B03D2C5747F70003675E /* KMSettingsRepository.h */, D861B03E2C5747F70003675E /* KMSettingsRepository.m */, + 29015ABB2C58D86F00CCBB94 /* KMDataRepository.h */, + 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */, 297A501128DF4D360074EB1B /* Privacy */, 98FE105B1B4DE86300525F54 /* Categories */, 98D6DA791A799EE700B09822 /* Frameworks */, @@ -982,6 +987,7 @@ D861B03F2C5747F70003675E /* KMSettingsRepository.m in Sources */, 984B8F441AF1C3D900E096A8 /* OSKWindowController.m in Sources */, 9836B3711AE5F11D00780482 /* mztools.c in Sources */, + 29015ABD2C58D86F00CCBB94 /* KMDataRepository.m in Sources */, 9836B3701AE5F11D00780482 /* ioapi.c in Sources */, E21799051FC5B7BC00F2D66A /* KMInputMethodEventHandler.m in Sources */, 98E6729F1B532F5E00DBDE2F /* KMDownloadKBWindowController.m in Sources */, diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h new file mode 100644 index 00000000000..ed1b8701fe4 --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -0,0 +1,21 @@ +/** + * Keyman is copyright (C) SIL International. MIT License. + * + * KMDataRepository.h + * Keyman + * + * Created by Shawn Schantz on 2024-07-30. + * + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KMDataRepository : NSObject ++ (KMDataRepository *)shared; +- (void)migrateResources; +- (NSString *)keymanDataDirectory; +@end + +NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m new file mode 100644 index 00000000000..fa422472e5d --- /dev/null +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -0,0 +1,85 @@ +/** + * Keyman is copyright (C) SIL International. MIT License. + * + * KMResourcesRepository.m + * Keyman + * + * Created by Shawn Schantz on 2024-07-30. + * + * Singleton object which serves as an abstraction for the reading and writing of Keyman data. + * The 'data' currently consists of keyman keyboards installed by the user. All data is saved locally on disk using NSFileManager. + * This is in contrast with the lighter weight Settings which is stored using UserDefaults and handled by KMSettingsRepository. + */ + +#import "KMDataRepository.h" +#import "KMLogs.h" + +@implementation KMDataRepository + +NSString* _obsoleteKeymanDataDirectory = nil; +NSString* _keymanDataDirectory = nil; + ++ (KMDataRepository *)shared +{ + static KMDataRepository *shared = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shared = [[KMDataRepository alloc] init]; + }); + return shared; +} + +- (void)migrateResources { + NSError *directoryError = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *applicationSupportUrl = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; + + os_log_info([KMLogs startupLog], "applicationSupportDirectory: '%{public}@'", applicationSupportUrl); + + NSString *appId = [[NSBundle mainBundle] bundleIdentifier]; + os_log_info([KMLogs startupLog], "application bundleIdentifier: '%{public}@'", appId); + + NSURL *keymanUrl = [applicationSupportUrl URLByAppendingPathComponent: appId isDirectory: TRUE]; + + //NSURL *keymanUrl = [NSURL fileURLWithPath:appId isDirectory:YES relativeToURL:applicationSupportUrl]; + + os_log_info([KMLogs startupLog], "keymanUrl: '%{public}@'", keymanUrl); + // returns -> '/Users/sgschantz/Library/Application Support' + + BOOL isDir; + BOOL exists = [fileManager fileExistsAtPath:keymanUrl.path isDirectory:&isDir]; + + if (exists) { + os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' exists", keymanUrl); + if (isDir) { + os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' is a directory", keymanUrl); + } + } else { + os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' does not exist", keymanUrl); + } +} + +/** + * Locate and create the Keyman data path; currently in ~/Documents/Keyman-Keyboards + */ +- (NSString *)_obsoleteKeymanDataDirectory { + if(_keymanDataDirectory == nil) { + NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; + _keymanDataDirectory = [documentDirPath stringByAppendingPathComponent:@"Keyman-Keyboards"]; + + os_log_debug([KMLogs dataLog], "creating keymanDataPath, %{public}@", _keymanDataDirectory); + + NSFileManager *fm = [NSFileManager defaultManager]; + if (![fm fileExistsAtPath:_keymanDataDirectory]) { + [fm createDirectoryAtPath:_keymanDataDirectory withIntermediateDirectories:YES attributes:nil error:nil]; + } + } + return _keymanDataDirectory; +} + +- (NSString *)keymanDataPath { + return _keymanDataDirectory; +} + +@end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index b7acec58e83..9afba1fa0a8 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -17,6 +17,7 @@ #import "KMInputMethodAppDelegate.h" #import "KMSettingsRepository.h" +#import "KMDataRepository.h" #import "KMConfigurationWindowController.h" #import "KMDownloadKBWindowController.h" #import "ZipArchive.h" @@ -763,10 +764,12 @@ - (void)setContextBuffer:(NSMutableString *)contextBuffer { - (void)awakeFromNib { if ([KMSettingsRepository.shared keyboardsMigrationNeeded]) { os_log_info([KMLogs startupLog], "keyboards migration needed"); + [KMDataRepository.shared migrateResources]; } else { os_log_info([KMLogs startupLog], "keyboards migration not needed"); } + [self setDefaultKeymanMenuItems]; [self updateKeyboardMenuItems]; } From bff17dc1c243b8fa92c1d3b51111110201ec31f5 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 31 Jul 2024 10:52:34 +0700 Subject: [PATCH 003/127] change(mac): customize menus after all views are created rather than reading from disk and adding keyboards include awakeFromNib, do so in applicationDidFinishLaunching --- mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 9afba1fa0a8..87a53824321 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -182,6 +182,9 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification { }]; // [SentrySDK captureMessage:@"Starting Keyman [test message]"]; + + [self setDefaultKeymanMenuItems]; + [self updateKeyboardMenuItems]; } #ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE @@ -769,9 +772,6 @@ - (void)awakeFromNib { os_log_info([KMLogs startupLog], "keyboards migration not needed"); } - - [self setDefaultKeymanMenuItems]; - [self updateKeyboardMenuItems]; } - (void)setDefaultKeymanMenuItems { From ec2e48c11ff16b12bcfe75ac59179fcf2e11a97c Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 31 Jul 2024 15:58:40 +0700 Subject: [PATCH 004/127] change(mac): moved directory locations into KMDataRepository --- .../Keyman4MacIM/KMDataRepository.h | 2 +- .../Keyman4MacIM/KMDataRepository.m | 105 +++++++++++++++--- 2 files changed, 90 insertions(+), 17 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index ed1b8701fe4..53790a21524 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @interface KMDataRepository : NSObject + (KMDataRepository *)shared; - (void)migrateResources; -- (NSString *)keymanDataDirectory; +- (NSURL *)keymanDataDirectory; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index fa422472e5d..40f8858aee6 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -14,10 +14,36 @@ #import "KMDataRepository.h" #import "KMLogs.h" +@interface KMDataRepository () +@property (readonly) NSURL *applicationSupportSubDirectory; // '~/Library/Application Support' +@property (readonly) NSURL *documentsSubDirectory; // '~/Documents' +@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/com.keyman.app' +@property (readonly) NSURL *keymanKeyboardsDirectory; +// keymanKeyboardsDirectory = '~/Library/Application Support/com.keyman.app/Keyman-Keyboards' +@property (readonly) NSURL *obsoleteKeymanDataDirectory; // '~/Library/Documents/Keyman-Keyboards' +@end + @implementation KMDataRepository +@synthesize applicationSupportSubDirectory = _applicationSupportSubDirectory; +@synthesize documentsSubDirectory = _documentsSubDirectory; +@synthesize keymanKeyboardsDirectory = _keymanKeyboardsDirectory; +@synthesize obsoleteKeymanDataDirectory = _obsoleteKeymanDataDirectory; +@synthesize keymanDataDirectory = _keymanDataDirectory; + +NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards"; +/* + name of the subdirectory within '~/Library/Application Support' + the convention is to use bundle identifier ("keyman.inputmethod.Keyman") + but we'll use this name, which matches our logging subsystem + */ +NSString *const kKeymanSubdirectoryName = @"com.keyman.app"; +/* NSString* _obsoleteKeymanDataDirectory = nil; NSString* _keymanDataDirectory = nil; +NSURL* _ApplicationSupportSubDirectory = nil; +NSURL* _DocumentsSubDirectory = nil; +*/ + (KMDataRepository *)shared { @@ -29,24 +55,69 @@ + (KMDataRepository *)shared return shared; } -- (void)migrateResources { - NSError *directoryError = nil; - - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSURL *applicationSupportUrl = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; - - os_log_info([KMLogs startupLog], "applicationSupportDirectory: '%{public}@'", applicationSupportUrl); +- (NSURL *)documentsSubDirectory { + if (self.documentsSubDirectory == nil) { + NSError *directoryError = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *documentsUrl = [fileManager URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; + + if (directoryError) { + os_log_error([KMLogs startupLog], "error getting Documents subdirectory: '%{public}@'", directoryError.localizedDescription); + } else { + os_log_info([KMLogs startupLog], "Documents subdirectory: '%{public}@'", documentsUrl); + _documentsSubDirectory = documentsUrl; + } + } + return self.documentsSubDirectory; +} - NSString *appId = [[NSBundle mainBundle] bundleIdentifier]; - os_log_info([KMLogs startupLog], "application bundleIdentifier: '%{public}@'", appId); - - NSURL *keymanUrl = [applicationSupportUrl URLByAppendingPathComponent: appId isDirectory: TRUE]; +- (NSURL *)applicationSupportSubDirectory { + if (self.applicationSupportSubDirectory == nil) { + NSError *directoryError = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *applicationSupportUrl = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; - //NSURL *keymanUrl = [NSURL fileURLWithPath:appId isDirectory:YES relativeToURL:applicationSupportUrl]; + if (directoryError) { + os_log_error([KMLogs startupLog], "error getting Application Support subdirectory: '%{public}@'", directoryError.localizedDescription); + } else { + os_log_info([KMLogs startupLog], "Application Support subdirectory: '%{public}@'", applicationSupportUrl); + _applicationSupportSubDirectory = applicationSupportUrl; + } + } + return self.applicationSupportSubDirectory; +} + +- (NSURL *)keymanDataDirectory { + if (self.keymanDataDirectory == nil) { + NSURL *keymanDataUrl = [self.applicationSupportSubDirectory URLByAppendingPathComponent:kKeymanSubdirectoryName isDirectory: TRUE]; + _keymanDataDirectory = keymanDataUrl; + } + return self.keymanDataDirectory; +} + +- (NSURL *)keymanKeyboardsDirectory { + if (self.keymanKeyboardsDirectory == nil) { + NSURL *keyboardsUrl = [self.keymanDataDirectory URLByAppendingPathComponent:kKeyboardsDirectoryName isDirectory: TRUE]; + _keymanKeyboardsDirectory = keyboardsUrl; + } + return self.keymanKeyboardsDirectory; +} + +- (NSURL *)obsoleteKeymanDataDirectory { + if (self.obsoleteKeymanDataDirectory == nil) { + NSURL *keymanUrl = [self.documentsSubDirectory URLByAppendingPathComponent:kKeymanSubdirectoryName isDirectory: TRUE]; + _obsoleteKeymanDataDirectory = keymanUrl; + } + return self.obsoleteKeymanDataDirectory; +} - os_log_info([KMLogs startupLog], "keymanUrl: '%{public}@'", keymanUrl); - // returns -> '/Users/sgschantz/Library/Application Support' +- (void)migrateResources { + os_log_info([KMLogs startupLog], "keymanKeyboardsDirectory: '%{public}@'", self.keymanKeyboardsDirectory); + os_log_info([KMLogs startupLog], "obsoleteKeymanDataDirectory: '%{public}@'", self.obsoleteKeymanDataDirectory); + /* BOOL isDir; BOOL exists = [fileManager fileExistsAtPath:keymanUrl.path isDirectory:&isDir]; @@ -58,11 +129,13 @@ - (void)migrateResources { } else { os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' does not exist", keymanUrl); } + */ } /** * Locate and create the Keyman data path; currently in ~/Documents/Keyman-Keyboards */ +/* - (NSString *)_obsoleteKeymanDataDirectory { if(_keymanDataDirectory == nil) { NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; @@ -78,8 +151,8 @@ - (NSString *)_obsoleteKeymanDataDirectory { return _keymanDataDirectory; } -- (NSString *)keymanDataPath { +- (NSString *)keymanDataDirectory { return _keymanDataDirectory; } - +*/ @end From 4fb5d74f496bfb102eb6e47e8c199db2415ca26d Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 1 Aug 2024 17:00:07 +0700 Subject: [PATCH 005/127] change(mac): implemented data migration and settings path updates --- .../Keyman4MacIM/KMDataRepository.h | 7 +- .../Keyman4MacIM/KMDataRepository.m | 112 +++++++++++------- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 29 +++-- .../Keyman4MacIM/KMSettingsRepository.h | 4 +- .../Keyman4MacIM/KMSettingsRepository.m | 103 ++++++++++++++-- 5 files changed, 194 insertions(+), 61 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index 53790a21524..836b8b742b4 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -13,9 +13,12 @@ NS_ASSUME_NONNULL_BEGIN @interface KMDataRepository : NSObject +@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/com.keyman.app' +@property (readonly) NSURL *keymanKeyboardsDirectory; +// keymanKeyboardsDirectory = '~/Library/Application Support/com.keyman.app/Keyman-Keyboards' + (KMDataRepository *)shared; -- (void)migrateResources; -- (NSURL *)keymanDataDirectory; +- (void)createDataDirectoriesIfNecessary; +- (BOOL)migrateData; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 40f8858aee6..2143d8b7f50 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -17,10 +17,7 @@ @interface KMDataRepository () @property (readonly) NSURL *applicationSupportSubDirectory; // '~/Library/Application Support' @property (readonly) NSURL *documentsSubDirectory; // '~/Documents' -@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/com.keyman.app' -@property (readonly) NSURL *keymanKeyboardsDirectory; -// keymanKeyboardsDirectory = '~/Library/Application Support/com.keyman.app/Keyman-Keyboards' -@property (readonly) NSURL *obsoleteKeymanDataDirectory; // '~/Library/Documents/Keyman-Keyboards' +@property (readonly) NSURL *obsoleteKeymanKeyboardsDirectory; // '~/Library/Documents/Keyman-Keyboards' @end @implementation KMDataRepository @@ -28,22 +25,17 @@ @implementation KMDataRepository @synthesize applicationSupportSubDirectory = _applicationSupportSubDirectory; @synthesize documentsSubDirectory = _documentsSubDirectory; @synthesize keymanKeyboardsDirectory = _keymanKeyboardsDirectory; -@synthesize obsoleteKeymanDataDirectory = _obsoleteKeymanDataDirectory; +@synthesize obsoleteKeymanKeyboardsDirectory = _obsoleteKeymanKeyboardsDirectory; @synthesize keymanDataDirectory = _keymanDataDirectory; NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards"; /* - name of the subdirectory within '~/Library/Application Support' - the convention is to use bundle identifier ("keyman.inputmethod.Keyman") - but we'll use this name, which matches our logging subsystem + The name of the subdirectory within '~/Library/Application Support'. + The convention is to use bundle identifier. + (Using the subsystem id, "com.keyman.app", is a poor choice because the API + createDirectoryAtPath sees the .app extension and creates an application file. */ -NSString *const kKeymanSubdirectoryName = @"com.keyman.app"; -/* -NSString* _obsoleteKeymanDataDirectory = nil; -NSString* _keymanDataDirectory = nil; -NSURL* _ApplicationSupportSubDirectory = nil; -NSURL* _DocumentsSubDirectory = nil; -*/ +NSString *const kKeymanSubdirectoryName = @"keyman.inputmethod.Keyman"; + (KMDataRepository *)shared { @@ -56,7 +48,7 @@ + (KMDataRepository *)shared } - (NSURL *)documentsSubDirectory { - if (self.documentsSubDirectory == nil) { + if (_documentsSubDirectory == nil) { NSError *directoryError = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; @@ -69,11 +61,11 @@ - (NSURL *)documentsSubDirectory { _documentsSubDirectory = documentsUrl; } } - return self.documentsSubDirectory; + return _documentsSubDirectory; } - (NSURL *)applicationSupportSubDirectory { - if (self.applicationSupportSubDirectory == nil) { + if (_applicationSupportSubDirectory == nil) { NSError *directoryError = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; @@ -86,50 +78,88 @@ - (NSURL *)applicationSupportSubDirectory { _applicationSupportSubDirectory = applicationSupportUrl; } } - return self.applicationSupportSubDirectory; + return _applicationSupportSubDirectory; } - (NSURL *)keymanDataDirectory { - if (self.keymanDataDirectory == nil) { + if (_keymanDataDirectory == nil) { NSURL *keymanDataUrl = [self.applicationSupportSubDirectory URLByAppendingPathComponent:kKeymanSubdirectoryName isDirectory: TRUE]; _keymanDataDirectory = keymanDataUrl; } - return self.keymanDataDirectory; + return _keymanDataDirectory; } - (NSURL *)keymanKeyboardsDirectory { - if (self.keymanKeyboardsDirectory == nil) { + if (_keymanKeyboardsDirectory == nil) { NSURL *keyboardsUrl = [self.keymanDataDirectory URLByAppendingPathComponent:kKeyboardsDirectoryName isDirectory: TRUE]; _keymanKeyboardsDirectory = keyboardsUrl; } - return self.keymanKeyboardsDirectory; + return _keymanKeyboardsDirectory; } -- (NSURL *)obsoleteKeymanDataDirectory { - if (self.obsoleteKeymanDataDirectory == nil) { - NSURL *keymanUrl = [self.documentsSubDirectory URLByAppendingPathComponent:kKeymanSubdirectoryName isDirectory: TRUE]; - _obsoleteKeymanDataDirectory = keymanUrl; +/** + * creates Keyman data directories if they do not exist yet + * This includes 1) the main data subdirectory: keyman.inputmethod.Keyman + * and 2) its subdirectory, Keyman-Keyboards + * + */ +- (void)createDataDirectoriesIfNecessary { + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL isDir; + BOOL exists = [fileManager fileExistsAtPath:self.keymanKeyboardsDirectory.path isDirectory:&isDir]; + + if (!exists) { + NSError *createError = nil; + [fileManager createDirectoryAtPath:self.keymanKeyboardsDirectory.path withIntermediateDirectories:YES attributes:nil error:nil]; + if (createError) { + os_log_error([KMLogs startupLog], "error creating Keyman-Keyboards directory: '%{public}@'", createError.localizedDescription); + } else { + os_log_info([KMLogs startupLog], "created Keyman-Keyboards subdirectory: '%{public}@'", self.keymanKeyboardsDirectory.path); + } + } else { + os_log_info([KMLogs startupLog], "Keyman-Keyboards already exists: '%{public}@'", self.keymanKeyboardsDirectory.path); } - return self.obsoleteKeymanDataDirectory; } -- (void)migrateResources { - os_log_info([KMLogs startupLog], "keymanKeyboardsDirectory: '%{public}@'", self.keymanKeyboardsDirectory); - os_log_info([KMLogs startupLog], "obsoleteKeymanDataDirectory: '%{public}@'", self.obsoleteKeymanDataDirectory); +- (NSURL *)obsoleteKeymanKeyboardsDirectory { + if (_obsoleteKeymanKeyboardsDirectory == nil) { + NSURL *keymanUrl = [self.documentsSubDirectory URLByAppendingPathComponent:kKeyboardsDirectoryName isDirectory: TRUE]; + _obsoleteKeymanKeyboardsDirectory = keymanUrl; + } + return _obsoleteKeymanKeyboardsDirectory; +} - /* +- (BOOL)keyboardsExistInDocumentsFolder { + NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; - BOOL exists = [fileManager fileExistsAtPath:keymanUrl.path isDirectory:&isDir]; + BOOL exists = ([fileManager fileExistsAtPath:self.obsoleteKeymanKeyboardsDirectory.path isDirectory:&isDir]); + return exists; +} + +- (BOOL)migrateData { + BOOL didMoveData = NO; + NSString *obsoleteKeymanKeyboardsDirectory = self.obsoleteKeymanKeyboardsDirectory.path; + NSString *dataDirectory = self.keymanDataDirectory.path; + os_log_info([KMLogs startupLog], "migrateData, move obsoleteKeymanKeyboardsDirectory: '%{public}@' to '%{public}@'", obsoleteKeymanKeyboardsDirectory, dataDirectory); + + // delete, happens whether migration or not + //[self createKeyboardsDirectoriesIfNecessary]; - if (exists) { - os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' exists", keymanUrl); - if (isDir) { - os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' is a directory", keymanUrl); - } - } else { - os_log_info([KMLogs startupLog], "keymanUrl '%{public}@' does not exist", keymanUrl); + BOOL dataExistsInOldLocation = [self keyboardsExistInDocumentsFolder]; + os_log([KMLogs startupLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); + + if (dataExistsInOldLocation) { + NSError *moveError = nil; + NSFileManager *fileManager = [NSFileManager defaultManager]; + didMoveData = [fileManager moveItemAtURL:self.obsoleteKeymanKeyboardsDirectory + toURL:self.keymanDataDirectory + error:&moveError]; + if (moveError) { + os_log_error([KMLogs startupLog], "error migrating data: '%{public}@'", moveError.localizedDescription); + } } - */ + + return didMoveData; } /** diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 87a53824321..ecd3e659e82 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -511,6 +511,7 @@ - (BOOL)useVerboseLogging { * Locate and create the Keyman data path; currently in ~/Documents/Keyman-Keyboards */ - (NSString *)keymanDataPath { + /* if(_keymanDataPath == nil) { NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; _keymanDataPath = [documentDirPath stringByAppendingPathComponent:@"Keyman-Keyboards"]; @@ -523,18 +524,22 @@ - (NSString *)keymanDataPath { } } return _keymanDataPath; + */ + return [KMDataRepository shared].keymanDataDirectory.path; } /** * Returns the root folder where keyboards are stored; currently the same * as the keymanDataPath, but may diverge in future versions (possibly a sub-folder) + * + * Actually divering now, get this from KMDataRepository */ - (NSString *)keyboardsPath { if (_keyboardsPath == nil) { _keyboardsPath = [self keymanDataPath]; } - return _keyboardsPath; + return [KMDataRepository shared].keymanKeyboardsDirectory.path; } - (NSArray *)kmxFileList { @@ -765,13 +770,23 @@ - (void)setContextBuffer:(NSMutableString *)contextBuffer { } - (void)awakeFromNib { - if ([KMSettingsRepository.shared keyboardsMigrationNeeded]) { - os_log_info([KMLogs startupLog], "keyboards migration needed"); - [KMDataRepository.shared migrateResources]; - } else { - os_log_info([KMLogs startupLog], "keyboards migration not needed"); - } + [self preparePersistence]; +} +/** + * Prepare the app for all the things that need to be persisted: + * namely, the settings in UserDefaults and keyboard data on disk + */ +- (void)preparePersistence { + [KMDataRepository.shared createDataDirectoriesIfNecessary]; + + if ([KMSettingsRepository.shared dataMigrationNeeded]) { + BOOL movedData = [KMDataRepository.shared migrateData]; + //os_log_info([KMLogs startupLog], "test: call migrateData again"); + //[KMDataRepository.shared migrateData]; + [KMSettingsRepository.shared convertSettingsForMigration]; + } + [KMSettingsRepository.shared createStorageFlagIfNecessary]; } - (void)setDefaultKeymanMenuItems { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h index e4b9f1c158a..9a2fcb4c413 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h @@ -14,7 +14,9 @@ NS_ASSUME_NONNULL_BEGIN @interface KMSettingsRepository : NSObject + (KMSettingsRepository *)shared; -- (BOOL)keyboardsMigrationNeeded; +- (BOOL)dataMigrationNeeded; +- (void)convertSettingsForMigration; +- (void)createStorageFlagIfNecessary; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index d5a26cccac7..84d6623d2c9 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -13,8 +13,12 @@ #import "KMSettingsRepository.h" #import "KMLogs.h" -NSString *const kStoreKeyboardsInLibraryKey = @"KMStoreKeyboardsInLibraryKey"; +NSString *const kStoreDataInLibraryKey = @"KMStoreDataInLibraryKey"; NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; +NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; + +NSString *const kObsoletePathComponent = @"/Documents/"; +NSString *const kNewPathComponent = @"/Application Support/keyman.inputmethod.Keyman/"; @implementation KMSettingsRepository @@ -28,30 +32,109 @@ + (KMSettingsRepository *)shared return shared; } +- (void)createStorageFlagIfNecessary { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kStoreDataInLibraryKey]; +} + - (BOOL)settingsExist { return [[NSUserDefaults standardUserDefaults] objectForKey:kActiveKeyboardsKey] != nil; } -- (BOOL)keyboardsStoredInLibraryFolder +- (BOOL)dataStoredInLibraryDirectory { - return [[NSUserDefaults standardUserDefaults] boolForKey:kStoreKeyboardsInLibraryKey]; + return [[NSUserDefaults standardUserDefaults] boolForKey:kStoreDataInLibraryKey]; } /** - * Determines whether the keyboards data needs to be moved from the old location in the Documents folder to the new location under /username/Library... + * Determines whether the keyboard data needs to be moved from the old location in ~/Documents to the new location ~/Library... * This is true if * 1) the UserDefaults exist (indicating that this is not a new installation of Keyman) and * 2) the value for KMStoreKeyboardsInLibraryKey is not set to true */ -- (BOOL)keyboardsMigrationNeeded { - BOOL keyboardSettingsExist = [self settingsExist]; - os_log([KMLogs startupLog], " keyboard settings exist: %@", keyboardSettingsExist ? @"YES" : @"NO" ); +- (BOOL)dataMigrationNeeded { + BOOL keymanSettingsExist = [self settingsExist]; + os_log([KMLogs startupLog], " keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" ); - BOOL keyboardsInLibrary = [self keyboardsStoredInLibraryFolder]; - os_log([KMLogs startupLog], " keyboards stored in Library: %@", keyboardsInLibrary ? @"YES" : @"NO" ); + BOOL dataInLibrary = [self dataStoredInLibraryDirectory]; + os_log([KMLogs startupLog], " data stored in Library: %{public}@", dataInLibrary ? @"YES" : @"NO" ); - return !(keyboardSettingsExist && keyboardsInLibrary); + return !(keymanSettingsExist && dataInLibrary); +} + +- (void)convertSettingsForMigration { + [self convertSelectedKeyboardPathForMigration]; + [self convertActiveKeyboardArrayForMigration]; +} + +- (void)convertSelectedKeyboardPathForMigration { + NSString *selectedKeyboardPath = [self selectedKeyboard]; + + if (selectedKeyboardPath != nil) { + NSString *newPathString = [self convertOldKeyboardPath:selectedKeyboardPath]; + + if ([selectedKeyboardPath isNotEqualTo:newPathString]) { + [self saveSelectedKeyboard:newPathString]; + os_log([KMLogs startupLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); + } + } +} + +/** + * Convert the path of the keyboard designating the Documents folder to its new location + * in the Application Support folder + */ + +- (NSString *)convertOldKeyboardPath:(NSString *)oldPath { + NSString *newPathString = @""; + if(oldPath != nil) { + newPathString = [oldPath stringByReplacingOccurrencesOfString:kObsoletePathComponent withString:kNewPathComponent]; + } + return newPathString; } +- (NSString *)selectedKeyboard { + return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey]; +} + +- (void)saveSelectedKeyboard:(NSString *)selectedKeyboard { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setObject:selectedKeyboard forKey:kSelectedKeyboardKey]; +} + +- (void)convertActiveKeyboardArrayForMigration { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + NSMutableArray *activeKeyboards = [self activeKeyboards]; + NSMutableArray *convertedActiveKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; + BOOL didConvert = NO; + + for (NSString *oldPath in activeKeyboards) { + NSString *newPath = [self convertOldKeyboardPath:oldPath]; + if ([oldPath isNotEqualTo:newPath]) { + [convertedActiveKeyboards addObject:newPath]; + os_log([KMLogs startupLog], "converted active keyboard from old path '%{public}@' to '%{public}@'", oldPath, newPath); + // if we have adjusted at least one path, set flag + didConvert = YES; + } else { + // if, somehow, the path does not need converting then retain it in new array + [convertedActiveKeyboards addObject:oldPath]; + } + } + + // only update array in UserDefaults if we actually converted something + if (didConvert) { + [[NSUserDefaults standardUserDefaults] setObject:convertedActiveKeyboards forKey:kActiveKeyboardsKey]; + } +} + +- (NSMutableArray *)activeKeyboards { + NSMutableArray * activeKeyboards = [[[NSUserDefaults standardUserDefaults] arrayForKey:kActiveKeyboardsKey] mutableCopy]; + + if (!activeKeyboards) { + activeKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; + } + return activeKeyboards; +} + + @end From c2e2cf53c61571d05883a3c6db904bbd89d140bb Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 2 Aug 2024 15:21:56 +0700 Subject: [PATCH 006/127] change(mac): successful migration but not loading from config --- .../Keyman4MacIM.xcodeproj/project.pbxproj | 4 ++ .../Keyman4MacIM/KMDataRepository.h | 3 +- .../Keyman4MacIM/KMDataRepository.m | 49 ++++++++++++++----- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 12 +++-- .../Keyman4MacIM/KMPackageReader.m | 3 ++ .../Keyman4MacIM/KMSettingsRepository.m | 5 +- .../KeymanTests/InputMethodTests.m | 17 +++++++ 7 files changed, 74 insertions(+), 19 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj index 9d63aac4685..8f49e2e0f24 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj +++ b/mac/Keyman4MacIM/Keyman4MacIM.xcodeproj/project.pbxproj @@ -31,6 +31,8 @@ 29B42A602728343B00EDD5D3 /* KMKeyboardHelpWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 29B42A622728343B00EDD5D3 /* KMKeyboardHelpWindowController.xib */; }; 29B4A0D52BF7675A00682049 /* KMLogs.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B4A0D32BF7675A00682049 /* KMLogs.m */; }; 29B6FB732BC39DD60074BF7F /* TextApiComplianceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B6FB722BC39DD60074BF7F /* TextApiComplianceTests.m */; }; + 29C1CDE22C5B2F8B003C23BB /* KMSettingsRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = D861B03E2C5747F70003675E /* KMSettingsRepository.m */; }; + 29C1CDE32C5B2F8B003C23BB /* KMDataRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = 29015ABC2C58D86F00CCBB94 /* KMDataRepository.m */; }; 37A245C12565DFA6000BBF92 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 37A245C02565DFA6000BBF92 /* Assets.xcassets */; }; 37AE5C9D239A7B770086CC7C /* qrcode.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 37AE5C9C239A7B770086CC7C /* qrcode.min.js */; }; 37C2B0CB25FF2C350092E16A /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 37C2B0CA25FF2C340092E16A /* Help */; }; @@ -1017,6 +1019,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 29C1CDE22C5B2F8B003C23BB /* KMSettingsRepository.m in Sources */, + 29C1CDE32C5B2F8B003C23BB /* KMDataRepository.m in Sources */, 2915DC512BFE35DB0051FC52 /* KMLogs.m in Sources */, 2992F4202A28482800E08929 /* PrivacyWindowController.m in Sources */, 2992F41F2A2847C900E08929 /* TextApiCompliance.m in Sources */, diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index 836b8b742b4..a5af2ccb881 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -17,7 +17,8 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) NSURL *keymanKeyboardsDirectory; // keymanKeyboardsDirectory = '~/Library/Application Support/com.keyman.app/Keyman-Keyboards' + (KMDataRepository *)shared; -- (void)createDataDirectoriesIfNecessary; +- (void)createDataDirectoryIfNecessary; +- (void)createKeyboardsDirectoryIfNecessary; - (BOOL)migrateData; @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 2143d8b7f50..3d0d0bacd7e 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -74,7 +74,7 @@ - (NSURL *)applicationSupportSubDirectory { if (directoryError) { os_log_error([KMLogs startupLog], "error getting Application Support subdirectory: '%{public}@'", directoryError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "Application Support subdirectory: '%{public}@'", applicationSupportUrl); + os_log_info([KMLogs startupLog], "Application Support subdirectory: '%{public}@'", applicationSupportUrl.path); _applicationSupportSubDirectory = applicationSupportUrl; } } @@ -98,18 +98,39 @@ - (NSURL *)keymanKeyboardsDirectory { } /** - * creates Keyman data directories if they do not exist yet - * This includes 1) the main data subdirectory: keyman.inputmethod.Keyman - * and 2) its subdirectory, Keyman-Keyboards - * + * Creates Keyman data directory if it do not exist yet. This is the main data subdirectory: keyman.inputmethod.Keyman + */ +- (void)createDataDirectoryIfNecessary { + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL isDir; + BOOL exists = [fileManager fileExistsAtPath:self.keymanDataDirectory.path isDirectory:&isDir]; + + if (!exists) { + NSError *createError = nil; + os_log_info([KMLogs startupLog], "createDataDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanDataDirectory.path); + [fileManager createDirectoryAtPath:self.keymanDataDirectory.path withIntermediateDirectories:YES attributes:nil error:nil]; + if (createError) { + os_log_error([KMLogs startupLog], "error creating Keyman data directory: '%{public}@'", createError.localizedDescription); + } else { + os_log_info([KMLogs startupLog], "created Keyman data directory: '%{public}@'", self.keymanDataDirectory.path); + } + } else { + os_log_info([KMLogs startupLog], "Keyman data directory already exists: '%{public}@'", self.keymanDataDirectory.path); + } +} + +/** + * Creates Keyman keyboard directory if it does not exist yet. This is the 'Keyman-Keyboards' directory. + * It should not be created until after migrating because its existence would block migrating data from the old location. */ -- (void)createDataDirectoriesIfNecessary { +- (void)createKeyboardsDirectoryIfNecessary { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; BOOL exists = [fileManager fileExistsAtPath:self.keymanKeyboardsDirectory.path isDirectory:&isDir]; if (!exists) { NSError *createError = nil; + os_log_info([KMLogs startupLog], "createKeyboardsDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanKeyboardsDirectory.path); [fileManager createDirectoryAtPath:self.keymanKeyboardsDirectory.path withIntermediateDirectories:YES attributes:nil error:nil]; if (createError) { os_log_error([KMLogs startupLog], "error creating Keyman-Keyboards directory: '%{public}@'", createError.localizedDescription); @@ -138,24 +159,30 @@ - (BOOL)keyboardsExistInDocumentsFolder { - (BOOL)migrateData { BOOL didMoveData = NO; + NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *obsoleteKeymanKeyboardsDirectory = self.obsoleteKeymanKeyboardsDirectory.path; NSString *dataDirectory = self.keymanDataDirectory.path; os_log_info([KMLogs startupLog], "migrateData, move obsoleteKeymanKeyboardsDirectory: '%{public}@' to '%{public}@'", obsoleteKeymanKeyboardsDirectory, dataDirectory); - // delete, happens whether migration or not - //[self createKeyboardsDirectoriesIfNecessary]; - + BOOL isDir; + BOOL dataDirectoryExistsInNewLocation = ([fileManager fileExistsAtPath:self.keymanDataDirectory.path isDirectory:&isDir]); + os_log([KMLogs startupLog], "data directory exists in new location, %{public}@: %{public}@", self.keymanDataDirectory.path, dataDirectoryExistsInNewLocation?@"YES":@"NO"); + + BOOL keyboardsDirectoryExistsInNewLocation = ([fileManager fileExistsAtPath:self.keymanKeyboardsDirectory.path isDirectory:&isDir]); + os_log([KMLogs startupLog], "keyboards directory exists in new location, %{public}@: %{public}@", self.keymanKeyboardsDirectory.path, keyboardsDirectoryExistsInNewLocation?@"YES":@"NO"); + BOOL dataExistsInOldLocation = [self keyboardsExistInDocumentsFolder]; os_log([KMLogs startupLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); if (dataExistsInOldLocation) { NSError *moveError = nil; - NSFileManager *fileManager = [NSFileManager defaultManager]; didMoveData = [fileManager moveItemAtURL:self.obsoleteKeymanKeyboardsDirectory - toURL:self.keymanDataDirectory + toURL:self.keymanKeyboardsDirectory error:&moveError]; if (moveError) { os_log_error([KMLogs startupLog], "error migrating data: '%{public}@'", moveError.localizedDescription); + } else { + os_log_error([KMLogs startupLog], "data migrated successfully to: '%{public}@'", self.keymanKeyboardsDirectory.path); } } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index ecd3e659e82..8352bf2a594 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -182,7 +182,7 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification { }]; // [SentrySDK captureMessage:@"Starting Keyman [test message]"]; - + [self setDefaultKeymanMenuItems]; [self updateKeyboardMenuItems]; } @@ -532,7 +532,7 @@ - (NSString *)keymanDataPath { * Returns the root folder where keyboards are stored; currently the same * as the keymanDataPath, but may diverge in future versions (possibly a sub-folder) * - * Actually divering now, get this from KMDataRepository + * Actually diverting now, get this from KMDataRepository */ - (NSString *)keyboardsPath { if (_keyboardsPath == nil) { @@ -774,11 +774,11 @@ - (void)awakeFromNib { } /** - * Prepare the app for all the things that need to be persisted: - * namely, the settings in UserDefaults and keyboard data on disk + * Prepare the app environment for all the things that need to be persisted: + * namely, the keyboard data on disk and the settings in UserDefaults */ - (void)preparePersistence { - [KMDataRepository.shared createDataDirectoriesIfNecessary]; + [KMDataRepository.shared createDataDirectoryIfNecessary]; if ([KMSettingsRepository.shared dataMigrationNeeded]) { BOOL movedData = [KMDataRepository.shared migrateData]; @@ -786,6 +786,8 @@ - (void)preparePersistence { //[KMDataRepository.shared migrateData]; [KMSettingsRepository.shared convertSettingsForMigration]; } + + [KMDataRepository.shared createKeyboardsDirectoryIfNecessary]; [KMSettingsRepository.shared createStorageFlagIfNecessary]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m index 7406488a8a0..186ec8ab5a0 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m @@ -69,6 +69,8 @@ - (KMPackageInfo *)loadPackageInfo:(NSString *)path { return packageInfo; } +/* + // TODO: not used, delete - (NSString *)packageNameFromPackageInfo:(NSString *)path { NSString *packageName = nil; @@ -77,6 +79,7 @@ - (NSString *)packageNameFromPackageInfo:(NSString *)path { return packageName; } +*/ /** * read JSON file and load it into KMPackageInfo object diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 84d6623d2c9..d0776e01fc2 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -11,14 +11,15 @@ */ #import "KMSettingsRepository.h" +//#import "KMDataRepository.h" #import "KMLogs.h" -NSString *const kStoreDataInLibraryKey = @"KMStoreDataInLibraryKey"; +NSString *const kStoreDataInLibraryKey = @"KMStoreDataInLibrary"; NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; NSString *const kObsoletePathComponent = @"/Documents/"; -NSString *const kNewPathComponent = @"/Application Support/keyman.inputmethod.Keyman/"; +NSString *const kNewPathComponent = @"/Library/Application Support/keyman.inputmethod.Keyman/"; @implementation KMSettingsRepository diff --git a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m index 8eb9d974ceb..38994c351a5 100644 --- a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m +++ b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m @@ -13,6 +13,9 @@ #import "KMInputMethodEventHandler.h" #import "AppleCompliantTestClient.h" #import "TextApiCompliance.h" +#import "KMSettingsRepository.h" +#import "KMDataRepository.h" +#import KMInputMethodEventHandler *testEventHandler = nil; @@ -85,4 +88,18 @@ - (void)testCalculateInsertRange_deleteOneBMPCharacterWithOneSelected_returnsRan XCTAssertTrue(correctResult, @"insert or replacement range expected to be {1,2}"); } +- (void)testMigrateData_oldDataExists_logsLocations { + os_log_t startupLog = os_log_create("com.keyman.app", "data-migration"); + if ([KMSettingsRepository.shared dataMigrationNeeded]) { + os_log_info(startupLog, "data migration needed, calling migrateData"); + [KMDataRepository.shared migrateData]; + os_log_info(startupLog, "test: call migrateData again"); + [KMDataRepository.shared migrateData]; + } else { + os_log_info(startupLog, "data migration not needed"); + } + + XCTAssertTrue(YES, @"test failed"); +} + @end From b435090a6fba6f9c29c15657e5ecef646b537017 Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Mon, 5 Aug 2024 16:43:02 +0700 Subject: [PATCH 007/127] change(mac): migrates options and changes keyboards successfully --- .../Keyman4MacIM/KMDataRepository.m | 40 ++------------- .../Keyman4MacIM/KMInputMethodAppDelegate.h | 1 - .../Keyman4MacIM/KMInputMethodAppDelegate.m | 33 ++----------- .../Keyman4MacIM/KMSettingsRepository.m | 49 +++++++++++++++++++ 4 files changed, 58 insertions(+), 65 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 3d0d0bacd7e..ac2d678ce57 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -157,23 +157,16 @@ - (BOOL)keyboardsExistInDocumentsFolder { return exists; } +/** + * Migrate the keyboards data from the old location in '/Documents' to the new location '/Application Support/keyman.inputmethod.Keyman/' + */ - (BOOL)migrateData { BOOL didMoveData = NO; NSFileManager *fileManager = [NSFileManager defaultManager]; - NSString *obsoleteKeymanKeyboardsDirectory = self.obsoleteKeymanKeyboardsDirectory.path; - NSString *dataDirectory = self.keymanDataDirectory.path; - os_log_info([KMLogs startupLog], "migrateData, move obsoleteKeymanKeyboardsDirectory: '%{public}@' to '%{public}@'", obsoleteKeymanKeyboardsDirectory, dataDirectory); - - BOOL isDir; - BOOL dataDirectoryExistsInNewLocation = ([fileManager fileExistsAtPath:self.keymanDataDirectory.path isDirectory:&isDir]); - os_log([KMLogs startupLog], "data directory exists in new location, %{public}@: %{public}@", self.keymanDataDirectory.path, dataDirectoryExistsInNewLocation?@"YES":@"NO"); - - BOOL keyboardsDirectoryExistsInNewLocation = ([fileManager fileExistsAtPath:self.keymanKeyboardsDirectory.path isDirectory:&isDir]); - os_log([KMLogs startupLog], "keyboards directory exists in new location, %{public}@: %{public}@", self.keymanKeyboardsDirectory.path, keyboardsDirectoryExistsInNewLocation?@"YES":@"NO"); - BOOL dataExistsInOldLocation = [self keyboardsExistInDocumentsFolder]; os_log([KMLogs startupLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); + // only move data if there is something there to move if (dataExistsInOldLocation) { NSError *moveError = nil; didMoveData = [fileManager moveItemAtURL:self.obsoleteKeymanKeyboardsDirectory @@ -182,34 +175,11 @@ - (BOOL)migrateData { if (moveError) { os_log_error([KMLogs startupLog], "error migrating data: '%{public}@'", moveError.localizedDescription); } else { - os_log_error([KMLogs startupLog], "data migrated successfully to: '%{public}@'", self.keymanKeyboardsDirectory.path); + os_log_info([KMLogs startupLog], "data migrated successfully to: '%{public}@'", self.keymanKeyboardsDirectory.path); } } return didMoveData; } -/** - * Locate and create the Keyman data path; currently in ~/Documents/Keyman-Keyboards - */ -/* -- (NSString *)_obsoleteKeymanDataDirectory { - if(_keymanDataDirectory == nil) { - NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; - _keymanDataDirectory = [documentDirPath stringByAppendingPathComponent:@"Keyman-Keyboards"]; - - os_log_debug([KMLogs dataLog], "creating keymanDataPath, %{public}@", _keymanDataDirectory); - - NSFileManager *fm = [NSFileManager defaultManager]; - if (![fm fileExistsAtPath:_keymanDataDirectory]) { - [fm createDirectoryAtPath:_keymanDataDirectory withIntermediateDirectories:YES attributes:nil error:nil]; - } - } - return _keymanDataDirectory; -} - -- (NSString *)keymanDataDirectory { - return _keymanDataDirectory; -} -*/ @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h index 4bf463c177f..7eddf31cb51 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h @@ -126,7 +126,6 @@ static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX = 0; - (NSString *)oskWindowTitle; - (void)postKeyboardEventWithSource: (CGEventSourceRef)source code:(CGKeyCode) virtualKey postCallback:(PostEventCallback)postEvent; - (KeymanVersionInfo)versionInfo; -- (NSString *)keymanDataPath; - (void)registerConfigurationWindow:(NSWindowController *)window; @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 8352bf2a594..fb7edaad012 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -85,7 +85,6 @@ @implementation KMInputMethodAppDelegate @synthesize alwaysShowOSK = _alwaysShowOSK; id _lastServerWithOSKShowing = nil; -NSString* _keymanDataPath = nil; - (id)init { self = [super init]; @@ -508,38 +507,14 @@ - (BOOL)useVerboseLogging { #pragma mark - Keyman Data /** - * Locate and create the Keyman data path; currently in ~/Documents/Keyman-Keyboards - */ -- (NSString *)keymanDataPath { - /* - if(_keymanDataPath == nil) { - NSString *documentDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; - _keymanDataPath = [documentDirPath stringByAppendingPathComponent:@"Keyman-Keyboards"]; - - os_log_debug([KMLogs dataLog], "creating keymanDataPath, %{public}@", _keymanDataPath); - - NSFileManager *fm = [NSFileManager defaultManager]; - if (![fm fileExistsAtPath:_keymanDataPath]) { - [fm createDirectoryAtPath:_keymanDataPath withIntermediateDirectories:YES attributes:nil error:nil]; - } - } - return _keymanDataPath; - */ - return [KMDataRepository shared].keymanDataDirectory.path; -} - -/** - * Returns the root folder where keyboards are stored; currently the same - * as the keymanDataPath, but may diverge in future versions (possibly a sub-folder) - * - * Actually diverting now, get this from KMDataRepository + * Returns the root folder where keyboards are stored */ - (NSString *)keyboardsPath { if (_keyboardsPath == nil) { - _keyboardsPath = [self keymanDataPath]; + _keyboardsPath = [KMDataRepository shared].keymanKeyboardsDirectory.path; } - return [KMDataRepository shared].keymanKeyboardsDirectory.path; + return _keyboardsPath; } - (NSArray *)kmxFileList { @@ -652,7 +627,7 @@ - (KMPackageInfo *)loadPackageInfo:(NSString *)path { - (NSString *)packageNameFromPackageInfo:(NSString *)packageFolder { NSString *packageName = nil; - NSString *path = [[self keymanDataPath] stringByAppendingPathComponent:packageFolder]; + NSString *path = [[self keyboardsPath] stringByAppendingPathComponent:packageFolder]; KMPackageInfo *packageInfo = [self.packageReader loadPackageInfo:path]; if (packageInfo) { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index d0776e01fc2..5381651e313 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -17,6 +17,7 @@ NSString *const kStoreDataInLibraryKey = @"KMStoreDataInLibrary"; NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; +NSString *const kPersistedOptionsKey = @"KMPersistedOptionsKey"; NSString *const kObsoletePathComponent = @"/Documents/"; NSString *const kNewPathComponent = @"/Library/Application Support/keyman.inputmethod.Keyman/"; @@ -66,6 +67,7 @@ - (BOOL)dataMigrationNeeded { - (void)convertSettingsForMigration { [self convertSelectedKeyboardPathForMigration]; [self convertActiveKeyboardArrayForMigration]; + [self convertPersistedOptionsPathsForMigration]; } - (void)convertSelectedKeyboardPathForMigration { @@ -137,5 +139,52 @@ - (NSMutableArray *)activeKeyboards { return activeKeyboards; } +- (void)convertPersistedOptionsPathsForMigration { + NSDictionary * optionsMap = [self persistedOptions]; + NSMutableDictionary *mutableOptionsMap = nil; + BOOL optionsChanged = NO; + + if (optionsMap != nil) { + os_log_info([KMLogs configLog], "optionsMap != nil"); + mutableOptionsMap = [[NSMutableDictionary alloc] initWithCapacity:0]; + for(id key in optionsMap) { + os_log_info([KMLogs configLog], "persisted options found in UserDefaults with key = %{public}@", key); + } + for (NSString *key in optionsMap) { + NSString *newPathString = [self convertOldKeyboardPath:key]; + NSDictionary *optionsValue = [optionsMap objectForKey:key]; + + if ([key isNotEqualTo:newPathString]) { + optionsChanged = YES; + + // insert options into new map with newly converted path as key + [mutableOptionsMap setObject:optionsValue forKey:newPathString]; + os_log([KMLogs startupLog], "converted option key from '%{public}@' to '%{public}@'", key, newPathString); + } else { + // retain options that did not need converting + [mutableOptionsMap setObject:optionsValue forKey:key]; + } + } + if (optionsChanged) { + [self savePersistedOptions:mutableOptionsMap]; + } + } +} + +- (NSDictionary *)persistedOptions { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData dictionaryForKey:kPersistedOptionsKey]; +} + +- (void)savePersistedOptions:(NSDictionary *) optionsDictionary { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setObject:optionsDictionary forKey:kPersistedOptionsKey]; +} + +- (void)removePersistedOptions { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData removeObjectForKey:kPersistedOptionsKey]; +} + @end From 8b408730b7ba04f502f6f1c9c0c165d8cbec6527 Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Tue, 6 Aug 2024 17:14:34 +0700 Subject: [PATCH 008/127] change(mac): uses Library directory instead of Documents Write new key KMDataModelVersion in UserDefaults with integer value that determines how data is expected to be stored. Migrates existing Keyman data to new location if it was written with an older (or no) version. Fixes: #2542 --- .../Keyman4MacIM/KMDataRepository.m | 36 +++--- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 10 +- .../Keyman4MacIM/KMSettingsRepository.h | 2 +- .../Keyman4MacIM/KMSettingsRepository.m | 112 ++++++++++-------- 4 files changed, 87 insertions(+), 73 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index ac2d678ce57..24495007bd4 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -55,9 +55,9 @@ - (NSURL *)documentsSubDirectory { NSURL *documentsUrl = [fileManager URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; if (directoryError) { - os_log_error([KMLogs startupLog], "error getting Documents subdirectory: '%{public}@'", directoryError.localizedDescription); + os_log_error([KMLogs dataLog], "error getting Documents subdirectory: '%{public}@'", directoryError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "Documents subdirectory: '%{public}@'", documentsUrl); + os_log_info([KMLogs dataLog], "Documents subdirectory: '%{public}@'", documentsUrl); _documentsSubDirectory = documentsUrl; } } @@ -72,9 +72,9 @@ - (NSURL *)applicationSupportSubDirectory { NSURL *applicationSupportUrl = [fileManager URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&directoryError]; if (directoryError) { - os_log_error([KMLogs startupLog], "error getting Application Support subdirectory: '%{public}@'", directoryError.localizedDescription); + os_log_error([KMLogs dataLog], "error getting Application Support subdirectory: '%{public}@'", directoryError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "Application Support subdirectory: '%{public}@'", applicationSupportUrl.path); + os_log_info([KMLogs dataLog], "Application Support subdirectory: '%{public}@'", applicationSupportUrl.path); _applicationSupportSubDirectory = applicationSupportUrl; } } @@ -107,15 +107,15 @@ - (void)createDataDirectoryIfNecessary { if (!exists) { NSError *createError = nil; - os_log_info([KMLogs startupLog], "createDataDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanDataDirectory.path); + os_log_info([KMLogs dataLog], "createDataDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanDataDirectory.path); [fileManager createDirectoryAtPath:self.keymanDataDirectory.path withIntermediateDirectories:YES attributes:nil error:nil]; if (createError) { - os_log_error([KMLogs startupLog], "error creating Keyman data directory: '%{public}@'", createError.localizedDescription); + os_log_error([KMLogs dataLog], "error creating Keyman data directory: '%{public}@'", createError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "created Keyman data directory: '%{public}@'", self.keymanDataDirectory.path); + os_log_info([KMLogs dataLog], "created Keyman data directory: '%{public}@'", self.keymanDataDirectory.path); } } else { - os_log_info([KMLogs startupLog], "Keyman data directory already exists: '%{public}@'", self.keymanDataDirectory.path); + os_log_info([KMLogs dataLog], "Keyman data directory already exists: '%{public}@'", self.keymanDataDirectory.path); } } @@ -130,15 +130,15 @@ - (void)createKeyboardsDirectoryIfNecessary { if (!exists) { NSError *createError = nil; - os_log_info([KMLogs startupLog], "createKeyboardsDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanKeyboardsDirectory.path); + os_log_info([KMLogs dataLog], "createKeyboardsDirectoryIfNecessary, about to attempt createDirectoryAtPath for: '%{public}@'", self.keymanKeyboardsDirectory.path); [fileManager createDirectoryAtPath:self.keymanKeyboardsDirectory.path withIntermediateDirectories:YES attributes:nil error:nil]; if (createError) { - os_log_error([KMLogs startupLog], "error creating Keyman-Keyboards directory: '%{public}@'", createError.localizedDescription); + os_log_error([KMLogs dataLog], "error creating Keyman-Keyboards directory: '%{public}@'", createError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "created Keyman-Keyboards subdirectory: '%{public}@'", self.keymanKeyboardsDirectory.path); + os_log_info([KMLogs dataLog], "created Keyman-Keyboards subdirectory: '%{public}@'", self.keymanKeyboardsDirectory.path); } } else { - os_log_info([KMLogs startupLog], "Keyman-Keyboards already exists: '%{public}@'", self.keymanKeyboardsDirectory.path); + os_log_info([KMLogs dataLog], "Keyman-Keyboards already exists: '%{public}@'", self.keymanKeyboardsDirectory.path); } } @@ -150,7 +150,7 @@ - (NSURL *)obsoleteKeymanKeyboardsDirectory { return _obsoleteKeymanKeyboardsDirectory; } -- (BOOL)keyboardsExistInDocumentsFolder { +- (BOOL)keyboardsExistInObsoleteDirectory { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; BOOL exists = ([fileManager fileExistsAtPath:self.obsoleteKeymanKeyboardsDirectory.path isDirectory:&isDir]); @@ -163,19 +163,19 @@ - (BOOL)keyboardsExistInDocumentsFolder { - (BOOL)migrateData { BOOL didMoveData = NO; NSFileManager *fileManager = [NSFileManager defaultManager]; - BOOL dataExistsInOldLocation = [self keyboardsExistInDocumentsFolder]; - os_log([KMLogs startupLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); + BOOL dataExistsInOldLocation = [self keyboardsExistInObsoleteDirectory]; + os_log([KMLogs dataLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); - // only move data if there is something there to move + // only move data if there is something to move if (dataExistsInOldLocation) { NSError *moveError = nil; didMoveData = [fileManager moveItemAtURL:self.obsoleteKeymanKeyboardsDirectory toURL:self.keymanKeyboardsDirectory error:&moveError]; if (moveError) { - os_log_error([KMLogs startupLog], "error migrating data: '%{public}@'", moveError.localizedDescription); + os_log_error([KMLogs dataLog], "data migration failed: '%{public}@'", moveError.localizedDescription); } else { - os_log_info([KMLogs startupLog], "data migrated successfully to: '%{public}@'", self.keymanKeyboardsDirectory.path); + os_log_info([KMLogs dataLog], "data migrated successfully to: '%{public}@'", self.keymanKeyboardsDirectory.path); } } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index fb7edaad012..7d3709ae4f2 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -745,25 +745,23 @@ - (void)setContextBuffer:(NSMutableString *)contextBuffer { } - (void)awakeFromNib { - [self preparePersistence]; + [self prepareStorage]; } /** * Prepare the app environment for all the things that need to be persisted: - * namely, the keyboard data on disk and the settings in UserDefaults + * namely, the keyboard data on disk and the settings in UserDefaults */ -- (void)preparePersistence { +- (void)prepareStorage { [KMDataRepository.shared createDataDirectoryIfNecessary]; if ([KMSettingsRepository.shared dataMigrationNeeded]) { BOOL movedData = [KMDataRepository.shared migrateData]; - //os_log_info([KMLogs startupLog], "test: call migrateData again"); - //[KMDataRepository.shared migrateData]; [KMSettingsRepository.shared convertSettingsForMigration]; } [KMDataRepository.shared createKeyboardsDirectoryIfNecessary]; - [KMSettingsRepository.shared createStorageFlagIfNecessary]; + [KMSettingsRepository.shared setDataModelVersionIfNecessary]; } - (void)setDefaultKeymanMenuItems { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h index 9a2fcb4c413..e6fe4dca38a 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN + (KMSettingsRepository *)shared; - (BOOL)dataMigrationNeeded; - (void)convertSettingsForMigration; -- (void)createStorageFlagIfNecessary; +- (void)setDataModelVersionIfNecessary; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 5381651e313..489c4e63dc6 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -7,14 +7,12 @@ * Created by Shawn Schantz on 2024-07-29. * * Singleton object for reading and writing Keyman application settings. - * Serves as an abstraction to StandardUserDefaults which is currently used to persist application settings. + * Serves as an abstraction to StandardUserDefaults which is currently used to store application settings. */ #import "KMSettingsRepository.h" -//#import "KMDataRepository.h" #import "KMLogs.h" -NSString *const kStoreDataInLibraryKey = @"KMStoreDataInLibrary"; NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; NSString *const kPersistedOptionsKey = @"KMPersistedOptionsKey"; @@ -22,6 +20,14 @@ NSString *const kObsoletePathComponent = @"/Documents/"; NSString *const kNewPathComponent = @"/Library/Application Support/keyman.inputmethod.Keyman/"; +/** + * Store the version number of the data model in the UserDefaults with this key. + * The first version, 1, is defined to indicate that we are storing the data/keyboards in the Library + * directory instead of in the Documents directory. + */ +NSString *const kDataModelVersion = @"KMDataModelVersion"; +NSInteger const kVersionStoreDataInLibraryDirectory = 1; + @implementation KMSettingsRepository + (KMSettingsRepository *)shared @@ -34,18 +40,29 @@ + (KMSettingsRepository *)shared return shared; } -- (void)createStorageFlagIfNecessary { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kStoreDataInLibraryKey]; +- (void)setDataModelVersionIfNecessary { + if (![self dataStoredInLibraryDirectory]) { + [[NSUserDefaults standardUserDefaults] setInteger:kVersionStoreDataInLibraryDirectory forKey:kDataModelVersion]; + } } +/** + * If the selectedKeyboard has not been set, then the settings have not been saved in the UserDefaults. + * If this method is called after applicationDidFinishLaunching, then it will always return true. + * If called from awakeFromNib, then it will return false when running for the first time. + */ - (BOOL)settingsExist { - return [[NSUserDefaults standardUserDefaults] objectForKey:kActiveKeyboardsKey] != nil; + return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey] != nil; } +/** + * For the first numbered version of the data model, the app stores the keyboards under the /Library directory + * For versions before version 1, the keyboards were stored under the /Documents directory. + */ - (BOOL)dataStoredInLibraryDirectory { - return [[NSUserDefaults standardUserDefaults] boolForKey:kStoreDataInLibraryKey]; + return [[NSUserDefaults standardUserDefaults] integerForKey:kDataModelVersion] == kVersionStoreDataInLibraryDirectory; } /** @@ -56,14 +73,47 @@ - (BOOL)dataStoredInLibraryDirectory */ - (BOOL)dataMigrationNeeded { BOOL keymanSettingsExist = [self settingsExist]; - os_log([KMLogs startupLog], " keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" ); + os_log([KMLogs dataLog], " keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" ); BOOL dataInLibrary = [self dataStoredInLibraryDirectory]; - os_log([KMLogs startupLog], " data stored in Library: %{public}@", dataInLibrary ? @"YES" : @"NO" ); + os_log([KMLogs dataLog], " data stored in Library: %{public}@", dataInLibrary ? @"YES" : @"NO" ); return !(keymanSettingsExist && dataInLibrary); } +- (NSString *)selectedKeyboard { + return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey]; +} + +- (void)saveSelectedKeyboard:(NSString *)selectedKeyboard { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setObject:selectedKeyboard forKey:kSelectedKeyboardKey]; +} + +- (NSMutableArray *)activeKeyboards { + NSMutableArray * activeKeyboards = [[[NSUserDefaults standardUserDefaults] arrayForKey:kActiveKeyboardsKey] mutableCopy]; + + if (!activeKeyboards) { + activeKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; + } + return activeKeyboards; +} + +- (NSDictionary *)persistedOptions { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData dictionaryForKey:kPersistedOptionsKey]; +} + +- (void)savePersistedOptions:(NSDictionary *) optionsDictionary { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setObject:optionsDictionary forKey:kPersistedOptionsKey]; +} + +- (void)removePersistedOptions { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData removeObjectForKey:kPersistedOptionsKey]; +} + - (void)convertSettingsForMigration { [self convertSelectedKeyboardPathForMigration]; [self convertActiveKeyboardArrayForMigration]; @@ -78,7 +128,7 @@ - (void)convertSelectedKeyboardPathForMigration { if ([selectedKeyboardPath isNotEqualTo:newPathString]) { [self saveSelectedKeyboard:newPathString]; - os_log([KMLogs startupLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); + os_log([KMLogs dataLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); } } } @@ -96,15 +146,6 @@ - (NSString *)convertOldKeyboardPath:(NSString *)oldPath { return newPathString; } -- (NSString *)selectedKeyboard { - return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey]; -} - -- (void)saveSelectedKeyboard:(NSString *)selectedKeyboard { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setObject:selectedKeyboard forKey:kSelectedKeyboardKey]; -} - - (void)convertActiveKeyboardArrayForMigration { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; NSMutableArray *activeKeyboards = [self activeKeyboards]; @@ -115,7 +156,7 @@ - (void)convertActiveKeyboardArrayForMigration { NSString *newPath = [self convertOldKeyboardPath:oldPath]; if ([oldPath isNotEqualTo:newPath]) { [convertedActiveKeyboards addObject:newPath]; - os_log([KMLogs startupLog], "converted active keyboard from old path '%{public}@' to '%{public}@'", oldPath, newPath); + os_log([KMLogs dataLog], "converted active keyboard from old path '%{public}@' to '%{public}@'", oldPath, newPath); // if we have adjusted at least one path, set flag didConvert = YES; } else { @@ -126,19 +167,10 @@ - (void)convertActiveKeyboardArrayForMigration { // only update array in UserDefaults if we actually converted something if (didConvert) { - [[NSUserDefaults standardUserDefaults] setObject:convertedActiveKeyboards forKey:kActiveKeyboardsKey]; + [[NSUserDefaults standardUserDefaults] setObject:convertedActiveKeyboards forKey:kActiveKeyboardsKey]; } } -- (NSMutableArray *)activeKeyboards { - NSMutableArray * activeKeyboards = [[[NSUserDefaults standardUserDefaults] arrayForKey:kActiveKeyboardsKey] mutableCopy]; - - if (!activeKeyboards) { - activeKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; - } - return activeKeyboards; -} - - (void)convertPersistedOptionsPathsForMigration { NSDictionary * optionsMap = [self persistedOptions]; NSMutableDictionary *mutableOptionsMap = nil; @@ -159,10 +191,10 @@ - (void)convertPersistedOptionsPathsForMigration { // insert options into new map with newly converted path as key [mutableOptionsMap setObject:optionsValue forKey:newPathString]; - os_log([KMLogs startupLog], "converted option key from '%{public}@' to '%{public}@'", key, newPathString); + os_log([KMLogs dataLog], "converted option key from '%{public}@' to '%{public}@'", key, newPathString); } else { // retain options that did not need converting - [mutableOptionsMap setObject:optionsValue forKey:key]; + [mutableOptionsMap setObject:optionsValue forKey:key]; } } if (optionsChanged) { @@ -171,20 +203,4 @@ - (void)convertPersistedOptionsPathsForMigration { } } -- (NSDictionary *)persistedOptions { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - return [userData dictionaryForKey:kPersistedOptionsKey]; -} - -- (void)savePersistedOptions:(NSDictionary *) optionsDictionary { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setObject:optionsDictionary forKey:kPersistedOptionsKey]; -} - -- (void)removePersistedOptions { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - return [userData removeObjectForKey:kPersistedOptionsKey]; -} - - @end From 1e805949ae762b49f8d96dc340f916b59174d4f2 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 9 Aug 2024 14:49:37 +0700 Subject: [PATCH 009/127] change(mac): store partial path in UserDefaults --- .../Keyman4MacIM/KMDataRepository.h | 1 + .../Keyman4MacIM/KMDataRepository.m | 7 ++- .../Keyman4MacIM/KMSettingsRepository.m | 44 ++++++++++++++----- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index a5af2ccb881..766e9c10e95 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)createDataDirectoryIfNecessary; - (void)createKeyboardsDirectoryIfNecessary; - (BOOL)migrateData; +- (NSString*)buildFullPathWith:(NSString *)partialPath; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 24495007bd4..0b3b8023e65 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -164,7 +164,7 @@ - (BOOL)migrateData { BOOL didMoveData = NO; NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL dataExistsInOldLocation = [self keyboardsExistInObsoleteDirectory]; - os_log([KMLogs dataLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); + os_log_debug([KMLogs dataLog], "obsolete keyman keyboards directory exists: %@", dataExistsInOldLocation?@"YES":@"NO"); // only move data if there is something to move if (dataExistsInOldLocation) { @@ -182,4 +182,9 @@ - (BOOL)migrateData { return didMoveData; } +- (NSString*)buildFullPathWith:(NSString *)partialPath { + NSString *fullPath = [self.keymanKeyboardsDirectory.path stringByAppendingString:partialPath]; + os_log_debug([KMLogs dataLog], "createFullPathWith: '%{public}@' with partialPath '%{public}@'", self.keymanKeyboardsDirectory.path, partialPath); + return fullPath; +} @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 489c4e63dc6..3109770067d 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -12,12 +12,14 @@ #import "KMSettingsRepository.h" #import "KMLogs.h" +#import "KMDataRepository.h" NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; NSString *const kPersistedOptionsKey = @"KMPersistedOptionsKey"; -NSString *const kObsoletePathComponent = @"/Documents/"; +//NSString *const kObsoletePathComponent = @"/Documents/"; +NSString *const kObsoletePathComponent = @"/Documents/Keyman-Keyboards"; NSString *const kNewPathComponent = @"/Library/Application Support/keyman.inputmethod.Keyman/"; /** @@ -53,7 +55,7 @@ - (void)setDataModelVersionIfNecessary { */ - (BOOL)settingsExist { - return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey] != nil; + return ([[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey] != nil); } /** @@ -122,13 +124,13 @@ - (void)convertSettingsForMigration { - (void)convertSelectedKeyboardPathForMigration { NSString *selectedKeyboardPath = [self selectedKeyboard]; - if (selectedKeyboardPath != nil) { - NSString *newPathString = [self convertOldKeyboardPath:selectedKeyboardPath]; + NSString *newPathString = [self trimObsoleteKeyboardPath:selectedKeyboardPath]; if ([selectedKeyboardPath isNotEqualTo:newPathString]) { [self saveSelectedKeyboard:newPathString]; - os_log([KMLogs dataLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); + os_log_debug([KMLogs dataLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); + os_log_debug([KMLogs dataLog], "full path of selected keyboard from buildFullPathWith = '%{public}@'", [KMDataRepository.shared buildFullPathWith:newPathString]); } } } @@ -137,7 +139,7 @@ - (void)convertSelectedKeyboardPathForMigration { * Convert the path of the keyboard designating the Documents folder to its new location * in the Application Support folder */ - +/* - (NSString *)convertOldKeyboardPath:(NSString *)oldPath { NSString *newPathString = @""; if(oldPath != nil) { @@ -145,18 +147,36 @@ - (NSString *)convertOldKeyboardPath:(NSString *)oldPath { } return newPathString; } +*/ + +/** + * To convert the keyboard path for the new location, just trim the parent directory from the path + * No need to repeatedly store the parent directory with the path of each keyboard + * If the old directory is not found in the string, then return the string unchanged + */ +- (NSString *)trimObsoleteKeyboardPath:(NSString *)oldPath { + NSString *newPath = oldPath; + if(oldPath != nil) { + NSRange range = [oldPath rangeOfString:kObsoletePathComponent]; + if (range.length > 0) { + newPath = [oldPath substringFromIndex:range.location + range.length]; + os_log_debug([KMLogs dataLog], "trimmed keyboard path from '%{public}@' to '%{public}@'", oldPath, newPath); + } + } + return newPath; +} - (void)convertActiveKeyboardArrayForMigration { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - NSMutableArray *activeKeyboards = [self activeKeyboards]; + NSMutableArray *keyboards = [self activeKeyboards]; NSMutableArray *convertedActiveKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; BOOL didConvert = NO; - for (NSString *oldPath in activeKeyboards) { - NSString *newPath = [self convertOldKeyboardPath:oldPath]; + for (NSString *oldPath in keyboards) { + NSString *newPath = [self trimObsoleteKeyboardPath:oldPath]; if ([oldPath isNotEqualTo:newPath]) { [convertedActiveKeyboards addObject:newPath]; - os_log([KMLogs dataLog], "converted active keyboard from old path '%{public}@' to '%{public}@'", oldPath, newPath); + os_log_debug([KMLogs dataLog], "converted active keyboard from old path '%{public}@' to '%{public}@'", oldPath, newPath); // if we have adjusted at least one path, set flag didConvert = YES; } else { @@ -183,7 +203,7 @@ - (void)convertPersistedOptionsPathsForMigration { os_log_info([KMLogs configLog], "persisted options found in UserDefaults with key = %{public}@", key); } for (NSString *key in optionsMap) { - NSString *newPathString = [self convertOldKeyboardPath:key]; + NSString *newPathString = [self trimObsoleteKeyboardPath:key]; NSDictionary *optionsValue = [optionsMap objectForKey:key]; if ([key isNotEqualTo:newPathString]) { @@ -191,7 +211,7 @@ - (void)convertPersistedOptionsPathsForMigration { // insert options into new map with newly converted path as key [mutableOptionsMap setObject:optionsValue forKey:newPathString]; - os_log([KMLogs dataLog], "converted option key from '%{public}@' to '%{public}@'", key, newPathString); + os_log_debug([KMLogs dataLog], "converted option key from '%{public}@' to '%{public}@'", key, newPathString); } else { // retain options that did not need converting [mutableOptionsMap setObject:optionsValue forKey:key]; From b1685f5865e5be975843c92748ad56fdb73e2af5 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 15 Aug 2024 15:41:38 +0700 Subject: [PATCH 010/127] change(mac): use partial paths in settings converts partial paths to full paths as needed and vice-versa when moving between file system access and referencing keyboards in UserDefaults --- .../KMConfigurationWindowController.m | 25 +++-- .../Keyman4MacIM/KMDataRepository.h | 4 +- .../Keyman4MacIM/KMDataRepository.m | 32 +++++- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 100 +++++++++++------- .../Keyman4MacIM/KMSettingsRepository.m | 1 - 5 files changed, 111 insertions(+), 51 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 3e2ffe24100..efafbed11a3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -8,6 +8,7 @@ #import "KMConfigurationWindowController.h" #import "KMDownloadKBWindowController.h" +#import "KMDataRepository.h" #import "KMLogs.h" @interface KMConfigurationWindowController () @@ -134,8 +135,10 @@ - (NSArray *)tableContents { NSArray *pArray = (NSArray *)obj; NSString *packageFolder = [self packageFolderFromPath:[pArray objectAtIndex:0]]; NSString *packageName = [self.AppDelegate packageNameFromPackageInfo:packageFolder]; + os_log_debug([KMLogs uiLog], "tableContents, packageFolder: %{public}@, packageName: %{public}@", packageFolder, packageName); [_tableContents addObject:[NSDictionary dictionaryWithObjectsAndKeys:packageName, @"HeaderTitle", nil]]; for (NSString *path in pArray) { + os_log_debug([KMLogs uiLog], "tableContents, path = '%{public}@'", path); NSDictionary *info = [KMXFile keyboardInfoFromKmxFile:path]; if (!info) { info = [[NSDictionary alloc] initWithObjectsAndKeys: @@ -150,6 +153,7 @@ - (NSArray *)tableContents { } else { NSString *path = (NSString *)obj; + os_log_debug([KMLogs uiLog], "tableContents, path = '%{public}@'", path); NSDictionary *info = [KMXFile keyboardInfoFromKmxFile:path]; if (!info) { info = [[NSDictionary alloc] initWithObjectsAndKeys: @@ -241,22 +245,27 @@ - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn BOOL isHeader = (headerTitle != nil); BOOL isOthers = NO; NSString *kmxFilePath = [self kmxFilePathAtIndex:row]; - if (kmxFilePath != nil) + if (kmxFilePath != nil) { isOthers = [[self packageFolderFromPath:kmxFilePath] isEqualToString:@"Others"]; - else if (isHeader && [headerTitle isEqualToString:@"Others"]) + } + else if (isHeader && [headerTitle isEqualToString:@"Others"]) { isOthers = YES; - + } if ([identifier isEqualToString:@"Column1"]) { KMConfigColumn1CellView *cellView = [tableView makeViewWithIdentifier:identifier owner:self]; - if (isHeader) + if (isHeader) { [cellView setHidden:YES]; + } else { [cellView setHidden:NO]; cellView.imageView.objectValue = [info objectForKey:kKMKeyboardIconKey]; [cellView.checkBox setTag:row]; [cellView.checkBox setAction:@selector(checkBoxAction:)]; - [cellView.checkBox setState:([self.activeKeyboards containsObject:[self kmxFilePathAtIndex:row]])?NSOnState:NSOffState]; + NSString *kmxFilePath = [self kmxFilePathAtIndex:row]; + NSString *partialPath = [KMDataRepository.shared trimToPartialPath:kmxFilePath]; + os_log_debug([KMLogs uiLog], "tableView:viewForTableColumn, kmxFilePath = %{public}@ for row %li, partialPath = %{public}@", kmxFilePath, (long)row, partialPath); + [cellView.checkBox setState:([self.activeKeyboards containsObject:partialPath])?NSOnState:NSOffState]; } return cellView; @@ -357,14 +366,16 @@ - (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id)info r - (void)checkBoxAction:(id)sender { NSButton *checkBox = (NSButton *)sender; NSString *kmxFilePath = [self kmxFilePathAtIndex:checkBox.tag]; + NSString *partialPath = [KMDataRepository.shared trimToPartialPath:kmxFilePath]; + os_log_debug([KMLogs uiLog], "checkBoxAction, kmxFilePath = %{public}@ for checkBox.tag %li, partialPath = %{public}@", kmxFilePath, checkBox.tag, partialPath); if (checkBox.state == NSOnState) { os_log_debug([KMLogs uiLog], "Adding active keyboard: %{public}@", kmxFilePath); - [self.activeKeyboards addObject:kmxFilePath]; + [self.activeKeyboards addObject:partialPath]; [self saveActiveKeyboards]; } else if (checkBox.state == NSOffState) { os_log_debug([KMLogs uiLog], "Disabling active keyboard: %{public}@", kmxFilePath); - [self.activeKeyboards removeObject:kmxFilePath]; + [self.activeKeyboards removeObject:partialPath]; [self saveActiveKeyboards]; } } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index 766e9c10e95..8f38c282fa5 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -20,7 +20,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)createDataDirectoryIfNecessary; - (void)createKeyboardsDirectoryIfNecessary; - (BOOL)migrateData; -- (NSString*)buildFullPathWith:(NSString *)partialPath; +- (NSString*)buildFullPath:(NSString *)fromPartialPath; +- (NSString*)trimToPartialPath:(NSString *)fromFullPath; +- (NSString *)buildPartialPathFrom:(NSString *)keyboardSubdirectory keyboardFile:(NSString *)kmxFilename; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 0b3b8023e65..59bac96bb4d 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -182,9 +182,35 @@ - (BOOL)migrateData { return didMoveData; } -- (NSString*)buildFullPathWith:(NSString *)partialPath { - NSString *fullPath = [self.keymanKeyboardsDirectory.path stringByAppendingString:partialPath]; - os_log_debug([KMLogs dataLog], "createFullPathWith: '%{public}@' with partialPath '%{public}@'", self.keymanKeyboardsDirectory.path, partialPath); +- (NSString*)buildFullPath:(NSString *)fromPartialPath { + NSString *fullPath = [self.keymanKeyboardsDirectory.path stringByAppendingString:fromPartialPath]; + os_log_debug([KMLogs dataLog], "buildFullPath: '%{public}@' fromPartialPath '%{public}@'", + fullPath, fromPartialPath); return fullPath; } + +- (NSString *)trimToPartialPath:(NSString *)fromFullPath { + NSString *partialPath = fromFullPath; + if(fromFullPath != nil) { + NSRange range = [fromFullPath rangeOfString:kKeyboardsDirectoryName]; + if (range.length > 0) { + partialPath = [fromFullPath substringFromIndex:range.location + range.length]; + os_log_debug([KMLogs dataLog], "trimToPartialPath: fromFullPath: '%{public}@' to partialPath: '%{public}@'", fromFullPath, partialPath); + } + } + return partialPath; +} + +- (NSString *)buildPartialPathFrom:(NSString *)keyboardSubdirectory keyboardFile:(NSString *)kmxFilename { + NSMutableArray *pathComponents = [[NSMutableArray alloc] initWithCapacity:0]; + [pathComponents addObject:@"/"]; + [pathComponents addObject:keyboardSubdirectory]; + [pathComponents addObject:kmxFilename]; + NSString *keyboardPartialPath = [NSString pathWithComponents:pathComponents]; + os_log_debug([KMLogs keyboardLog], "buildPartialPathFrom, keyboardSubdirectory: %{public}@, kmxFileName: %{public}@, keyboardPartialPath : %{public}@", + keyboardSubdirectory, kmxFilename, keyboardPartialPath); + return keyboardPartialPath; +} + + @end diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 845e1f2140a..947bb803f13 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -169,12 +169,9 @@ -(void)applicationDidFinishLaunching:(NSNotification *)aNotification { [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"NSApplicationCrashOnExceptions": @YES }]; [KMLogs reportLogStatus]; - [self startSentry]; - [self setDefaultKeymanMenuItems]; [self updateKeyboardMenuItems]; - [self setPostLaunchKeymanSentryTags]; // [SentrySDK captureMessage:@"Starting Keyman [test message]"]; } @@ -544,12 +541,13 @@ - (NSString *)keyboardsPath { } - (NSArray *)kmxFileList { - os_log_debug([KMLogs dataLog], "kmxFileList"); if (_kmxFileList == nil) { - NSArray *kmxFiles = [self KMXFiles]; + os_log_debug([KMLogs dataLog], "creating kmxFileList"); + NSArray *kmxFiles = [self getKmxFilesInKeyboardsDirectory]; _kmxFileList = [[NSMutableArray alloc] initWithCapacity:0]; NSMutableArray *others = nil; for (NSString *filePath in kmxFiles) { + os_log_debug([KMLogs dataLog], "kmxFileList, filePath: %{public}@", filePath); NSString *packageFolder = [self packageFolderFromPath:filePath]; NSInteger index = [self indexForPackageFolder:packageFolder]; if ([packageFolder isEqualToString:@"Others"]) { @@ -666,7 +664,7 @@ - (NSString *)packageNameFromPackageInfo:(NSString *)packageFolder { - (NSArray *)keyboardNamesFromFolder:(NSString *)packageFolder { os_log_debug([KMLogs dataLog], "keyboardNamesFromFolder, folder = %{public}@", packageFolder); NSMutableArray *kbNames = [[NSMutableArray alloc] initWithCapacity:0];; - for (NSString *kmxFile in [self KMXFilesAtPath:packageFolder]) { + for (NSString *kmxFile in [self getKmxFilesAtPath:packageFolder]) { NSDictionary * infoDict = [KMXFile keyboardInfoFromKmxFile:kmxFile]; if (infoDict != nil) { NSString *name = [infoDict objectForKey:kKMKeyboardNameKey]; @@ -684,7 +682,8 @@ - (NSString *)selectedKeyboard { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; _selectedKeyboard = [userData objectForKey:kKMSelectedKeyboardKey]; } - + os_log_debug([KMLogs dataLog], "selectedKeyboard = %{public}@", _selectedKeyboard); + return _selectedKeyboard; } @@ -697,16 +696,20 @@ - (void)setSelectedKeyboard:(NSString *)selectedKeyboard { - (NSMutableArray *)activeKeyboards { if (!_activeKeyboards) { + os_log_debug([KMLogs dataLog], "initializing activeKeyboards"); NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; _activeKeyboards = [[userData arrayForKey:kKMActiveKeyboardsKey] mutableCopy]; - if (!_activeKeyboards) - _activeKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; + if (!_activeKeyboards) { + os_log_debug([KMLogs dataLog], "KMActiveKeyboardsKey key not found in NSUserDefualts"); + _activeKeyboards = [[NSMutableArray alloc] initWithCapacity:0]; + } } - + return _activeKeyboards; } - (void)saveActiveKeyboards { + os_log_debug([KMLogs dataLog], "saveActiveKeyboards, entering"); NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; [userData setObject:_activeKeyboards forKey:kKMActiveKeyboardsKey]; [userData synchronize]; @@ -725,8 +728,12 @@ - (void)resetActiveKeyboards { // Remove entries with missing files NSMutableArray *pathsToRemove = [[NSMutableArray alloc] initWithCapacity:0]; for (NSString *path in self.activeKeyboards) { - if (![[NSFileManager defaultManager] fileExistsAtPath:path]) + NSString *fullPath = [KMDataRepository.shared buildFullPath:path]; + os_log_debug([KMLogs dataLog], "resetActiveKeyboards, checking fullPath: '%{public}@' for path: '%{public}@'", fullPath, path); + if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { + os_log_debug([KMLogs dataLog], "resetActiveKeyboards, need to remove non-existent path: %{public}@", fullPath); [pathsToRemove addObject:path]; + } } BOOL found = FALSE; @@ -814,6 +821,7 @@ - (void)updateKeyboardMenuItems { } - (int)calculateNumberOfKeyboardMenuItems { + os_log_debug([KMLogs uiLog], "calculateNumberOfKeyboardMenuItems, entered"); if (self.activeKeyboards.count == 0) { // if there are no active keyboards, then we will insert one placeholder menu item 'No Active Keyboards' return 1; @@ -835,6 +843,7 @@ - (void)removeDynamicKeyboardMenuItems { } - (void)addDynamicKeyboardMenuItems { + os_log_debug([KMLogs startupLog], "addDynamicKeyboardMenuItems, entered"); BOOL didSetSelectedKeyboard = NO; NSInteger itag = KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG; NSString *keyboardMenuName = @""; @@ -846,7 +855,9 @@ - (void)addDynamicKeyboardMenuItems { // loop through the active keyboards list and add them to the menu for (NSString *path in self.activeKeyboards) { - NSDictionary *infoDict = [KMXFile keyboardInfoFromKmxFile:path]; + NSString *fullPath = [KMDataRepository.shared buildFullPath:path]; + os_log_debug([KMLogs dataLog], "addDynamicKeyboardMenuItems, path = '%{public}@', full path = '%{public}@'", path, fullPath); + NSDictionary *infoDict = [KMXFile keyboardInfoFromKmxFile:fullPath]; if (!infoDict) { continue; } @@ -876,10 +887,12 @@ - (void)addDynamicKeyboardMenuItems { - (void) setSelectedKeyboard:(NSString*)keyboardName inMenuItem:(NSMenuItem*) menuItem { KVKFile *kvk = nil; + NSString *fullPath = [KMDataRepository.shared buildFullPath:keyboardName]; + os_log_debug([KMLogs dataLog], "setSelectedKeyboard, keyboardName = '%{public}@', full path = '%{public}@'", keyboardName, fullPath); [menuItem setState:NSOnState]; - KMXFile *kmx = [[KMXFile alloc] initWithFilePath:keyboardName]; + KMXFile *kmx = [[KMXFile alloc] initWithFilePath:fullPath]; [self setKmx:kmx]; - NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:keyboardName]; + NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:fullPath]; NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; if (kvkFilename != nil) { NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; @@ -931,10 +944,13 @@ - (void)selectKeyboardFromMenu:(NSInteger)tag { } NSString *path = [self.activeKeyboards objectAtIndex:tag-KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG]; - KMXFile *kmx = [[KMXFile alloc] initWithFilePath:path]; + NSString *fullPath = [KMDataRepository.shared buildFullPath:path]; + os_log_debug([KMLogs dataLog], "setSelectedKeyboard, keyboardName = '%{public}@', full path = '%{public}@'", path, fullPath); + + KMXFile *kmx = [[KMXFile alloc] initWithFilePath:fullPath]; [self setKmx:kmx]; KVKFile *kvk = nil; - NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:path]; + NSDictionary *kmxInfo = [KMXFile keyboardInfoFromKmxFile:fullPath]; NSString *kvkFilename = [kmxInfo objectForKey:kKMVisualKeyboardKey]; if (kvkFilename != nil) { NSString *kvkFilePath = [self kvkFilePathFromFilename:kvkFilename]; @@ -953,12 +969,12 @@ - (void)selectKeyboardFromMenu:(NSInteger)tag { [self showOSK]; } -- (NSArray *)KMXFiles { - return [self KMXFilesAtPath:self.keyboardsPath]; +- (NSArray *)getKmxFilesInKeyboardsDirectory { + return [self getKmxFilesAtPath:self.keyboardsPath]; } -- (NSArray *)KMXFilesAtPath:(NSString *)path { - os_log_debug([KMLogs dataLog], "Reading KMXFiles at path %{public}@", path); +- (NSArray *)getKmxFilesAtPath:(NSString *)path { + os_log_debug([KMLogs dataLog], "getKmxFilesAtPath, path: '%{public}@'", path); NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:path]; NSMutableArray *kmxFiles = [[NSMutableArray alloc] initWithCapacity:0]; NSString *filePath; @@ -973,23 +989,23 @@ - (NSArray *)KMXFilesAtPath:(NSString *)path { return kmxFiles; } -- (NSArray *)KVKFiles { +- (NSArray *)getKvkFilesArray { NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:self.keyboardsPath]; - NSMutableArray *kvkFiles = [[NSMutableArray alloc] initWithCapacity:0]; + NSMutableArray *kvkFilesArray = [[NSMutableArray alloc] initWithCapacity:0]; NSString *filePath; while (filePath = (NSString *)[dirEnum nextObject]) { NSString *extension = [[filePath pathExtension] lowercaseString]; if ([extension isEqualToString:@"kvk"]) - [kvkFiles addObject:[self.keyboardsPath stringByAppendingPathComponent:filePath]]; + [kvkFilesArray addObject:[self.keyboardsPath stringByAppendingPathComponent:filePath]]; } - return kvkFiles; + return kvkFilesArray; } - (NSString *)kvkFilePathFromFilename:(NSString *)kvkFilename { NSString *kvkFilePath = nil; - NSArray *kvkFiles = [self KVKFiles]; - for (NSString *filePath in kvkFiles) { + NSArray *kvkFilesArray = [self getKvkFilesArray]; + for (NSString *filePath in kvkFilesArray) { if ([[filePath lastPathComponent] isEqualToString:kvkFilename]) { kvkFilePath = filePath; break; @@ -1338,7 +1354,8 @@ - (BOOL)unzipFile:(NSString *)filePath { NSError *error = nil; NSString *fileName = filePath.lastPathComponent; NSString *folderName = [fileName stringByDeletingPathExtension]; - + os_log_debug([KMLogs keyboardLog], "unzipFile, folderName: %{public}@, fileName: %{public}@", folderName, fileName); + // First we unzip into a temp folder, and check kmp.json for the fileVersion // before we continue installation. We don't want to overwrite existing // package if it is there if the files are not compatible with the installed @@ -1349,9 +1366,9 @@ - (BOOL)unzipFile:(NSString *)filePath { ZipArchive *za = [[ZipArchive alloc] init]; if ([za UnzipOpenFile:filePath]) { - os_log_debug([KMLogs keyboardLog], "Unzipping %{public}@ to %{public}@", filePath, tempDestFolder); + os_log_debug([KMLogs keyboardLog], "unzipFile, Unzipping %{public}@ to %{public}@", filePath, tempDestFolder); if ([[NSFileManager defaultManager] fileExistsAtPath:tempDestFolder]) { - os_log_debug([KMLogs keyboardLog], "The temp destination folder already exists. Overwriting..."); + os_log_debug([KMLogs keyboardLog], "unzipFile, The temp destination folder already exists. Overwriting..."); } didUnzip = [za UnzipFileTo:tempDestFolder overWrite:YES]; @@ -1359,11 +1376,11 @@ - (BOOL)unzipFile:(NSString *)filePath { } if (!didUnzip) { - os_log_error([KMLogs keyboardLog], "Failed to unzip file: %{public}@", filePath); + os_log_error([KMLogs keyboardLog], "unzipFile, Failed to unzip file: %{public}@", filePath); return NO; } - os_log_debug([KMLogs keyboardLog], "Unzipped file: %{public}@", filePath); + os_log_debug([KMLogs keyboardLog], "unzipFile, Unzipped file: %{public}@", filePath); BOOL didInstall = [self verifyPackageVersionInTempFolder:tempDestFolder filePath:filePath]; @@ -1371,10 +1388,10 @@ - (BOOL)unzipFile:(NSString *)filePath { // Remove existing package if it exists if (didInstall && [[NSFileManager defaultManager] fileExistsAtPath:destFolder]) { - os_log_debug([KMLogs keyboardLog], "The destination folder already exists. Overwriting..."); + os_log_debug([KMLogs keyboardLog], "unzipFile, The destination folder already exists. Overwriting..."); [[NSFileManager defaultManager] removeItemAtPath:destFolder error:&error]; if (error != nil) { - os_log_error([KMLogs keyboardLog], "Unable to remove destination folder %{public}@", destFolder); + os_log_error([KMLogs keyboardLog], "unzipFile, Unable to remove destination folder %{public}@", destFolder); didInstall = NO; } } @@ -1387,7 +1404,7 @@ - (BOOL)unzipFile:(NSString *)filePath { if(didInstall) { [[NSFileManager defaultManager] moveItemAtPath:tempDestFolder toPath:destFolder error:&error]; if (error != nil) { - os_log_error([KMLogs keyboardLog], "Unable to move temp folder %{public}@ to dest folder %{public}@", tempDestFolder, destFolder); + os_log_error([KMLogs keyboardLog], "unzipFile, Unable to move temp folder %{public}@ to dest folder %{public}@", tempDestFolder, destFolder); didInstall = NO; } } @@ -1395,7 +1412,7 @@ - (BOOL)unzipFile:(NSString *)filePath { if(!didInstall) { [[NSFileManager defaultManager] removeItemAtPath:tempDestFolder error:&error]; if (error != nil) { - os_log_error([KMLogs keyboardLog], "Unable to remove temp folder %{public}@", tempDestFolder); + os_log_error([KMLogs keyboardLog], "unzipFile, Unable to remove temp folder %{public}@", tempDestFolder); } return NO; @@ -1404,11 +1421,16 @@ - (BOOL)unzipFile:(NSString *)filePath { // Package has installed, now scan for keyboards and fonts // TODO: we need to be reading the kmp.json data to determine keyboards to install NSString * keyboardFolderPath = [self.keyboardsPath stringByAppendingPathComponent:folderName]; + os_log_debug([KMLogs keyboardLog], "unzipFile, folderName: %{public}@, keyboardFolderPath: %{public}@", folderName, keyboardFolderPath); [self installFontsAtPath:keyboardFolderPath]; - for (NSString *kmxFile in [self KMXFilesAtPath:keyboardFolderPath]) { - os_log_debug([KMLogs keyboardLog], "Adding keyboard to list of active keyboards: %{public}@", kmxFile); - if (![self.activeKeyboards containsObject:kmxFile]) - [self.activeKeyboards addObject:kmxFile]; + + for (NSString *kmxFile in [self getKmxFilesAtPath:keyboardFolderPath]) { + NSString *partialPath = [KMDataRepository.shared buildPartialPathFrom:folderName keyboardFile:[kmxFile lastPathComponent]]; + // TODO: encapsulate this in KMSettingsRepository, insertIfNotExists + if (![self.activeKeyboards containsObject:partialPath]) { + os_log_debug([KMLogs keyboardLog], "unzipFile, adding keyboard to list of active keyboards: %{public}@", partialPath); + [self.activeKeyboards addObject:partialPath]; + } } [self saveActiveKeyboards]; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 3109770067d..54c779c00d7 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -130,7 +130,6 @@ - (void)convertSelectedKeyboardPathForMigration { if ([selectedKeyboardPath isNotEqualTo:newPathString]) { [self saveSelectedKeyboard:newPathString]; os_log_debug([KMLogs dataLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); - os_log_debug([KMLogs dataLog], "full path of selected keyboard from buildFullPathWith = '%{public}@'", [KMDataRepository.shared buildFullPathWith:newPathString]); } } } From 5364a741dadd7a75bb5137c08110bd9664113753 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Fri, 16 Aug 2024 16:34:19 +0700 Subject: [PATCH 011/127] change(mac): some refactoring Mostly taking advantage of KMSettingsRepository so that more of the UserDefaults changes happen through it Still some refactoring remains for active keyboards list --- .../Keyman4MacIM/KMInputMethodAppDelegate.h | 3 +- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 98 +++------------ .../Keyman4MacIM/KMInputMethodEventHandler.m | 2 +- .../Keyman4MacIM/KMPackageReader.h | 2 - .../Keyman4MacIM/KMPackageReader.m | 3 - .../Keyman4MacIM/KMSettingsRepository.h | 8 ++ .../Keyman4MacIM/KMSettingsRepository.m | 115 ++++++++++++++---- 7 files changed, 114 insertions(+), 117 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h index 7eddf31cb51..376e531f7f2 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.h @@ -23,7 +23,6 @@ typedef void(^PostEventCallback)(CGEventRef eventToPost); -extern NSString *const kKMSelectedKeyboardKey; extern NSString *const kKMActiveKeyboardsKey; extern NSString *const kKeymanKeyboardDownloadCompletedNotification; @@ -99,7 +98,7 @@ static const int KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX = 0; - (NSMenu *)menu; - (void)saveActiveKeyboards; -- (void)readPersistedOptions; +- (void)applyPersistedOptions; - (void)writePersistedOptions:(NSString *)storeKey withValue:(NSString* )value; - (void)showAboutWindow; - (void)showOSK; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 947bb803f13..fddecc55fa3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -6,15 +6,6 @@ // Copyright (c) 2017 SIL International. All rights reserved. // -// *** TO INVESTIGATE *** -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (activateServerWithReply:) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (deactivateServerWithReply:) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (menusDictionaryWithClientAsync:reply:) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (modesWithClientAsync:reply:) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (commitCompositionWithReply:) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (hidePalettes) block performed very slowly (0.00 secs) -// Keyman4MacIM[6245]: IMK Stall detected, *please Report* your user scenario in - (sessionFinished) block performed very slowly (0.00 secs) - #import "KMInputMethodAppDelegate.h" #import "KMSettingsRepository.h" #import "KMDataRepository.h" @@ -28,20 +19,9 @@ #import "KMLogs.h" @import Sentry; +// TODO: move Active Keyboards UserDefaults code to KMSettingsRepository /** NSUserDefaults keys */ -NSString *const kKMSelectedKeyboardKey = @"KMSelectedKeyboardKey"; NSString *const kKMActiveKeyboardsKey = @"KMActiveKeyboardsKey"; -/** - The following constant "KMSavedStoresKey" is left here for documentation - though we have abandoned stores written to UserDefaults with this key because - they used a less-reliable numeric key prior to integration with Keyman Core. - It is replaced by the renamed "KMPersistedOptionsKey" which directly - represents what it is saving. - */ -NSString *const kKMDeprecatedPersistedOptionsKey = @"KMSavedStoresKey"; -NSString *const kKMPersistedOptionsKey = @"KMPersistedOptionsKey"; -NSString *const kKMAlwaysShowOSKKey = @"KMAlwaysShowOSKKey"; -NSString *const kKMUseVerboseLogging = @"KMUseVerboseLogging"; NSString *const kKeymanKeyboardDownloadCompletedNotification = @"kKeymanKeyboardDownloadCompletedNotification"; @@ -409,7 +389,6 @@ - (KMEngine *)kme { - (KMPackageReader *)packageReader { if (_packageReader == nil) { _packageReader = [[KMPackageReader alloc] init]; - [_packageReader setDebugMode:self.debugMode]; } return _packageReader; @@ -440,55 +419,17 @@ - (void)setKeyboardName:(NSString *)keyboardName { [_oskWindow.window setTitle:self.oskWindowTitle]; } -- (void)readPersistedOptions { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - NSDictionary *allPersistedOptions = [userData dictionaryForKey:kKMPersistedOptionsKey]; - if (!allPersistedOptions) { - return; - } - NSDictionary *persistedOptionsForSelectedKeyboard = [allPersistedOptions objectForKey:_selectedKeyboard]; - if (!persistedOptionsForSelectedKeyboard) { - os_log_info([KMLogs configLog], "no persisted options found in UserDefaults for keyboard %{public}@ ", _selectedKeyboard); - return; - } +- (void)applyPersistedOptions { + NSDictionary *selectedPersistedOptions = [[KMSettingsRepository shared] readOptionsForSelectedKeyboard]; // TODO: pass array instead of making repeated calls - for (NSString *key in persistedOptionsForSelectedKeyboard) { - NSString *value = [persistedOptionsForSelectedKeyboard objectForKey:key]; + for (NSString *key in selectedPersistedOptions) { + NSString *value = [selectedPersistedOptions objectForKey:key]; os_log_info([KMLogs configLog], "persisted options found in UserDefaults for keyboard %{public}@, key: %{public}@, value: %{public}@", _selectedKeyboard, key, value); [self.kme setCoreOptions:key withValue:value]; } } -- (void)writePersistedOptions:(NSString *)storeKey withValue:(NSString* )value { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - NSDictionary *allPersistedOptions = [userData dictionaryForKey:kKMPersistedOptionsKey]; - NSDictionary *persistedOptionsForSelectedKeyboard; - - if (allPersistedOptions) { - persistedOptionsForSelectedKeyboard = [allPersistedOptions objectForKey:_selectedKeyboard]; - } - - if (persistedOptionsForSelectedKeyboard) { - NSMutableDictionary *newSavedStores = [persistedOptionsForSelectedKeyboard mutableCopy]; - [newSavedStores setObject:value forKey:storeKey]; - persistedOptionsForSelectedKeyboard = newSavedStores; - } else { - persistedOptionsForSelectedKeyboard = [[NSDictionary alloc] initWithObjectsAndKeys:value, storeKey, nil]; - } - - if (allPersistedOptions) { - NSMutableDictionary *newAllSavedStores = [allPersistedOptions mutableCopy]; - [newAllSavedStores setObject:persistedOptionsForSelectedKeyboard forKey:_selectedKeyboard]; - allPersistedOptions = newAllSavedStores; - } else { - allPersistedOptions = [[NSDictionary alloc] initWithObjectsAndKeys:persistedOptionsForSelectedKeyboard, _selectedKeyboard, nil]; - } - - [userData setObject:allPersistedOptions forKey:kKMPersistedOptionsKey]; - [userData synchronize]; -} - - (NSString *)oskWindowTitle { if (_keyboardName == nil || !_keyboardName.length) return [NSString stringWithFormat:@"Keyman"]; @@ -498,9 +439,7 @@ - (NSString *)oskWindowTitle { - (void)setAlwaysShowOSK:(BOOL)alwaysShowOSK { _alwaysShowOSK = alwaysShowOSK; - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setBool:alwaysShowOSK forKey:kKMAlwaysShowOSKKey]; - [userData synchronize]; + [[KMSettingsRepository shared] writeAlwaysShowOsk:alwaysShowOSK]; } - (void)setUseVerboseLogging:(BOOL)useVerboseLogging { @@ -508,23 +447,17 @@ - (void)setUseVerboseLogging:(BOOL)useVerboseLogging { _debugMode = useVerboseLogging; if (_kme != nil) [_kme setUseVerboseLogging:useVerboseLogging]; - if (_packageReader != nil) { - [_packageReader setDebugMode:useVerboseLogging]; - } - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setBool:useVerboseLogging forKey:kKMUseVerboseLogging]; - [userData synchronize]; + + [[KMSettingsRepository shared] writeUseVerboseLogging:useVerboseLogging]; } - (BOOL)alwaysShowOSK { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - _alwaysShowOSK = [userData boolForKey:kKMAlwaysShowOSKKey]; + _alwaysShowOSK = [[KMSettingsRepository shared] readAlwaysShowOsk]; return _alwaysShowOSK; } - (BOOL)useVerboseLogging { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - return [userData boolForKey:kKMUseVerboseLogging]; + return [[KMSettingsRepository shared] readUseVerboseLogging]; } #pragma mark - Keyman Data @@ -679,8 +612,7 @@ - (NSArray *)keyboardNamesFromFolder:(NSString *)packageFolder { - (NSString *)selectedKeyboard { if (_selectedKeyboard == nil) { - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - _selectedKeyboard = [userData objectForKey:kKMSelectedKeyboardKey]; + _selectedKeyboard = [[KMSettingsRepository shared] readSelectedKeyboard]; } os_log_debug([KMLogs dataLog], "selectedKeyboard = %{public}@", _selectedKeyboard); @@ -688,10 +620,8 @@ - (NSString *)selectedKeyboard { } - (void)setSelectedKeyboard:(NSString *)selectedKeyboard { + [[KMSettingsRepository shared] writeSelectedKeyboard:selectedKeyboard]; _selectedKeyboard = selectedKeyboard; - NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setObject:_selectedKeyboard forKey:kKMSelectedKeyboardKey]; - [userData synchronize]; } - (NSMutableArray *)activeKeyboards { @@ -903,7 +833,7 @@ - (void) setSelectedKeyboard:(NSString*)keyboardName inMenuItem:(NSMenuItem*) me [self setKvk:kvk]; [self setKeyboardName:[kmxInfo objectForKey:kKMKeyboardNameKey]]; [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; - [self readPersistedOptions]; + [self applyPersistedOptions]; } // defaults to the whatever keyboard happens to be first in the list @@ -964,7 +894,7 @@ - (void)selectKeyboardFromMenu:(NSInteger)tag { [self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]]; [self setContextBuffer:nil]; [self setSelectedKeyboard:path]; - [self readPersistedOptions]; + [self applyPersistedOptions]; if (kvk != nil && self.alwaysShowOSK) [self showOSK]; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index efe628c43a3..da1a3192238 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -429,7 +429,7 @@ -(void) persistOptions:(NSDictionary*)options{ NSString *value = [options objectForKey:key]; if(key && value) { os_log_debug([KMLogs keyLog], "persistOptions, key: %{public}@, value: %{public}@", key, value); - [self.appDelegate writePersistedOptions:key withValue:value]; + [[KMSettingsRepository shared] writeOptionForSelectedKeyboard:key withValue:value]; } else { os_log_debug([KMLogs keyLog], "invalid values in persistOptions, not writing to UserDefaults, key: %{public}@, value: %{public}@", key, value); diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.h b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.h index 2c138d8215a..008f0c025e6 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.h @@ -19,8 +19,6 @@ NS_ASSUME_NONNULL_BEGIN @interface KMPackageReader : NSObject -@property (assign, nonatomic) BOOL debugMode; - - (instancetype)init; - (KMPackageInfo *)loadPackageInfo:(NSString *)path; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m index 186ec8ab5a0..e2cf1757a82 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m @@ -44,9 +44,6 @@ @implementation KMPackageReader - (instancetype)init { self = [super init]; - if (self) { - _debugMode = NO; - } return self; } diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h index e6fe4dca38a..8b74ce23d21 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h @@ -17,6 +17,14 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)dataMigrationNeeded; - (void)convertSettingsForMigration; - (void)setDataModelVersionIfNecessary; +- (NSString *)readSelectedKeyboard; +- (void)writeSelectedKeyboard:(NSString *)selectedKeyboard; +- (NSDictionary *)readOptionsForSelectedKeyboard; +- (void)writeOptionForSelectedKeyboard:(NSString *)key withValue:(NSString*)value; +- (BOOL)readAlwaysShowOsk; +- (void)writeAlwaysShowOsk:(BOOL)alwaysShowOsk; +- (BOOL)readUseVerboseLogging; +- (void)writeUseVerboseLogging:(BOOL)verboseLogging; @end NS_ASSUME_NONNULL_END diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 54c779c00d7..83b16a7e8bb 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -17,6 +17,17 @@ NSString *const kActiveKeyboardsKey = @"KMActiveKeyboardsKey"; NSString *const kSelectedKeyboardKey = @"KMSelectedKeyboardKey"; NSString *const kPersistedOptionsKey = @"KMPersistedOptionsKey"; +NSString *const kAlwaysShowOSKKey = @"KMAlwaysShowOSKKey"; +NSString *const kUseVerboseLogging = @"KMUseVerboseLogging"; + +/** + The following constant "KMSavedStoresKey" is left here for documentation + though we have abandoned stores written to UserDefaults with this key because + they used a less-reliable numeric key prior to integration with Keyman Core. + It is replaced by the renamed "KMPersistedOptionsKey" which directly + represents what it is saving. + */ +NSString *const kKMDeprecatedPersistedOptionsKey = @"KMSavedStoresKey"; //NSString *const kObsoletePathComponent = @"/Documents/"; NSString *const kObsoletePathComponent = @"/Documents/Keyman-Keyboards"; @@ -58,6 +69,32 @@ - (BOOL)settingsExist return ([[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey] != nil); } +- (void)writeOptionForSelectedKeyboard:(NSString *)key withValue:(NSString*)value { + NSDictionary *optionsMap = [self readOptionsForSelectedKeyboard]; + NSDictionary *newOptionsMap = nil; + // if we can read an existing options map, then add the specified key-value pair + if (optionsMap != nil) { + NSMutableDictionary *mutableOptionsMap = [optionsMap mutableCopy]; + [mutableOptionsMap setObject:value forKey:key]; + os_log_info([KMLogs dataLog], "writeOptionsForSelectedKeyboard, setting key: %{public}@, value %{public}@", key, value); + newOptionsMap = mutableOptionsMap; + } else { + newOptionsMap = [[NSDictionary alloc] initWithObjectsAndKeys:value, key, nil]; + } + + // write the fully built dictionary to the dictionary of options + NSString *selectedKeyboard = [self readSelectedKeyboard]; + [self writeKeyboardOptionsMap: selectedKeyboard withOptions:newOptionsMap]; +} + +- (void)writeKeyboardOptionsMap:(NSString *)keyboardName withOptions:(NSDictionary*) optionsMap { + NSDictionary *fullOptionsMap = [self readOptions]; + NSMutableDictionary *newFullOptionsMap = [fullOptionsMap mutableCopy]; + + [newFullOptionsMap setObject:optionsMap forKey:keyboardName]; + [self writeOptions:newFullOptionsMap]; +} + /** * For the first numbered version of the data model, the app stores the keyboards under the /Library directory * For versions before version 1, the keyboards were stored under the /Documents directory. @@ -83,11 +120,11 @@ - (BOOL)dataMigrationNeeded { return !(keymanSettingsExist && dataInLibrary); } -- (NSString *)selectedKeyboard { +- (NSString *)readSelectedKeyboard { return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey]; } -- (void)saveSelectedKeyboard:(NSString *)selectedKeyboard { +- (void)writeSelectedKeyboard:(NSString *)selectedKeyboard { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; [userData setObject:selectedKeyboard forKey:kSelectedKeyboardKey]; } @@ -101,53 +138,61 @@ - (NSMutableArray *)activeKeyboards { return activeKeyboards; } -- (NSDictionary *)persistedOptions { +/* + * returns dictionary of persisted options for the single selected keyboard + */ +- (NSDictionary *)readOptionsForSelectedKeyboard { + NSDictionary *optionsMap = [self readOptions]; + NSString *selectedKeyboard = [self readSelectedKeyboard]; + NSDictionary *selectedOptionsMap = [optionsMap objectForKey: selectedKeyboard]; + if (selectedOptionsMap == nil) { + os_log_info([KMLogs dataLog], "no persisted options found in UserDefaults for keyboard %{public}@ ", selectedKeyboard); + } else { + for (NSString *key in optionsMap) { + NSString *value = [optionsMap objectForKey:key]; + os_log_info([KMLogs dataLog], "option for keyboard %{public}@ key: %{public}@, value %{public}@", selectedKeyboard, key, value); + } + } + return selectedOptionsMap; +} + +/* + * returns dictionary of all persisted options for all keyboards + */ +- (NSDictionary *)readOptions { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; return [userData dictionaryForKey:kPersistedOptionsKey]; } -- (void)savePersistedOptions:(NSDictionary *) optionsDictionary { +- (void)writeOptions:(NSDictionary *) optionsDictionary { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; [userData setObject:optionsDictionary forKey:kPersistedOptionsKey]; } -- (void)removePersistedOptions { +- (void)removeAllOptions { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; return [userData removeObjectForKey:kPersistedOptionsKey]; } - (void)convertSettingsForMigration { + os_log_debug([KMLogs dataLog], "converting settings in UserDefaults for migration"); [self convertSelectedKeyboardPathForMigration]; [self convertActiveKeyboardArrayForMigration]; - [self convertPersistedOptionsPathsForMigration]; + [self convertOptionsPathsForMigration]; } - (void)convertSelectedKeyboardPathForMigration { - NSString *selectedKeyboardPath = [self selectedKeyboard]; + NSString *selectedKeyboardPath = [self readSelectedKeyboard]; if (selectedKeyboardPath != nil) { NSString *newPathString = [self trimObsoleteKeyboardPath:selectedKeyboardPath]; if ([selectedKeyboardPath isNotEqualTo:newPathString]) { - [self saveSelectedKeyboard:newPathString]; + [self writeSelectedKeyboard:newPathString]; os_log_debug([KMLogs dataLog], "converted selected keyboard setting from '%{public}@' to '%{public}@'", selectedKeyboardPath, newPathString); } } } -/** - * Convert the path of the keyboard designating the Documents folder to its new location - * in the Application Support folder - */ -/* -- (NSString *)convertOldKeyboardPath:(NSString *)oldPath { - NSString *newPathString = @""; - if(oldPath != nil) { - newPathString = [oldPath stringByReplacingOccurrencesOfString:kObsoletePathComponent withString:kNewPathComponent]; - } - return newPathString; -} -*/ - /** * To convert the keyboard path for the new location, just trim the parent directory from the path * No need to repeatedly store the parent directory with the path of each keyboard @@ -190,8 +235,8 @@ - (void)convertActiveKeyboardArrayForMigration { } } -- (void)convertPersistedOptionsPathsForMigration { - NSDictionary * optionsMap = [self persistedOptions]; +- (void)convertOptionsPathsForMigration { + NSDictionary * optionsMap = [self readOptions]; NSMutableDictionary *mutableOptionsMap = nil; BOOL optionsChanged = NO; @@ -217,9 +262,29 @@ - (void)convertPersistedOptionsPathsForMigration { } } if (optionsChanged) { - [self savePersistedOptions:mutableOptionsMap]; + [self writeOptions:mutableOptionsMap]; } } } +- (BOOL)readAlwaysShowOsk { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData boolForKey:kAlwaysShowOSKKey]; +} + +- (void)writeAlwaysShowOsk:(BOOL)alwaysShowOsk { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setBool:alwaysShowOsk forKey:kAlwaysShowOSKKey]; +} + +- (BOOL)readUseVerboseLogging { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + return [userData boolForKey:kUseVerboseLogging]; +} + +- (void)writeUseVerboseLogging:(BOOL)verboseLogging { + NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; + [userData setBool:verboseLogging forKey:kUseVerboseLogging]; +} + @end From be55dabdc4c5dab3aba888de1c9248d459529117 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 16 Aug 2024 22:15:42 +1000 Subject: [PATCH 012/127] feat(windows): add right modifier key option pt1 --- common/windows/cpp/include/registry.h | 6 +- .../windows/delphi/general/RegistryKeys.pas | 3 +- .../delphi/tools/test-klog/test_klog.dpr | 8 +- .../delphi/tools/test-klog/test_klog.dproj | 4 + windows/src/desktop/kmshell/xml/strings.xml | 5 + windows/src/engine/keyman/UfrmKeyman7Main.pas | 4 +- .../keyman32/k32_lowlevelkeyboardhook.cpp | 96 +++++++------------ .../delphi/general/Keyman.System.Settings.pas | 22 +---- 8 files changed, 53 insertions(+), 95 deletions(-) diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h index 67cdfc2f69e..ebaca81c9cf 100644 --- a/common/windows/cpp/include/registry.h +++ b/common/windows/cpp/include/registry.h @@ -123,11 +123,7 @@ /* REGSZ_Keyman_Debug DWORD: Use old non-chiral Win32 API RegisterHotkey instead of left-only hotkeys */ -#define REGSZ_Flag_UseRegisterHotkey "Flag_UseRegisterHotkey" - -/* REGSZ_Flag_UseCachedHotkeyModifierState DWORD: Use old cached modifier state when checking hotkeys; ignores UseRegisterHotkey if FALSE */ - -#define REGSZ_Flag_UseCachedHotkeyModifierState "Flag_UseCachedHotkeyModifierState" +#define REGSZ_Flag_UseRightModifierHotKey "Flag_UseRightModifierHotKey" /* DWORD: Enable/disable deep TSF integration, default enabled; 0 = disabled, 1 = enabled, 2 = default */ diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 47e7df754a0..8cbd6d7d0a3 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -379,8 +379,7 @@ interface SRegKey_KeymanEngineDebug_CU = SRegKey_KeymanEngineRoot_CU + '\Debug'; - SRegValue_Flag_UseRegisterHotkey = 'Flag_UseRegisterHotkey'; - SRegValue_Flag_UseCachedHotkeyModifierState = 'Flag_UseCachedHotkeyModifierState'; + SRegValue_Flag_UseRightModifierHotKey = 'Flag_UseRightModifierHotKey'; SRegValue_Flag_ShouldSerializeInput = 'Flag_ShouldSerializeInput'; SRegValue_Flag_UseAutoStartTask = 'Flag_UseAutoStartTask'; SRegValue_Flag_SyncLanguagesToCloud = 'Flag_SyncLanguagesToCloud'; diff --git a/common/windows/delphi/tools/test-klog/test_klog.dpr b/common/windows/delphi/tools/test-klog/test_klog.dpr index 072042334a0..7f9d0e213aa 100644 --- a/common/windows/delphi/tools/test-klog/test_klog.dpr +++ b/common/windows/delphi/tools/test-klog/test_klog.dpr @@ -7,13 +7,17 @@ uses klog in '..\..\..\..\..\common\windows\delphi\general\klog.pas', VersionInfo in '..\..\..\..\..\common\windows\delphi\general\VersionInfo.pas', ErrorControlledRegistry in '..\..\..\..\..\common\windows\delphi\vcl\ErrorControlledRegistry.pas', - Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas'; + Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas', + DebugPaths in '..\..\..\..\..\common\windows\delphi\general\DebugPaths.pas', + RegistryKeys in '..\..\..\..\..\common\windows\delphi\general\RegistryKeys.pas', + KeymanVersion in '..\..\..\..\..\common\windows\delphi\general\KeymanVersion.pas', + KeymanPaths in '..\..\..\..\..\common\windows\delphi\general\KeymanPaths.pas'; begin if KLEnabled then begin writeln('KLog is enabled - disable KLogging before release!'); - ExitCode := 1; + ExitCode := 0; end else begin diff --git a/common/windows/delphi/tools/test-klog/test_klog.dproj b/common/windows/delphi/tools/test-klog/test_klog.dproj index 27d8e8d7d5d..3a7cd7fa050 100644 --- a/common/windows/delphi/tools/test-klog/test_klog.dproj +++ b/common/windows/delphi/tools/test-klog/test_klog.dproj @@ -214,6 +214,10 @@ + + + + Cfg_2 Base diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 1e1df09ce00..8bdb8b0221e 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -377,6 +377,11 @@ Simulate AltGr with Ctrl+Alt + + + + Simulate AltGr with Ctrl+Alt + diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index 5034c0e664f..4c14c375ed3 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -2050,7 +2050,7 @@ procedure TfrmKeyman7Main.RegisterHotkeys; language: IKeymanLanguage; id: Integer; begin - if not Reg_GetDebugFlag(SRegValue_Flag_UseRegisterHotkey) then Exit; + if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit; TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []); @@ -2104,7 +2104,7 @@ procedure TfrmKeyman7Main.UnregisterHotkeys; var i, hk: Integer; begin - if not Reg_GetDebugFlag(SRegValue_Flag_UseRegisterHotkey) then Exit; + if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit; TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []); diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 019f88b0737..ce2ab3480e6 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -130,26 +130,16 @@ BOOL IsTouchPanelVisible() { } /* - Cache UseRegisterHotkey debug flag for this session + Cache UseRightModifierHotKey debug flag for this session */ -BOOL UseRegisterHotkey() { - static BOOL flag_UseRegisterHotkey = FALSE; +BOOL UseRightModifierHotKey() { + static BOOL flag_UseRightModifierHotKey = FALSE; static BOOL loaded = FALSE; if (!loaded) { loaded = TRUE; - flag_UseRegisterHotkey = Reg_GetDebugFlag(REGSZ_Flag_UseRegisterHotkey, FALSE); + flag_UseRightModifierHotKey = Reg_GetDebugFlag(REGSZ_Flag_UseRightModifierHotKey, FALSE); } - return flag_UseRegisterHotkey; -} - -BOOL UseCachedHotkeyModifierState() { - static BOOL flag_UseCachedHotkeyModifierState = FALSE; - static BOOL loaded = FALSE; - if (!loaded) { - loaded = TRUE; - flag_UseCachedHotkeyModifierState = Reg_GetDebugFlag(REGSZ_Flag_UseCachedHotkeyModifierState, FALSE); - } - return flag_UseCachedHotkeyModifierState; + return flag_UseRightModifierHotKey; } LRESULT _kmnLowLevelKeyboardProc( @@ -171,58 +161,38 @@ LRESULT _kmnLowLevelKeyboardProc( SendDebugMessageFormat("wparam: %x lparam: %x [vk:%s scan:%x flags:%x extra:%x]", wParam, lParam, Debug_VirtualKey((WORD) hs->vkCode), hs->scanCode, hs->flags, hs->dwExtraInfo); // I4674 - DWORD Flag = 0; - if (!UseCachedHotkeyModifierState()) { - // #5190: Don't cache modifier state because sometimes we won't receive - // modifier change events (e.g. on lock screen) - FHotkeyShiftState = 0; - if (GetKeyState(VK_LCONTROL) < 0) FHotkeyShiftState |= HK_CTRL; - if (GetKeyState(VK_RCONTROL) < 0) FHotkeyShiftState |= HK_RCTRL_INVALID; - if (GetKeyState(VK_LMENU) < 0) FHotkeyShiftState |= HK_ALT; - if (GetKeyState(VK_RMENU) < 0) FHotkeyShiftState |= HK_RALT_INVALID; - if (GetKeyState(VK_LSHIFT) < 0) FHotkeyShiftState |= HK_SHIFT; - if (GetKeyState(VK_RSHIFT) < 0) FHotkeyShiftState |= HK_RSHIFT_INVALID; - //TODO: #8064. Can remove debug message once issue #8064 is resolved - SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x Flag:%x]", FHotkeyShiftState, Flag); + if (GetKeyState(VK_LCONTROL) < 0) { + FHotkeyShiftState |= HK_CTRL; } - else if (UseRegisterHotkey()) { - // The old RegisterHotkey pattern does not support chiral modifier keys - switch (hs->vkCode) { - case VK_LCONTROL: - case VK_RCONTROL: - case VK_CONTROL: Flag = HK_CTRL; break; - case VK_LMENU: - case VK_RMENU: - case VK_MENU: Flag = HK_ALT; break; - case VK_LSHIFT: - case VK_RSHIFT: - case VK_SHIFT: Flag = HK_SHIFT; break; - } - //TODO: #8064. Can remove debug message once issue #8064 is resolved - SendDebugMessageFormat("UseRegisterHotkey [FHotkeyShiftState:%x Flag:%x]", FHotkeyShiftState, Flag); + if (GetKeyState(VK_RCONTROL) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; } - else { - // #4619: We differentiate between Left and Right Ctrl/Shift/Alt. The right modifiers are - // not used for hotkeys, leaving them available for use as keystroke modifiers within a - // Keyman keyboard. But we need to track them anyway, so that a user doesn't press them - // and receive a hotkey event when they shouldn't (e.g. RALT+F4 if the hotkey is F4). - switch (hs->vkCode) { - case VK_LCONTROL: Flag = HK_CTRL; break; - case VK_RCONTROL: Flag = HK_RCTRL_INVALID; break; - case VK_CONTROL: Flag = extended ? HK_RCTRL_INVALID : HK_CTRL; break; - case VK_LMENU: Flag = HK_ALT; break; - case VK_RMENU: Flag = HK_RALT_INVALID; break; - case VK_MENU: Flag = extended ? HK_RALT_INVALID : HK_ALT; break; - case VK_LSHIFT: Flag = HK_SHIFT; break; - case VK_RSHIFT: Flag = HK_RSHIFT_INVALID; break; - case VK_SHIFT: Flag = hs->scanCode == SCANCODE_RSHIFT ? HK_RSHIFT_INVALID : HK_SHIFT; break; - } + if (GetKeyState(VK_CONTROL) < 0) { + FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RCTRL_INVALID : HK_CTRL; + } + + if (GetKeyState(VK_LMENU) < 0) { + FHotkeyShiftState |= HK_ALT; + } + + if (GetKeyState(VK_RMENU) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID; + } + + if (GetKeyState(VK_MENU) < 0) { + FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RALT_INVALID : HK_ALT; + } + + if (GetKeyState(VK_LSHIFT) < 0) { + FHotkeyShiftState |= HK_SHIFT; + } + if (GetKeyState(VK_RSHIFT) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; } - if(Flag != 0) { - if(isUp) FHotkeyShiftState &= ~Flag; - else FHotkeyShiftState |= Flag; + if (GetKeyState(VK_SHIFT) < 0) { + FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; } // #7337 Post the modifier state ensuring the serialized queue is in sync @@ -304,7 +274,7 @@ LRESULT _kmnLowLevelKeyboardProc( } BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { - if (UseRegisterHotkey()) { + if (UseRightModifierHotKey()) { return FALSE; } diff --git a/windows/src/global/delphi/general/Keyman.System.Settings.pas b/windows/src/global/delphi/general/Keyman.System.Settings.pas index b021e56cddf..d8acd9d25a6 100644 --- a/windows/src/global/delphi/general/Keyman.System.Settings.pas +++ b/windows/src/global/delphi/general/Keyman.System.Settings.pas @@ -95,7 +95,7 @@ TKeymanSettings = class(TObjectList) ValueType: kstInteger ); - BaseKeymanSettings: array[0..33] of TKeymanSettingBase = ( + BaseKeymanSettings: array[0..31] of TKeymanSettingBase = ( // TIKE:UTikeDebugMode.TikeDebugMode ( @@ -370,14 +370,6 @@ TKeymanSettings = class(TObjectList) // keyman:TfrmKeyman7Main.RegisterHotkeys, // keyman:TfrmKeyman7Main.UnregisterHotkeys // keyman32:k32_lowlevelkeyboardhook - ( - ID: 'engine.compatibility.old_hotkey_registration'; - Name: SRegValue_Flag_UseRegisterHotkey; - RootKey: HKCU; - Key: SRegKey_KeymanEngineDebug_CU; - Description: 'Set to 1 for old RegisterHotkey pathway'; - ValueType: kstInteger - ), ( ID: 'engine.compatibility.use_keyman_core'; @@ -391,18 +383,6 @@ TKeymanSettings = class(TObjectList) ValueType: kstInteger ), - // keyman32:k32_lowlevelkeyboardhook - ( - ID: 'engine.compatibility.old_cached_hotkey_modifier_state'; - Name: SRegValue_Flag_UseCachedHotkeyModifierState; - RootKey: HKCU; - Key: SRegKey_KeymanEngineDebug_CU; - Description: 'Set to 1 to use a cached modifer state when checking hotkeys; if '+ - 'set to 0 then engine.compatibility.old_hotkey_registration may not '+ - 'work'; - ValueType: kstInteger - ), - // keyman32:keyman32.Initialise_Flag_ShouldSerializeInput ( ID: 'engine.compatibility.serialize_input'; From b7b17686ece2b29c43889131011aa89205401f11 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:01:43 +1000 Subject: [PATCH 013/127] feat(windows): add rmodifier hk to keyman config UI --- common/windows/cpp/include/registry.h | 6 ++++-- common/windows/delphi/general/RegistryKeys.pas | 2 +- windows/src/desktop/kmshell/xml/strings.xml | 2 +- .../src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 10 ++++++++-- windows/src/engine/kmcomapi/util/utilkeymanoption.pas | 1 + .../src/global/delphi/general/KeymanOptionNames.pas | 5 ++++- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h index ebaca81c9cf..c6d1bf85ec1 100644 --- a/common/windows/cpp/include/registry.h +++ b/common/windows/cpp/include/registry.h @@ -110,6 +110,10 @@ #define REGSZ_KeyboardHotkeysAreToggle "hotkeys are toggles" #define REGSZ_DeadkeyConversionMode "deadkey conversion mode" // CU // I4552 #define REGSZ_ZapVirtualKeyCode "zap virtual key code" // LM, defaults to 0x0E (_VK_PREFIX_DEFAULT) +/* Non-chiral use of hotkeys instead of left-only hotkeys */ +#define REGSZ_UseRightModifierHotKey "use right modifier for hotkey" + + /* Debug flags These are all stored in HKCU\Software\Keyman\Debug @@ -121,9 +125,7 @@ #define REGSZ_Flag_ShouldSerializeInput "Flag_ShouldSerializeInput" -/* REGSZ_Keyman_Debug DWORD: Use old non-chiral Win32 API RegisterHotkey instead of left-only hotkeys */ -#define REGSZ_Flag_UseRightModifierHotKey "Flag_UseRightModifierHotKey" /* DWORD: Enable/disable deep TSF integration, default enabled; 0 = disabled, 1 = enabled, 2 = default */ diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 8cbd6d7d0a3..0553b823065 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -115,6 +115,7 @@ interface SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU + SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true @@ -379,7 +380,6 @@ interface SRegKey_KeymanEngineDebug_CU = SRegKey_KeymanEngineRoot_CU + '\Debug'; - SRegValue_Flag_UseRightModifierHotKey = 'Flag_UseRightModifierHotKey'; SRegValue_Flag_ShouldSerializeInput = 'Flag_ShouldSerializeInput'; SRegValue_Flag_UseAutoStartTask = 'Flag_UseAutoStartTask'; SRegValue_Flag_SyncLanguagesToCloud = 'Flag_SyncLanguagesToCloud'; diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 8bdb8b0221e..e15ba789453 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -380,7 +380,7 @@ - Simulate AltGr with Ctrl+Alt + Right Modifier keys work with Hotkeys diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index ce2ab3480e6..66d7d943aba 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -135,9 +135,15 @@ BOOL IsTouchPanelVisible() { BOOL UseRightModifierHotKey() { static BOOL flag_UseRightModifierHotKey = FALSE; static BOOL loaded = FALSE; + if (!loaded) { - loaded = TRUE; - flag_UseRightModifierHotKey = Reg_GetDebugFlag(REGSZ_Flag_UseRightModifierHotKey, FALSE); + RegistryReadOnly reg(HKEY_CURRENT_USER); + if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) { + if (reg.ValueExists(REGSZ_UseRightModifierHotKey)) { + flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_UseRightModifierHotKey); + } + } + loaded = TRUE; // Set loaded to TRUE whether or not the key exists } return flag_UseRightModifierHotKey; } diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index ce1b8af33a8..9d9f95465d4 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -127,6 +127,7 @@ TKeymanOptionInfo = record (opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koSwitchLanguageForAllApplications; RegistryName: SRegValue_SwitchLanguageForAllApplications; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I2277 // I4393 (opt: koAltGrCtrlAlt; RegistryName: SRegValue_AltGrCtrlAlt; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), + (opt: koRightModifierHK; RegistryName: SRegValue_UseRightModifierHotKey; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koShowHints; RegistryName: SRegValue_EnableHints; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), (opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'), diff --git a/windows/src/global/delphi/general/KeymanOptionNames.pas b/windows/src/global/delphi/general/KeymanOptionNames.pas index 27aef82ab55..73356d19cb3 100644 --- a/windows/src/global/delphi/general/KeymanOptionNames.pas +++ b/windows/src/global/delphi/general/KeymanOptionNames.pas @@ -5,7 +5,10 @@ interface type TUtilKeymanOption = ( // General options - koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress, + koKeyboardHotkeysAreToggle, + koAltGrCtrlAlt, + koRightModifierHK, + koReleaseShiftKeysAfterKeyPress, koShowHints, // I1256 // Startup options koTestKeymanFunctioning, From 49bfd08fb3617386dbf3b7d93dbc52811cedac93 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Mon, 19 Aug 2024 12:49:46 +0700 Subject: [PATCH 014/127] change(mac): persist options fix when dictionary exists testing showed that when an option already existed, it would be deleted when attempting to update it to a new value --- .../Keyman4MacIM/KMSettingsRepository.m | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 83b16a7e8bb..752ea86b660 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -72,27 +72,38 @@ - (BOOL)settingsExist - (void)writeOptionForSelectedKeyboard:(NSString *)key withValue:(NSString*)value { NSDictionary *optionsMap = [self readOptionsForSelectedKeyboard]; NSDictionary *newOptionsMap = nil; + // if we can read an existing options map, then add the specified key-value pair if (optionsMap != nil) { NSMutableDictionary *mutableOptionsMap = [optionsMap mutableCopy]; [mutableOptionsMap setObject:value forKey:key]; - os_log_info([KMLogs dataLog], "writeOptionsForSelectedKeyboard, setting key: %{public}@, value %{public}@", key, value); newOptionsMap = mutableOptionsMap; } else { + // if no options map exists, create a new one add the specified key-value pair newOptionsMap = [[NSDictionary alloc] initWithObjectsAndKeys:value, key, nil]; } - // write the fully built dictionary to the dictionary of options + // write the options map for the selected keyboard to the dictionary of options NSString *selectedKeyboard = [self readSelectedKeyboard]; + os_log_info([KMLogs dataLog], "writeOptionForSelectedKeyboard, adding options map: %{public}@, to keyboard %{public}@", newOptionsMap, selectedKeyboard); [self writeKeyboardOptionsMap: selectedKeyboard withOptions:newOptionsMap]; } - (void)writeKeyboardOptionsMap:(NSString *)keyboardName withOptions:(NSDictionary*) optionsMap { - NSDictionary *fullOptionsMap = [self readOptions]; - NSMutableDictionary *newFullOptionsMap = [fullOptionsMap mutableCopy]; - - [newFullOptionsMap setObject:optionsMap forKey:keyboardName]; - [self writeOptions:newFullOptionsMap]; + NSMutableDictionary *newFullOptionsMap = nil; + os_log_debug([KMLogs dataLog], "writeKeyboardOptionsMap, adding options map: %{public}@, to keyboard %{public}@", optionsMap, keyboardName); + + NSDictionary *fullOptionsMap = [self readFullOptionsMap]; + // if we can read the existing full options map, then add for the specified keyboard + if (fullOptionsMap != nil) { + newFullOptionsMap = [fullOptionsMap mutableCopy]; + [newFullOptionsMap setObject:optionsMap forKey:keyboardName]; + } else { + // otherwise, create the full options map and add for the specified keyboard + newFullOptionsMap = [[NSMutableDictionary alloc] initWithObjectsAndKeys:optionsMap, keyboardName, nil]; + } + + [self writeFullOptionsMap:newFullOptionsMap]; } /** @@ -142,14 +153,14 @@ - (NSMutableArray *)activeKeyboards { * returns dictionary of persisted options for the single selected keyboard */ - (NSDictionary *)readOptionsForSelectedKeyboard { - NSDictionary *optionsMap = [self readOptions]; + NSDictionary *optionsMap = [self readFullOptionsMap]; NSString *selectedKeyboard = [self readSelectedKeyboard]; NSDictionary *selectedOptionsMap = [optionsMap objectForKey: selectedKeyboard]; if (selectedOptionsMap == nil) { os_log_info([KMLogs dataLog], "no persisted options found in UserDefaults for keyboard %{public}@ ", selectedKeyboard); } else { - for (NSString *key in optionsMap) { - NSString *value = [optionsMap objectForKey:key]; + for (NSString *key in selectedOptionsMap) { + NSString *value = [selectedOptionsMap objectForKey:key]; os_log_info([KMLogs dataLog], "option for keyboard %{public}@ key: %{public}@, value %{public}@", selectedKeyboard, key, value); } } @@ -158,15 +169,16 @@ - (NSDictionary *)readOptionsForSelectedKeyboard { /* * returns dictionary of all persisted options for all keyboards + * (options are stored in UserDefaults as a map of maps) */ -- (NSDictionary *)readOptions { +- (NSDictionary *)readFullOptionsMap { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; return [userData dictionaryForKey:kPersistedOptionsKey]; } -- (void)writeOptions:(NSDictionary *) optionsDictionary { +- (void)writeFullOptionsMap:(NSDictionary *) fullOptionsMap { NSUserDefaults *userData = [NSUserDefaults standardUserDefaults]; - [userData setObject:optionsDictionary forKey:kPersistedOptionsKey]; + [userData setObject:fullOptionsMap forKey:kPersistedOptionsKey]; } - (void)removeAllOptions { @@ -236,7 +248,7 @@ - (void)convertActiveKeyboardArrayForMigration { } - (void)convertOptionsPathsForMigration { - NSDictionary * optionsMap = [self readOptions]; + NSDictionary * optionsMap = [self readFullOptionsMap]; NSMutableDictionary *mutableOptionsMap = nil; BOOL optionsChanged = NO; @@ -262,7 +274,7 @@ - (void)convertOptionsPathsForMigration { } } if (optionsChanged) { - [self writeOptions:mutableOptionsMap]; + [self writeFullOptionsMap:mutableOptionsMap]; } } } From 65b9e49bac88976beedb9667ab7c010ede2e6cc3 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:48:06 +1000 Subject: [PATCH 015/127] feat(windows): remove old UseRegisterHotkey --- windows/src/engine/keyman/UfrmKeyman7Main.pas | 2 -- windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 3 --- 2 files changed, 5 deletions(-) diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index 4c14c375ed3..155ab9208c0 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -2050,7 +2050,6 @@ procedure TfrmKeyman7Main.RegisterHotkeys; language: IKeymanLanguage; id: Integer; begin - if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit; TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []); @@ -2104,7 +2103,6 @@ procedure TfrmKeyman7Main.UnregisterHotkeys; var i, hk: Integer; begin - if not Reg_GetDebugFlag(SRegValue_Flag_UseRightModifierHotKey) then Exit; TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []); diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 66d7d943aba..6d5067516e9 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -280,9 +280,6 @@ LRESULT _kmnLowLevelKeyboardProc( } BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { - if (UseRightModifierHotKey()) { - return FALSE; - } Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if (!hotkeys) { From 977d2948e6400e1c3524629818d61ed39ac07581 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:06:04 +1000 Subject: [PATCH 016/127] feat(windows): fix out of bounds --- windows/src/engine/kmcomapi/util/utilkeymanoption.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index 9d9f95465d4..2df38b5c825 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -121,7 +121,7 @@ TKeymanOptionInfo = record GroupName: string; end; -const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 +const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 // Global options (opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), From 98787afbdcacf7a8e1a4f9e64e929fd3948f7007 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:15:50 +1000 Subject: [PATCH 017/127] feat(windows): restore removal of klogging --- common/windows/delphi/tools/test-klog/test_klog.dpr | 8 ++------ common/windows/delphi/tools/test-klog/test_klog.dproj | 4 ---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/common/windows/delphi/tools/test-klog/test_klog.dpr b/common/windows/delphi/tools/test-klog/test_klog.dpr index 7f9d0e213aa..072042334a0 100644 --- a/common/windows/delphi/tools/test-klog/test_klog.dpr +++ b/common/windows/delphi/tools/test-klog/test_klog.dpr @@ -7,17 +7,13 @@ uses klog in '..\..\..\..\..\common\windows\delphi\general\klog.pas', VersionInfo in '..\..\..\..\..\common\windows\delphi\general\VersionInfo.pas', ErrorControlledRegistry in '..\..\..\..\..\common\windows\delphi\vcl\ErrorControlledRegistry.pas', - Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas', - DebugPaths in '..\..\..\..\..\common\windows\delphi\general\DebugPaths.pas', - RegistryKeys in '..\..\..\..\..\common\windows\delphi\general\RegistryKeys.pas', - KeymanVersion in '..\..\..\..\..\common\windows\delphi\general\KeymanVersion.pas', - KeymanPaths in '..\..\..\..\..\common\windows\delphi\general\KeymanPaths.pas'; + Unicode in '..\..\..\..\..\common\windows\delphi\general\Unicode.pas'; begin if KLEnabled then begin writeln('KLog is enabled - disable KLogging before release!'); - ExitCode := 0; + ExitCode := 1; end else begin diff --git a/common/windows/delphi/tools/test-klog/test_klog.dproj b/common/windows/delphi/tools/test-klog/test_klog.dproj index 3a7cd7fa050..27d8e8d7d5d 100644 --- a/common/windows/delphi/tools/test-klog/test_klog.dproj +++ b/common/windows/delphi/tools/test-klog/test_klog.dproj @@ -214,10 +214,6 @@ - - - - Cfg_2 Base From 3326ac2c6b62b66b0567965b3bb834ee432d9d6c Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:14:57 +1000 Subject: [PATCH 018/127] feat(windows): remove check for non-chiral vkey --- .../keyman32/k32_lowlevelkeyboardhook.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 6d5067516e9..f5fbdb8f301 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -169,15 +169,14 @@ LRESULT _kmnLowLevelKeyboardProc( if (GetKeyState(VK_LCONTROL) < 0) { FHotkeyShiftState |= HK_CTRL; + SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); } if (GetKeyState(VK_RCONTROL) < 0) { FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; + SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); } - if (GetKeyState(VK_CONTROL) < 0) { - FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RCTRL_INVALID : HK_CTRL; - } - + if (GetKeyState(VK_LMENU) < 0) { FHotkeyShiftState |= HK_ALT; } @@ -186,10 +185,6 @@ LRESULT _kmnLowLevelKeyboardProc( FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID; } - if (GetKeyState(VK_MENU) < 0) { - FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RALT_INVALID : HK_ALT; - } - if (GetKeyState(VK_LSHIFT) < 0) { FHotkeyShiftState |= HK_SHIFT; } @@ -197,9 +192,9 @@ LRESULT _kmnLowLevelKeyboardProc( FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; } - if (GetKeyState(VK_SHIFT) < 0) { - FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; - } + //if (GetKeyState(VK_SHIFT) < 0) { + // FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; + //} // #7337 Post the modifier state ensuring the serialized queue is in sync // Note that the modifier key may be posted again with WM_KEYMAN_KEY_EVENT, From c48a4a72428626aad3137480cd36b66486297089 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:56:55 +1000 Subject: [PATCH 019/127] feat(windows): Use RegisterHotkey only for chirl mode --- windows/src/engine/keyman/UfrmKeyman7Main.pas | 36 +++++++++++++++++++ windows/src/engine/keyman32/hotkeys.cpp | 10 ++++-- .../keyman32/k32_lowlevelkeyboardhook.cpp | 31 ++++++++++------ 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index 155ab9208c0..fbed70b24d0 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -2049,7 +2049,25 @@ procedure TfrmKeyman7Main.RegisterHotkeys; i: Integer; language: IKeymanLanguage; id: Integer; + RegistryErrorControlled: TRegistryErrorControlled;// I2890 + UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey begin + RegistryErrorControlled := TRegistryErrorControlled.Create; + try + if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and + RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then + begin + UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); + end + else + begin + UseRegisterHotKey := False; + end; + finally + RegistryErrorControlled.Free; + end; + + if not UseRegisterHotKey then Exit; TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []); @@ -2102,7 +2120,25 @@ procedure TfrmKeyman7Main.RegisterHotkeys; procedure TfrmKeyman7Main.UnregisterHotkeys; var i, hk: Integer; + RegistryErrorControlled: TRegistryErrorControlled;// I2890 + UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey begin + RegistryErrorControlled := TRegistryErrorControlled.Create; + try + if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and + RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then + begin + UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); + end + else + begin + UseRegisterHotKey := False; + end; + finally + RegistryErrorControlled.Free; + end; + + if not UseRegisterHotKey then Exit; TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []); diff --git a/windows/src/engine/keyman32/hotkeys.cpp b/windows/src/engine/keyman32/hotkeys.cpp index 8327a786498..e7fdbe3d79d 100644 --- a/windows/src/engine/keyman32/hotkeys.cpp +++ b/windows/src/engine/keyman32/hotkeys.cpp @@ -137,9 +137,13 @@ void Hotkeys::Load() { // I4390 Hotkey *Hotkeys::GetHotkey(DWORD hotkey) { - for(int i = 0; i < m_nHotkeys; i++) - if(m_hotkeys[i].HotkeyValue == hotkey) - return &m_hotkeys[i]; + for (int i = 0; i < m_nHotkeys; i++) { + if (m_hotkeys[i].HotkeyValue == hotkey) { + SendDebugMessageFormat( + "LanguageHotkey[%d] = {HotkeyValue: %x, hkl: %x} passed in: %x", i, m_hotkeys[i].HotkeyValue, m_hotkeys[i].hkl, hotkey); + return &m_hotkeys[i]; + } + } return NULL; } diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index f5fbdb8f301..2bdfae62e39 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -131,8 +131,10 @@ BOOL IsTouchPanelVisible() { /* Cache UseRightModifierHotKey debug flag for this session + when using right modifier for Hotkeys use the Win32 API + ResisterHotkey functionality */ -BOOL UseRightModifierHotKey() { +BOOL UseRegisterHotkey() { static BOOL flag_UseRightModifierHotKey = FALSE; static BOOL loaded = FALSE; @@ -169,31 +171,33 @@ LRESULT _kmnLowLevelKeyboardProc( if (GetKeyState(VK_LCONTROL) < 0) { FHotkeyShiftState |= HK_CTRL; - SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); + // TODO remove + SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); } if (GetKeyState(VK_RCONTROL) < 0) { - FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; - SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); + FHotkeyShiftState |= UseRegisterHotkey() ? HK_CTRL : HK_RCTRL_INVALID; + // TODO remove + SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); } - + if (GetKeyState(VK_LMENU) < 0) { FHotkeyShiftState |= HK_ALT; } if (GetKeyState(VK_RMENU) < 0) { - FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID; + FHotkeyShiftState |= UseRegisterHotkey() ? HK_ALT : HK_RALT_INVALID; } if (GetKeyState(VK_LSHIFT) < 0) { FHotkeyShiftState |= HK_SHIFT; } if (GetKeyState(VK_RSHIFT) < 0) { - FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; + FHotkeyShiftState |= UseRegisterHotkey() ? HK_SHIFT : HK_RSHIFT_INVALID; } //if (GetKeyState(VK_SHIFT) < 0) { - // FHotkeyShiftState |= (!UseRightModifierHotKey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; + // FHotkeyShiftState |= (!UseRegisterHotkey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; //} // #7337 Post the modifier state ensuring the serialized queue is in sync @@ -275,28 +279,35 @@ LRESULT _kmnLowLevelKeyboardProc( } BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { - + if (UseRegisterHotkey()){ + return FALSE; + } Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if (!hotkeys) { + SendDebugMessageFormat("Failed to get Instance"); return FALSE; } Hotkey *hotkey = hotkeys->GetHotkey(ShiftState | vkCode); // I4641 if (!hotkey) { + SendDebugMessageFormat("GetHotkey Null"); return FALSE; } if (isUp) { + SendDebugMessageFormat("Is Up"); return TRUE; } if (hotkey->HotkeyType == hktInterface) { + SendDebugMessageFormat("PostMasterController"); Globals::PostMasterController(wm_keyman_control, MAKELONG(KMC_INTERFACEHOTKEY, hotkey->Target), 0); } else { + SendDebugMessageFormat("ReportKeyboardChanged"); ReportKeyboardChanged(PC_HOTKEYCHANGE, hotkey->hkl == 0 ? TF_PROFILETYPE_INPUTPROCESSOR : TF_PROFILETYPE_KEYBOARDLAYOUT, 0, hotkey->hkl, GUID_NULL, hotkey->profileGUID); } - + SendDebugMessageFormat("PostDummyKeyEvent"); /* Generate a dummy keystroke to block menu activations, etc but let the shift key through */ PostDummyKeyEvent(); // I3301 - this is imperfect because we don't deal with HC_NOREMOVE. But good enough? // I3534 // I4844 From 24f4a61adacbbfd7e721b48904282bfe9bae86e3 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 21 Aug 2024 17:05:07 +0700 Subject: [PATCH 020/127] change(mac): responded to review comments --- .../Keyman4MacIM/KMDataRepository.h | 6 +-- .../Keyman4MacIM/KMDataRepository.m | 42 +++++++++++++------ .../Keyman4MacIM/KMInputMethodEventHandler.m | 11 ----- .../Keyman4MacIM/KMPackageReader.m | 12 ------ .../Keyman4MacIM/KMSettingsRepository.m | 35 +++++++++------- .../KeymanTests/InputMethodTests.m | 14 ------- 6 files changed, 52 insertions(+), 68 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index a5af2ccb881..0a1cc8cca37 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -1,4 +1,4 @@ -/** +/* * Keyman is copyright (C) SIL International. MIT License. * * KMDataRepository.h @@ -13,9 +13,9 @@ NS_ASSUME_NONNULL_BEGIN @interface KMDataRepository : NSObject -@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/com.keyman.app' +@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/keyman.inputmethod.Keyman' @property (readonly) NSURL *keymanKeyboardsDirectory; -// keymanKeyboardsDirectory = '~/Library/Application Support/com.keyman.app/Keyman-Keyboards' +// keymanKeyboardsDirectory = '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards' + (KMDataRepository *)shared; - (void)createDataDirectoryIfNecessary; - (void)createKeyboardsDirectoryIfNecessary; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 24495007bd4..20d6e892a46 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -1,4 +1,4 @@ -/** +/* * Keyman is copyright (C) SIL International. MIT License. * * KMResourcesRepository.m @@ -15,30 +15,39 @@ #import "KMLogs.h" @interface KMDataRepository () -@property (readonly) NSURL *applicationSupportSubDirectory; // '~/Library/Application Support' -@property (readonly) NSURL *documentsSubDirectory; // '~/Documents' -@property (readonly) NSURL *obsoleteKeymanKeyboardsDirectory; // '~/Library/Documents/Keyman-Keyboards' +@property (readonly) NSURL *applicationSupportSubDirectory; +@property (readonly) NSURL *documentsSubDirectory; +@property (readonly) NSURL *obsoleteKeymanKeyboardsDirectory; @end @implementation KMDataRepository - +/** + * Two directory trees are represented by the following properties, one in active use + * and one that is obsolete. + * The actively used directories, begin with the parent + * applicationSupportSubDirectory: '~/Library/Application Support' + * keymanDataDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman' + * keymanKeyboardsDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards' + * The obsolete directories, begin with the parent + * documentsSubDirectory: '~/Documents' + * obsoleteKeymanKeyboardsDirectory: '~/Documents/Keyman-Keyboards' + */ @synthesize applicationSupportSubDirectory = _applicationSupportSubDirectory; -@synthesize documentsSubDirectory = _documentsSubDirectory; +@synthesize keymanDataDirectory = _keymanDataDirectory; @synthesize keymanKeyboardsDirectory = _keymanKeyboardsDirectory; +@synthesize documentsSubDirectory = _documentsSubDirectory; @synthesize obsoleteKeymanKeyboardsDirectory = _obsoleteKeymanKeyboardsDirectory; -@synthesize keymanDataDirectory = _keymanDataDirectory; NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards"; /* The name of the subdirectory within '~/Library/Application Support'. - The convention is to use bundle identifier. - (Using the subsystem id, "com.keyman.app", is a poor choice because the API + We follow the convention of using the bundle identifier rather than our subsystem id. + (Also, using the subsystem id, "com.keyman.app", is a poor choice because the API createDirectoryAtPath sees the .app extension and creates an application file. */ NSString *const kKeymanSubdirectoryName = @"keyman.inputmethod.Keyman"; -+ (KMDataRepository *)shared -{ ++ (KMDataRepository *)shared { static KMDataRepository *shared = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ @@ -149,7 +158,11 @@ - (NSURL *)obsoleteKeymanKeyboardsDirectory { } return _obsoleteKeymanKeyboardsDirectory; } - +/** + * Only called from migrateData. + * Causes user to be prompted for permission to access ~/Documents, but they should already have it. + * otherwise we would not be attempting to migrate. + */ - (BOOL)keyboardsExistInObsoleteDirectory { NSFileManager *fileManager = [NSFileManager defaultManager]; BOOL isDir; @@ -158,7 +171,10 @@ - (BOOL)keyboardsExistInObsoleteDirectory { } /** - * Migrate the keyboards data from the old location in '/Documents' to the new location '/Application Support/keyman.inputmethod.Keyman/' + * Migrate the keyboards data from the old location in '~/Documents' to the new location '~/Application Support/keyman.inputmethod.Keyman/' + * This should only be called if the Keyman settings written to the UserDefaults indicates that we have data in the old location. + * If this is the case, then we expect the user to have already granted permission for Keyman to access the ~/Documents directory. + * If that permission has been removed for some reason, then calling this code will cause the user to be asked for permission again. */ - (BOOL)migrateData { BOOL didMoveData = NO; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m index efe628c43a3..02521b51cb3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodEventHandler.m @@ -243,17 +243,6 @@ - (BOOL)handleEvent:(NSEvent *)event client:(id)sender { // return NO to pass through to client app return NO; } - - // TODO: remove test code - /* - if (event.keyCode == kVK_ANSI_Slash) { - if ([KMSettingsRepository.shared keyboardsMigrationNeeded]) { - os_log_info([KMLogs startupLog], "keyboards migration needed"); - } else { - os_log_info([KMLogs startupLog], "keyboards migration not needed"); - } - } - */ } if (event.type == NSEventTypeFlagsChanged) { diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m index 186ec8ab5a0..bd9156bdb50 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m @@ -69,18 +69,6 @@ - (KMPackageInfo *)loadPackageInfo:(NSString *)path { return packageInfo; } -/* - // TODO: not used, delete -- (NSString *)packageNameFromPackageInfo:(NSString *)path { - NSString *packageName = nil; - - KMPackageInfo *packageInfo = [self loadPackageInfo:path]; - packageName = packageInfo.packageName; - - return packageName; -} -*/ - /** * read JSON file and load it into KMPackageInfo object * returns nil if the file does not exist or it cannot be parsed as JSON diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index 489c4e63dc6..a605ea6e6ec 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -1,4 +1,4 @@ -/** +/* * Keyman is copyright (C) SIL International. MIT License. * * KMSettingsRepository.h @@ -27,6 +27,7 @@ */ NSString *const kDataModelVersion = @"KMDataModelVersion"; NSInteger const kVersionStoreDataInLibraryDirectory = 1; +NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInLibraryDirectory; @implementation KMSettingsRepository @@ -41,7 +42,7 @@ + (KMSettingsRepository *)shared } - (void)setDataModelVersionIfNecessary { - if (![self dataStoredInLibraryDirectory]) { + if (![self dataModelWithKeyboardsInLibrary]) { [[NSUserDefaults standardUserDefaults] setInteger:kVersionStoreDataInLibraryDirectory forKey:kDataModelVersion]; } } @@ -51,34 +52,38 @@ - (void)setDataModelVersionIfNecessary { * If this method is called after applicationDidFinishLaunching, then it will always return true. * If called from awakeFromNib, then it will return false when running for the first time. */ -- (BOOL)settingsExist -{ +- (BOOL)settingsExist { return [[NSUserDefaults standardUserDefaults] objectForKey:kSelectedKeyboardKey] != nil; } /** - * For the first numbered version of the data model, the app stores the keyboards under the /Library directory - * For versions before version 1, the keyboards were stored under the /Documents directory. + * For the first numbered version of the data model, the app stores the keyboards under the ~/Library directory + * For versions before version 1, the keyboards were stored under the ~/Documents directory. */ -- (BOOL)dataStoredInLibraryDirectory -{ - return [[NSUserDefaults standardUserDefaults] integerForKey:kDataModelVersion] == kVersionStoreDataInLibraryDirectory; +- (BOOL)dataModelWithKeyboardsInLibrary { + // NSUserDefaults returns zero if the key does not exist + NSInteger dataModelVersion = [[NSUserDefaults standardUserDefaults] integerForKey:kDataModelVersion]; + + return dataModelVersion >= kVersionStoreDataInLibraryDirectory; } /** - * Determines whether the keyboard data needs to be moved from the old location in ~/Documents to the new location ~/Library... + * Determines whether the keyboard data needs to be moved from the old location to the new location * This is true if * 1) the UserDefaults exist (indicating that this is not a new installation of Keyman) and - * 2) the value for KMStoreKeyboardsInLibraryKey is not set to true + * 2) the value for kVersionStoreDataInLibraryDirectory is < 1, */ - (BOOL)dataMigrationNeeded { BOOL keymanSettingsExist = [self settingsExist]; - os_log([KMLogs dataLog], " keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" ); + os_log([KMLogs dataLog], "keyman settings exist: %{public}@", keymanSettingsExist ? @"YES" : @"NO" ); - BOOL dataInLibrary = [self dataStoredInLibraryDirectory]; - os_log([KMLogs dataLog], " data stored in Library: %{public}@", dataInLibrary ? @"YES" : @"NO" ); + BOOL keyboardsStoredInLibrary = [self dataModelWithKeyboardsInLibrary]; + os_log([KMLogs dataLog], "settings indicate that keyboards are stored in ~/Library: %{public}@", keyboardsStoredInLibrary ? @"YES" : @"NO" ); - return !(keymanSettingsExist && dataInLibrary); + BOOL migrationNeeded = keymanSettingsExist && !keyboardsStoredInLibrary; + os_log([KMLogs dataLog], "dataMigrationNeeded: %{public}@", migrationNeeded ? @"YES" : @"NO" ); + + return migrationNeeded; } - (NSString *)selectedKeyboard { diff --git a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m index 38994c351a5..5a339931e70 100644 --- a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m +++ b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m @@ -88,18 +88,4 @@ - (void)testCalculateInsertRange_deleteOneBMPCharacterWithOneSelected_returnsRan XCTAssertTrue(correctResult, @"insert or replacement range expected to be {1,2}"); } -- (void)testMigrateData_oldDataExists_logsLocations { - os_log_t startupLog = os_log_create("com.keyman.app", "data-migration"); - if ([KMSettingsRepository.shared dataMigrationNeeded]) { - os_log_info(startupLog, "data migration needed, calling migrateData"); - [KMDataRepository.shared migrateData]; - os_log_info(startupLog, "test: call migrateData again"); - [KMDataRepository.shared migrateData]; - } else { - os_log_info(startupLog, "data migration not needed"); - } - - XCTAssertTrue(YES, @"test failed"); -} - @end From ed8f8508d390bfe9c588007f877e6b5c86e8db5f Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:42:23 +1000 Subject: [PATCH 021/127] feat(windows): update sil logo for windows UI --- oem/firstvoices/windows/src/xml/config.css | 10 +++++----- windows/src/desktop/kmshell/xml/config.css | 8 ++++---- windows/src/desktop/kmshell/xml/splash.css | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/oem/firstvoices/windows/src/xml/config.css b/oem/firstvoices/windows/src/xml/config.css index 28f09464765..763c7229a1c 100644 --- a/oem/firstvoices/windows/src/xml/config.css +++ b/oem/firstvoices/windows/src/xml/config.css @@ -762,10 +762,10 @@ th color: #444; position: absolute; bottom: 32px; - left: 80px; - height: 50px; - padding-top: 25px; - padding-left: 56px; + left: 73px; + height: 64px; + padding-top: 32px; + padding-left: 110px; box-sizing: border-box; } @@ -1021,4 +1021,4 @@ th width:100%; height:100%; border:none; -} \ No newline at end of file +} diff --git a/windows/src/desktop/kmshell/xml/config.css b/windows/src/desktop/kmshell/xml/config.css index 88c8d22b39c..851964112bf 100644 --- a/windows/src/desktop/kmshell/xml/config.css +++ b/windows/src/desktop/kmshell/xml/config.css @@ -840,10 +840,10 @@ th color: #444; position: absolute; bottom: 32px; - left: 80px; - height: 50px; - padding-top: 25px; - padding-left: 56px; + left: 73px; + height: 64px; + padding-top: 32px; + padding-left: 110px; box-sizing: border-box; } diff --git a/windows/src/desktop/kmshell/xml/splash.css b/windows/src/desktop/kmshell/xml/splash.css index 413280ce057..de0a33b188f 100644 --- a/windows/src/desktop/kmshell/xml/splash.css +++ b/windows/src/desktop/kmshell/xml/splash.css @@ -33,7 +33,7 @@ div { } #silLogo { - position: absolute; right: 20px; top: 24px; background: url("sil-logo-blue.png"); width: 48px; height: 50px; + position: absolute; right: 20px; top: 15px; background: url("sil-logo-blue.png"); width: 107px; height: 64px; } #family { From 05d52463f95dbee638ac7b0cd0fc7337b6fa0da2 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:45:23 +1000 Subject: [PATCH 022/127] feat(windows): remove registerhotkey and cache modifier Remove the feature flags that allows the use of cached modifier for hotkeys. Remove the feature flag that uses the Win 32 API RegisterHotkeys. --- .../windows/delphi/general/RegistryKeys.pas | 1 - windows/src/desktop/kmshell/xml/strings.xml | 16 +- windows/src/engine/keyman/UfrmKeyman7Main.pas | 153 ------------------ .../keyman32/k32_lowlevelkeyboardhook.cpp | 65 ++------ .../engine/kmcomapi/util/utilkeymanoption.pas | 3 +- .../delphi/general/KeymanOptionNames.pas | 5 +- 6 files changed, 22 insertions(+), 221 deletions(-) diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 0553b823065..1557de58657 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -115,7 +115,6 @@ interface SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU - SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index e15ba789453..774a4d5e425 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -377,11 +377,6 @@ Simulate AltGr with Ctrl+Alt - - - - Right Modifier keys work with Hotkeys - @@ -797,13 +792,18 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman Start Keyman + + + + Start %1$s + @@ -860,7 +860,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman @@ -1026,7 +1026,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index fbed70b24d0..d8cb3e30e73 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -228,9 +228,6 @@ TfrmKeyman7Main = class(TForm) FActiveHKL: Integer; FTrayIcon: TIcon; // I4359 - FHotkeyWindow: HWND; - FHotkeys: TIntegerList; - FInputPane: TFrameworkInputPane; FIsInputPaneVisible: Boolean; @@ -295,12 +292,6 @@ TfrmKeyman7Main = class(TForm) procedure UnregisterControllerWindows; // I4731 function IsSysTrayWindow(AHandle: THandle): Boolean; procedure GetTrayIconHandle; // I4731 - - procedure RegisterHotkeys; - procedure UnregisterHotkeys; - procedure HotkeyWndProc(var Message: TMessage); - - procedure DoLanguageHotkey(Index: Integer); protected procedure DoInterfaceHotkey(Target: Integer); @@ -550,8 +541,6 @@ procedure TfrmKeyman7Main.FormDestroy(Sender: TObject); FreeAndNil(FInputPane); - UnregisterHotkeys; - with TRegistryErrorControlled.Create do // I2890 try if OpenKey(SRegKey_KeymanOSK_CU, True) then @@ -833,7 +822,6 @@ function TfrmKeyman7Main.ProcessWMKeymanControl(Command, WParam: Word; LParam: D end; FOSKManuallyClosedThisSession := False; FRunningProduct.FLangSwitchConfiguration.Refresh; - RegisterHotkeys; end; KMC_NOTIFYWELCOME: // I1248 - Redesigned welcome begin @@ -869,23 +857,6 @@ function TfrmKeyman7Main.ProcessWMKeymanControl(Command, WParam: Word; LParam: D end; end; -procedure TfrmKeyman7Main.DoLanguageHotkey(Index: Integer); -var - FKeyboard: TLangSwitchKeyboard; -begin - if (Index >= 0) and (Index < kmcom.Languages.Count) then - begin - FKeyboard := FLangSwitchManager.FindKeyboard(kmcom.Languages[Index].HKL, kmcom.Languages[Index].ProfileGUID); - if not Assigned(FKeyboard) then Exit; - - // Handle toggle hotkey - if (FKeyboard = FLangSwitchManager.ActiveKeyboard) and (kmcom.Options['koKeyboardHotkeysAreToggle'].Value) then - FKeyboard := FLangSwitchManager.Languages[0].Keyboards[0]; - - ActivateKeyboard(FKeyboard); - end; -end; - procedure TfrmKeyman7Main.DoInterfaceHotkey(Target: Integer); begin if not Assigned(FRunningProduct) then @@ -1356,7 +1327,6 @@ function TfrmKeyman7Main.StartKeymanEngine: Boolean; // I1951 StartKeymanX64; - RegisterHotkeys; end; procedure TfrmKeyman7Main.RequestCurrentActiveKeyboard(Command: WORD); // I3961 @@ -2023,18 +1993,6 @@ procedure TfrmKeyman7Main.StartKeymanX64; end; end; -procedure TfrmKeyman7Main.HotkeyWndProc(var Message: TMessage); -begin - if Message.Msg = WM_HOTKEY then - begin - KL.Log('Hotkey %d', [Message.WParam]); - if Message.WParam > kh__High - then DoLanguageHotkey(Message.WParam - kh__High - 1) - else DoInterfaceHotkey(Message.WParam); - end; - Message.Result := DefWindowProc(FHotkeyWindow, Message.Msg, Message.WParam, Message.LParam); -end; - function KeymanHotkeyModifiersToWindowsHotkeyModifiers(v: KeymanHotkeyModifiers): Integer; begin Result := 0; @@ -2043,117 +2001,6 @@ function KeymanHotkeyModifiersToWindowsHotkeyModifiers(v: KeymanHotkeyModifiers) if (v and HK_ALT) = HK_ALT then Result := Result or MOD_ALT; end; -procedure TfrmKeyman7Main.RegisterHotkeys; -var - hk: IKeymanHotkey; - i: Integer; - language: IKeymanLanguage; - id: Integer; - RegistryErrorControlled: TRegistryErrorControlled;// I2890 - UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey -begin - RegistryErrorControlled := TRegistryErrorControlled.Create; - try - if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and - RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then - begin - UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); - end - else - begin - UseRegisterHotKey := False; - end; - finally - RegistryErrorControlled.Free; - end; - - if not UseRegisterHotKey then Exit; - - TDebugLogClient.Instance.WriteMessage('Enter RegisterHotkeys', []); - - if FHotkeyWindow = 0 then - FHotkeyWindow := AllocateHWnd(HotkeyWndProc); - - if not Assigned(FHotkeys) then - FHotkeys := TIntegerList.Create; - - UnregisterHotkeys; - - for i := 0 to kmcom.Hotkeys.Count - 1 do - begin - hk := kmcom.Hotkeys[i]; - if not hk.IsEmpty and (hk.VirtualKey <> 0) then - begin - // Note, if hk.VirtualKey is 0, this indicates a modifier-only hotkey such - // as Alt+Left Shift. These are handled in keyman32 k32_lowlevelkeyboardhook - // because RegisterHotkey cannot handle modifier-only hotkeys. - if RegisterHotkey(FHotkeyWindow, hk.Target, KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey) then - begin - TDebugLogClient.Instance.WriteMessage('Added hotkey %d -> %x %x', [hk.Target, - KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey]); - FHotkeys.Add(hk.Target) - end - else - TDebugLogClient.Instance.WriteLastError('RegisterHotkeys', 'RegisterHotkey', 'Failed to register hotkey '+IntToStr(hk.Target)); - end; - end; - - for i := 0 to kmcom.Languages.Count - 1 do - begin - language := kmcom.Languages[i]; - hk := language.Hotkey; - if Assigned(hk) and not hk.IsEmpty and (hk.VirtualKey <> 0) then - begin - id := kh__High + 1 + i; - if RegisterHotkey(FHotkeyWindow, id, KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey) then - begin - TDebugLogClient.Instance.WriteMessage('Added hotkey for language %s [%d] -> %x %x', [language.LocaleName, id, - KeymanHotkeyModifiersToWindowsHotkeyModifiers(hk.Modifiers), hk.VirtualKey]); - FHotkeys.Add(id); - end - else - TDebugLogClient.Instance.WriteLastError('RegisterHotkeys', 'RegisterHotkey', 'Failed to register hotkey '+IntToStr(id)); - end; - end; -end; - -procedure TfrmKeyman7Main.UnregisterHotkeys; -var - i, hk: Integer; - RegistryErrorControlled: TRegistryErrorControlled;// I2890 - UseRegisterHotKey: Boolean; // Use Win32 API RegisterHotkey -begin - RegistryErrorControlled := TRegistryErrorControlled.Create; - try - if RegistryErrorControlled.OpenKeyReadOnly(SRegKey_KeymanEngine_CU) and - RegistryErrorControlled.ValueExists(SRegValue_UseRightModifierHotKey) then - begin - UseRegisterHotKey := RegistryErrorControlled.ReadBool(SRegValue_UseRightModifierHotKey); - end - else - begin - UseRegisterHotKey := False; - end; - finally - RegistryErrorControlled.Free; - end; - - if not UseRegisterHotKey then Exit; - - TDebugLogClient.Instance.WriteMessage('Enter UnregisterHotkeys', []); - - if not Assigned(FHotkeys) then - Exit; - - for i := 0 to FHotkeys.Count - 1 do - begin - hk := FHotkeys[i]; - if not UnregisterHotKey(FHotkeyWindow, hk) then - TDebugLogClient.Instance.WriteLastError('UnregisterHotkeys', 'UnregisterHotkey', 'Failed to unregister hotkey '+IntToStr(hk)); - end; - FHotkeys.Clear; -end; - { TLangSwitchRefreshWatcher } constructor TLangSwitchRefreshWatcher.Create(AOwnerHandle: THandle); diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 2bdfae62e39..8e3fe92a3ce 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -129,27 +129,6 @@ BOOL IsTouchPanelVisible() { return touchPanelVisible; } -/* - Cache UseRightModifierHotKey debug flag for this session - when using right modifier for Hotkeys use the Win32 API - ResisterHotkey functionality -*/ -BOOL UseRegisterHotkey() { - static BOOL flag_UseRightModifierHotKey = FALSE; - static BOOL loaded = FALSE; - - if (!loaded) { - RegistryReadOnly reg(HKEY_CURRENT_USER); - if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) { - if (reg.ValueExists(REGSZ_UseRightModifierHotKey)) { - flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_UseRightModifierHotKey); - } - } - loaded = TRUE; // Set loaded to TRUE whether or not the key exists - } - return flag_UseRightModifierHotKey; -} - LRESULT _kmnLowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, @@ -169,36 +148,18 @@ LRESULT _kmnLowLevelKeyboardProc( SendDebugMessageFormat("wparam: %x lparam: %x [vk:%s scan:%x flags:%x extra:%x]", wParam, lParam, Debug_VirtualKey((WORD) hs->vkCode), hs->scanCode, hs->flags, hs->dwExtraInfo); // I4674 - if (GetKeyState(VK_LCONTROL) < 0) { - FHotkeyShiftState |= HK_CTRL; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); - } - - if (GetKeyState(VK_RCONTROL) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_CTRL : HK_RCTRL_INVALID; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRegisterHotkey()); - } - - if (GetKeyState(VK_LMENU) < 0) { - FHotkeyShiftState |= HK_ALT; - } - - if (GetKeyState(VK_RMENU) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_ALT : HK_RALT_INVALID; - } - - if (GetKeyState(VK_LSHIFT) < 0) { - FHotkeyShiftState |= HK_SHIFT; - } - if (GetKeyState(VK_RSHIFT) < 0) { - FHotkeyShiftState |= UseRegisterHotkey() ? HK_SHIFT : HK_RSHIFT_INVALID; - } + // #5190: Don't cache modifier state because sometimes we won't receive + // modifier change events (e.g. on lock screen) + FHotkeyShiftState = 0; + if (GetKeyState(VK_LCONTROL) < 0) FHotkeyShiftState |= HK_CTRL; + if (GetKeyState(VK_RCONTROL) < 0) FHotkeyShiftState |= HK_RCTRL_INVALID; + if (GetKeyState(VK_LMENU) < 0) FHotkeyShiftState |= HK_ALT; + if (GetKeyState(VK_RMENU) < 0) FHotkeyShiftState |= HK_RALT_INVALID; + if (GetKeyState(VK_LSHIFT) < 0) FHotkeyShiftState |= HK_SHIFT; + if (GetKeyState(VK_RSHIFT) < 0) FHotkeyShiftState |= HK_RSHIFT_INVALID; + //TODO: #8064. Can remove debug message once issue #8064 is resolved + SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); - //if (GetKeyState(VK_SHIFT) < 0) { - // FHotkeyShiftState |= (!UseRegisterHotkey() && extended) ? HK_RSHIFT_INVALID : HK_SHIFT; - //} // #7337 Post the modifier state ensuring the serialized queue is in sync // Note that the modifier key may be posted again with WM_KEYMAN_KEY_EVENT, @@ -279,9 +240,7 @@ LRESULT _kmnLowLevelKeyboardProc( } BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { - if (UseRegisterHotkey()){ - return FALSE; - } + Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if (!hotkeys) { SendDebugMessageFormat("Failed to get Instance"); diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index 2df38b5c825..ce1b8af33a8 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -121,13 +121,12 @@ TKeymanOptionInfo = record GroupName: string; end; -const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 +const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 // Global options (opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koSwitchLanguageForAllApplications; RegistryName: SRegValue_SwitchLanguageForAllApplications; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I2277 // I4393 (opt: koAltGrCtrlAlt; RegistryName: SRegValue_AltGrCtrlAlt; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), - (opt: koRightModifierHK; RegistryName: SRegValue_UseRightModifierHotKey; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koShowHints; RegistryName: SRegValue_EnableHints; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), (opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'), diff --git a/windows/src/global/delphi/general/KeymanOptionNames.pas b/windows/src/global/delphi/general/KeymanOptionNames.pas index 73356d19cb3..27aef82ab55 100644 --- a/windows/src/global/delphi/general/KeymanOptionNames.pas +++ b/windows/src/global/delphi/general/KeymanOptionNames.pas @@ -5,10 +5,7 @@ interface type TUtilKeymanOption = ( // General options - koKeyboardHotkeysAreToggle, - koAltGrCtrlAlt, - koRightModifierHK, - koReleaseShiftKeysAfterKeyPress, + koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress, koShowHints, // I1256 // Startup options koTestKeymanFunctioning, From f1d9f5304863fee2afa012ba57fc977632b9bc20 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:32:39 +1000 Subject: [PATCH 023/127] feat(windows): add right modifier included in HotKey --- windows/src/desktop/kmshell/xml/strings.xml | 16 +++--- .../keyman32/k32_lowlevelkeyboardhook.cpp | 52 +++++++++++++++++++ .../engine/kmcomapi/util/utilkeymanoption.pas | 3 +- .../delphi/general/KeymanOptionNames.pas | 5 +- 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index 774a4d5e425..e15ba789453 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -377,6 +377,11 @@ Simulate AltGr with Ctrl+Alt + + + + Right Modifier keys work with Hotkeys + @@ -792,18 +797,13 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman Start Keyman - - - - Start %1$s - @@ -860,7 +860,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman @@ -1026,7 +1026,7 @@ keyboard that you use in Windows. Keyman keyboards will adapt automatically to - Keyman + Keyman diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 8e3fe92a3ce..4d842401dd8 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -129,6 +129,27 @@ BOOL IsTouchPanelVisible() { return touchPanelVisible; } +/* + Cache UseRightModifierHotKey debug flag for this session +*/ +BOOL UseRightModifierHotKey() { + static BOOL flag_UseRightModifierHotKey = FALSE; + static BOOL loaded = FALSE; + + if (!loaded) { + RegistryReadOnly reg(HKEY_CURRENT_USER); + if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) { + if (reg.ValueExists(REGSZ_UseRightModifierHotKey)) { + flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_UseRightModifierHotKey); + } + } + loaded = TRUE; // Set loaded to TRUE whether or not the key exists + } + return flag_UseRightModifierHotKey; +} + + + LRESULT _kmnLowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, @@ -157,6 +178,37 @@ LRESULT _kmnLowLevelKeyboardProc( if (GetKeyState(VK_RMENU) < 0) FHotkeyShiftState |= HK_RALT_INVALID; if (GetKeyState(VK_LSHIFT) < 0) FHotkeyShiftState |= HK_SHIFT; if (GetKeyState(VK_RSHIFT) < 0) FHotkeyShiftState |= HK_RSHIFT_INVALID; + + if (GetKeyState(VK_LCONTROL) < 0) { + FHotkeyShiftState |= HK_CTRL; + // TODO remove + SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); + } + + if (GetKeyState(VK_RCONTROL) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; + // TODO remove + SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); + } + + if (GetKeyState(VK_LMENU) < 0) { + FHotkeyShiftState |= HK_ALT; + } + + if (GetKeyState(VK_RMENU) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID; + } + + if (GetKeyState(VK_LSHIFT) < 0) { + FHotkeyShiftState |= HK_SHIFT; + } + if (GetKeyState(VK_RSHIFT) < 0) { + FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; + } + + + + //TODO: #8064. Can remove debug message once issue #8064 is resolved SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas index ce1b8af33a8..2df38b5c825 100644 --- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas +++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas @@ -121,12 +121,13 @@ TKeymanOptionInfo = record GroupName: string; end; -const KeymanOptionInfo: array[0..15] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 +const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I3620 // I4552 // Global options (opt: koKeyboardHotkeysAreToggle; RegistryName: SRegValue_KeyboardHotkeysAreToggle; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koSwitchLanguageForAllApplications; RegistryName: SRegValue_SwitchLanguageForAllApplications; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), // I2277 // I4393 (opt: koAltGrCtrlAlt; RegistryName: SRegValue_AltGrCtrlAlt; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), + (opt: koRightModifierHK; RegistryName: SRegValue_UseRightModifierHotKey; OptionType: kotBool; BoolValue: False; GroupName: 'kogGeneral'), (opt: koShowHints; RegistryName: SRegValue_EnableHints; OptionType: kotBool; BoolValue: True; GroupName: 'kogGeneral'), (opt: koBaseLayout; RegistryName: SRegValue_UnderlyingLayout; OptionType: kotLong; IntValue: 0; GroupName: 'kogGeneral'), diff --git a/windows/src/global/delphi/general/KeymanOptionNames.pas b/windows/src/global/delphi/general/KeymanOptionNames.pas index 27aef82ab55..73356d19cb3 100644 --- a/windows/src/global/delphi/general/KeymanOptionNames.pas +++ b/windows/src/global/delphi/general/KeymanOptionNames.pas @@ -5,7 +5,10 @@ interface type TUtilKeymanOption = ( // General options - koKeyboardHotkeysAreToggle, koAltGrCtrlAlt, koReleaseShiftKeysAfterKeyPress, + koKeyboardHotkeysAreToggle, + koAltGrCtrlAlt, + koRightModifierHK, + koReleaseShiftKeysAfterKeyPress, koShowHints, // I1256 // Startup options koTestKeymanFunctioning, From 259d044f395ff8c14fa0a7ebfe3fda2720691092 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:02:04 +1000 Subject: [PATCH 024/127] feat(windows): new sil logo --- .../windows/src/xml/sil-logo-blue.png | Bin 906 -> 2350 bytes .../src/desktop/kmshell/xml/sil-logo-blue.png | Bin 906 -> 2350 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/oem/firstvoices/windows/src/xml/sil-logo-blue.png b/oem/firstvoices/windows/src/xml/sil-logo-blue.png index e0d7ab6b37385b8f7ec090867ec71ff343d11a43..b65c2a4e086c081529363bfd7722cb087ab8aee6 100644 GIT binary patch delta 2337 zcmV++3EuXK2d)w!iBL{Q4GJ0x0000DNk~Le0001M0000$2nGNE03Fnc`H>+fe=Z^b z04^c{s^Z;}000QXNklF|sm>3h^2GqnSA0#oL7!@#tP(VSDQUuyUU$k4=?e4Z+?|=3# zJ2QJ{cV;`A-R;gVnateT?Ctjcf9ITg?zv~k!otGB!otGBB8Rc@a||UrTFTjJS-6#1 zRJikKZka3QxA*!-&mCA({SR+a{f2Mmj)tg)H?sn}&35SY$7{QJQ$akjZege2!>!EX zx^fqly7G7{jBg}F$9n?XyVlok;+a(2jp*ZbESr19iI(p2qp>)j4;8i6bmACFtKtKU1DKwYG5u;ojr)4^`yfxk~OYk zX2lR(POpD-+~@z|kx;BMHV@S^p+tk;8yKadJpuaT@(>;B@=H;g94Av3t}_{su~5_H z&t0nmaYqt~(>WSKf1PI$*e;kzMGeibDI>eqM4bjSf5}~Yf7(~D4}arL3GBu;b^A$R zKoXeW7O;p>4upjz8UafK^}f}qzM!70#ddFFo#CD0l?x}+=Eg--H>HT*iPAR^pa-|^ zqvp1LeuwC*msirvs$$+Ey7{>uDInWVJNWh*%6CO0*?Ttcr3;+{ycHkQc8bqo45efxLJTB_EGQ?Y9N(x<6QS82Us3|RUvhPI?CIJ6r zZ0HsX?yrwUfAMe$e$+5~w2e~WQ2s3RkczDk4D`0gmPjs83s^+IFUVWzMVDBx4n3|6 z(W4q3EE+=H4+0nSrD9gKd>R$zE8Xq!mMiqyXHB%}fBi%B?yi4m&yhC%N&3+x)+OJF z6q+YOl-TUuC`_RjR+A@9>rlWU=9^UpVeZIGue%ODW-u&io+Pd=?|1|w1 z6br+I9a%jT2<952VhNU4Da%?ExRq9QsmDh{!OUHFClm`AZao8z=}Mg*!WbJJXoq0_ zNLAs|f4R$7`Bj*CHKjCfy3*P*iG*Uc59)i;FwdxmS+qz_gus)s2sAa8^}~Vl?175* z?Xc(3&X;bb`&fjSiNqBP>nfCb>A|Cl;6O5BiK5&Tc|kgT(MuoybcVOWAk=>A>1FiU ziz}$A(!=j&264seG_W1v5txK;BpLq|+fRzLf0B6p%j5Jt3ntX8STLD(ZMj{_Vq^+& z#WIrR76ljCP$o9Q%=QHqrXyS*7*YmOSchT3TwbKi%A^ZTv0D0rFZ?kqzFK_D7930JD{12c^XQ?KwY-Ng zColBTShSikrHC4)mMD(dI8=WhziXCk>qU*`e{AH8cAVSzZ}4YDXOxyW~%BLzADt`INSr2?$KzF;Cf@z#FnIup>H7Sf-2_n64eo6e}faEV10Kz3n);F5dp=Wr&)gh?-gU7i-0mXF0jH4 ze*61>y4)ahm;8!o&_65n?nI_4GRjr6452d(SQ>r(h|g zlT~*tt`ctRn<5rESw1O0X_tn1r`fBt8Uz%G0Ode@?5%+tC%Uf%87PTEe+?resTzz- zBIR%E;LUmj18sxGUfY579cJRTvNPOeWSP3O(5z@BG2eCngMJ-lgQVPRomVPRomAwl#%=YLn~YS(md00000NkvXX Hu0mjfMI(4D delta 882 zcmV-&1C9Ky5{d^QiBL{Q4GJ0x0000DNk~Le0000j0000o2nGNE0LYqB)R7@4e+v)* z01FTSts}j40009YNkl;r22042L3a_7BQnsjYBVUXB3=Omz6>RLw_+sJ&O=pLM*BR+VP zE-grbBG~zDKP)!%4bQ@0nupECq>bxHT3Bnx^%_bdf?#rC6Lys}BenPql8c&9*ELQ* z<%3)4&0!%3S2~wP6On#jh*M9=tZXjHWBisX^>tOo~zAs4g0ze+*Hl z?{+QEAij>K-)5Kaf23`c(r@eq=v;;ND6`pYtN!?+i;bpPWo^rK?yIz~_*EW`3{EWI zTxE~T!dy%ImKJX5{rW*>l4FqAT<)Y z_%P(s%)aiWl_7FiS?66`vMxW;t$XPX!xZ{P=Ijq0;$t506E)%o;k%E8(f|Me07*qo IM6N<$f*S0ZjsO4v diff --git a/windows/src/desktop/kmshell/xml/sil-logo-blue.png b/windows/src/desktop/kmshell/xml/sil-logo-blue.png index e0d7ab6b37385b8f7ec090867ec71ff343d11a43..b65c2a4e086c081529363bfd7722cb087ab8aee6 100644 GIT binary patch delta 2337 zcmV++3EuXK2d)w!iBL{Q4GJ0x0000DNk~Le0001M0000$2nGNE03Fnc`H>+fe=Z^b z04^c{s^Z;}000QXNklF|sm>3h^2GqnSA0#oL7!@#tP(VSDQUuyUU$k4=?e4Z+?|=3# zJ2QJ{cV;`A-R;gVnateT?Ctjcf9ITg?zv~k!otGB!otGBB8Rc@a||UrTFTjJS-6#1 zRJikKZka3QxA*!-&mCA({SR+a{f2Mmj)tg)H?sn}&35SY$7{QJQ$akjZege2!>!EX zx^fqly7G7{jBg}F$9n?XyVlok;+a(2jp*ZbESr19iI(p2qp>)j4;8i6bmACFtKtKU1DKwYG5u;ojr)4^`yfxk~OYk zX2lR(POpD-+~@z|kx;BMHV@S^p+tk;8yKadJpuaT@(>;B@=H;g94Av3t}_{su~5_H z&t0nmaYqt~(>WSKf1PI$*e;kzMGeibDI>eqM4bjSf5}~Yf7(~D4}arL3GBu;b^A$R zKoXeW7O;p>4upjz8UafK^}f}qzM!70#ddFFo#CD0l?x}+=Eg--H>HT*iPAR^pa-|^ zqvp1LeuwC*msirvs$$+Ey7{>uDInWVJNWh*%6CO0*?Ttcr3;+{ycHkQc8bqo45efxLJTB_EGQ?Y9N(x<6QS82Us3|RUvhPI?CIJ6r zZ0HsX?yrwUfAMe$e$+5~w2e~WQ2s3RkczDk4D`0gmPjs83s^+IFUVWzMVDBx4n3|6 z(W4q3EE+=H4+0nSrD9gKd>R$zE8Xq!mMiqyXHB%}fBi%B?yi4m&yhC%N&3+x)+OJF z6q+YOl-TUuC`_RjR+A@9>rlWU=9^UpVeZIGue%ODW-u&io+Pd=?|1|w1 z6br+I9a%jT2<952VhNU4Da%?ExRq9QsmDh{!OUHFClm`AZao8z=}Mg*!WbJJXoq0_ zNLAs|f4R$7`Bj*CHKjCfy3*P*iG*Uc59)i;FwdxmS+qz_gus)s2sAa8^}~Vl?175* z?Xc(3&X;bb`&fjSiNqBP>nfCb>A|Cl;6O5BiK5&Tc|kgT(MuoybcVOWAk=>A>1FiU ziz}$A(!=j&264seG_W1v5txK;BpLq|+fRzLf0B6p%j5Jt3ntX8STLD(ZMj{_Vq^+& z#WIrR76ljCP$o9Q%=QHqrXyS*7*YmOSchT3TwbKi%A^ZTv0D0rFZ?kqzFK_D7930JD{12c^XQ?KwY-Ng zColBTShSikrHC4)mMD(dI8=WhziXCk>qU*`e{AH8cAVSzZ}4YDXOxyW~%BLzADt`INSr2?$KzF;Cf@z#FnIup>H7Sf-2_n64eo6e}faEV10Kz3n);F5dp=Wr&)gh?-gU7i-0mXF0jH4 ze*61>y4)ahm;8!o&_65n?nI_4GRjr6452d(SQ>r(h|g zlT~*tt`ctRn<5rESw1O0X_tn1r`fBt8Uz%G0Ode@?5%+tC%Uf%87PTEe+?resTzz- zBIR%E;LUmj18sxGUfY579cJRTvNPOeWSP3O(5z@BG2eCngMJ-lgQVPRomVPRomAwl#%=YLn~YS(md00000NkvXX Hu0mjfMI(4D delta 882 zcmV-&1C9Ky5{d^QiBL{Q4GJ0x0000DNk~Le0000j0000o2nGNE0LYqB)R7@4e+v)* z01FTSts}j40009YNkl;r22042L3a_7BQnsjYBVUXB3=Omz6>RLw_+sJ&O=pLM*BR+VP zE-grbBG~zDKP)!%4bQ@0nupECq>bxHT3Bnx^%_bdf?#rC6Lys}BenPql8c&9*ELQ* z<%3)4&0!%3S2~wP6On#jh*M9=tZXjHWBisX^>tOo~zAs4g0ze+*Hl z?{+QEAij>K-)5Kaf23`c(r@eq=v;;ND6`pYtN!?+i;bpPWo^rK?yIz~_*EW`3{EWI zTxE~T!dy%ImKJX5{rW*>l4FqAT<)Y z_%P(s%)aiWl_7FiS?66`vMxW;t$XPX!xZ{P=Ijq0;$t506E)%o;k%E8(f|Me07*qo IM6N<$f*S0ZjsO4v From fed6582f6280983d2d67ab7dfaee8ee891facea9 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 23 Aug 2024 08:32:25 +0700 Subject: [PATCH 025/127] fix(android): Check in material-stepper as internal dependency Follows this guide on [setting up a local maven respository](https://brightinventions.pl/blog/migrating-away-from-bintray-jcenter-when-there-is-no-alternative-repository/#setting-up-a-local-maven-repository) now that jcenter is deprecated. --- android/KMAPro/build.gradle | 11 ++- android/KMAPro/kMAPro/build.gradle | 2 +- .../4.3.1/material-stepper-4.3.1-javadoc.jar | Bin 0 -> 219877 bytes .../4.3.1/material-stepper-4.3.1-sources.jar | Bin 0 -> 48791 bytes .../4.3.1/material-stepper-4.3.1.aar | Bin 0 -> 121509 bytes .../4.3.1/material-stepper-4.3.1.pom | 90 ++++++++++++++++++ 6 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-javadoc.jar create mode 100644 android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-sources.jar create mode 100644 android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.aar create mode 100644 android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.pom diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle index b1f2d240a72..07a61850c93 100644 --- a/android/KMAPro/build.gradle +++ b/android/KMAPro/build.gradle @@ -2,8 +2,12 @@ buildscript { repositories { google() - jcenter() + //jcenter() deprecated August 2024 + mavenLocal() mavenCentral() + flatDir { + dirs "kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/" + } } dependencies { classpath 'com.android.tools.build:gradle:7.4.2' @@ -13,14 +17,15 @@ buildscript { // From jcenter() which could be sunset in future // https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ - classpath 'com.stepstone.stepper:material-stepper:4.3.1' + classpath 'com.stepstone.stepper:material-stepper:4.3.1@aar' } } allprojects { repositories { + maven { url uri("${projectDir}/libs") } google() - jcenter() + //jcenter() deprecated August 2024 mavenCentral() maven { url "https://jitpack.io" } } diff --git a/android/KMAPro/kMAPro/build.gradle b/android/KMAPro/kMAPro/build.gradle index 7eec37bcefa..e44f72ad576 100644 --- a/android/KMAPro/kMAPro/build.gradle +++ b/android/KMAPro/kMAPro/build.gradle @@ -145,7 +145,7 @@ repositories { dirs 'libs' } google() - jcenter() + //jcenter() } dependencies { diff --git a/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-javadoc.jar b/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-javadoc.jar new file mode 100644 index 0000000000000000000000000000000000000000..895d772c3976617b65c3fb988fb60f6e132438c5 GIT binary patch literal 219877 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%0Aqz|3wIo{y6{Jwzh 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 literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-sources.jar b/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..a3c414838713504399b6d6f14d80f2819f7730b0 GIT binary patch literal 48791 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 L%J~=G{`CI<+YfEJ literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.aar b/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.aar new file mode 100644 index 0000000000000000000000000000000000000000..9bc9a3f05cded90a5eb50afa9d58e61f9dea1bdd GIT binary patch literal 121509 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 iR2C)(9tunsvZS%+t}R%x7^ZIsnp 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ℑxqJ%n+D+cm27gpq`Ek#qHoKI`af7Fy|; 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 Tlw`yJVFMg6+#dvvlOX;dJX;_6 literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.pom b/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.pom new file mode 100644 index 00000000000..5bd1fc5d399 --- /dev/null +++ b/android/KMAPro/kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/material-stepper-4.3.1.pom @@ -0,0 +1,90 @@ + + + 4.0.0 + com.stepstone.stepper + material-stepper + 4.3.1 + aar + Android Material Stepper + This library allows to use Material steppers inside Android applications. + https://github.com/stepstone-tech/android-material-stepper + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + zawadz88 + Piotr Zawadzki + piotr.zawadzki@stepstone.com + + + + https://github.com/stepstone-tech/android-material-stepper.git + https://github.com/stepstone-tech/android-material-stepper.git + https://github.com/stepstone-tech/android-material-stepper + + + + com.android.support + appcompat-v7 + 25.4.0 + compile + + + junit + junit + 4.12 + test + + + org.mockito + mockito-core + 2.7.21 + test + + + com.squareup.assertj + assertj-android + 1.1.1 + test + + + org.robolectric + robolectric + 3.3.1 + test + + + httpclient + org.apache.httpcomponents + + + commons-logging + commons-logging + + + + + org.jetbrains.kotlin + kotlin-stdlib-jre7 + 1.1.4-3 + test + + + org.jetbrains.kotlin + kotlin-reflect + 1.1.4-3 + test + + + com.nhaarman + mockito-kotlin + 1.4.0 + test + + + From 2927f57c04fc779d917149ea9fda2ebcddfa9d3c Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:41:31 +1000 Subject: [PATCH 026/127] feat(windows): missed checked in file --- common/windows/delphi/general/RegistryKeys.pas | 1 + 1 file changed, 1 insertion(+) diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas index 1557de58657..0553b823065 100644 --- a/common/windows/delphi/general/RegistryKeys.pas +++ b/common/windows/delphi/general/RegistryKeys.pas @@ -115,6 +115,7 @@ interface SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU + SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true From e402ea19c7d8bb2880e96c71a4db846c74a5570c Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 23 Aug 2024 15:44:09 +0700 Subject: [PATCH 027/127] chore(android): Update deprecation comment --- android/KMAPro/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle index 07a61850c93..87d5ed9bedd 100644 --- a/android/KMAPro/build.gradle +++ b/android/KMAPro/build.gradle @@ -15,7 +15,7 @@ buildscript { classpath 'io.sentry:sentry-android-gradle-plugin:4.6.0' classpath 'name.remal:gradle-plugins:1.5.0' - // From jcenter() which could be sunset in future + // From jcenter() which was deprecated August 2024 // https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ classpath 'com.stepstone.stepper:material-stepper:4.3.1@aar' } From a22a40fe2e8049792b9288938d6e527f3309ccbd Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Fri, 23 Aug 2024 22:36:54 +0200 Subject: [PATCH 028/127] fix(linux): add `keymanFacename` to .ldml file This change adds the `keymanFacename` attribute based on UnicodeFont or AnsiFont to the root element of the generated .ldml file so that onboard-keyman can display the proper font for the osk. Fixes: #12019 --- linux/keyman-config/keyman_config/kvk2ldml.py | 6 +++++- linux/keyman-config/tests/test_kvk2ldml.py | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 linux/keyman-config/tests/test_kvk2ldml.py diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index 3b3aee281bb..f57cfe2dd47 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -349,7 +349,11 @@ def convert_ldml(kvkData): else: keymaps["shift"] = (uskey,) - ldml = etree.Element("keyboard", locale="zzz-keyman") + if kvkData.UnicodeFont: + font = kvkData.UnicodeFont.name + else: + font = kvkData.AnsiFont.name + ldml = etree.Element("keyboard", locale="zzz-keyman", keymanFacename=font) etree.SubElement(ldml, "version", platform="11") names = etree.SubElement(ldml, "names") names.append(etree.Element("name", value="ZZZ")) diff --git a/linux/keyman-config/tests/test_kvk2ldml.py b/linux/keyman-config/tests/test_kvk2ldml.py new file mode 100644 index 00000000000..b3107642a0d --- /dev/null +++ b/linux/keyman-config/tests/test_kvk2ldml.py @@ -0,0 +1,14 @@ +import unittest + +from keyman_config.kvk2ldml import KVKData, NFont, convert_ldml + +class Kvk2LdmlTests(unittest.TestCase): + def test_convert_ldml__adds_keymanFacename(self): + kvkData = KVKData() + kvkData.AssociatedKeyboard = 'khmer_angkor' + kvkData.UnicodeFont = NFont() + kvkData.UnicodeFont.name='KbdKhmr' + + ldml = convert_ldml(kvkData) + self.assertEqual(ldml.get('locale'), "zzz-keyman") + self.assertEqual(ldml.get('keymanFacename'), 'KbdKhmr') From 16ce5b0408b598293f8388b96c4fd49031e4864f Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Sat, 24 Aug 2024 10:07:36 +0800 Subject: [PATCH 029/127] fix(linux): get oskFont from `kmp.json` instead of UnicodeFont --- .../keyman_config/install_kmp.py | 2 +- linux/keyman-config/keyman_config/kvk2ldml.py | 25 ++++++---- linux/keyman-config/km-kvk2ldml | 3 +- linux/keyman-config/tests/test_kvk2ldml.py | 47 +++++++++++++++++-- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/linux/keyman-config/keyman_config/install_kmp.py b/linux/keyman-config/keyman_config/install_kmp.py index d82c8e06e57..fed67952ca5 100755 --- a/linux/keyman-config/keyman_config/install_kmp.py +++ b/linux/keyman-config/keyman_config/install_kmp.py @@ -177,8 +177,8 @@ def _install_files(self, keyboards, files): # Special handling to convert kvk into LDML logging.info("Converting %s to LDML and installing both as as keyman file", f['name']) - ldml = convert_kvk_to_ldml(fpath) name, ext = os.path.splitext(f['name']) + ldml = convert_kvk_to_ldml(name, fpath) ldmlfile = os.path.join(self.packageDir, f"{name}.ldml") output_ldml(ldmlfile, ldml) elif ftype == KMFileTypes.KM_ICON: diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index f57cfe2dd47..d80fc2c1077 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -1,11 +1,14 @@ #!/usr/bin/python3 import logging +import os import struct import sys from lxml import etree +from keyman_config.kmpmetadata import parsemetadata + # .kvk file format # KVK files are variable length files with variable sized structures. @@ -311,7 +314,7 @@ def _get_modifer(key): return modifier -def convert_ldml(kvkData): +def convert_ldml(keyboardName, kvkData, kmpJsonFilename): keymaps = {} for key in kvkData.Keys: @@ -349,11 +352,16 @@ def convert_ldml(kvkData): else: keymaps["shift"] = (uskey,) - if kvkData.UnicodeFont: - font = kvkData.UnicodeFont.name - else: - font = kvkData.AnsiFont.name - ldml = etree.Element("keyboard", locale="zzz-keyman", keymanFacename=font) + info, system, options, keyboards, files = parsemetadata(kmpJsonFilename) + + ldml = etree.Element("keyboard", locale="zzz-keyman") + for keyboard in keyboards: + if keyboard['id'] != keyboardName: + continue + if 'oskFont' in keyboard: + ldml.set('keymanFacename', keyboard['oskFont']) + break + etree.SubElement(ldml, "version", platform="11") names = etree.SubElement(ldml, "names") names.append(etree.Element("name", value="ZZZ")) @@ -406,6 +414,7 @@ def parse_kvk_file(kvkfile): return kvkData -def convert_kvk_to_ldml(kvkfile): +def convert_kvk_to_ldml(name, kvkfile): kvkData = parse_kvk_file(kvkfile) - return convert_ldml(kvkData) + kmpJsonFilename = os.path.join(os.path.dirname(kvkfile), 'kmp.json') + return convert_ldml(name, kvkData, kmpJsonFilename) diff --git a/linux/keyman-config/km-kvk2ldml b/linux/keyman-config/km-kvk2ldml index d669dfa72cd..34c4e76fdf5 100755 --- a/linux/keyman-config/km-kvk2ldml +++ b/linux/keyman-config/km-kvk2ldml @@ -56,7 +56,8 @@ def main(): try: with open(outputfile, 'wb') as ldmlfile: - ldml = convert_ldml(kvkData) + kmpJsonFilename = os.path.join(os.path.dirname(args.kvkfile), 'kmp.json') + ldml = convert_ldml(name, kvkData, kmpJsonFilename) output_ldml(ldmlfile, ldml) except PermissionError: logging.error(f'km-kvk2ldml: error, permission denied writing file `{outputfile}`') diff --git a/linux/keyman-config/tests/test_kvk2ldml.py b/linux/keyman-config/tests/test_kvk2ldml.py index b3107642a0d..51b30ab6446 100644 --- a/linux/keyman-config/tests/test_kvk2ldml.py +++ b/linux/keyman-config/tests/test_kvk2ldml.py @@ -1,14 +1,53 @@ +import os +import tempfile import unittest from keyman_config.kvk2ldml import KVKData, NFont, convert_ldml class Kvk2LdmlTests(unittest.TestCase): + def _createKmpJson(self, packagedir): + kmpJsonFilename = os.path.join(packagedir, 'kmp.json') + with open(kmpJsonFilename, 'w') as file: + file.write('''{ + "system": { + "keymanDeveloperVersion": "18.0", + "fileVersion": "7.0" + }, + "files": [ { + "name": "khmer_angkor.kmx", + "description": "Keyboard Khmer Angkor" + }, { + "name": "kmp.json", + "description": "Package information (JSON)" + } ], + "keyboards": [ { + "name": "Khmer Angkor", + "id": "khmer_angkor", + "version": "1.5", + "oskFont": "KbdKhmr.ttf", + "languages": [ { + "name": "Central Khmer (Khmer, Cambodia)", + "id": "km" + } ]} + ]}''') + return kmpJsonFilename + def test_convert_ldml__adds_keymanFacename(self): + # Setup + keyboardName = 'khmer_angkor' kvkData = KVKData() - kvkData.AssociatedKeyboard = 'khmer_angkor' + kvkData.AssociatedKeyboard = keyboardName kvkData.UnicodeFont = NFont() - kvkData.UnicodeFont.name='KbdKhmr' + kvkData.UnicodeFont.name='DontUseThis!' + + workdir = tempfile.TemporaryDirectory() + kmpJsonFilename = self._createKmpJson(workdir.name) - ldml = convert_ldml(kvkData) + # Execute + ldml = convert_ldml(keyboardName, kvkData, kmpJsonFilename) + + # Verify self.assertEqual(ldml.get('locale'), "zzz-keyman") - self.assertEqual(ldml.get('keymanFacename'), 'KbdKhmr') + self.assertEqual(ldml.get('keymanFacename'), 'KbdKhmr.ttf') + + workdir.cleanup() From c99e833c8e78e3ec76ca1da84aef06ae3631ef33 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Sat, 24 Aug 2024 10:25:57 +0800 Subject: [PATCH 030/127] fix(linux): Add font name without file extension --- linux/keyman-config/keyman_config/kvk2ldml.py | 3 ++- linux/keyman-config/tests/test_kvk2ldml.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index d80fc2c1077..4109e37def8 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -359,7 +359,8 @@ def convert_ldml(keyboardName, kvkData, kmpJsonFilename): if keyboard['id'] != keyboardName: continue if 'oskFont' in keyboard: - ldml.set('keymanFacename', keyboard['oskFont']) + font, ext = os.path.splitext(keyboard['oskFont']) + ldml.set('keymanFacename', font) break etree.SubElement(ldml, "version", platform="11") diff --git a/linux/keyman-config/tests/test_kvk2ldml.py b/linux/keyman-config/tests/test_kvk2ldml.py index 51b30ab6446..cd46d10e1fd 100644 --- a/linux/keyman-config/tests/test_kvk2ldml.py +++ b/linux/keyman-config/tests/test_kvk2ldml.py @@ -48,6 +48,6 @@ def test_convert_ldml__adds_keymanFacename(self): # Verify self.assertEqual(ldml.get('locale'), "zzz-keyman") - self.assertEqual(ldml.get('keymanFacename'), 'KbdKhmr.ttf') + self.assertEqual(ldml.get('keymanFacename'), 'KbdKhmr') workdir.cleanup() From c8cbc2fefe44c89e76bca8b086f592754b1882a3 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Sat, 24 Aug 2024 11:31:23 +0800 Subject: [PATCH 031/127] fix(linux): get font facename from .ttf file --- common/resources/fonts/KbdKhmr.ttf | Bin 0 -> 129124 bytes linux/debian/control | 1 + linux/keyman-config/keyman_config/kvk2ldml.py | 15 ++++++++++++++- linux/keyman-config/tests/test_kvk2ldml.py | 6 +++++- 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 common/resources/fonts/KbdKhmr.ttf diff --git a/common/resources/fonts/KbdKhmr.ttf b/common/resources/fonts/KbdKhmr.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cceeaba52fe59c7a2e41b3226bc2897fe7aa6608 GIT binary patch literal 129124 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 3.5), python3-dbus, + python3-fonttools, python3-gi, python3-lxml, python3-magic, diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index 4109e37def8..dbacfef47cd 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -5,6 +5,7 @@ import struct import sys +from fontTools import ttLib from lxml import etree from keyman_config.kmpmetadata import parsemetadata @@ -314,6 +315,17 @@ def _get_modifer(key): return modifier +def _fontFacename(fontFilename): + """Get the facename from fontFilename's TTF tables""" + # From https://github.com/mcfletch/ttfquery/blob/master/ttfquery/describe.py + FONT_SPECIFIER_NAME_ID = 4 + font = ttLib.TTFont(fontFilename) + for record in font['name'].names: + if record.nameID == FONT_SPECIFIER_NAME_ID: + return record.string + return '' + + def convert_ldml(keyboardName, kvkData, kmpJsonFilename): keymaps = {} @@ -359,7 +371,8 @@ def convert_ldml(keyboardName, kvkData, kmpJsonFilename): if keyboard['id'] != keyboardName: continue if 'oskFont' in keyboard: - font, ext = os.path.splitext(keyboard['oskFont']) + fontFile = os.path.join(os.path.dirname(kmpJsonFilename), keyboard['oskFont']) + font = _fontFacename(fontFile) ldml.set('keymanFacename', font) break diff --git a/linux/keyman-config/tests/test_kvk2ldml.py b/linux/keyman-config/tests/test_kvk2ldml.py index cd46d10e1fd..0be6c497012 100644 --- a/linux/keyman-config/tests/test_kvk2ldml.py +++ b/linux/keyman-config/tests/test_kvk2ldml.py @@ -1,4 +1,6 @@ import os +import shutil +import sys import tempfile import unittest @@ -24,7 +26,7 @@ def _createKmpJson(self, packagedir): "name": "Khmer Angkor", "id": "khmer_angkor", "version": "1.5", - "oskFont": "KbdKhmr.ttf", + "oskFont": "KbdKhmrTest.ttf", "languages": [ { "name": "Central Khmer (Khmer, Cambodia)", "id": "km" @@ -42,6 +44,8 @@ def test_convert_ldml__adds_keymanFacename(self): workdir = tempfile.TemporaryDirectory() kmpJsonFilename = self._createKmpJson(workdir.name) + shutil.copyfile(os.path.join(sys.path[0], '../../../common/resources/fonts/KbdKhmr.ttf'), + os.path.join(workdir.name, 'KbdKhmrTest.ttf')) # Execute ldml = convert_ldml(keyboardName, kvkData, kmpJsonFilename) From 50228a8266599fbb34580b6c7321a1a727635949 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Sat, 24 Aug 2024 12:14:47 +0800 Subject: [PATCH 032/127] fix(linux): properly deal with types of names Names can be Unicode strings or byte arrays. This change allows for both kinds. Also properly deal with the case when we can't get the name from the .ttf file. And finally change the test so that we don't need the `KbdKhmr.ttf` font. --- common/resources/fonts/KbdKhmr.ttf | Bin 129124 -> 0 bytes linux/keyman-config/keyman_config/kvk2ldml.py | 7 ++++--- linux/keyman-config/tests/test_kvk2ldml.py | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 common/resources/fonts/KbdKhmr.ttf diff --git a/common/resources/fonts/KbdKhmr.ttf b/common/resources/fonts/KbdKhmr.ttf deleted file mode 100644 index cceeaba52fe59c7a2e41b3226bc2897fe7aa6608..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129124 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 Date: Mon, 26 Aug 2024 09:25:59 +0700 Subject: [PATCH 033/127] fix(android): Remove use of mavenLocal() --- android/KMAPro/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle index 87d5ed9bedd..ab7158c8d88 100644 --- a/android/KMAPro/build.gradle +++ b/android/KMAPro/build.gradle @@ -3,7 +3,6 @@ buildscript { repositories { google() //jcenter() deprecated August 2024 - mavenLocal() mavenCentral() flatDir { dirs "kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/" From 558636886c7a776fcd6eeb3791efae29d432c6d6 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:39:47 +1000 Subject: [PATCH 034/127] feat(windows): remove left modifier only bit flag --- windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index 4d842401dd8..e33a610e61b 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -172,12 +172,6 @@ LRESULT _kmnLowLevelKeyboardProc( // #5190: Don't cache modifier state because sometimes we won't receive // modifier change events (e.g. on lock screen) FHotkeyShiftState = 0; - if (GetKeyState(VK_LCONTROL) < 0) FHotkeyShiftState |= HK_CTRL; - if (GetKeyState(VK_RCONTROL) < 0) FHotkeyShiftState |= HK_RCTRL_INVALID; - if (GetKeyState(VK_LMENU) < 0) FHotkeyShiftState |= HK_ALT; - if (GetKeyState(VK_RMENU) < 0) FHotkeyShiftState |= HK_RALT_INVALID; - if (GetKeyState(VK_LSHIFT) < 0) FHotkeyShiftState |= HK_SHIFT; - if (GetKeyState(VK_RSHIFT) < 0) FHotkeyShiftState |= HK_RSHIFT_INVALID; if (GetKeyState(VK_LCONTROL) < 0) { FHotkeyShiftState |= HK_CTRL; @@ -207,8 +201,6 @@ LRESULT _kmnLowLevelKeyboardProc( } - - //TODO: #8064. Can remove debug message once issue #8064 is resolved SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); From 930221376c09d8004c81ba22f55a7b25d31b28d5 Mon Sep 17 00:00:00 2001 From: Shawn Schantz Date: Tue, 27 Aug 2024 04:19:51 +0700 Subject: [PATCH 035/127] fix(mac): show package info after keyboard install Move to updated APIs that no longer require window dismissal. Fixes: #9308 --- .../Keyman4MacIM/KMInputMethodAppDelegate.m | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 9189e39d58e..0482f784328 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -1119,14 +1119,16 @@ - (void)windowWillClose:(NSNotification *)notification { * TODO: this should really be refactored */ -- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { - NSButton *button = (NSButton *)[alert.buttons objectAtIndex:0]; - if (button.tag == -1) { +- (void)downloadComplete:(NSModalResponse) returnCode { + os_log_debug([KMLogs uiLog], "downloadComplete, NSModalResponse returnCode: %ld", (long)returnCode); + if (returnCode == NSModalResponseCancel) { + os_log_debug([KMLogs uiLog], "downloadComplete, returnCode == NSModalResponseCancel"); [_connection cancel]; } - else if (button.tag == 1) { - [_downloadKBWindow close]; + else if (returnCode == NSModalResponseOK) { + os_log_debug([KMLogs uiLog], "downloadComplete, returnCode == NSModalResponseOK"); if (self.configWindow.window != nil) { + os_log_debug([KMLogs uiLog], "downloadComplete, self.configWindow.window != nil"); [self.configWindow.window makeKeyAndOrderFront:nil]; if (![[self.configWindow.window childWindows] containsObject:self.infoWindow.window]) { [self.configWindow.window addChildWindow:self.infoWindow.window ordered:NSWindowAbove]; @@ -1135,6 +1137,7 @@ - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInf [self.infoWindow.window makeKeyAndOrderFront:nil]; } else { + os_log_debug([KMLogs uiLog], "downloadComplete, self.configWindow.window == nil"); [self.infoWindow.window centerInParent]; [self.infoWindow.window makeKeyAndOrderFront:nil]; [self.infoWindow.window setLevel:NSFloatingWindowLevel]; @@ -1152,6 +1155,7 @@ - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInf } - (NSAlert *)downloadInfoView { + os_log_debug([KMLogs uiLog], "downloadInfoView"); if (_downloadInfoView == nil) { _downloadInfoView = [[NSAlert alloc] init]; [_downloadInfoView setMessageText:NSLocalizedString(@"message-keyboard-downloading", nil)]; @@ -1165,6 +1169,7 @@ - (NSAlert *)downloadInfoView { } - (NSProgressIndicator *)progressIndicator { + os_log_debug([KMLogs uiLog], "progressIndicator"); if (_progressIndicator == nil) { _progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0, 0, 300, 20)]; [_progressIndicator setIndeterminate:NO]; @@ -1186,36 +1191,39 @@ - (void)downloadKeyboardFromKeyboardId:(NSString *)keyboardId { - (void)downloadKeyboardFromURL:(NSURL *)url { NSURL* downloadUrl = url; - + os_log_debug([KMLogs uiLog], "downloadKeyboardFromURL, url.path: %{public}@", url.path); + if (downloadUrl && _downloadFilename) { if (_infoWindow.window != nil) [_infoWindow close]; [self.downloadInfoView setInformativeText:self.downloadFilename]; + if (self.configWindow.window != nil) { + os_log_debug([KMLogs uiLog], "downloadKeyboardFromURL, self.configWindow.window != nil"); [self.configWindow.window makeKeyAndOrderFront:nil]; if (![[self.configWindow.window childWindows] containsObject:self.downloadKBWindow.window]) { [self.configWindow.window addChildWindow:self.downloadKBWindow.window ordered:NSWindowAbove]; } [self.downloadKBWindow.window centerInParent]; [self.downloadKBWindow.window makeKeyAndOrderFront:nil]; - [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window - modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:nil]; + [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window completionHandler:^(NSModalResponse returnCode) { + [self downloadComplete:returnCode]; + }]; } else { + os_log_debug([KMLogs uiLog], "downloadKeyboardFromURL, self.configWindow.window == nil"); [self.downloadKBWindow.window centerInParent]; [self.downloadKBWindow.window makeKeyAndOrderFront:nil]; [self.downloadKBWindow.window setLevel:NSFloatingWindowLevel]; - [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window - modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:nil]; + [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window completionHandler:^(NSModalResponse returnCode) { + [self downloadComplete:returnCode]; + }]; } if (_connection == nil) { - [_downloadInfoView setMessageText:NSLocalizedString(@"message-keyboard-downloading", nil)]; + os_log_debug([KMLogs uiLog], "downloadKeyboardFromURL, _connection == nil, set button title cancel downloading, tag = -1"); + [_downloadInfoView setMessageText:NSLocalizedString(@"message-keyboard-downloading", nil)]; NSButton *button = (NSButton *)[_downloadInfoView.buttons objectAtIndex:0]; [button setTitle:NSLocalizedString(@"button-cancel-downloading", nil)]; [button setTag:-1]; @@ -1257,6 +1265,7 @@ - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheRespo } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + os_log_debug([KMLogs uiLog], "connectionDidFinishLoading"); NSString *filePath = [self.keyboardsPath stringByAppendingPathComponent:self.downloadFilename]; [self.receivedData writeToFile:filePath atomically:YES]; [self unzipFile:filePath]; @@ -1264,6 +1273,7 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [_downloadInfoView setMessageText:NSLocalizedString(@"message-keyboard-download-complete", nil)]; NSButton *button = (NSButton *)[_downloadInfoView.buttons objectAtIndex:0]; + os_log_debug([KMLogs uiLog], "connectionDidFinishLoading, set button title download complete, tag = 1"); [button setTitle:NSLocalizedString(@"button-download-complete", nil)]; [button setTag:1]; [[NSNotificationCenter defaultCenter] postNotificationName:kKeymanKeyboardDownloadCompletedNotification From 500c800bb495ab44db66e3b4558cd40224230f1e Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:01:50 +1000 Subject: [PATCH 036/127] feat(windows): remove developer debug logging --- common/windows/cpp/include/registry.h | 2 +- windows/src/desktop/kmshell/xml/strings.xml | 4 ++-- windows/src/engine/keyman32/hotkeys.cpp | 2 -- .../keyman32/k32_lowlevelkeyboardhook.cpp | 24 ++++--------------- 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/common/windows/cpp/include/registry.h b/common/windows/cpp/include/registry.h index c6d1bf85ec1..842176e9edc 100644 --- a/common/windows/cpp/include/registry.h +++ b/common/windows/cpp/include/registry.h @@ -110,7 +110,7 @@ #define REGSZ_KeyboardHotkeysAreToggle "hotkeys are toggles" #define REGSZ_DeadkeyConversionMode "deadkey conversion mode" // CU // I4552 #define REGSZ_ZapVirtualKeyCode "zap virtual key code" // LM, defaults to 0x0E (_VK_PREFIX_DEFAULT) -/* Non-chiral use of hotkeys instead of left-only hotkeys */ +/* Default is to only use left modifier in hotkeys trigger */ #define REGSZ_UseRightModifierHotKey "use right modifier for hotkey" diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml index ea09ca5b744..9409d6d8c12 100644 --- a/windows/src/desktop/kmshell/xml/strings.xml +++ b/windows/src/desktop/kmshell/xml/strings.xml @@ -379,8 +379,8 @@ - - Right Modifier keys work with Hotkeys + + Right-side modifier keys trigger hotkeys diff --git a/windows/src/engine/keyman32/hotkeys.cpp b/windows/src/engine/keyman32/hotkeys.cpp index e7fdbe3d79d..1652397d77b 100644 --- a/windows/src/engine/keyman32/hotkeys.cpp +++ b/windows/src/engine/keyman32/hotkeys.cpp @@ -139,8 +139,6 @@ Hotkey *Hotkeys::GetHotkey(DWORD hotkey) { for (int i = 0; i < m_nHotkeys; i++) { if (m_hotkeys[i].HotkeyValue == hotkey) { - SendDebugMessageFormat( - "LanguageHotkey[%d] = {HotkeyValue: %x, hkl: %x} passed in: %x", i, m_hotkeys[i].HotkeyValue, m_hotkeys[i].hkl, hotkey); return &m_hotkeys[i]; } } diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp index e33a610e61b..8e16d536f2a 100644 --- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp +++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp @@ -130,7 +130,7 @@ BOOL IsTouchPanelVisible() { } /* - Cache UseRightModifierHotKey debug flag for this session + Cache UseRightModifierHotKey for this session */ BOOL UseRightModifierHotKey() { static BOOL flag_UseRightModifierHotKey = FALSE; @@ -148,8 +148,6 @@ BOOL UseRightModifierHotKey() { return flag_UseRightModifierHotKey; } - - LRESULT _kmnLowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, @@ -169,20 +167,14 @@ LRESULT _kmnLowLevelKeyboardProc( SendDebugMessageFormat("wparam: %x lparam: %x [vk:%s scan:%x flags:%x extra:%x]", wParam, lParam, Debug_VirtualKey((WORD) hs->vkCode), hs->scanCode, hs->flags, hs->dwExtraInfo); // I4674 - // #5190: Don't cache modifier state because sometimes we won't receive - // modifier change events (e.g. on lock screen) FHotkeyShiftState = 0; - if (GetKeyState(VK_LCONTROL) < 0) { + if (GetKeyState(VK_LCONTROL) < 0) { FHotkeyShiftState |= HK_CTRL; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_LCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); } if (GetKeyState(VK_RCONTROL) < 0) { FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID; - // TODO remove - SendDebugMessageFormat("ProcessHotkey VK_RCONTROL [vkCode:%x isUp:%d FHotkeyShiftState:%x useRight:%d", hs->vkCode, isUp, FHotkeyShiftState, UseRightModifierHotKey()); } if (GetKeyState(VK_LMENU) < 0) { @@ -200,10 +192,8 @@ LRESULT _kmnLowLevelKeyboardProc( FHotkeyShiftState |= UseRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID; } - - //TODO: #8064. Can remove debug message once issue #8064 is resolved - SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); - + //TODO: #8064. Can remove debug message once issue #8064 is resolved + SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState); // #7337 Post the modifier state ensuring the serialized queue is in sync // Note that the modifier key may be posted again with WM_KEYMAN_KEY_EVENT, @@ -287,30 +277,24 @@ BOOL ProcessHotkey(UINT vkCode, BOOL isUp, DWORD ShiftState) { Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if (!hotkeys) { - SendDebugMessageFormat("Failed to get Instance"); return FALSE; } Hotkey *hotkey = hotkeys->GetHotkey(ShiftState | vkCode); // I4641 if (!hotkey) { - SendDebugMessageFormat("GetHotkey Null"); return FALSE; } if (isUp) { - SendDebugMessageFormat("Is Up"); return TRUE; } if (hotkey->HotkeyType == hktInterface) { - SendDebugMessageFormat("PostMasterController"); Globals::PostMasterController(wm_keyman_control, MAKELONG(KMC_INTERFACEHOTKEY, hotkey->Target), 0); } else { - SendDebugMessageFormat("ReportKeyboardChanged"); ReportKeyboardChanged(PC_HOTKEYCHANGE, hotkey->hkl == 0 ? TF_PROFILETYPE_INPUTPROCESSOR : TF_PROFILETYPE_KEYBOARDLAYOUT, 0, hotkey->hkl, GUID_NULL, hotkey->profileGUID); } - SendDebugMessageFormat("PostDummyKeyEvent"); /* Generate a dummy keystroke to block menu activations, etc but let the shift key through */ PostDummyKeyEvent(); // I3301 - this is imperfect because we don't deal with HC_NOREMOVE. But good enough? // I3534 // I4844 From 30ec15c5fa7de4d085e720273523534131b3ba03 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Tue, 27 Aug 2024 09:05:05 +0700 Subject: [PATCH 037/127] fix(android): Auto-mirror Text Size icons for RTL support --- .../drawable-hdpi/ic_light_action_textsize.png | Bin 135 -> 214 bytes .../ic_light_action_textsize.png | Bin 0 -> 217 bytes .../ic_light_action_textsize.png | Bin 0 -> 168 bytes .../ic_light_action_textsize.png | Bin 0 -> 180 bytes .../ic_light_action_textsize.png | Bin 0 -> 326 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/ic_light_action_textsize.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-mdpi/ic_light_action_textsize.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xhdpi/ic_light_action_textsize.png create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xxhdpi/ic_light_action_textsize.png diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-hdpi/ic_light_action_textsize.png b/android/KMAPro/kMAPro/src/main/res/drawable-hdpi/ic_light_action_textsize.png index 3809ef23536c1503e7240029e194a1550f232ff3..9c8e3354e6b793baad6a56d8579ad95602a512ee 100644 GIT binary patch delta 197 zcmV;$06PDN0oDPK8Gi-<007|tn3wdXGLMCUfx(+IKp05*dAc};R4^t>97+(eF!-a+W!00=EFvKl@PK*6G4_l{ zTua#gF|KfAzo5!?Pr;{u@{`CGN0!Bh60ay6dgOd!L142RuUCVZ5T{E=e^Vd>gPxf1 VAA$9PE|k1|%Oc%$NbBSc;uILpXq-h9ji|$e-Zp;usRq z`gZDB&K3g!H~A#_sIH|qP9~{qsxCd^RmNZKX=BmDC-k9u!r=qrpH4hsZxJ}ZiQ)c% zjTNkI)&D+voJg{{!g|B+leR(VSH2~aYj!?(qI6mAmdsv<@4CAWpV_}OPAD{cajTv9 zvsA5x@1oQeW*F_uet-7+c4whY6DG8_=%}PT{QFk;ZFY3iXQz(uADJa~>WN0>OTGcR Ojlt8^&t;ucLK6Tu301KG literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-mdpi/ic_light_action_textsize.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-mdpi/ic_light_action_textsize.png new file mode 100644 index 0000000000000000000000000000000000000000..a31690d1271909d78d605835e0ccc8e184b92ef6 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBSc;uILpXq-h9ji|$dC7QaSVxQ zeS5{4i$Rgc^`geR`qQ_%6wdn}5&0exd{R|7iS5DKE4A0#^Yu@k6THq5RQB)lj%0W1 zMJ=-h9K8x_UVrOT-P|Co`$#J7E9- literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xhdpi/ic_light_action_textsize.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xhdpi/ic_light_action_textsize.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9829d1788b88326c0a16341121cd247bfe4b1a GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmSQK*5Dp-y;YjHK^0Pf%978f1 z-(C&mYETex4eb85|LLs;r;87qZJuB5e_~{^jqSj>zH>Ka_x#?x`H`|G(G-|K#NG5T0O`%-tLJY|``^2v<$P*I`zJ2_wUSb8@PG WSRB^-GdlsTW$<+Mb6Mw<&;$T$3P2+O literal 0 HcmV?d00001 diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xxhdpi/ic_light_action_textsize.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-xxhdpi/ic_light_action_textsize.png new file mode 100644 index 0000000000000000000000000000000000000000..d15adad0acdcff6bf06e65d23c87f92d696727fd GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^IUvlz1|<8_!p{OJmSQK*5Dp-y;YjHK^8b3eIEGZr zd3(!|ugO7x!BOSk|I@!1H*vb%$z8Ln=;no)r&G4^0@Zc4M9vnBp^r@q-N zf55WoD2JGGL{EYt3d6X#zN{>K=8dnhXIro;P>wiL{Eb;JWdCZLJ9B4kkT{sc(k-at yhQ`?WS?^ Date: Tue, 27 Aug 2024 09:52:48 +0700 Subject: [PATCH 038/127] Apply suggestions from code review Co-authored-by: Marc Durdin --- android/KMAPro/build.gradle | 2 -- android/KMAPro/kMAPro/build.gradle | 1 - 2 files changed, 3 deletions(-) diff --git a/android/KMAPro/build.gradle b/android/KMAPro/build.gradle index ab7158c8d88..5614fcae6a6 100644 --- a/android/KMAPro/build.gradle +++ b/android/KMAPro/build.gradle @@ -2,7 +2,6 @@ buildscript { repositories { google() - //jcenter() deprecated August 2024 mavenCentral() flatDir { dirs "kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/" @@ -24,7 +23,6 @@ allprojects { repositories { maven { url uri("${projectDir}/libs") } google() - //jcenter() deprecated August 2024 mavenCentral() maven { url "https://jitpack.io" } } diff --git a/android/KMAPro/kMAPro/build.gradle b/android/KMAPro/kMAPro/build.gradle index e44f72ad576..05a684f34db 100644 --- a/android/KMAPro/kMAPro/build.gradle +++ b/android/KMAPro/kMAPro/build.gradle @@ -145,7 +145,6 @@ repositories { dirs 'libs' } google() - //jcenter() } dependencies { From ea6e29581bd930d42d39cef5c774263fc4d56652 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Tue, 27 Aug 2024 13:06:37 +0700 Subject: [PATCH 039/127] change(mac): some minor changes after review comments --- mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h | 10 +++++----- mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m | 14 ++++++-------- .../Keyman4MacIM/KMSettingsRepository.m | 6 +----- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h index 0a1cc8cca37..87d240701d9 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.h @@ -1,9 +1,6 @@ /* * Keyman is copyright (C) SIL International. MIT License. * - * KMDataRepository.h - * Keyman - * * Created by Shawn Schantz on 2024-07-30. * */ @@ -13,9 +10,12 @@ NS_ASSUME_NONNULL_BEGIN @interface KMDataRepository : NSObject -@property (readonly) NSURL *keymanDataDirectory; // '~/Library/Application Support/keyman.inputmethod.Keyman' +// keymanDataDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman' +@property (readonly) NSURL *keymanDataDirectory; + +// keymanKeyboardsDirectory: '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards' @property (readonly) NSURL *keymanKeyboardsDirectory; -// keymanKeyboardsDirectory = '~/Library/Application Support/keyman.inputmethod.Keyman/Keyman-Keyboards' + + (KMDataRepository *)shared; - (void)createDataDirectoryIfNecessary; - (void)createKeyboardsDirectoryIfNecessary; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m index 20d6e892a46..9ecedab2314 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMDataRepository.m @@ -1,9 +1,6 @@ /* * Keyman is copyright (C) SIL International. MIT License. * - * KMResourcesRepository.m - * Keyman - * * Created by Shawn Schantz on 2024-07-30. * * Singleton object which serves as an abstraction for the reading and writing of Keyman data. @@ -39,11 +36,11 @@ @implementation KMDataRepository @synthesize obsoleteKeymanKeyboardsDirectory = _obsoleteKeymanKeyboardsDirectory; NSString *const kKeyboardsDirectoryName = @"Keyman-Keyboards"; -/* - The name of the subdirectory within '~/Library/Application Support'. - We follow the convention of using the bundle identifier rather than our subsystem id. - (Also, using the subsystem id, "com.keyman.app", is a poor choice because the API - createDirectoryAtPath sees the .app extension and creates an application file. +/** + * The name of the subdirectory within '~/Library/Application Support'. + * We follow the convention of using the bundle identifier rather than our subsystem id. + * (Also, using the subsystem id, "com.keyman.app", is a poor choice because the API + * createDirectoryAtPath sees the .app extension and creates an application file.) */ NSString *const kKeymanSubdirectoryName = @"keyman.inputmethod.Keyman"; @@ -158,6 +155,7 @@ - (NSURL *)obsoleteKeymanKeyboardsDirectory { } return _obsoleteKeymanKeyboardsDirectory; } + /** * Only called from migrateData. * Causes user to be prompted for permission to access ~/Documents, but they should already have it. diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index a605ea6e6ec..630e2c324e5 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -1,9 +1,6 @@ /* * Keyman is copyright (C) SIL International. MIT License. * - * KMSettingsRepository.h - * Keyman - * * Created by Shawn Schantz on 2024-07-29. * * Singleton object for reading and writing Keyman application settings. @@ -61,7 +58,7 @@ - (BOOL)settingsExist { * For versions before version 1, the keyboards were stored under the ~/Documents directory. */ - (BOOL)dataModelWithKeyboardsInLibrary { - // NSUserDefaults returns zero if the key does not exist + // [NSUserDefaults integerForKey] returns zero if the key does not exist NSInteger dataModelVersion = [[NSUserDefaults standardUserDefaults] integerForKey:kDataModelVersion]; return dataModelVersion >= kVersionStoreDataInLibraryDirectory; @@ -142,7 +139,6 @@ - (void)convertSelectedKeyboardPathForMigration { * Convert the path of the keyboard designating the Documents folder to its new location * in the Application Support folder */ - - (NSString *)convertOldKeyboardPath:(NSString *)oldPath { NSString *newPathString = @""; if(oldPath != nil) { From 745bbd5cd57283f2d6445a862501613d673e60d3 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 28 Aug 2024 09:57:30 +0700 Subject: [PATCH 040/127] fix(android): Clarify directions on Text Size menu --- .../kMAPro/src/main/res/drawable/textsize_decrease.xml | 5 +++++ .../kMAPro/src/main/res/drawable/textsize_increase.xml | 5 +++++ .../kMAPro/src/main/res/layout/text_size_controller.xml | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable/textsize_decrease.xml create mode 100644 android/KMAPro/kMAPro/src/main/res/drawable/textsize_increase.xml diff --git a/android/KMAPro/kMAPro/src/main/res/drawable/textsize_decrease.xml b/android/KMAPro/kMAPro/src/main/res/drawable/textsize_decrease.xml new file mode 100644 index 00000000000..3e8ea253f78 --- /dev/null +++ b/android/KMAPro/kMAPro/src/main/res/drawable/textsize_decrease.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/android/KMAPro/kMAPro/src/main/res/drawable/textsize_increase.xml b/android/KMAPro/kMAPro/src/main/res/drawable/textsize_increase.xml new file mode 100644 index 00000000000..b51b51139b5 --- /dev/null +++ b/android/KMAPro/kMAPro/src/main/res/drawable/textsize_increase.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/android/KMAPro/kMAPro/src/main/res/layout/text_size_controller.xml b/android/KMAPro/kMAPro/src/main/res/layout/text_size_controller.xml index c250b1bf072..cfd36374deb 100644 --- a/android/KMAPro/kMAPro/src/main/res/layout/text_size_controller.xml +++ b/android/KMAPro/kMAPro/src/main/res/layout/text_size_controller.xml @@ -15,7 +15,7 @@ android:layout_marginStart="5dp" android:layout_marginEnd="5dp" android:contentDescription="@string/ic_text_size_down" - android:src="@drawable/ic_action_decrement" /> + android:src="@drawable/textsize_decrease" /> + android:src="@drawable/textsize_increase" /> From 24daed27f7bf4fe964f8178c7b69a77f08834e93 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Wed, 28 Aug 2024 12:54:42 +0700 Subject: [PATCH 041/127] change(mac): minor comment cleanup Fixes: #2542 --- .../Keyman4MacIM/KMSettingsRepository.m | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m index c4001b5acde..c7d655593aa 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m @@ -18,15 +18,14 @@ NSString *const kUseVerboseLogging = @"KMUseVerboseLogging"; /** - The following constant "KMSavedStoresKey" is left here for documentation - though we have abandoned stores written to UserDefaults with this key because - they used a less-reliable numeric key prior to integration with Keyman Core. - It is replaced by the renamed "KMPersistedOptionsKey" which directly - represents what it is saving. + * The following constant "KMSavedStoresKey" is left here for documentation + * though we have abandoned stores written to UserDefaults with this key because + * they used a less-reliable numeric key prior to integration with Keyman Core. + * It is replaced by the renamed "KMPersistedOptionsKey" which directly + * represents what it is saving. */ NSString *const kKMDeprecatedPersistedOptionsKey = @"KMSavedStoresKey"; -//NSString *const kObsoletePathComponent = @"/Documents/"; NSString *const kObsoletePathComponent = @"/Documents/Keyman-Keyboards"; NSString *const kNewPathComponent = @"/Library/Application Support/keyman.inputmethod.Keyman/"; @@ -152,7 +151,7 @@ - (NSMutableArray *)activeKeyboards { return activeKeyboards; } -/* +/** * returns dictionary of persisted options for the single selected keyboard */ - (NSDictionary *)readOptionsForSelectedKeyboard { @@ -170,7 +169,7 @@ - (NSDictionary *)readOptionsForSelectedKeyboard { return selectedOptionsMap; } -/* +/** * returns dictionary of all persisted options for all keyboards * (options are stored in UserDefaults as a map of maps) */ From 2a6e9507eeaacf5fc8dc7da249fc1e5d33ccb69c Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 28 Aug 2024 14:30:16 +0700 Subject: [PATCH 042/127] docs(core): improve formatting of KMX+ doc --- docs/file-formats/kmx-plus-file-format.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/file-formats/kmx-plus-file-format.md b/docs/file-formats/kmx-plus-file-format.md index 75e1df42950..ddca82a6e1e 100644 --- a/docs/file-formats/kmx-plus-file-format.md +++ b/docs/file-formats/kmx-plus-file-format.md @@ -368,8 +368,8 @@ For each element: Either `to` or `id` must be set, not both. Entries with an `to` field are sorted in a binary codepoint sort on the `to` field, -followed by entries with an `id` field set sorted in a binary codepoint sort on the `id` field. - +followed by entries with an `id` field set sorted in a binary codepoint sort +on the `id` field. ### C7043.2.15 `key2`—Extended keybag @@ -402,7 +402,8 @@ For each key: |28+| 32 | multiTap | list: index into `list` section with multiTap key id list or 0 | |32+| 32 | flicks | int: index into `key2.flicks` subtable | -- `id`: The original string id from XML. This may be 0 to save space (i.e. omit the string id). +- `id`: The original string id from XML. This may be 0 to save space (i.e. + omit the string id). - `flags`: Flags is a 32-bit bitfield defined as below: | Bit position | Meaning | Description | @@ -412,7 +413,8 @@ For each key: - `to`: If `extend` is 0, `to` is a UTF-32LE codepoint. If `extend` is 1, `to` is a 32 bit index into the `strs` table. The string may be zero-length. -- `longPress`, `longPressDefault`, and `multiTap` refer to key ids or lists of key ids in this same `key2.keys` subtable. +- `longPress`, `longPressDefault`, and `multiTap` refer to key ids or lists + of key ids in this same `key2.keys` subtable. #### `key2.flicks` flick list subtable @@ -424,11 +426,14 @@ For each flicks in the flick list: |12+| 32 | flick | int: index into `flick` subtable for first flick element | |16+| 32 | id | str: flick id | -- `id`: The original string id from XML. This may be 0 to save space (i.e. omit the string id). +- `id`: The original string id from XML. This may be 0 to save space (i.e. omit + the string id). Elements are ordered by the string id. -If this section is present, it must have a 'flicks' in the list at position zero with count=0, index=0 and id=0 meaning 'no flicks'. +If this section is present, it must have a 'flicks' in the list at position zero +with count=0, index=0 and id=0 meaning 'no flicks'. + #### `key2.flick` flick element subtable For each flick element: @@ -438,7 +443,8 @@ For each flick element: | 0+| 32 | directions | list: index into `list` section with direction list | | 8+| 32 | keyId | str: id of key | -If this section is present, it must have a 'flick element' at position zero with directions=0, flags=0, and to=0 meaning 'no flick'. +If this section is present, it must have a 'flick element' at position zero with +directions=0, flags=0, and to=0 meaning 'no flick'. There is not a 'null' flick element at the end of each list. From 5b570517b174ce1ffd294629b0249011ba055260 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 28 Aug 2024 16:14:17 +0700 Subject: [PATCH 043/127] fix(linux): display error and abort if fonttools are missing --- linux/keyman-config/keyman_config/__init__.py | 9 +++++++++ linux/keyman-config/km-config | 17 ++++++++++++++++- linux/keyman-config/km-kvk2ldml | 8 +++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/linux/keyman-config/keyman_config/__init__.py b/linux/keyman-config/keyman_config/__init__.py index 2bb3cdbaa25..26fbeddf7dd 100644 --- a/linux/keyman-config/keyman_config/__init__.py +++ b/linux/keyman-config/keyman_config/__init__.py @@ -1,5 +1,6 @@ import atexit import gettext +import importlib import logging import os import pathlib @@ -53,6 +54,14 @@ def initialize_sentry(): SentryErrorHandling().initialize_sentry() +def are_requirements_missing(): + try: + ttLib = importlib.import_module('fontTools.ttLib') + except ImportError: + return True + return False + + class FileCleanup(): """ Allow to register files that will be deleted when the process exits diff --git a/linux/keyman-config/km-config b/linux/keyman-config/km-config index f40ebeebb4b..641fb964706 100755 --- a/linux/keyman-config/km-config +++ b/linux/keyman-config/km-config @@ -9,7 +9,10 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk -from keyman_config import __versionwithtag__, __pkgversion__, add_standard_arguments, initialize_logging, initialize_sentry, verify_dbus_running +from keyman_config import ( + _, __versionwithtag__, __pkgversion__, add_standard_arguments, + are_requirements_missing, initialize_logging, initialize_sentry, + verify_dbus_running) from keyman_config.handle_install import download_and_install_package from keyman_config.ibus_util import verify_ibus_daemon from keyman_config.view_installed import ViewInstalledWindow @@ -42,6 +45,18 @@ if __name__ == '__main__': initialize_sentry() verify_dbus_running() + if are_requirements_missing(): + if args.install or args.url: + logging.error('Missing requirements. Please install python3-fonttools.') + else: + dialog = Gtk.MessageDialog( + None, 0, Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, _("Missing requirements. Please install python3-fonttools.")) + dialog.run() + dialog.destroy() + sys.exit(1) + + logging.info('Keyman version %s %s', __versionwithtag__, __pkgversion__) verify_ibus_daemon(False) diff --git a/linux/keyman-config/km-kvk2ldml b/linux/keyman-config/km-kvk2ldml index 34c4e76fdf5..2ddddc5becc 100755 --- a/linux/keyman-config/km-kvk2ldml +++ b/linux/keyman-config/km-kvk2ldml @@ -5,7 +5,9 @@ import logging import os import sys -from keyman_config import add_standard_arguments, initialize_logging, initialize_sentry, verify_dbus_running +from keyman_config import ( + are_requirements_missing, add_standard_arguments, initialize_logging, + initialize_sentry, verify_dbus_running) from keyman_config.kvk2ldml import parse_kvk_file, print_kvk, convert_ldml, output_ldml @@ -25,6 +27,10 @@ def main(): initialize_sentry() verify_dbus_running() + if are_requirements_missing(): + logging.error('km-kvk2ldml: Missing requirements. Please install python3-fonttools.') + sys.exit(1) + name, ext = os.path.splitext(args.kvkfile) # Check if input file extension is kvk if ext != ".kvk": From ce5c590db2282a7692ed43d42a54b68ddf248adf Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Wed, 28 Aug 2024 21:49:58 +1000 Subject: [PATCH 044/127] feat(windows): update setup form SIL logo --- windows/src/desktop/setup/UfrmRunDesktop.dfm | 975 ++++++++++-------- .../src/desktop/setup/keyman_setup_sil.xcf | Bin 0 -> 36105 bytes 2 files changed, 569 insertions(+), 406 deletions(-) create mode 100644 windows/src/desktop/setup/keyman_setup_sil.xcf diff --git a/windows/src/desktop/setup/UfrmRunDesktop.dfm b/windows/src/desktop/setup/UfrmRunDesktop.dfm index c9872c3b511..c298bf1243f 100644 --- a/windows/src/desktop/setup/UfrmRunDesktop.dfm +++ b/windows/src/desktop/setup/UfrmRunDesktop.dfm @@ -30,412 +30,575 @@ object frmRunDesktop: TfrmRunDesktop AutoSize = True Picture.Data = { 0954506E67496D61676589504E470D0A1A0A0000000D49484452000002BB0000 - 0067080600000000008AFF000000017352474200AECE1CE90000000467414D41 - 0000B18F0BFC6105000000097048597300000D8A00000D8A01FD2DA348000032 - 5A4944415478DAED9D097C54D5D9FF9F3B6B32931D02041209229B828A056BF1 - 558322B5B56EADEBEB025671EFDF0DB10256D00275A9A27D5BADD58A5A972E2A - 2E6D5544032AB24A70615F12CC0209D993C93699F99F27F74EBC33B9F7CEB977 - EECC2433CFD7CFF94466EE3DDBDCE577CE79CEF308DEBBC00F0441104452B2FA - CD29F1AE0291C4AC7CFAAFF1AE029104082476098220921712BB443C21B14BC4 - 0212BB044110490C895D229E90D8256201895D8220882486C42E114F48EC12B1 - 80C42E411044124362978827247689584062972008228921B14BC41312BB442C - 10FC7ED2BA0441100441104462426297200882200882485848EC120441100441 - 10090B895D822008822008226121B14B100441100441242C2476098220088220 - 888485C42E41100441100491B090D825088220088220121612BB044110044110 - 44C2426297200882200882485848EC12044110044110090B895D822008822008 - 226121B14B100441100441242C2476098220088220888485C42E411004411004 - 91B090D825088220088220121612BB04411004411044C2426297200882200882 - 485848EC12044110044110090B895D822008822008226121B14B100441100431 - 8011AE7936A1C49CFFA51B0433F323B14B1004411004318021B1AB0D895D8220 - 08822088010C895D6D48EC1204411004410C6048EC6A43629720088220086200 - 4362571B12BB044110044110031812BBDA90D825088220088218C090D8D586C4 - 2E4110044110C40086C4AE36247609822008822006302476B521B14B10044110 - 04318021B1AB4DD289DDB9AB77CE028B7F76CF3FFCFE524180958F4E3FF6ED78 - D78B2008225A088290CDFE4C65691A4B53583A86A571B24376B154C6D25E96BE - 64690B7EC6DE0F6DF1AE3B4110E121B1AB4D5289DDB91F6F7F813579B6C2570D - 2C15835F58D96D6D7FFB89A2131BE25D573DB01719BEB4FECED209610EDDC6D2 - 65EC37DF65429967B03F2FB23492F3141C50DCCACAAE88675F1144B2C0EE5127 - FB339DA55B59FA99812C9A595ACDD2B32C1593F02588FE0B895D6D9246EC6A08 - DDBE084CF8FA80095F8109DFF1A5F1AE7BD8EAC658EC92D02588FE0BBB3FF125 - 3199A5C5604CE42A81B3BE7F606905BB8F6BE3DD4682208221B1AB4D52885D5D - 42B72FA5AC87565A2DFE171F293AB624DE6D5122966297953591FD798EA51F72 - 9EF2214BB7B132F7C4BB9F0822D19166736F6069094BE95128029F1D0FB2F406 - BBA73BE2DD5E9DFD82038014D9C75E96B6B17634C7BB7E0411292476B54968B1 - 7B67714996D5EF7C0BFC506452960DEC2758D9DFEC7C632576593913D81F3670 - E016BA1B58BA9695B723DE7D4410890EBB3FDDECCF7C29A981C20E07EDEB590A - CCD05A599AC452214BA77016F7164B73D9BDBD3FDEEDE6EC9B41ECCF2B2CFD58 - F6B169665D04116F48EC6A93B062775EF1F6137DDDC20B20C0896AC7D8AC42D3 - A014CB6E6F77B7B3C6E39B64B158F414D1E00761F9EFCF1CBF38DE6D8D85D865 - 658C607FFEC8D2059CA790D0258818C1EE4F1BFB73374BBF5339E43596FEC4D2 - 46764F766AE4930AA2F0BD9CA59F83B6A9123E47EE60F9BD1FEFF673F40F895D - 22A121B1AB4D428ADDB9AB77DCCE44EEA2E16ECBFEA64E5F8ADBEA1B7AB8DD82 - 0F3B18ECB26FC9B0FBB35D0EFBA0B45467A6FCBC5D15D50DF5DD8E2C3D65592C - FEC9F1366F88B6D865F90F657FFE0CFA842EDAE86E8967BF1044B2C0EED15341 - 1473A1E214EFF97B585ACDEE479FCE3C71A6F8621045F42485437076F746966F - 4DBCDBCFD11612BB44424362579B8412BBF77CB2FD02BF4F5884B3B9D9A9F612 - ABB76D58B7603B227477E5D575DB7BC4EEA4A1AE52B7D3511838A7AAAEB1C3E9 - B07565A4A6B86D56AB5072A0A2D623A40EE29DE5EDB608A3E2BD892D9A6297E5 - 9D03E26CD11CCE5330EF1B58196BE3D92704912CB07B3403C4CD63D7847C65CA - EA8A247AD10E78214B39D2C798E7E52CEFAFE2DD7ECE3690D825121A12BBDA0C - 78B18BE60ADD3E6116EB950B41B439EB25DD61DB75DCB0B471D50DCDB0F38807 - 1C0E67606637674866DAA8F223F5D0D025EC28C8700ECE74A7E6E2395DDE6EF8 - F6BB43B5ED56F7A0403E68EE906EB7EC6FF0740CF75B6C43BEEF3D78F1B1E913 - 66C7BB0FA22576A597DC232CDDC25915DCB13D8BE5BF26DE7D4210C902BB4FCF - 02719655BE21CDD47B51E6E161194B3F62E926965EF30F901708895D22D121B1 - ABCD8013BBB8E9CCE2733E20E0A6330D7B5C64689A75B3C7D391E5B4DB5B335D - F6D4EE6E5F4A63AB2763507A5A4D5D53D3D195AD3E6B4E7ADA9E3183538F4A75 - D871B72EECADAC69CF4A733794D6B678BB7CFE144F47A77FFAF811199BF7957B - DC2E57CD91968E7C67AADBC50E6DECB60827CA67758B474DCEEAF2DA67E1FFDB - 6D5D2F161DD81A137FBDD110BB9C9B5DE4E0CBF5972C7D32505E800431D09144 - E802961E0AF9EA2996E699ED31415AE9B988A5570792DF5D12BB44A24362579B - 012776EFF9686791DFE2FF44EDFB3487757757479BA34370148E1DEC5A93E372 - 9C117A4CA3A7ADA3BCBEA522D3ED3AE2F37A3306A7A78EB6DBAC56BBD51A64BB - D0D8DAD6D5D4D6E139DCD279B80B2CC3058B2DADB7E398EE7EF4CC09CBE5C77F - 943F15EB5524FDB3C466F74E8F85E0355BEC726C76090585EE5D2CBD45429720 - 6207BB57713617378E5E1DF2D54C762BAE8A77FDFA0B2476894447AFD8C561F2 - 4985B970C6F83C38664806DE235076A419B61DAC852F4B8FC0E1A6BE6359AB45 - 00FC2F800FFCE0F305176B67324A0891A95D5E3C521F492F7691B91FEF409139 - 9BA5A00D662874270C71175A2D164793A7DDE372DA7B34AC1965767577FBBE39 - 585D357C50567963ABA763FE69138344F4EAFC29CBFD20DC1E725AC98CF24D93 - A3DD1F668A5D49E8E212E552E0F3D3D90C262E694AE58F66E97FA4846D92F7E1 - 5610ED82D749E96BADDDE5898CD457E80E0E4D787083128683C599B73A107F6B - 742FF51F08B3033F244F7CC0E4B33413C4FE1F0FDFBBA3C2410DFA4BDE04A2FF - E40D036976CF0CA4150FEC6BDCAC795248DF7C0B629FA37782ADAC6FBC31A80F - 9A5FBDCAD20CD9C75FB374292B7F67BCFBABBF4062974874F488DD1F8D190A4F - 5D350D4E1A99DB4798223EF62ABFFF8DCDB0ECDDADBD9FA5D8ADF0F5D24BA030 - F77B59F0EABABD30EBD9E0B9C7B50BCE87696386067D36F4B697A1B6A55D577B - 48EC4AA03983CDE7B88309CC3B4012BDE307A79664B99CBDA60D0D2D1EA86E6A - 3D929F9399ED4A7158CD28B7AEC5537AB0AEA9E8B7674E2E0B7CF651C1D42236 - 6C519C6D16C0BFE2ACF2CDD746B32FCC12BB92D0B982A56720C64257DA647325 - 4B3783F2CE6F35F077789EA51759150EAAE43D0A44D74B3CFE816F62F9FCD960 - 1BD06DD3132CDDC87138CE9CA3107D1DC2FF6E1F60DF042257B1727005E24C10 - 07245339CA42F183B6966FAA2D6B4B79E2000E67E879A36E61DF3FC9D2B32CDF - 56837DE6607FD0AD1DDEB728DCF1B747C18ED783DCE72B3E7571D77F254B9FB1 - 849E3EB6EB1DE8B0F2F01AFB1BC7A1BF61793F243B4F699356447D6E062AF73E - 89B81048EC12890EAFD8BDE0A44278FD96B3C069D7964437BEF029FCA5F8FBBD - AD2876BF5D76298C9289DD57D6ED81ABFF1C2C7D3E5B78411FB19B7BEB4B2476 - 2325207A339CB673321C82B3BDCB6BF7777B0795D7B7B81CAE8C8C805785B139 - 293B5ADBDB87170CCECA345A161BED7898783DF59231237A5D8D952E5E9EB56D - D5E77BDCA5A583D5CE8BB6E03543EC4A42F732109744795EE62874EF0451641A - 9EC192221BFD82A5DFB0342E826EC0D9CC47B1FEA1119158197857A370B98F23 - 9F9741749BA63BAA928EDFA10AC4D9D846CEE37BC5AE6433896DE1DD3428E79F - 2CDD191AB699E5390CC4885BBF34902782B3BCB7F3CE24B2F2B241141DE8C715 - 3757F15C6F4AE06F8E8398BFB254C2E35ACB88D865E7E00C2EDAC09E6AA08E78 - 3DA1EDEC21836D0CD79E012B76A5670EBE158B583A0D8267CA119C25C76B0A07 - 371FB1F49D5EF769B2B248EC2A20DD8BD358FA2988034D1C74A29A09041FC141 - 1B3E7FD6B37EAA8E777D097578C4EEB0CC54D8F1F0659099EA089BDF49BF7903 - 4ACABE8F0C4E62378A7816E4BD037E388F35FB73BF5F78CB39F607DB6CD7BEF7 - 91DAF18F7CF6D573992ED7150D9EF63AAF5F68AEEBF01504EC6CD11599A5CB93 - 376AE8A04136ABC5A6B72EAC979AC0EF3B432E74918F27CE5CED1F9493EFDDB7 - 6FACD638299A82D724B18BB37A2F82B613F900F8204421F04484421745167A7B - B8DA681E0ABCC7D25DA1E1895576AC2B81E75D6CC4A5920E21D523A8591A0E3A - C42E88A14E71E6F89208FA0723FFA16FD4C3529D7167FDD31C750887A69B2B69 - E61867D67125003738991DCAF625961E60E5976A1DA447ECB2F45B1067BB71A5 - 23928158509F9B096B0F5E4328E28A42BE3AA3BFBAFF33B88A807C0AE24AC27B - 5AB3E53A575878095D5DC181CF6721C7E08AD09D6699F6A89411B4E2C0D1E6FF - 61C77FAE707C2188D738FA51E65DC543F31C1CF4AD333AE820A2078FD8FDDDA5 - 27C3BC73FBEEEB6FEDE8823D879AC0EBF3C1886C3764B91C9075D30AE8EAFEFE - 6726B11B253CF3F37049BA00FFDF923964A7FFE893C1969D3BBEBDA6A6BAABA5 - 7169CE9C7F3CA976EE931B77FCCEE570DC989DE6CADA515E7DA8C96F73DB05A1 - 657CAE3BA5B9ADA36568567A819EBAB01EDAD6ED152EBC7CFCB052F9E7ABF3A7 - BCE00761366F3E4CF03EC904EF1D66F755A462979D7F3AFBF32CF0BFD07FCDD2 - EF2314BA58169A1F18992D0B479FA016D20C06967711C7F9D7B3739FD7D91E9C - A146E1FEFF78F3D7F1BBE18B16CD1E70F69537B08716FFC7D23C964E06FE010E - 0FAAA24E3203C072679B5496123D11BDB0BFD4CC6A748ADDB526F60F462F9B67 - D4DC430DD61E5CA97A0E44D12207AF9727FADB8651565FB401C715183D223714 - 1CD0DECF9AA618CC87C46E104162573A0EEF91B9607C45856B6049C496706217 - 378E6D79F0E730313FF8675FB7E7305CF4E4074C8C76F41E37B970106CD85B1D - B4A98CC46E1468BB2FEF36BFD0E3241DACC7CF28B60C2E280A3DA6ABB9A9ADA3 - F6C8CBD9D7BFAEFA407BF4F3AFAE670395BB2A5A7D13C6E5BA0FEEA8ACCF9D7A - F4D0C39EF6CE82DCCC34EBB60315AD8DDD36F7292307B73478DABA8664A66587 - 64D1C8BA7CF9C5C70C5F149AF7FAABE6BDEEA9AF3BC55352323245E0FF4D9838 - BEF6ECF28D2BCCECAF48C42E3B17ED245F003E7B56045D913D1E891DA281328D - D067A691958B66178F739CBB82A5DBF4081396370A22DC28342DCCA1BDBF81CE - DFED3B884C20C8C1591A147CB8746996D00D802FD2A79444166BEF75200AB368 - A2E95F5687D8C5592C7C1E98758D629F63B095D7CD6CAC86890E5E3357F49770 - DDD26C2E9A2BA1D035E39A4313965FB1F47AE82C2389DD207AC5AE14F23DD295 - A100789F6164BE376896B77F104EECA6A5D861D72397415EA62BE8F3E9CBDE85 - 353BABC2E64F62D76C168F70793A7C3D22C37ECACFD7812B53533C74B7B77B3B - 6AABD7648E1C7331143DA0E8E6EBCEE29D85369F6F36CEC21E3B38A5B3ACBA6E - 48E1D0412D95758DCE4EB0D53577C1D8F1B9A9DFE4B85327E2F13EBFBFC222C0 - 73365BE7F20B0B0BFBE4B9F186074ADA1B1A0A3A76ED6EB2646576E68C19E76D - F7768EAE5DB5CAC9237CCD16BC46C5AE01D1891BA29646323B6520F47024E00C - C4AF587D9BA4B28F03D16E754298F350205CC2CEFB5647BBCE077166331CBDFE - 4F75FC6E03091C64A0C83AA0D047BCFD6F461D144D2A7488DD68F00E4B73CCB6 - 7D646D42DBE73714BEC2EBF1D6501BED58C3E1E10585EBBF411C60544A9FA188 - 3F16C48D9867A99C870308B45D7F552EB848EC06D12376D9F763405C5999A950 - 14F63F7AB6D9C852A7D4F7F84CC2F782D6C004FB1F273F9E8985E711421B2EB1 - FB3013BB59C16277C6C3FF868FB7877F4490D83519CFFCE11FB2669E0D29EEC3 - F66997E2D2671ACF797E5FB7BFBDA6669BB7BDFDBE9CEB5E7D5FEDB85BDEDD74 - 43BA3BF5948943D37F9AEA74F4FC221B761F6CB0B932BF1D3728A52CDDE5FCE7 - 2F46E7AD543A1737A3D555377F9199331897E2A072EFDE4ECFA76B1DEEDCDC5D - D63163BD5D020C3EF2D9A7433384F0A186CD14BC46C4AE34CAC7CD68BCA233E2 - 6558E9A58726100F19CDC300BD338D464C0D38DB85D6FEE893F84E8EC32F60F9 - BE239D97886217B98AB5F195D00F6364CA10405178C459ECA238B888D569B599 - 99B236E58138B09BA1F035BA89C37BE08B78983484F1F082836E5CC17B393020 - 55C9033797E1E6497C76842EBDF7993197EE479C453E4A761C8AC14B2178A085 - D359683F5FC7D114DC4CFA37564E8B54C68011BB2CED85BE130CD86FB88701CD - D7362889556936BE10442F247340D9ECC1948DCA44E48413BBE823F7D385E7C3 - 29A38385E86A26742F58FE01783AB47F3E12BB26D271DF8899DD820F47D0609D - 34BDD8925B5864249FF62335FBBDEDADCF64CF7EF551B86F64362C2BAB8FB46E - 9B6E5C7C434666E6C336A7334BFEF986E79F832192C787A13FFEF1BA0307CBA6 - D976EC0007C46E8657AFD8650967ABF5CCAE9A626F28D906E34B298FF314DC69 - BF42AA37DE89289671B6011FBCBC4BFAA1B3D96AB360A160B95CA60C1A9B8442 - C1CD95D7B03CABA4F31255ECE24BF7D74A6EC16264CA80280ACB388B5D04DD91 - A1BD69B79999B2765D0EA27051DB6C8462184D08B6C772D95963E32B0AADB9AC - 2EFB75E4A5E615437373A474AEA9DE180690D83D87255C75927B6F41EF2968F6 - B2957700246D68C399F92B14BEC6E7190E703F36A3DD84317836A8CD3E6D2CFC - F5FAA23E9F6F3A5003B39F2D861D95EA5289C4AE592C166C9E8E615D817FDA4F - BBA204EC292746926567637DB5B7A9FEADCC6B5FBFC9681E6BAFBA77566676D6 - 436959597D36B5757576C2972FBFD42B76475C76D98E92E24F46E71EAE0EEFD7 - 438209DEC94CF096F01EAF844EB18B4211BD42DCCC99FD5F40142E3CB31F5A75 - 44BFA9388B730DC7E1F8F2C10D36FF557A314B330E3F0171669AC7FEAF77B34E - 98593039DCA60C2CCFB3417C8184E37E9696045E3006C52E8A38140F3868D80D - 18C4469C7D3997250C6A6274D309123AB81802E2CB125FA07ABC11E092F4D5AC - 997D9E9C614C19D0D55493547EC0E70D3E5931A8089EA7D7D6B38FE8362876F1 - DA7F526A57A9F4592118EBF37F81B86AD0A8B30E9A48B3E6B86A11CE251D7A34 - C0DF197D3C1B76E5C55927F4B6F29CD44F727036F56E56768D813CD596E37B36 - 5DAA09CD2416BB78CDCAFB1F9FC10B0CBA56C49531F4A0B154E16BB40BBE8A36 - ADC50F1EB18B9BCF3EB9EFBC3E6214C199DDE51F7E0D0FADFC123ABC7DC7E224 - 764DC2333F0F6FC2DB02FF8E64663708D6BEF623D5ADA9B9C316DB042672CE5A - C2E5FE67E39C0716399CCE39E9D9D9C3B58E3BB0ADA4213523C3DF527AA02E6F - F20F5277BDF9AFE1D91C660C321A98E09D1E89E0D5E9DF15FD7DEA89EA8662F7 - 4E136675795D7F696E300AC913EDF950B8849B29EE9D5195965517009F294558 - 53066983D003200A592D7A7CEBB2FC36CACED52B7671060B37E56C56D90086E6 - 3528CA6672E61700FB1C5DA1A90D2EF4BA88D37271173065C065669C75459323 - 5CCD29D75A0695063868C3899B6278064C483188769695B27CF48A5D45DFC4B2 - FC8E0671B6F15CCEFCD043C8E52CBFBD3AEAC085E48319CD69E6709E82BFCF9B - 523F61BDEACC327590EE3334175A1EF255C46ED8241188C2553EF8D134114962 - B12B079F0D0B4C3045530B258FF6BB8F98BD6A41F0C11B54A220270D56DD7B2E - 8C1DA61C720067792F7EEA43F8AE2EF83221B16B02EDF7E715F9BA8323905986 - 1DBDDE7AEC19A718CD53CEA18FDEED1876D6CFEC4C5456B29BF571FB8C254F28 - 1D57BAF899C2C6BAFA67535DEE33AC36BBE6EC6C6D4545D3A15D3BBB5CDDDE7A - D7D061AD35BB761664E70DAFA8DFBD7B925B87770689069BDD3BAAE8C0D606BD - 272231580E4737558F1B7D88E9B49545FBB0E7785EBA3A6D80E5B6B2E8720BED - B2C389E41510C69481E585C14470A6EA9C3079F599D1D3F9BB710D02589EC783 - 38EBCBBB098C2B0A9E64E38DED9CCE91A7A6AF626976EEB0969DA6463DF0379F - 05E28B9DC73F6890BF599D62179F495787DBE0A573A3675443F94AA207C5C83C - CEFE9183A20FC522CEFAAE539A99D7510FA5A885A62C776B08E9DECD9F0AE724 - BBD8C541DB8D91FCA6B2B2DC5259A1832ADD1B7B09F3D0132E78707A0ABC7CE3 - 74387B623E5814F4CAAEAA0698F6E0DB50EFF9FE5622B16B02729FBABD1573BA - 0ED94EBD6C9819F91F2AFED03BE4B8B19F7D3F532C3CCB046FD04301379F7575 - D9BFB30816AE0D715FAD5DD3993F6AD4A1CA55AB8E32206E95B87346F9A6E546 - 4E8C81D8E59E6D55A91FAF5BAE209B56CEBC794301F72E69EBD82815F6E12DBD - 90FE0BE185459F59629DBF9BEA8B3C244FDE99E60038DB7E1DCF4B50A7BDADA2 - 337B3390064FE873F86E8EC3F1BA7D4976AE1EB1FB0B76EE9B9C75E2756B17D5 - BE91EA820F245CBD590CC6DDD5E12008852FDA0117EB117052F9D74BE7CAF93D - 88338B11874F56197CA9DEAF492E76B15F2E37122847A36E6A83EA7EE9DF3919 - D0237611DCB076E5B431F087AB4F85F4147B9FEF577CBA1BAE7BAEB8D7D72E89 - DD08699F3F7CA10FFC8A3373669932547DF2210C9D3836282FBF0D26388A96F6 - CEAEECBDFF992201FC9FE8CDBBEE5095AFDDD3D25EF9F917D6415EAFD3702505 - 583CE3BB4D8B0C9D1A9B8D4E866DB274B8E5BA89E5FF679D79F386024621FDBF - 013B411DC24DD59441874984E24B58E7EF36939DBF8AB34F702320EFC084BBCF - 2533897F801856341CD11674BCB3F341E24087D82D8610138830F5C1973FCEDE - 8F8977DFC8EA14885A87A62F574490150E76D1CC6C45C0F556987295025DF431 - E389B06D6AF79EE2F59CE462D774F3028D4135F7E0993017BD6237009A33BC7D - C78F615C5ED0DE7B6869EF82D1735F839A6651A492D88D80B68523A6F97D3ECD - 87BE75E8D15F76A60C72415A768AD5959E6D4FCFC8E4CD3F008ADD21E347ADB1 - E68D3923F0995FF0CF779CB56C59E0DF7B16FCE9448B45D86AB42D8DB5B5B07F - F5AAA6F4564F86D54806024C6762B7D8D0A9B1DBD56FC82B03AB1F0AD1A5610E - 8B244C2FCF06317CD99E1788AAA6634658F505A6232A9BE2ACAC19619E55FAE3 - 1810675D7EC07138B7F092DA8BB3693CF6A9D116BBB920AE1684DB6888D72C6E - 866A97CEE315BBBA848B8A988A4BDFA8D40F371B5E08A2FBADB30C6683D7DF83 - 200612D00AD78BD7DDBB103C10E909916D64639446394AAB2A41BFB7ECD86415 - BB51332D501970063D6789D86154EC226398E0FD7AC925E0B005EF37BAE24FAB - E1EF1BF6F5FC3F89DD08E8F5A9AB03EBB853FF6B1931F6277ACEA9DBF625A45A - DABF4D9D34EDB8DE0FFDFE75F6B39705B9B0D97DDF1F0E5B6DB62146DBF3CD9A - 4F1A1C35D55DF6E6D65C9DA7AE9951BEA9C868B9317661859B945ED1E1B286D7 - C1BBEA0E7E8E3278671CE576BBBCCBFD5A9BAD945EEA4A282E87EB0C177C25CF - AC9A942FAFF0D22BA2F538EB0F2BE824FB5BBC27A7B0846EA5C68238332ADF78 - 8403D01AA9AEB889139DDF978328707884779000D1132E584954C4AA6FA28934 - 68990AA2AB3CB435D7B36115414179BF9A8716953EBE8B1DFF44D89CF5B543C9 - E55FD00A8EECD86415BBA6D629A44CB550D541A643446C8844ECA249C3C6453F - 87C92307057DBEF08D4DB0F41D710E90C4AE41DAE6E7CD63253F6CE45CEBC917 - 6EB5A465733FA05BCB0F42FBC19DF583A6CD0C0A076CCF2E74C00F6EE87577B6 - 77C19F5E162CC25546DBB4E59FAFB7E4B478D26C191915DEDC5C0FECDB177649 - 5300FF36ABBDBBC8E8E6B49E3C622B767149F34A1DB381BCC20B67089E063182 - 8F5EF0A18B4B9A53C31C17F4C2D5E121422D48028F9D6631A82C8727ABD865F9 - A0B37FDC6486A6244642C7E23588261D682F786A986349EC86AF3BDE3F183D12 - 852F0E1E789EAD8A5E1524F38207A42487DB0C4747BD3114147A18B85EF6B1E2 - 06C02416BBBA4DC374D44FEDB7D675EF10E61089D8B531B1BB6DC925306178B0 - 29C3DDAFAD8727DE17175B49EC1AC0B370F814F0F937193DDF7ECACFD7822BF3 - 743DE794BFF152C7E0A93FDADDD9D631C2027E8FBFABA3C1D2EDDD9875F7C7D7 - 058ED977FFD3B8CCF796913AEDFE720B7496944060B35A46D1F45DEDDECEACE6 - 3D7BBD368FC76E6D6E569A316EF4835014433FBB4AE04B0B378EA0494738E120 - 3F87CB7D90CE25F568136ABFC96B86D0E725A631AB110A96B758C95E2ED9C4AE - B43110BD6D2C84C8FC01EB81C4AE0E240193CF12065FC167A3D66A491FB32695 - 7E306CA2C4515725B1A574ED25ABD88DB63991D2FD14B5D964421DE72F9FF787 - 5587020485BBB25A2C302C33156E3C7302CCFD49DFD7D0E94BDE81CF761FEAF9 - FF48C46EC11DAF405D6B07F0EA4D3CAAFDF9EB1240EC2EC87B87B5E63CA3E71B - 0938D1527600BA0E95D5A53ABCD5FE6EBF0DEA2B8EB158FC8BD396552D921FC7 - 04AFEE0E69AAAB85C6AACA8ACAF51B4604024C205E87A33975E2C4CA8C11C3D3 - 2BB77C09CECA4AB9CF5E53842E1281D8453B5774ADB54723D2911A5C3BABFB59 - 94B03EF67CAC7EF8727826CC797D5E8A9C1B92D03EF1271A339C492376D9B9F8 - F4C34D4E97F094652224760D22B509BD39A06F63B55593A0550F9D76DDD1023D - 0FFC3DA42DC92876A3EAE64E2A576933ACE9F6D944781A5A3BF9B48B10FCBF28 - 621DB6BE3B8DCA6A5BE0D85FFF03DA3A45F7E79188DDE6B62EF0813E6995E572 - 0C6CB1DB367FF81D7E88CC762B92E86ADD6D6D50FDC13F61704637FED2EFBA96 - 549D2FFF7EE7BCE5ABED4EE7997AF23C54560A759B36D4399B5B73E4E6DD68A2 - C004ED0996C1B9FBBD9D6D2E4B53CB30DB8993F779F7EFF5FBC64E583873E51F - FFAEA71C350C0ACAA0109B619C852BC1EB9FB53F895DA5195AAD885E72425FEA - 3C2259736772B2885D4900A1D0BD92A71C9321B11B2152B00AEC0BA5E86C6803 - 3F87B5A75A3A56CF46BD68D1C7EC2849C5AEE1F64558475DCF2BC21CD85BD854 - 3177CB8B9FC1331F6FEFFD772462D7088200035BEC7AE6E77D03E2A614C3D87F - 78D13A706785F3D9DA075F571734EDDDE9B1946D71A53A7ADADD068277B46B49 - 4DAF5FD7FD0B9FBEC32F806E31EE696E064F636353D5964D5D6975F5BD56DED9 - A79FB1A17CEBE6B1EEE6D66C183CB8CCDFD4946DE9E8987556C5E69566F5A9C1 - 485C7D62C94BA2041FD8BCB36FF830BD224C4CFAFE2E7679035EF49EABC34FAF - E6A69C6410BB1A01006205895D13D008471C14B98CC42E895D20B11B17CC12BB - DD3E3F2CFFE06B98F7FAFAA00C49ECEA84895D9C01D0EBAD2008EB0FCE5D6BC9 - 1CA268B38B6EC6864D1CF337217754EF46B3B6C395DECE9A4375C2E13DA9A982 - 27643392FF3CD7D243EF05FE8551D4BABDFE0346EB86B6BBFE6D25E0907EA7C2 - 59B33D5B3FFEC89AD6D0D024389C1DD6DABAFBCF2EDFB8C2CC3ED5292851E8A2 - EFD86F54F2D2130D0AD1B4DFD51150221628BE8C38FD00F7BE3838FB9B272045 - 32885D5E176F0170961DCD69D01F6B6D207CB15436B60BBD36A09D342E93F3D8 - FD92D83509D6C64210FB2ED4B67F3E6BCF32E918255B7614C468AE152B1BCE3F - B1FA04DDCF2476A3834A1DF1F7BF9D95EB8956B9445F2215BB1DDE6EF8B6BC1E - 16BDB519FEBDED20844A4312BB3AF1CC1FCE6E04FF758633B0D85BADD32EA9B1 - 389C85F28FBDAD2DD0DDD1D164B1D9D2EC1999BDD604351B3E6D7337ED4BB55B - 95DBC93E7DC4BDB4EA5EF9673BE73DB9DFEE748C523ABEB6AA0A8EECDC593168 - E4C8D6ECA38E1A8533BAE9D9D9F6B21DDFB6A7BADC4D75E5E516FBEEDD83B102 - 1687A369E4955765E0795B56BED99477C2092F9EF6B7C77842E6EA4287680A1B - AE539A894307F4B844CF1B6E1443F6FE9EE5EB55C8AF3FD8F005507B51A0EB30 - 749513CE676BCF8C11A7605A01E1430D2783D8E50DDE8175B803DBCA192A1AC3 - 34A3FFE270C11248EC9A84462007F9AA87523FC4DDF76A928A5D8436A8250977 - BFB63E48EE86D3BE81A7ACB7DB07E5F5ADB0B5EC0854D4B582D7A77C9ECD6A81 - 7B7E7A3CE4B8BF8F9DF565692DBCB67E6FD071B7CE380E0A077305A2D564EE4F - 4F18D862B7737EDEB15E515818DA9D6F3F6146310C2A280AFDBCED5015F83ADA - EADD238FEE712FD6D9500F0DEB3EE8CC4E697384C9F22BD7D2AA20B1B1F3DEE5 - 7FB63B9C37281D8C33B7F66DDB823E4B2938EA2BA1706476EDDAB5052E59E8E0 - F471E3360E9E76EAC93D79AEFFE2837357BD744E34FAD4ECE0043AC3B1223873 - 7375E86C8A94570A889BD96E099387A27FCC5820BDC4EF94EAA9053EC417487D - 134ED4840D359BE86297A52DC0F7DBAB5E3F26D485C4AE89A8AC8204F9C866C7 - A0EFEA07438EE9F5711DA77A27ABD855749B68162A0183C8F5581C88C4F5587F - 24215C8F219EFB865DCF8A9F0542CF4B910BEBD0C22D96E3A6AB8AE483EFFCB3 - E5A8F32FE9195234EEDA01B07F03B89CE1DB27586CF9A9BFFDAE22F06FADD0C1 - DB3E2DEECED8BBBFCFD6C594DCDC5DED0505C3DD3983EC7EAFB7E5F0E68DB6CC - CE2E61E879E7D7B7B4B6B4FDF0B9878E8D565F46231297B47B1E1FDE17705643 - D10E58CA8B67335790ED5FACE10C3F8BFD87A1377F03DACBF2D81768CBAC690E - 9304627727673D74871825B11B1F786C3455FA1805F012DE603451A8772CC4AE - A9CBF72AFDA857ECE267BF66E718F15F1EAE7EB8F2F74710030DC989AAC02694 - 21B1AB4D5C23A8216DF70DFF85DFE29FC5E38A2C9C1786FA6FBE82ECF1133683 - CD3EE5D0DA8F21ABB30CAC9670B962270817A72EAB7C43FED9DEF9FFE711ACD6 - D4D063BFFCCFBF5BB20F1FEE33478F260BCE3163F7B70B9069B73B5B3CF547D2 - 2D757529BEC6E64FCEA9D8F4BFD1ECC328869DD5EB8E0C67EC7FC5F26F0AC947 - 29ACA7128A617563818E4D67FF61E9A7618E41FBC5FBC3C5A24F02B17B84B37D - 8B41F445CCFD30D278D1864262D74454445EE8CCAE526441DD031A93EB1D0BB1 - 6BDAEA94DE800D1AD71FD7C0DB601D953CD9C4DD64255921B1AB4DDCC56E8096 - F97967B096A11761D59797FDE40B3E83B41CD599E0E6FD7BC19D7FD4115F6767 - 4ED5076F5A86656B6A8D5E5817BCE45E56354BFED9F6BB1E7BCF62B79FDBD6D2 - 0C1939DF87D02B595BEC4BDDB7CFE250B09D7616147CDDED74DAB2274ECC49CB - CE195A535EBEEF9417961C13EDBE8BA2D8C5466274A2677554A78FFDAE8EE00D - BA97B343EA8BA21C9DE0BFAF643FCC713E3AD27F43EF790A6DE09AA126B1DB8B - EE654F1D7D97F06257721BE86679369A95A746594A660CA17DACB6492D9E2B37 - 668B5DA5EBCFB4E0191ACF4CBD6217415BF8A7CC9C55D730FD8AEBA0269921B1 - AB4DBF11BB019AE60D1963B5D96E13C08FE23353FE9D75D2F4624B6E61916AE7 - 78BD20D86C3D33BC50B615D2527DBCC5D6BB965605EDEC5E957FF26C4766DA43 - 2D6D1D59479D7AEA662664A759AD36475767276CFBCF7B2D83EA1B342DB0D1C7 - EEE8395715153E7087E130C0BC444BEC4A79ABB91C520343B9626CF435B23CF4 - 8866ACE3CDECFC2F74D411F3FF1188EEADC6B3F45B969ED43B436CC0738012EF - 8328D88F709447625744D752AB4E7766092D76651B4AE7B2F42B96D645CB5440 - 63835A9F9979958D892B20CCA6CD681105B18B1E85D0CB4CE8A6565396F03542 - 991B11BBA67B65D0F0CCA1E96E91881E2476B5E9776237C0E17B86B9D36CC26D - ECF17A3348CBE8E1C46E7BF561E8A82E6F80EFBECE425B5DCBD153FED301CE51 - 9DDBBF98E04ED116BE16104E4F595AF969E0DFC5A3266779BB6CBDA3538BC3D1 - 9872FCA483D963C68DAAADACB4A7656494EF7967E5E86CA1AF9D040A5DABBDBB - A8E8C0D6A80BDD9EF2A22876A5FCF5BA23C3A533147C7B64791482F2C35109AC - 1F6E70798323421B2E95DE0EA21897BF183038C6523D517C585E688B8DCB86F7 - EBE99F107053DF139C1E05125DECF2DAEC46D3BC26D1C5AEBC2F70A08936E5FF - 30B2B2C151D608103DAB4C0FF9AACFE633958123DE8B37B0635F37B14EB899D6 - 1ACE4E360A6257EDF75634E5D299B75BCA7B8EC2D746C42ED227B47304F5C395 - 041CE0CC0FF92AEAAECE087548EC6AD36FC5AE9CD6F9C3AF6602F23626763D6A - 62B7B5E23B68DFFA3164B87A82D235D94FBFB256B03946D56EDD0CA935DF80DD - 16C60D07C063EEA555F7C83F5B9D3FA50423A0F5E934267C3B9DF64E4B736B6E - E84EB5580BDD9E32A32C76A5326682181E97D71D59D0C3559A1542A1F1B28E62 - 31DC250A135CFA2C957D8EEEDCD0761B97F8B4FCAD625977EBB1A1D3615FAC84 - 2E7BB52410BB5FEA38FE2F20CEEED669948FC206039EE0CC3DAF1D79C28A5D8D - 41E8632C3D62A667138D088BEB40B4532D0B395E6DF65DD3CFB7CE3AE1F57017 - 8803E85B43EB1072AC9A0BC433D8796B0D96AFB4F1362241CFE1FAD1A8D84550 - 9C3E1EC99E8830F5C3FC1F09B75781880E2476B51910623740FBAB973D68C939 - EA56C1660F12371DB547A069DBBA962CA8ED312DB08E995262299874A2B7B515 - 6A56BD2186060ED71102EC4A5D52355EFED9470553173115FC40D893BFA7D1DB - 6D3BF19CAA2F4A63D92F3112BB7AC30923E8BEEDB9C02CA701930833C0CD339A - 2FC29076F2DA172BB102742CD326BAD895FCECF278E208B009447184EDADC3EB - 46BAEEF259C2194C5C1A3F8D33AF0009297659792EA9AFE6A81C827D89E2E3E3 - 40608E08CAC2E52BDC648B03586E81232DF563FF87DE4B110B5E8510C6D89FD7 - A95DCB1ABF0FF74A8C429E6AA1C60DB54F1292386BFE57501FCCE915BB380097 - 6F14C419D9478DCCF04AD7C1E52086FE0E9D6040EF45B89A57A1375FC21C48EC - 6A33A0C46E0FC58B535A8E1CBA57B05A6F76A4670C6DDCBD03FC7B37803B456A - 476AD676FB8F2E3A16430357AFF9B0335BA8765838BBACBBDB323EFDE18ADE87 - E5AAFC934F14C0BF95B3668D7E108ACE2EDF5812EB2E8985D895CAD1EB8E4CC9 - 7E57AF4984193C09E2AC613B673B79032184822FB8E7790F4E12B1AB26086245 - 428A5DA94C1493B84148CB23055E3B8FB2B4C6E0A64D1CA0E2EC29AE7A850A5D - 6C03DAA8966A9C3F05C415A150F186D7DC4296DED423C625C185AB06E8DB35D4 - 246A9D549F032AE72AF9840D1BF25CA32E6ACBF9817C6F054E1B6A69961A0714 - 382B1F109238500F9D89D62B762F656956483E1831142771B6F28A7CE95AC381 - 41A8B918D2E7394FC41E12BBDA0C3CB12BE3D06F4FBDB7BDA2ECD221D9DD7823 - 16F47C6873001CF3A30DAD7BB78F4DEDAAC9E615BA3D9DC11EE8A94BAB1E937F - F651FED45208BF641A37A1DB53EF18895DA9ACE3D91F5CA2E3152F7DC209B33C - 2682282663217835C319ABB4D18840D3EDE22749C4AE1976D09190B06257562E - 0A10EC632DD31BB949D0D75A9B01A519461CD8A237055C9D99A4701897C091F2 - C299DDC741F939FA96D46F5F688971960D06073A596AAB52D43CAC0FEEEF785F - 4DC0699828E12C380AB9CF4385B7AC2FD08CEBDD502F03ECEB31209A47283DCB - D0A401AF3F749157A6542FA95DA783B8C1507EBFE22C3ADA41BF1F728AEE086A - 2C619B9E86E0E70CD6ED5FD2393B54A25F62DBF3A5FEBE45E5F7C37C6E62E9B5 - 78F950264406AAD8C5ABECD21F8E86821C37941D69817F6DDCDF13FB8DC4AE12 - 8B8F73B4B6D5DE2C58045CD23BCE6836AC273E752FAD3A5DFED9AAFC9357489E - 2134CE1326C74BE8223116BB46C209A3FFDA79F2C84292A0C41701CF8635A3E8 - B6D995EA86B32C686EA127B4B36E1FC1C92076A5F3F4AE08F08075CF82F003D1 - 8416BB52D9784FA26F5B346BE0BD9F70C50A7F7714C10113041C98A0B09DCCD2 - 388D7375091C0EC18BA0582D6669A3542FAC13CE2AE373026787D13B819A6DFE - 2EA93E6BB4EA239928E1F57089469FA0179883D2BF8F02D1CB0BF687E23DA8E3 - 79B84BCA7BA7F4EF74A95D5315DAD533406709DD569A122E987D8FEF35F486A3 - F4BBA29DFC3AA9EF7110A4E73AC059ED67A2B12192D0C74015BBF94CE4CE9C98 - 0F3327E5C3EA6F2BE0D52FF6426B8797C46E38DA17E45DE3F3FB6F604D3324A2 - BAFC8E9CCC6565BDA3F7D523A65CE81784B7D48E6742F75A267457C4B3CDB114 - BB5279F8604531781BE7298A2F4769696C11986FC38BE5E1D2EDE346771FB3BA - 9DCDFE7CA8E39499ACAC553ACB480AB12B9D6BA6F90A0E6270397A39471B135E - ECCAEA80E2106762D13B09EF063EBDE0B5827E5B3FD0190444EE1E70AA89F5C1 - 25F97B585576F21C2CCDEEBE62A07F54EF41C99C012744F0F737B2B1550E3E73 - D0EE7F8F49E182E583CE93401C949B31C160C80C85881E0355ECA6A5D8E1CE1F - 4F82D223CD307A48062C7D772B747A7D247679F12CC83B177C7033087D6C9E34 - B108302B6549D54B817F87BA2093D31F842E126BB12B95A9E686480DB489BB3C - D4E1BA6483772688E2C58C97E07B525EEB235956935C9AE1753083E3708C9C74 - 0D2BAE4A6719492376A5F3474AE71BD9FC87E020066D247189D7C5D9C6A411BB - B2BAE0EF3F1B44BFBB668A5EBC1F1ED0B2D1E5A89B96EDA71E703612BD723CAB - 67402B89EECB40342DC8E13D0FC2DC8352BE782DA2981FA7235F39785D2F0AAC - 44992D76A5E3CC986088F83A20CC67A08A5DC4EDB4C3B1C3B3607B6503B47674 - F57C466257279E85C3A7F87DBE3B04E879C9F1F4C8DBAE25872E947FF451C1D4 - 954CD9062DC1F617A1DB53E538885DA95CBDE18455ED6725D30114CEF8B0C625 - 4B3D2F42144138FB8ECB741BCC5852D38810A404DAA32ED12BAE934DEC4A79E0 - EFFC3396EE05FEC14DC0BE10C5CD01C94B036F1B934EEC86D40967D2AF01D184 - 448FB80B80A21207B5D88F3BCDB2CB64754313019C0DC5CDA07A04399A5DE07D - FE1AEFFDA05036DEDBB8448F03A79F719C82D71F3EE7EE6365B684C91BC5245E - 03F8ECE0ED6FBCBF1F06D10CC327CBCB74B11BD27E9C99E51D78069EB168AEB1 - 816673FB1FC2357F492831E77F690E895D23B42D1C51E0F3F9E7B206DF080238 - 350EDDEB5A5A3546FE818229C39D33CA37F1446F220C20D9D6A1109A06A25D1B - DAAEC9674BD0B60E6DFC706309DA9A6D8D46A854CEF0C1389B7B212B7F63BCFB - 6D20212DFD8E05716083BF33FEBE93A5AF5160A1105F0FA21DE7FA489CF413BD - FD8D9B8DB08F7183282E6963844A1C68054459A0DF03F7166EBAD4DCCC6642BD - 708316DA874E93D250599D764975D926FD3FAEA07C6796D09256958E0551F09D - 02A27D704078E3B587A6112844D17D5BB5CEBC03038D22109F65F2BC03CF2FDC - DC879BD04A4D700FC72D7665E70436DF611D4F937E07F45F8E130D286E711FCA - D7521FACD7DB0704D19F481AB1DBCBE2E31C9E8EDAB97EBF703BBBD587847E8D - 0129DC4BAB32433FEF11BC16011F04C533BEDB541CEF66109123B945C2DFBA8F - 5B261D36A638EB75AB9E486D044110666244EC124432917C62578667FEB0EBD8 - 53E26EA6707B5D4CB1A16E71EAD22A5E3B54628012E27101678DD0D518465242 - 83219CFDC297068FED9D2EDFBA0441106643629720B4496AB11B0037B3097E98 - EB17A0C6B5A4EAD278D787883E1ACEEEF56068631A4110849990D825086D48EC - 12498789810ED005D353E44C9D20887842629720B421B14B241D2685B0A558F0 - 0441F40B48EC128436247689A442A74B313570331A0ADDB7E3DD1E82200812BB - 04A10D895D22A9602F8551ECCF6B105924AF5FB3F47B0A914910447F80C42E41 - 68436297482AD84B019DEBFF158C39D84716B1F448204801411044BC21B14B10 - DA90D825920E83E154D1B9FA22965652F4208220FA13247609421B12BB44D222 - 45953A9E250CCB89D19B0A418CA48404A249A1C8C5E8791B6836972088FE0889 - 5D82D086C42E41100441100491B090D825088220088220121612BB0441100441 - 1044C2426297200882200882485848EC12044110044110090B895D8220088220 - 08226121B14B100441100441242C24760982200882208884E5FF037933C780A7 - F045C20000000049454E44AE426082} + 0067080600000000008AFF000000C67A5458745261772070726F66696C652074 + 7970652065786966000078DA6D505B0E032108FCE7143D02022A1EC77D25BD41 + 8F5F5036A99B4EE2803C4604CECFFB8297839280E4AAA595820669D2A89BA338 + D1072794C103DB8614D1250EA546135988CDF2BC6A9936DDF168B86DEAE6E51F + 21DD23B1AD8926A1AF0FA178887D229FED08A116424C339142A0CF6F61695A97 + AF9DB842E701A73D6309B181E75DAA6DEFC8F60E139D9C188D9975D6B01F01EE + E6A831B17AA195B95F8D33D798C416F26F4F37E00BBA4A59FA71D652FC000001 + 84694343504943432070726F66696C650000789C7D913D48C3401CC55F53B545 + 2A0E7610E990A13AD9C58A38962A16C142692BB4EA6072E917343124292E8E82 + 6BC1C18FC5AA838BB3AE0EAE8220F801E2ECE0A4E82225FE2F29B488F1E0B81F + EFEE3DEEDE0142ABCE54B32F01A89A65645349B1505C1103AF08228201C41097 + 98A9A7730B79788EAF7BF8F87A17E359DEE7FE1C434AC964804F244E30DDB088 + D78967362D9DF33E7198552585F89C78D2A00B123F725D76F98D73C561816786 + 8D7C768E384C2C567A58EE61563554E269E2A8A26A942F145C56386F7156EB0D + D6B9277F61A8A42DE7B84E3382141691460622643450431D16F55583468A892C + ED273DFC638E3F432E995C353072CC63032A24C70FFE07BFBB35CBF129372994 + 04FA5F6CFB631C08EC02EDA66D7F1FDB76FB04F03F03575AD7BFD102663F496F + 76B5E81130BC0D5C5C7735790FB8DC01469F74C9901CC94F53289781F733FAA6 + 2230720B0CAEBABD75F671FA00E4A9ABA51BE0E01098A850F69AC7BB83BDBDFD + 7BA6D3DF0F168772E851144DAD00000D7669545874584D4C3A636F6D2E61646F + 62652E786D7000000000003C3F787061636B657420626567696E3D22EFBBBF22 + 2069643D2257354D304D7043656869487A7265537A4E54637A6B633964223F3E + 0A3C783A786D706D65746120786D6C6E733A783D2261646F62653A6E733A6D65 + 74612F2220783A786D70746B3D22584D5020436F726520342E342E302D457869 + 7632223E0A203C7264663A52444620786D6C6E733A7264663D22687474703A2F + 2F7777772E77332E6F72672F313939392F30322F32322D7264662D73796E7461 + 782D6E7323223E0A20203C7264663A4465736372697074696F6E207264663A61 + 626F75743D22220A20202020786D6C6E733A786D704D4D3D22687474703A2F2F + 6E732E61646F62652E636F6D2F7861702F312E302F6D6D2F220A20202020786D + 6C6E733A73744576743D22687474703A2F2F6E732E61646F62652E636F6D2F78 + 61702F312E302F73547970652F5265736F757263654576656E7423220A202020 + 20786D6C6E733A64633D22687474703A2F2F7075726C2E6F72672F64632F656C + 656D656E74732F312E312F220A20202020786D6C6E733A47494D503D22687474 + 703A2F2F7777772E67696D702E6F72672F786D702F220A20202020786D6C6E73 + 3A746966663D22687474703A2F2F6E732E61646F62652E636F6D2F746966662F + 312E302F220A20202020786D6C6E733A786D703D22687474703A2F2F6E732E61 + 646F62652E636F6D2F7861702F312E302F220A202020786D704D4D3A446F6375 + 6D656E7449443D2267696D703A646F6369643A67696D703A6161396535366135 + 2D333431342D343666352D613332652D636634366131363238666130220A2020 + 20786D704D4D3A496E7374616E636549443D22786D702E6969643A3338336433 + 3663392D303533352D343866372D613937392D39376362663636653861386522 + 0A202020786D704D4D3A4F726967696E616C446F63756D656E7449443D22786D + 702E6469643A33393739313537392D393962652D346132322D393138362D3261 + 66363332643536316464220A20202064633A466F726D61743D22696D6167652F + 706E67220A20202047494D503A4150493D22322E30220A20202047494D503A50 + 6C6174666F726D3D2257696E646F7773220A20202047494D503A54696D655374 + 616D703D2231373234383434343935383930383934220A20202047494D503A56 + 657273696F6E3D22322E31302E3338220A202020746966663A4F7269656E7461 + 74696F6E3D2231220A202020786D703A43726561746F72546F6F6C3D2247494D + 5020322E3130220A202020786D703A4D65746164617461446174653D22323032 + 343A30383A32385432313A32373A35372B31303A3030220A202020786D703A4D + 6F64696679446174653D22323032343A30383A32385432313A32373A35372B31 + 303A3030223E0A2020203C786D704D4D3A486973746F72793E0A202020203C72 + 64663A5365713E0A20202020203C7264663A6C690A2020202020207374457674 + 3A616374696F6E3D227361766564220A20202020202073744576743A6368616E + 6765643D222F220A20202020202073744576743A696E7374616E636549443D22 + 786D702E6969643A65363665353134362D313361392D346661642D393062322D + 393933653737386139353165220A20202020202073744576743A736F66747761 + 72654167656E743D2247696D7020322E3130202857696E646F777329220A2020 + 2020202073744576743A7768656E3D22323032342D30382D32385432313A3238 + 3A3135222F3E0A202020203C2F7264663A5365713E0A2020203C2F786D704D4D + 3A486973746F72793E0A20203C2F7264663A4465736372697074696F6E3E0A20 + 3C2F7264663A5244463E0A3C2F783A786D706D6574613E0A2020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020202020202020202020200A202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 200A202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020200A20202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020200A2020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020200A202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020200A20202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020202020202020202020200A2020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020202020202020202020202020200A + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020200A202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020200A20202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020200A2020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020200A202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020200A20202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020202020202020202020202020200A2020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20200A2020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020200A202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020200A20202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 20202020202020202020202020202020200A2020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 202020202020202020202020202020202020202020200A202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020202020202020 + 2020202020202020202020202020202020202020202020202020200A20202020 + 20202020202020202020202020202020202020202020200A3C3F787061636B65 + 7420656E643D2277223F3EDC58905300000006624B474400FF00FF00FFA0BDA7 + 93000000097048597300000D8A00000D8A01FD2DA3480000000774494D4507E8 + 081C0B1C0F66E13F84000036CA4944415478DAED9D099C1C6599FF9FEA73667A + EEC9E44E980472410209240A412111C2211EE80A2E8B0AC8A1ACEC7F410E09A0 + 06C50485D5B8BBCAEAA2465C76659143D6658580098781404212AE1CE49884CC + 643293B9677AA6A78FFAD76FAA7BA6BA52D5FD56754DF74CF7F3FD7C5EC854D7 + F9D6F1FEDEE77DDEE79122DF24991886619882E4C52717E7FA149802E6E9877E + 9DEB53600A0089C52EC3304CE1C26297C9252C76996CC062976118A68061B1CB + E41216BB4C3660B1CB300C53C0B0D86572098B5D261BB0D8651886296058EC32 + B984C52E930D58EC320CC314302C76995CC26297C90652AE4F80611886611886 + 61460A16BB0CC3300CC3304CDEC26297611886611886C95B58EC320CC3300CC3 + 30790B8B5D866118866118266F61B1CB300CC3300CC3E42D2C76198661188661 + 98BC85C52EC3300CC3300C93B7B0D865188661188661F21616BB0CC3300CC330 + 4CDEC26297611886611886C95B58EC320CC3300CC330790B8B5D866118866118 + 266F61B1CB300CC3300CC3E42D2C7619866118866198BC85C52EC3300CC3300C + 93B7B0D865188661188661F21616BB0CC3300CC3304CDEC26297611886611886 + C95B58EC320CC3300CC330790B8B5D866118866118266F61B1CB300CC3300CC3 + E42D2C7619866118866198BC85C52EC3300CC3300C93B7B0D865188661188661 + F21616BB0CC3300CC3304CDEC26297611886611886C95B58EC320CC3300CC318 + 50FEE8812AE57F1FC9F5791851ED77D1BC4ADF713AAE2314AB7FED9229BB127F + CFBAE6897931994EC8F5F95AC12D496FEEF9CDE75B9DDA1F8B5D866118866118 + 0314B17BB6F2BF57737D1E462CA8F25185CF95B4AC2F2AD33B6D036B8F5D5177 + 4B62D9CCABFEB05696E91F737DBE5670B9A415FBD6FDCD0B4EED8FC52EC3300C + C3308C01A355EC4E29F1D08C324FD2B2984CF476DB00F544626BBBAE9CC16257 + 43C189DD5B5FD87915B9E4AB07FF90E57A49A2A71FFCC4297FCCF579310CC38C + 20188A5DA294A54A59AC9493943247F3FB6EA51C54CA5EA5BCA594ADF1657DB9 + 3E7186C925A351EC16B9253ABDC64F2E9D823BD01DA1866004FF64B1ABA3A0C4 + EEAD2FBEF71BE592AF36F8A943291B49969E8EBAFBFFB876F9A28E5C9FAB45D0 + 683DA694D3D2ACB743295F24B511CB947395F25BA588FA01A143F10DA534E4A8 + 8E18A6D0F02B6539A9EFDDA76C6CDFAD941795F24BC2F791852F53808C46B17B + 4AA58FAAFCC9EE0B5DE118DC174856FF64B1ABA360C46E0AA17B3C92F2618F91 + 227C2545F8CEABCFF5B90B906DB1CB429761462FF8AE2F52CABD644FE41A01AB + EFBF28659D521C9B34C230A39DD126763129ED6445EC6A81FBC2B6B610F545E4 + C42216BB3A0A42EC5A12BAC753AF3C3E4FBB5DF26F1F587ECAF65C5F8B09D914 + BBF395F2B0523E2AB8FEF34AB949291FE4B88E18A6108035F706A5FC40296523 + B07F7C3BBEA794279412CAF5C55AAC1774008A34CB30DE8B6F6277AE4F8E19BD + 8C26B13BD88BADF153892759BA7DD81BA1833D11ED2216BB3AF25AECDEBC615B + A55BF63F45322D7368971D44F2D3A3D0CF375B62779E52948E83B0D0DDAC946B + 94B233D715C4300540402977C58B191076E8B4BF4EC3165AB7521628A54E2967 + 0A1EEB29A5DCA694FDB9BE68416A94F2A8522ED42C73D2AD8BC9534693D89D50 + ECA659E5DEA465A1A84C5B5B4383D65D0D2C7675E4ADD8BD7DC37B0B6351E937 + CA152E345BC7E396BA6A8A5C7B22D1A8BF25185BE072B9AC1CA2432669ED8FCF + 9B776FAEAF95B22376A728E5674AF9ACE0FA2C7419267B605AF6AD4AB9DFE4F7 + FF52CACF95F286520652ECA79854E1FBB74AF93CA57655C277E466A5FC39D717 + 2F008B5DC616A345EC42AC9D3ECE4FC5EE64D9B6A7334CCDFD51FDEA2C7675E4 + A5D8BDF585F7FF51B9B2559303AEFD5D03B1A2803B36E168BF0B1F3B1A57E2DD + 5AEE95AB4A7CDE9AD2627F8576BBDD0DCD1DED515FA59563B95CF2A251E0DE30 + D2627782527E41D6842E7C74B7E6B85E18A65040830C31A717A778E76F2775A2 + 59CCE23E6129FE02A9227A81C1EFB0EE7E4D292DB9BE780158EC32B6182D6277 + 5C919BE656245B75831199B6B586483E7E7516BB3AF24AECDEF697F73E2BC7A4 + 55B0E656157BB7BB237D13A392E798140D4F6A8B7A07C5EE820925F501BFAF2E + B1CD91B6CE90DFE709971717053C6EB7B4FD40436B502AAE11B5F2465DD28C51 + 30896D24C56E35A9D6A2EB05D7C7BEE133F8728EEB84610A857252278F7D45B7 + DCA9D115885EBCD3F790FA3DA0F83E61FD7D3BD7172F088B5DC616E9C42E0CAD + 357E3795FB5C835657FC1D56D467E7408C8E042314952D1C2C05A756FBA8DC9B + AC4B767786A9E578AB2E60B1AB63CC8B5DB82B4463D255CA855C4AAACFD91065 + 3ECFEE532696CE69EEE8A65DC782E4F3F91396DDEAF115A5330E1F6BA78EB0B4 + 735AB97F5C45A0B816DB8423517AEFC3A6D67E77A026B11FB83B94795DFB3B82 + A1C9B2CB335E537BBFFDA74F9C7C75AEEB80464EECA291FB9152FE5E707DCCD8 + BE4A292FE5BA4218A680388F542BAB76429AD3EF6222C2C31AA59CA594AF93EA + 1AE150533EE2B0D8656C61267611E3765AC043934B3CE4365152F0A77DAF6360 + D0029B09989086B8BAFA7D6F3916327B0159ECEA1873621793CE5C31FF77254C + 3A4BE18F0B2694BAB70483A14ABFD7DB5B51E22D8E4663459DBDC1F29AB2D296 + B6AEAE998DBD31777559E907B3C6154F2FF679079FA4BD8D2DFD95A5818EFAD6 + 9E48382617054303F2F2B953CAB7EC3B1C0C9494B41CEB094DF517074A94553B + A32E69A1D6AABBA16E616538E24503435E4FF8B7CBEBB7672B5EEF48885D91C9 + 2E5AD0B87E15D54063A7016498B10EBEE1772BE5FBBAE5FFAC943BC8F98809B0 + EC7E4E29FF49632BEE2E8B5DC6164662B7D4EBA23915DEE3FC678D802885AB41 + 267A1799D290314D4B7D4F840EF746CC3661B1AB63CC89DDDBD6EF5C26BBE40D + 66BF97FADC7BC2A13E5F48F2D5CD1E57F2527589EF5CFD3A9DC1BED0E1F69E86 + 8A40C9B15824523EAEACF844AFC7EDF6BADD4963049DBD7DE1AEBE50F068CFC0 + D130B9264B2E4FA9A6E26E79F0BC93D76AD75F3F6531CE6B59FCCFED1E6F6479 + 9604AFD36237DD64173D10BADF24D5BAC4429761B207ACB99838FA65DDF20B94 + B23ED727378A60B1CBD8422F76E13B3BBBDC7B5CF6B2544094D6F744C437D0B1 + 649C9FFC1A618D46F6CD96100DC44C9B5B16BB3AC69CD805B7BEF83E44E6D54A + 499A6006A13B6F7CA0CEED72F9BA82FDC112BF7750C33A71CC70341A7BF750F3 + 91C93595873B7B83A1BBCF599024A25F9872C65A9924FDC3B47D45C3964559A8 + 1227C52E842E86285793589CCE6E72764813C73F51291F8B175C93B60EB7C5CF + 7F53BCBC43A96797E733A82B8483830B0F3EC848070BCB5B1BA9F71AE1A59EA5 + F433F0B5E09B309554B184FA9F4BC3E1A8D0A941BCE437498D9F0C9FD0B164DD + 73028C78A0AE3159F3745DDDBC476A9D233A019E53FBAD9B3870BF8295F57CCD + 32BC13972B6557AE2B6B14C16297B18556EC8E5784EEAC0AAFA970420368F45B + 5811A56FB4846C3590655E179D569D9C44A23D141B748F48018B5D1D6352EC02 + B8337862BE9B158189D03783A277EEB8E2ED9525FE21D7868E9E203577F51E9B + 5A5D515552E4733B71DCB69E60FDA1B6AE653F38EFF4838965EBA72E5EA63CC5 + 86D66689E475E7376CBD6684ABC329B18BE7E10AA5FC1B655FE86292CD954AB9 + 918C677E9B81FBF02B5233BA1D32596746FC1C45E203E37A7E61F31A10B6E927 + A4CE504F072CE710A2BFA7F4F7EDB978DD24E2A26204E213A4764896081C0BE2 + 07BE964F92F9B036F6890E1C2CF4A259B750F73F25359D6CAFCD3AC3571C61ED + F0DE42B8E3DE43B0E379D0C67C8578C4ACFF46521B1E44FA789FAC7774508FFF + 21B0DE7728D935C06892562A44EADC098CDE7D1671C7C36297B14542EC56FA5C + 744A95CF5034750CC406933A748763831658A4F3D5277ED8D13630F8BB554E28 + F50CFA066BF9A02B4C47FBA2A93663B1AB63CC8ADD0409D15BEEF75C54EE93FC + FDE188578E466A0EB7F794F84ACACB135115665717EDECEDEF9F3C6D5C6585DD + 63C56439A888D7B32F9F3D7528D4D881553FA9DCB1FEAF1F04EAEBC7996D9705 + C1EB84D895E2BF614854A43187D0C5CB04919989050BBED27F43AAB89893C17E + 60CD7C207EFEFA8C48E8E840B8AC14D8CFEF480D9B6627AB92E87D3842AA35B6 + 53707DADD8AD8E5F8BE8A4412D8F937ACFF4699B27929A71EBAB36F60960E5C5 + 8754D4925845AAE8401CD7F348EC793302F71C9D985F939A2841A425B1237661 + C1850FECD936CE11CF137C679B6C5E633AC6B2D8C53707610D9729E5E3946C29 + 07B092E39942E7068DDE87643D7C5A0216BBC6E05D5CAA944F92DAD144A71386 + 8E44F21174DAF0FDC1BD68CEF5C9E60288DD22B7F4EAC26A1F790C7C170EF546 + E890CE45A1B6C83DE8D3AB65AF22509B520B544370DC525D1486CD2DA1416B71 + 0A58ECEA18D562B7F7AE89CF904C9F2692FF2ACBD253FED967ECF07EF57F4D2F + FE87AFEC78B8A2A4E48A8E607F5B4496BADB42B169093F5B842273858393664C + A8A9F1B85D1EF1B350511EAB2E9263E76A852E78F194152FCA35D55323FBF6CD + 4E653A1E61C1EB84D885550FC2F5044A0F3E841002B06266227421B210EDE1CB + 19EC43CF9F48B54EEAD3131BCD583702DB21B6A89D904AA2422A21A8279335B1 + 8B54A7A8F3CB32A81F64FE83E5F968FC6FCCAC7F48E01CD2912ECC15BED6B0AC + C3728E094E4EA7B27D4429DF554A7D9AF5AC88DDFB487D2F30D29149474C5FE7 + 4E826708226E996E39CE7BB486FFB3338A005E21752401EF782A6BB995111651 + F4A32B4633F431220481E1946B8FD131F4230EE9AE19AE487F3558BF2EBE2F7C + EB4447F1E09E834E1FDCC7EC763AC61C55FF79E0EC53AA7CAFEAC37E0158733F + 34982466E47A60248AD301E3F047C7172509B5DE488CB6B5A61DD062B1AB63D4 + 8ADDDE951331243D6DF0A22BC6EF92677E843C55B573FB5B5A9AC33D9DAB6B6E + 78FCA766DBAEDDFCFEFD253EDFD7AA4A4B2A771E6E6EEA923D01AF24F5CCAD0D + 1475F7857A2654964DB3722E8AD0DD118D48975E316F52BD76F90B53CEF88D4C + D2D5A2FB5104EF4F15C17BF3085457A662F71C5287A2451BF43B95F24F9499D0 + C5B1E07E60C75A960EA3A41655F1E37D4E60FBEBE2EB5A01166A08F7FF6761FF + A2F70D0D2DDC1E607D154DEC918A7F25D5DAF81112EFE088904AD405E2C7BDDA + A1631991C8E885FA32337B5811BB2F3B583FC85E863AB7EBEE610646AA1E2655 + B468C1F3F2131A7D1346E1038E11182B22570FC4EEB749B53C1AC1627718BDD8 + C57A784790EAD9EE888A68C7322FB870FD918FB9A5C18E5612C85A86EC654640 + 189FAA13BB7626A955C55D27B43406A3B4BF3B9C6E53DB62D7254974DACC2A3A + F9844A0A1479A8B52B44BB3EEC1C2CD158F63E2705217683774EBC49960683A4 + 93FBD4F337BAC64D5BA65F27DCDDD5176A3DF6BBEAEB1F33FDA0FDE8D51DD7C5 + 62F4CD86DED8BC39B581433B1BDB6B97CC9C7034D83F30ADB6A2D4BDE340436F + 67D41338F384713D1DC1BEF0F88AD22ADD2E3A95B662ED65B3A6ACD2EFFBB52B + 6FFF7DB0BDEDCCE0F6ED271449E2D5A888E36B2E6878739DC3559689D8859FE4 + 6F48CC9F152014D98F29333F44ABC7B48391A5F196F8B9A7639D526E226BC204 + 8208138596A6594F7B0FACDC370CE1662210B4C04A03C1F749724EE82640430A + EB8FD157F15A5285D948922EBEACA8D885150BDF03A79E51D4397C7E7FEFF0F5 + 9AB9E8E09981FFFD6849D70DB318DC9520749D78E6E0C2F20FA4D6A7DECAC862 + 7718ADD89D42998F0C25C07B86CC7C4F509E5B792F7EE1C8C7244A16BB7D5199 + B6B7864C1346C0BF77BE4EA4C2027CD0A2D885AF2E7C76B5A44824A1C596D83D + F7D409F49D2B17D28C89A5C7FDD6D93B405FB86F23ED6B1CF6F07BECAE73E9C4 + C9C303034B6F7E960622C38FC3EB3FBD84B4D3A53EFD9D17E9C316B16635EFC5 + AEBC6A724930141BAC0DEF999FDF44251529C543B4BF3F126A6D7EA9E284595F + 9096AF320CF375F3869D759E58EC6A58614F1E573470B0B96D7CDD849A9EC6B6 + 4EFF0079DA944ED2ECB9B5C5EF56078AE763FD982C37B8247AD8E31958FBB919 + 338EDBE7E6EBBFB3BDBFA3635A68F79E2E5765C540F5AC3991FEC8C089ADEBD7 + FB4584EF08085EBB62D7AAE85C1D2F9958A7ACA61ECE045820D02076C5FF3E85 + 54BFD57969B683404083F09E85637D8654CB663AB4F14F45EFDB58029D0C88AC + 0306BF89D6BF13E760E652212A7647826748CD44E8B4EF237C9F9F30588EE711 + 231C0DD676E738E922BC40B8FE2FA91D8CC6F832B49027933A11F33C93EDD0EA + C2771D9D4CADE062B13B4C42ECCE227564E502836D51FF704D48446D41DDE39B + 84762155C704F50FE307DC7CB2117924271889DD77DA070633A4996194DAD7CC + E52115D807F6A5E52D45640B24A9B02C763F73D634FAF1D7960C5A768D50B6A7 + 85373E43DD7DC356E5FFFBC10A9A33B57CF87CAF7D2A49ECEE7CF852F27B87CF + 7FF91DCFD1C1A33D42D79EF762B777E5A4E7956A5D414581A3DEA59763E8B354 + 643B391695FB5B5A7644FAFB57D65CF75F7F365BEFC667DEB8A12C507CE6FC09 + 659F2CF6FB20BC68F39E431D9E928AF7E6D4141D2C2BF13FFE8593263F6DB42D + 26A3B53577BF56513D0E4371D4B877EF40F095977D81DADADDEE59B3236189C6 + 1D7BF59509E552FA54C30E0B5E3B6217BD7C4CE612159D4E0CC3A2D1830BC4F7 + 33D88755B496463BAE0622A00B8F98C4B708AC8BFA7E26FEEF7C14BBE04BA4FA + 91EAC9862B430233E1914BB10B7100379A171DDEEF24523B76E71BFC86307178 + 075EA3DCB834A48AF082EF1046F0E0C3DE95621F985C86C993F876E887DE8D2C + E6781F61459EAE59063188706CDA8ED691F8B1DB04AE039349F1DC245AEAB124 + 76F7D2F10606D41BE630C07D0D9D4323158686AC2E5EBFE8A419B93D38355179 + D4A217BBA9DC171220ABDACCB2648BECBEEE301D095A9BA0B6A8C64F014F727C + DD4D47FB455E644B62B7BACC4F2F3D78D1A0DB8219879A7B69D9EDC9D28AC5AE + 4DFAEF9C7C41548AA1074DEE05CB37BA6AEB96D9DACFB196FD91FEDE7FABBEE6 + BF1E90EF9C5E25DD7FA83DD3737BE3865537945754FCD0E3F7576A976FFED5C3 + 343E1EF161C285176E3A70E8E052CFCE9DE413A85A0705AF55B10B6BB515EBAA + 53FE86F00D46A33449707DCCB45F173F6F7C48F126C2DA800FAFE890BEDE9A6D + 6605D383E38ABA32984D12D28317F72BA436B2205FC52E1A5D0813A35914D970 + 650066C232976217201C19FC4DAD4FCB4ECDDF922A5CCC261B410CC38500E1DA + B239EC6C36F115420B7EA3FB2DECCB2C2A46BAC991C0E9680C6345EC5E44EAA8 + 93367A0BA2A7C0ED05E1FC443B4075A45AE6AF30F80DDF337470FFE2D0758F2A + B462172EAB5B5B438359D15231B3CCAB08DE648BEC2E45201F4BEF7E90C459E3 + 8B925211C37D62EB31210F424B62F7EA1527D177BE94DC0CBD73A09DFEF0CA41 + EAEA0BD38993CAA8C4EFA6FBFE3379DE368B5D1BC8ABC8130C4D1CEA2E793F7E + C576F2162DCC649F039DEDCD91AEF6A72ABFFAD8D7EDEEE3A52BEFB8AAA2AAF2 + FBA59595C74D6A0B0F0CD05BBF7B6448EC4EF9E217776EDFB8E1C4DAA3CD3ED1 + FD2B8277912278B78BAE6F8215B10BA18886E146C17DFF3BA9C245C4FA910ABC + 11B0E27C45605D343E9860F37F64DC30A3C22F26D5322DE2FFA79DAC93CA0AA6 + C58A2BC30A521B907440E4FC80861B183B6217220EE2019D863DF1FAA953CA25 + A486FFB23BE904E83B17E3496D2CBF46D6A21160481A11368C3A99A95C1910DE + A82B7EFCC47031C4DBA2F876567D3D8D44B71DB18B67FFA7F1EBAA8F2FAB237B + 75FE0752470D3A2D9E433A6035C7A845BA907468B4719F11E33993505E2220DA + CAC3F17AD2026B2ADEC9161BFB341B8E4F4CBA34139A852A76F1CC6AEB1FDF60 + A497B6135A11236388A0B1DAE037B84A40F0D63B74EDA306ADD8159C1C361867 + B7CA9F3CC26B35CE2EC29C9D59EB4F5A06D709B850086049EC3E78FD62FAFCC7 + 863FAFCD1DFDB4ECB63F537F38B53867B16B83DE9513F112DE94F83B13CB6E12 + CA1DEE3FD6DC5B5C3BF15E8F448F48E7AF160AFFB3F9BAEFACF2F9FDD7975555 + 4D4EB5DE811DDB3B8ACBCBE59EFA036D93169D51BCFBC93F4CAE127063D0D0A1 + 08DEE5190A5E2BF15D11EFD34A5637885DBC34995A7545437FA59B60A405FE7C + 102EE92CC55A8B2A9E797CEC455C29445C19F0266366F2B7D3AC9788ADFB8666 + 9955B10B0B167C90B790B14506EE3510651708EE2F01EA1CBE9D669D0BAB21E2 + 528988842B0386996175C5B81846730E53EA6150BC54F0E1C4A418910E13D848 + AAB86DD42CB32A76CD6213279849AAB5F112C1FD214208ACB07B2D9C832810DD + 70A7B95E707DDC9F27E3F584F382A877CAD501EF19DC85D6EA963B11860D2210 + C255DBF949E72252A862570BBE0DF8F665EA8A66964A1EFEBBF84E383D6A9153 + 1262172FC69663E9ADBA60F1383F15B993E5D51BA9D3FB1E0792529C5E932C76 + 31316D77677AB14D16C5EECF6E3A932E5E3265E8EFB7F7B7D3A5F7A637D4B3D8 + B548DF3D1397C5A2C919C85C1367BEEE3EF9DC33EDEE534BD30BFF139A78DEA7 + BC8AA86C9424E9C7BE15AB7F62B4DE81550FD575B6B5FFB2B82470AEDBE34D69 + 9D6D6D68E86ADABD2B5C128DB4974C98D8DBB27BD7B4AA49931BDAF7EC5910B0 + 109D214E87C71B99B1BC7E7B87D50DE38CF470382C26886260F72366C55716FE + 61B006897C15ACF8006B7D6511720B7ED9E944F23A4AEFCA806422B0545D9466 + 5F46163D2BF74DB413702AA9565FD14960A259F0A6C4AF73B9C03ED3C52A8675 + 0E62A74B605F7A3CF17AC03B2C121F541F6FD68AD8C53709023FDD042F2B133D + 473A952F440FC4C81D82F5A305A20F6211565F4C58CAC4FDCB286BA153C3DD66 + 425A3BF9534FA18BDDC7E3BF65ECD2476A8715C7D277AAEC4CEC1DF524C4AEA8 + D044DE89B374B171A1713735F75B3AAE51F832F8FCEE13B02C9345B17BFB65F3 + E9C64F0D0FDE45A231BA74D5067AFF506A49C262D722DA98BA4327E62F69F29C + FDC5894EECBF69E3F391F1A7CC7E75D8522CFD5211BC491F054C3E0B87BD1FBA + 2497D084B8B75F7E6960EA8C194D8DEBD74FB7216E8DB86545C396B536B71D69 + B16BC5DA6A8468582EBD4FAB08A2A980B543DAA213A5443EDE689060114D272C + 8CACC456EE5BAA865C8BA8A53901ACEDF0A3156904ADF8DB9A05B37702749EE0 + 0E72ABC0BA786E1FD1FC6D45ECC2FAFCA4E0BAA261ED46BA6E003E4818BDB997 + EC87AB432708C2177EC01BC99A80C3F1AF8B6FAB05B1B9615974227DB251E72B + D5FB5AC86217F582D1043B8972CC30EB548FD6F8CEB64988DDB7DB06A84BC00D + C1C8228BE80988A26005A318BB1662F55A12BBB315C1FAEC7DE7274562E80A86 + E9BB8F6CA33FBEF6A1E94158EC5AA06FE5A47B62241B5AE69C726538B2E1799A + 307F76D2BE640FCDF32F5F33645DF9E09E879649246FB0BAEFB6A623B1FE604F + 7FE35F5F73D744227EABDB0F21D1BD2B0E6F596573EB6C4C74CAC4274B342C17 + 2C8CBFB0B86FD154C07869FE8E86FD0445855B2A5706519708B346D8CA7D836B + C27AC13AC14440D18E89953A879BC47F939A56341D232DE844ADF37A71202A76 + 37D2F12E10A940E30FEBFDAC515037091259EBE0FA724506FB4167176E66EB68 + D8973A1546892E8CDC7832C1ECDD337B9E0B59EC8E847B8159A7DA4AE7794C00 + B1DB1F955F119C18661876AC2D14A3F73B847C6D87A8F1BB685EA52E0B9B2274 + 0F89852FB31C7AECEEBF3B95AEBDF0F8CFD7ABEF1EA53B7FFD1635B6068FFB8D + C5AE20C1BB272F9563B1941F7DF784996F0D14D59450695591BBA4ACCA5B565E + 61F53810BBE3E7CE78C93D69D6B98965B224DFE53FFFFE3589BFF7DCF5B3854A + E56EB37B2D9DADADB4FFC5F55D65BDC172B79D1D48B45C11BB1B6D1E3E5BB3FA + ED466580105D9D669D4CD2F48A4C104363FB691ACEAA266A114ED58089666533 + B3CA3A91E6D9889348B5BA9C21B0AE15E185EB85354DC43F75A4055D2DA9A305 + E9261AE29985B5293186282A76AD0A17233195ABBA3102930D2136E142719ECD + 7DE0F9FB1EA9D14C52B5FC78EEFE87923B228914D9762646996134AAA2BFDF09 + 0A55EC8EA46B81518753FF9D1DF340EC7ED81379455064D2F48087A6EB124134 + 042374A0DB5A64B61ABF5B11BBB663F55A16BB6E97440F5CBF982E5D3AFDB8DF + DABA4374D503AFD27B0793DD1A58EC0A321453D702EE3967FF9F6BCAEC8BAD6C + D3B6E32D2A76F5BF57BC60E929430B657993EF82FB9342D8ECBEF39F8FBA3D9E + F176AFE7DD973674F85A9AC3DEEEDE5A8B9BBEB4A261CB32DB1599DD1056F061 + 44A3213A4C251AE03DD50CFE74885A1CB57EBBA2C3FDA91A44A346DD08B3E170 + 2BE982B501EDD3212ABCAC36F65682F58B083AB408782717931A566A36A99651 + EDC42374405BE2E78A499CF025C56436081C11E1AD172056D2055B8907ED74DD + 8C24E8B42C2135541E7CCDAD4C58051094786FCC22B418D5F137E3F5E3244621 + FFF42338090A55EC3A7D4E5ACC5255EB5D87C63410BBDB5A43AF08247218644E + 85976A758920F67685A9A9CF9A613DDB621740107EE9BC13E98ECBE71F177317 + 111A2EBE7B3DB5F70C5BA859EC0A105C39F10EE5D1F9A19D6DDD1FB9749BABB4 + 4AF803DD7BF810F51FDAD55EB3F482A474C0DEAA3A9FB4F86B43DEDE1FDCF5B3 + DF492EE94B76AF69EBE3BFEFA9EE09967ACACB1B22B5B541DAB72FED90A644F2 + 0EB737BA2C83C969209B6217439A68CC441B6B51E1050BC143641C9B351DF8E8 + 624873499AF5F40DAE688408B32409227E9A1BC97C38BC50C52E4C07681031DC + 6927752C9E41B874C05FF0EC34EBB2D84D0FDE1F648F84F045E741E4DB6A1655 + 016DCA77E3458B15371C514A488D30709D6699D904C04215BB765CC34431BBD7 + 56DF9D51CDDCA70E7DAC31187D4574FD85D53E2AF52647647AB77D803A06AC45 + F9ABF6BBE8E44ADB29876D89DD04D36A03F4AFDFF8282D98912499E897CFEEA1 + FB1F7B67E86F16BB69E8BD7BD2628AC96FDADDDE7BE6E75FA6928A73AC6C73F8 + 894742E3969CB567A02F34C54572500E873A5CD1C81B55B76DB836B1CEDE7B7E + 8E61BEA7EC9CD39EB7B6D2C0F6ED9498AC56BE6CF9EEFEC84065F7077B239E60 + D0EBEEEE36B21877CA242DCB629C5D23D06861E2085C3AD20907ED36A2E183AC + 0CA98F34FA8FB0A81B8251236666D5D083E361A29051B7BED0C42E260622DAC6 + 3D94593C602BB0D8B5063E6053494DBE826F63AAD11223B726A37AC8C44529DD + B91A892DA3FA2D54B13BD2CF9AD1FB3492D6E4AC53FEE801A3FB608A3E110440 + C8B27E8190655A2A7C2E5AA09BA066C11D2223B10B4A8BBD8A983D9FA6D4940C + 2D3BDCD24BE7DC369C458DC56E1A7AEF9AF80CC9837E3DB6B09370A2E7E0010A + 371D6C2BF6459AE5A8ECA1F686935C2EF9DEB2FB9B5669D75304AFE559A45D6D + ADD479A4B1A1F1F5CD5312092640C4E7EB2E9E3FBFB17CCAE4B2C6AD6F91BFB1 + 511BB3D729A10BEC8A5DF8B922B4161A23B34C476688CEAC1E4D59C28CFCF9D0 + 38FC5B9AED8C1A45910949F04F84CB8D596353486217A9B931C9E932C1633905 + 8B5DFBE09A10CD01B18DCD464DF4A31E56FCBA470A441E784CB7AC10C5EE4887 + B90346936147C23F3B675811BB5E97441FD52582B090E23789528F8B16D6248B + 5DB842C02542808CC52EB8EB8A53E9BA8B869B38651F34FBAB4F52341E2F98C5 + 6E0A822B27DD2C939C91EF5626D9D5A27D7DD4FCDCE334AE3C8AABFF9FC0EAA6 + CF687FDF79FB4F5EF4FAFD9FB0B2CFA683F5D4F6E6E6367F776FB576F0022E0A + 8AA03DCD35AE767F64A0AFC4D5D533D1B370D1BEC8FEBD726CF6BC7B2EFCE3CF + 1FB3729C14D81194FA149BA982851B211A9F7534895DA3C62855462F2DFA465D + 4424A79B995C28621702E85FE2D7906D58EC664E75BC2E8CB2B3C1071EF1569B + E37F5B99A8375218B91D15A2D8CDE4FA323947ABDFAB518D15B11BF048B44817 + 760C892490504214651783111DE0B3ABCFC206E370AF22269149ADB93F4A7DE6 + 7EC48E88DDEF5FB588AEFCC4CCA1BFC3CAB1E75EF7D4A0E8052C7653D0BB72E2 + BBA40A0CDB783FFAB94D14A84C17B3F53862E13075EDDD15741DDC5A52EC1BBC + 5B7D24454E0CAC3E3614D775DFDD3FBF5996AC4FA408767753B0B3B3EBC8D637 + C3A56DED3589E555E79CBBF9F0B62DB303DDBD55346EDC41B9ABABCA150A5D75 + 7EE3D6A71DAC563B99B88C72C94394E0832D6A7DC3C7F40A4A9D937EB48B5DD1 + 8417DA6D45E3F4A69B94530862D72C0140B660B1EB0C66E988F599CB58ECB2D8 + 2D58B16BE47A0071BAAD35FD54145885A706DC34B1D8739C1B84194874B1BF3B + 42E1E333B32589DD0B573EBF562663B16B74A8D2122F7D7CFE04FAFB4FCF21AF + 7B5870BF7DA09D2E5D359C13C6AAD8BDF6C77F3D2E84993CF49FE46592442B9E + 5B7DC19816BBB000588D569084FB8C4B5E76558C37F4D94598B189F367FD8754 + 3B6368A259DFD1C6C8404B539B74F483E26229A89B8C247F3AB0E6E89F127F21 + 8B5A34221FB07B6EF0DD95776C275FBC6AEBAEBA3AB8ED2F2FB84B3B3ABA249F + 3FE46E6DFBF6050D6FAE73B85AAD084A085D4CE878D7E4772BD9A0403AFF5DD1 + 8412D9C0AC31128903AC6D3844EA5B24E44F21885DD1106F096065873BCD1BF1 + EB4D7C398BE3D785A80DF0FFC430B988DF2F8B5DE7A823B5EEF4BEFD88E39A08 + E368E4CB0E410C77AD6CF970C25D49FF3EB3D81D198CCE11F71FC22A687D77A3 + 0F2B62D7685219125120218519C8B836B5C4435302E222570B2CC7EFB787A927 + 9234012E49ECCAB20C638365CBAE9E6FFF761B3DFA97FD437F5B15BB16395F92 + A417ED6EAC2707627792F222C8D7DADE81CBDBEB5E7A598BCBE7AFD32E8EF4F6 + 503414EA72793CA5DEF28AA1AE48CBE657FA025DFB8ABD6E6373BFB2F447A56B + 9ABEA55DB6F3F6B5FBBD7EDF0CA3F55B8F1CA163BB7635D49C70426FD5F4E933 + 60D12DABAAF21EDCF95E7F7149A0ABEDF0619777CF9E71380197CFD775C2955F + 1A7C12B63EFD64D7A4D34EFBED398FFE9348CA5CAB888A2691749D782660ADC5 + 10BD68BA516426830FAF91E7FC68F0E14B60D65020741842E5A48BD99AB01889 + 08A675943ED57021885DD1E41D38879BE3D72AE2DE8634CD885F9C2E59028B5D + E7304BE4A0AD63A37A180DB1570B51EC029EA0962156C4AE51B8B0546217E278 + 6699978AECA85C0DB0ECEE508EA19904E7B8D8DDF47EF360ACDDA8C68ACC6237 + 05A195134F8EA8C2C2D6EC7CEF69E76FA49A69CBF4CBFB9A8E502CD4D71E3861 + E660AC8C818E76EAD8F4DC4055519F2FCD2EDF0EAC694A121B3BEFF8C92FBC3E + FF0D462BC372EBDDB1236959D1B4E96F4B752754B5BEFCF2B4124DBABDB23973 + DE18B7F46C04DEA65DAFBFF6DCA75EF8DD452354AD4E2727B0928E15C0728318 + B946D6D1225285F0DFA7D987597CCC6C809B764BFC3C53818FF8DDF1BA49276A + 4452CDE6BBD885B811B9F7A99E9F4CCF85C5AEB3188D82E863642306EFF774EB + 68635CE7824215BB6661139DC22861505E851EB32276E1637B8ACEB26BE4B35B + AC88DB198AC8ADD6F9E4EA0929E2D5AF13C248190C4D8B6DCB3421CEDA43317A + 6F384B9B636217E2F6BF5FAEA7FB1EDD417D03C9418558EC0AD07BE784EB94C3 + 5FA59CC1C744B7714FA8DBEA3A65B9A9483EF4CCE33DD33F735929FEDDB97B27 + D1FECD54E24F6F24925C9EA9253F38DC90F83B55EAE01DAF6C8C96EFDD7FDCDD + 2BAAADDDDD3F6DDAE440758D578E447A8E6E79C353311096267CFA33ED3DBD3D + 7D67FEEABE9347B03A4722131766CFE3E3FD59C17330F303062293B9F4BE7FD9 + 4624FD2CEA0F43B6F898A71A96475DC0E298CE1D26DFC5EE2EC1F3B0936294C5 + 6E6E10F1D134AA63086074122D47BB71886C885DA787EF8DEAD1AAD8C5328CBC + D9895F9E0E8CFCFD8CD48E8E969116D859C58AD82DF14874BA6E821A400485A3 + 7D512A567E9F5CE2A109C5EE94E20B93CF206A91C8E2B46A5F92A86D56F6B327 + 1E91618AB2AF1965C3C91FDE3C161A14C8A413BB4FBE7A5048ECCAF2F0EB190C + 45696F6317BDB8FD08351C337EA4EFFDF2429A326E3834D9D7FFF9758A4487C5 + EE43FF7026793DA9057D0A569CB768F2D8F5D9D513BC73D2DFC82EF92A915064 + E9A230B4BFFB3655CD9DB7853CDEC54D2FFF852A070E925BA09E2559FA42C9FD + 479ED02EFB60E5BF0425B7BB58BFEE5BCFFE6F4FD5D1A3A5FAE57059F0CF9ABD + BF5FA20AAFD7DF136C3F56E66A6B2B8A75766FB8B871CBDF8D70358E54DA59AB + E1C860B1FF07A574E9961BA5F534C22CAD6E36109D74F6AC523E99661DF82FA2 + 714F973227DFC5EE31C1EBBB375EAC0821B386560F8B5D67316AF8F5965DA3CC + 82763A344E920DB1EBE4E894D5840D66CF9F68C7DB0E46916C4683CB8AA35811 + BBB869671AC4D915057EB7FBBA22D41D1E168CE58AD03DB53AD95AACCDC88650 + 6798DC0634C92B1C89C6904BC67C340633BA574E3C5739996BA5148D97F7239F + 7D954AAB4D2DC1DDFBF75260EAF463B18181EA23CF3DE99A5825969E4F79081E + 29BDBFE92AEDB2F76E79E04F2EAFF792BE9E6E2AAF1E0AAE40DB5FDE182BDEB7 + CFE533A83AFFB469EF44FD7E4FD5FCF9D5A555D5135A0E1FDE77D6BAD52765A1 + FA464AECE2223199ED9716CEC5C87F573479839DE16C2D10E50882FF6732F61F + 4E0702E93F61633BFD35885AA859ECAAD819F614ADBB4210BB30EDA0B3D6E9E0 + 3ECD307263D0D7B1D924B55C8EDC382D768D9E3F279367987D33AD8A5D005F78 + 18129CB4AA9BB97EE5BA53E33856934ACC2AF70E5A6EAD0083EAA1DEC8A035D7 + E826D5957A686A20397D6F6B283AE8A30B4B71428DC037B82BCC62D788512376 + 1374DE5E3BCBEDF1DC24910CF159A1FDCDBD60F946576DDD32B36DE54884248F + 67D0C24B07B75169B1707ABEF6C09AA6A499DDCF4F5972B5AFA2F4FB3D7DA1CA + E9679FBD4511B24BDD6E8F2F3C30403B9EFD534F4D7B4769AA1D22C6EE89D77F + 69D98C55B764920658949112BBC02CE4901948E58A7BA70D346E4534E31C6F54 + CA6B16CE11FB3F8BD4F0567395721FA96944AD5A88AD460E3002421B82FD98C0 + BA2C7655AC0EB55A096796EF623731A1F43652475536D1C8B90A984D5033B2CC + 1B4D4C5C47E9276D8E144E8B5D4414429419FDA456A786F0CD5299DB11BB2311 + 95A18E8C2373A40BB738E6B02A7631D90CAE0C2E4175D51B91694F6778304499 + 19D8D5EC0A2FD516998B68CC1BDBDCD24FF1396A2C76758C3AB19BA0E9B60981 + 528F7493240D0A9FC161F47462B7BFF928859A0F77D087EF54C257D73573F1B3 + 21F2CF1878FFB57981A2D4C2D745D239C56B8E0CE5BFDE50B7B03212F60CF54E + 5D3E5F67D1A90B0E55CD9A33A3B5B1D15B5A5E7EF883679E3EB14A3ADE4F0242 + D7ED8D2E5B5EBF3D1B42178CA4D80556C39161E80C82EF03CDB23A32FE381A81 + F3C304175859D309560C95E2258618D7360C488E81891356B2F8E04B8261C36F + 5BAC1F2D98D4878FBD88E0C877B12BEAB33B92EE35F92E76B575818E267CCAFF + 9BEC8D6CA4630AA9915596EB961B4D3E33EA38E25DC4C4DFDF3B784E7090C47B + 9BCE4FD669B16B76BFCD5CB9AC1088EFFB7A83DFEC885D6094DAD92E3031A273 + 73976E7936429D651DAB62172029C49C722F4929141622287CD81BA123C1A870 + EF745AC043D39562B45F58860FF50CBDF62C76758C5AB1ABA567E5A42F2B02F2 + 2645EC06CDC46E6FC387D4BFED2F545E12C383D3E53DE7CA56C9E39BD1BA6D0B + 15B7BC4B5E4FEAC749F9F5C1D2354DB76B97BD30E58CEDC880765CA529C277C0 + EF1D7075F7D6EAFB593910BA60A4C52EB880D4F4B8A2E1C8F41F573C6B101ABF + B3704CA4BB8430C1D067BD6639A67FC2771B437CA9E2ADE258109F567CE844FD + 8B8DB0EAAF96EF62F72D0BEBFF3BA9D6DDB614EB40D82076312CF7A27EE4F92C + 76CD3AA10F923A1AE3646413B30C8BB024C34FF5A06EB999F53D5D9C6F2BE079 + 802511EFEC370CCE418B59084474165EB6797CA389B7990AFA74A11FED8A5D00 + 71FA63CA6C4E44AAF3C3FEF1DC89F90F8E11EC885D806C6AD34B3D54E5730F59 + 79617D859B019241A0C46C8CC1C0723CA9D84DE53E1779941D433463D25AC287 + 370E8B5D1D6342EC26E87BF4F2EFB9AAA77F43F27893C44DA8F51875EDD8D453 + 49AD83AE05EE598BB7BBA62D5818E9EDA596F54FA8A981D3558444BB4B5637CD + D52E5B3F75F12A45057F37EDC6C37446A29E851737BD5E9FE5AAC986D8B59A4E + 18E0A38FA1CCC42B6DD525C2093079265D43A845D4BFD88875646D9836DFC5EE + 5F492C12478237491547B85E885E3C3778EEA6922A4A3034FE71C17D25C857B1 + 5B12AFABEB4D7E475D427C20A6B6B03F970918BE82A04507D68AC0C1503FEA5F + FF2E392178F5298C13319DCD9E65B3FB636524468F59AA71BBD787F61856F35F + 937967CEAAD845075C3B511016D907C89E8517CFC1DF929AFA5B6F6040F4228C + E63558DDE968C7AED84D809BEA89ABDDB01D756B0F16BB3AC694D805F2865545 + 3DC79ABE25B9DD37FACACA2774EED949F2DECD14288A3F44C595EF7BCFFADCC9 + 480DDCFCD2F3035552B34FD477261A75CD2DFF51E3D0C7F2F9294B164A246F13 + 3CB54E99A4651734BCB93D07D5920DB10BAC862333F2DFB5EA12E104F0DF85D5 + B05F707DD144087AD0C0FDCAC2FA852076CD0441B6C857B10B20263141285544 + 0A3C3B10377807EDB836A0830AEB2946BDF44217D7001FD5FA14DB2F26754448 + 2FDEF0CCDD436A2C6A2B62DC15AF3FB828E95DA236C5CFC72CF280514C589194 + E766980DE727F6FB0D12F7A186951A1D0A58E51342121D75BD25DAAAD8BD9CD4 + 6FB0763FC8180A23CE36C1730378D6D031D0BB8B01A3EF7CDE90A9D8CD112C76 + 758C39B1ABE5C8F7977EABBFE1E0E5E3ABA27811A70D2EF4F8884E3A6B73EFDE + F76717875BAA44856EBC326E2F59D3F4A076D9FA298BEB29FD90692E852EC896 + D805A7923A44272A5E8CD209CF27554C6643F0A64B676C841D816627C44F2188 + 5D27FCA033219FC56EE2B81020A8E354AE375A9720FC3BD564407C35D1B14564 + 018CCE2C30584754E0605FB0EC62F8DCE83BFA54BCDE302135951847ECA58FC4 + AFD5286B1ECE07F33B3041D44CC099B928C10A0E21877BA217DE89BA801B17C2 + A9E9A30CCC22D53DC2E85B0697063C7F3F8B9F9FD179E1BACE217582A1F67D85 + 15FD99F8F568B193410DD7F410257F67706E7F886FB3D3A4EE71ED53E3F58D7A + 37BA7FD8CFD749F5CFCE550CE51185C56E6E60B16B80BCEA645F6F5FEB8D924B + C290DE29B6F743F44AE99AA673B4CB9E9FB2645D3C32448AEDA4453914BA209B + 62D74E3A61C4AF85FFAE36B310EE131A0291096B76B1E3B30B6065C1D0AC95D4 + CE7662041782D80556470444C0B95752FA8E68BE8B5D807712B16DE1D620FA3E + C1AA87FB0EE19B704140C704C27611A9CFA61956054E3AC10B2006372AE58DF8 + 79E19C6055C67702D661442730F3CDDF1D3F9F97D29C0F5C94F03C5C96A24E20 + BA0FC5FF9E4E6A9417D487D93B28FA3DDC1DDFF7AEF8DF65F1EB5A62705D890E + 3AC2563A952E18ED1AA2E118DD57B80C6D8AD73D3A41569E83BBE2D73E121322 + 47052C76B3C315CB665065A98FB6EE6DA537761D63B19B8EBEBB267E2526CB37 + 2897664B4485655F75E5FD87867AEF2F4C3EE35259929E325B5F11BAD7284277 + 5D8E2F3B9B6217E0C30A317893E0FA668D232CF2ABC8791F5E1C0F43B7685CED + CE3E5EA194E72DAC0FCBCF7A8BC72814B10B9C745F412706C3D16B05AEB110C4 + 6E0288435862D1A8894EE0B30A9E15C46DC53369C592A70D0FB8C4C1F3C1903C + 5C2C7609AE8F76E1511BF593EA1D843B030C22B8FF7626B66AC13707DFD50FC8 + 9974C1DA67ED74523BE54E1818ECBAA18C3958EC8E3C1EB78BAEBD681645A331 + 3AD8DC4BEBDF6A64B12B4AEF5D132F515EC11B952BBCC4CA762E89AE2A5EDDF4 + 48E26F7D08322DA344E8826C8B5D601686C80C0C956172833EE03A7CF03E41AA + 7871A211FC537C5FAF5366C36A98D481E7E07C8175F1427E85D4C920562824B1 + 0B4E886F6F67F21F4027063E9218E22D11BCC64212BB0970FFAF2635049693A2 + 17EF03DC25EA33D8472ADF4F2BC01A89A81CB0565AE9D0A2CDC3330FD7826A0B + DBA57B07B15F3C8B10F3734477AA03CFF52A1A1E89725AEC02270C0C4E3C0763 + 0616BBD9E1AC79B554E473D381A61EAA3FDAC362D72ABD774F5A2CC762374B24 + 5D29B48124FF31B0FAE8A5DA45EBA72E7E5A914D4943B0A348E8825C885D6035 + 9D702AFF59B80E2C8FFF8E214B2B0D214410ACEF68F8E03BEBC4909A59862023 + E08FFA03B22EAE0B4DEC02DCE74F29E55B24DEB949F81742DCC0275AB6708D85 + 2876B5E7044B3A3A62F87E59117709202AD1A9453DC27AEA945F265C04600DC5 + 64502B821C6E1778CF314A24FA3EE8C1BB8D217A749C3E25B03E9E3F7CE730C1 + AD27CDBA10937806F0CC89D637DEEF1F92EA86A1B5928E84D8D55E3F2CB3A21D + CFC437162E0B9B29CFADB95A58ECE60616BB3609DE3D795A2C26DF26C9F2D794 + ABF6A758756F604DD32CED020357865B56346C11C9DEC4D803BE7510424B49F5 + 6B83EF9AD65A02DF3AF8F86162C9A6F8DF23912A55247D30ACB9E81CBD91DB2A + 1B7360E87736A91D1BDC67DCDF45F1DF20B020C4619DDF18FF7F2641FA99E110 + 6EA8634C10C590363254A2A3951065897A4FBC5B1035E926B3650A2668C13F74 + 69BC4CD09CD3EEF8B9EC88FF1B0DDF87E49CD0C2A8D2C9A40ABE3349F50F4E08 + 6F3C7310F710A208DFD66C71DF898EC63252BF65DA7D27BE5F10B7988456EFC0 + 355911BB091293EF708E08E987FB80F8E5303440DC621ECA3BF13A78DD461DE4 + 058AD84DC4751F4B342862775FE28F59D73C394796E5E9B93E292BB85DD2D6DD + BFFE7C5BE67B522918B19B0093D982A1D6DB6459FA4749A2F1C7FDAE34AAA56B + 9A2AF4CB0705AF4BC203BF71C5E12D1B737D1D8C234048E35E1B856512F53185 + D50B2186AC646A63188671123B6297610A868213BB5A7A574EB89624E95645E1 + 0E8598522A6463C99A26513F5466ECA28DB800AB11428D2193529854EB171A0D + 11DF3BABB1751986619C86C52EC3A4A0A0C56E024C669364BA4D96A825B0BAE9 + F25C9F0F9315CC82DD5BC1EEC4348661182761B1CB302960B1CB14224E253A40 + 082684F2C9CB60EA0CC38C1958EC324C0A58EC32858813296CF336173CC33063 + 0E16BB0C930216BB4CA16125A49819988C06A1FBC75C5F0CC3300CB1D8659894 + B0D8650A8D19A4C6E8CC2493D79DA48AE5BC4D91C930CC9882C52EC3A480C52E + 536820B8FEAFC95E807DB08AD4280E7D36B7671886711A16BB0C930216BB4C21 + 62279D2A82ABAF52CAD35440D98318861913B0D8659814B0D8650A1964953A95 + D4B49CC8DE54476A262590C82605918BEC79C826C5D65C866146232C76192605 + 2C7619866118866198BC85C52EC3300CC3300C93B7B0D865188661188661F216 + 16BB0CC3300CC3304CDEC26297611886611886C95B58EC320CC3300CC330790B + 8B5D866118866118266F61B1CB300CC3300CC3E42DFF1FCED20B5884D2840600 + 00000049454E44AE426082} end object panContent: TPanel Left = 0 diff --git a/windows/src/desktop/setup/keyman_setup_sil.xcf b/windows/src/desktop/setup/keyman_setup_sil.xcf new file mode 100644 index 0000000000000000000000000000000000000000..61a535061318bda1af8bfbd614bb5ce2f1bd0c7a GIT binary patch literal 36105 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 literal 0 HcmV?d00001 From 0918b3985f68ff895fb25d53486e0cbad2307c0f Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 29 Aug 2024 08:48:06 +0700 Subject: [PATCH 045/127] fix(linux): add dependency --- linux/debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/debian/control b/linux/debian/control index 53d3710098b..fbe7066f5c2 100644 --- a/linux/debian/control +++ b/linux/debian/control @@ -91,6 +91,7 @@ Depends: gir1.2-webkit2-4.1 | gir1.2-webkit2-4.0, keyman-engine, python3-bs4, + python3-fonttools, python3-gi, python3-packaging, python3-sentry-sdk (>= 1.1), From 721bc9172eefd570bf59aa377dd455231cddae19 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Thu, 29 Aug 2024 10:01:45 +0700 Subject: [PATCH 046/127] fix(web): prevent unintuitive space-output blocking for mid-context suggestions Fixes: #12309 --- .../engine/interfaces/src/prediction/predictionContext.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/engine/interfaces/src/prediction/predictionContext.ts b/web/src/engine/interfaces/src/prediction/predictionContext.ts index cd856153b23..3ce0e936b45 100644 --- a/web/src/engine/interfaces/src/prediction/predictionContext.ts +++ b/web/src/engine/interfaces/src/prediction/predictionContext.ts @@ -209,7 +209,9 @@ export default class PredictionContext extends EventEmitter Date: Thu, 29 Aug 2024 13:21:08 +0700 Subject: [PATCH 047/127] docs(web): add documentation comments for touch layout interfaces --- .../keyman-touch-layout-file.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts index 786d9213e2b..4512024541e 100644 --- a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts +++ b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts @@ -7,6 +7,7 @@ // writing // +/** touch layout file consisting of specific layouts for tablet, phone, and desktop */ export interface TouchLayoutFile { tablet?: TouchLayoutPlatform; phone?: TouchLayoutPlatform; @@ -17,6 +18,7 @@ export type TouchLayoutFont = string; export type TouchLayoutFontSize = string; export type TouchLayoutDefaultHint = "none"|"dot"|"longpress"|"multitap"|"flick"|"flick-n"|"flick-ne"|"flick-e"|"flick-se"|"flick-s"|"flick-sw"|"flick-w"|"flick-nw"; +/** touch layout specification for a specific platform like phone or tablet */ export interface TouchLayoutPlatform { font?: TouchLayoutFont; fontsize?: TouchLayoutFontSize; @@ -27,6 +29,7 @@ export interface TouchLayoutPlatform { export type TouchLayoutLayerId = string; // pattern = /^[a-zA-Z0-9_-]+$/ +/** a layer with rows of keys on a touch layout */ export interface TouchLayoutLayer { id: TouchLayoutLayerId; row: TouchLayoutRow[]; @@ -34,6 +37,7 @@ export interface TouchLayoutLayer { export type TouchLayoutRowId = number; +/** a row of keys on a touch layout */ export interface TouchLayoutRow { id: TouchLayoutRowId; key: TouchLayoutKey[]; @@ -62,22 +66,37 @@ export const PRIVATE_USE_IDS = [ * * Make sure that when one is updated, the other also is. TS types are compile-time only, * so the run-time-accessible mapping in activeLayout.ts cannot be auto-generated by TS. */ +/** defines a key on a touch layout */ export interface TouchLayoutKey { + /** key id: used to find key in VKDictionary */ id?: TouchLayoutKeyId; + /** text to display on key cap */ text?: string; + /** current layer */ layer?: TouchLayoutLayerId; + /** next layer */ nextlayer?: TouchLayoutLayerId; + /** font */ font?: TouchLayoutFont; + /** fontsize */ fontsize?: TouchLayoutFontSize; + /** special key */ sp?: TouchLayoutKeySp; + /** padding */ pad?: TouchLayoutKeyPad; + /** width of the key */ width?: TouchLayoutKeyWidth; + /** subkeys */ sk?: TouchLayoutSubKey[]; + /** flicks */ flick?: TouchLayoutFlick; + /** multitaps */ multitap?: TouchLayoutSubKey[]; + /** hint e.g. for longpress */ hint?: string; }; +/** special keys like framekeys, deadkeys, blank, etc. */ export const enum TouchLayoutKeySp { normal=0, /** A 'frame' key, such as Shift or Enter, which is styled accordingly; uses @@ -102,29 +121,51 @@ export const enum TouchLayoutKeySp { spacer=10 }; +/** padding for a key */ export type TouchLayoutKeyPad = number; // 0-100000 +/** width of a key */ export type TouchLayoutKeyWidth = number; // 0-100000 +/** defines a subkey */ export interface TouchLayoutSubKey { + /** key id: used to find key in VKDictionary */ id: TouchLayoutKeyId; + /** text to display on key cap */ text?: string; + /** current layer */ layer?: TouchLayoutLayerId; + /** next layer */ nextlayer?: TouchLayoutLayerId; + /** font */ font?: TouchLayoutFont; + /** fontsize */ fontsize?: TouchLayoutFontSize; + /** special key */ sp?: TouchLayoutKeySp; + /** padding */ pad?: TouchLayoutKeyPad; + /** width of the key */ width?: TouchLayoutKeyWidth; + /** use this subkey if no other selected */ default?: boolean; // Only used for longpress currently }; +/** defines all possible flicks for a key */ export interface TouchLayoutFlick { + /** flick up */ n?: TouchLayoutSubKey; + /** flick down */ s?: TouchLayoutSubKey; + /** flick right */ e?: TouchLayoutSubKey; + /** flick left */ w?: TouchLayoutSubKey; + /** flick up-right */ ne?: TouchLayoutSubKey; + /** flick up-left */ nw?: TouchLayoutSubKey; + /** flick down-right */ se?: TouchLayoutSubKey; + /** flick down-left */ sw?: TouchLayoutSubKey; }; From 0f39a898412789f50f3ec016768c85df39f0dac0 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 29 Aug 2024 14:28:21 +0700 Subject: [PATCH 048/127] fix(android): Prioritize certain actions over multi-line for ENTER key --- .../java/com/keyman/engine/KMManager.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java index b921ac6c0ad..89690dffec0 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java @@ -1274,17 +1274,13 @@ public boolean accept(File pathname) { /** * Sets enterMode which specifies how the System keyboard ENTER key is handled * - * @param imeOptions EditorInfo.imeOptions - * @param inputType InputType + * @param imeOptions EditorInfo.imeOptions used to determine the action + * @param inputType InputType used to determine if the text field is multi-line */ public static void setEnterMode(int imeOptions, int inputType) { - if ((inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0) { - enterMode = EnterModeType.NEWLINE; - return; - } - - int imeActions = imeOptions & EditorInfo.IME_MASK_ACTION; EnterModeType value = EnterModeType.DEFAULT; + int imeActions = imeOptions & EditorInfo.IME_MASK_ACTION; + boolean isMultiLine = (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0; switch (imeActions) { case EditorInfo.IME_ACTION_GO: @@ -1296,7 +1292,8 @@ public static void setEnterMode(int imeOptions, int inputType) { break; case EditorInfo.IME_ACTION_SEND: - value = EnterModeType.SEND; + value = isMultiLine ? + EnterModeType.NEWLINE :EnterModeType.SEND; break; case EditorInfo.IME_ACTION_NEXT: @@ -1304,7 +1301,8 @@ public static void setEnterMode(int imeOptions, int inputType) { break; case EditorInfo.IME_ACTION_DONE: - value = EnterModeType.DONE; + value = isMultiLine ? + EnterModeType.NEWLINE : EnterModeType.DONE; break; case EditorInfo.IME_ACTION_PREVIOUS: @@ -1312,7 +1310,8 @@ public static void setEnterMode(int imeOptions, int inputType) { break; default: - value = EnterModeType.DEFAULT; + value = isMultiLine ? + EnterModeType.NEWLINE : EnterModeType.DEFAULT; } enterMode = value; From 9fa3eb098a1466c6d9b208038159e02cb03b6f01 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 29 Aug 2024 14:54:35 +0700 Subject: [PATCH 049/127] Apply suggestions from code review Co-authored-by: Marc Durdin --- .../keyman-touch-layout-file.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts index 4512024541e..7ea749906bc 100644 --- a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts +++ b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts @@ -7,7 +7,11 @@ // writing // -/** touch layout file consisting of specific layouts for tablet, phone, and desktop */ +/** + * On screen keyboard description consisting of specific layouts for tablet, phone, + * and desktop. Despite its name, this format is used for both touch layouts and + * hardware-style layouts. + */ export interface TouchLayoutFile { tablet?: TouchLayoutPlatform; phone?: TouchLayoutPlatform; @@ -68,25 +72,28 @@ export const PRIVATE_USE_IDS = [ * so the run-time-accessible mapping in activeLayout.ts cannot be auto-generated by TS. */ /** defines a key on a touch layout */ export interface TouchLayoutKey { - /** key id: used to find key in VKDictionary */ + /** key id: used to find key in VKDictionary, or a standard key from the K_ enumeration */ id?: TouchLayoutKeyId; /** text to display on key cap */ text?: string; - /** current layer */ + /** + * the modifier combination (not layer) that should be used in key events, + * for this key, overriding the layer that the key is a part of. + */ layer?: TouchLayoutLayerId; - /** next layer */ + /** the next layer to switch to after this key is pressed */ nextlayer?: TouchLayoutLayerId; /** font */ font?: TouchLayoutFont; /** fontsize */ fontsize?: TouchLayoutFontSize; - /** special key */ + /** the type of key */ sp?: TouchLayoutKeySp; /** padding */ pad?: TouchLayoutKeyPad; /** width of the key */ width?: TouchLayoutKeyWidth; - /** subkeys */ + /** longpress keys, also known as subkeys */ sk?: TouchLayoutSubKey[]; /** flicks */ flick?: TouchLayoutFlick; @@ -152,7 +159,7 @@ export interface TouchLayoutSubKey { /** defines all possible flicks for a key */ export interface TouchLayoutFlick { - /** flick up */ + /** flick up (north) */ n?: TouchLayoutSubKey; /** flick down */ s?: TouchLayoutSubKey; From 1d55100cb3ba246c9f5c789faf8ab134fd73fa17 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 29 Aug 2024 14:54:48 +0700 Subject: [PATCH 050/127] chore(common): Update crowdin strings for Czech --- .../src/main/res/values-cs-rCZ/strings.xml | 19 +++++++++++--- .../src/main/res/values-cs-rCZ/strings.xml | 24 +++++++++--------- .../KeymanEngine/cs.lproj/Localizable.strings | 2 +- .../cs.lproj/preferences.strings | 2 +- .../cs.lproj/KMInfoWindowController.strings | 2 +- .../Keyman4MacIM/cs.lproj/Localizable.strings | 21 +++++++++------- .../desktop/kmshell/locale/cs-CZ/strings.xml | 25 +++++++++++-------- .../desktop/setup/locale/cs-CZ/strings.xml | 8 +++--- 8 files changed, 61 insertions(+), 42 deletions(-) diff --git a/android/KMAPro/kMAPro/src/main/res/values-cs-rCZ/strings.xml b/android/KMAPro/kMAPro/src/main/res/values-cs-rCZ/strings.xml index bec7931da85..97da3115df7 100644 --- a/android/KMAPro/kMAPro/src/main/res/values-cs-rCZ/strings.xml +++ b/android/KMAPro/kMAPro/src/main/res/values-cs-rCZ/strings.xml @@ -33,6 +33,8 @@ Velikost textu nahoru Velikost textu dolů + + Posuvník velikosti textu \nVeškerý text bude vymazán\n @@ -51,6 +53,7 @@ Pro instalaci balíčků klávesnice povolte klávesnici oprávnění ke čtení externího úložiště. Žádost o oprávnění k úložišti byla zamítnuta. Může selhat instalace balíčku klávesnice + Žádost o oprávnění k úložišti se nezdařila. Zkuste nastavení Keyman - Instalovat z místního souboru Nastavení @@ -67,6 +70,8 @@ Upravit výšku klávesnice + Upravit zpoždění dlouhého stisknutí + Titulek mezerníku Keyboard @@ -85,7 +90,7 @@ Nezobrazovat titulek v mezerníku - Vibrate when typing + Při psaní vibrovat Vždy zobrazovat banner @@ -122,6 +127,14 @@ Otočit zařízení pro nastavení na výšku a na šířku Obnovit výchozí nastavení + + Doba zpoždění: %1$.1f sekund + + Prodloužit dobu zpoždění + + Zkrátit dobu zpoždění + + Posuvník doby zpoždění dlouhého stisknutí Hledat nebo zadat URL @@ -157,7 +170,7 @@ Neplatná/chybějící metadata v balíčku - Keyboard requires a newer version of Keyman + Klávesnice vyžaduje novější verzi Keyman - Unable to launch web browser + Nelze spustit webový prohlížeč diff --git a/android/KMEA/app/src/main/res/values-cs-rCZ/strings.xml b/android/KMEA/app/src/main/res/values-cs-rCZ/strings.xml index 1bcc7926603..db45a6706e0 100644 --- a/android/KMEA/app/src/main/res/values-cs-rCZ/strings.xml +++ b/android/KMEA/app/src/main/res/values-cs-rCZ/strings.xml @@ -49,7 +49,7 @@ Aktualizovat - No internet connection + Žádné připojení k internetu Nelze se připojit k Keyman serveru! @@ -88,7 +88,7 @@ Chyba v klávesnici %1$s:%2$s pro jazyk %3$s. Kontroluji související slovník ke stažení - Cannot connect to Keyman server to check for associated dictionary to download + Nelze se připojit ke Keyman serveru a zkontrolovat, zda je možné stáhnout přidružený slovník Chcete stáhnout nejnovější verzi tohoto slovníku? @@ -111,7 +111,7 @@ Stahování slovníku začalo na pozadí Vybraný slovník se již stahuje; zkuste to prosím za chvíli znovu! - + Stahování slovníku je dokončeno. Stahování se nezdařilo @@ -123,7 +123,7 @@ "Všechny zdroje jsou aktuální!" Aktualizace jednoho nebo více zdrojů selhala! - + Zdroje byly úspěšně aktualizovány! Verze slovníku @@ -132,11 +132,11 @@ Chcete odstranit tento slovník? - Dictionary deleted + Slovník smazán Klávesnice %1$s nainstalována - Keyboard deleted + Klávesnice smazána Povolit opravy @@ -144,14 +144,14 @@ Slovník - Dictionary - Dictionaries - Dictionaries - Dictionaries + Slovník + Slovníky + Slovníků + Slovníků Zkontrolovat dostupný slovník - Check for dictionaries online + Kouknout se na slovníky online Slovník: %1$s @@ -176,5 +176,5 @@ Klepnutím sem změníte klávesnici - Unable to launch web browser + Nelze spustit webový prohlížeč diff --git a/ios/engine/KMEI/KeymanEngine/cs.lproj/Localizable.strings b/ios/engine/KMEI/KeymanEngine/cs.lproj/Localizable.strings index 86f138adffe..0653ed3aeb0 100644 --- a/ios/engine/KMEI/KeymanEngine/cs.lproj/Localizable.strings +++ b/ios/engine/KMEI/KeymanEngine/cs.lproj/Localizable.strings @@ -125,7 +125,7 @@ "kmp-error-missing-resource" = "Tento balíček neobsahuje požadovanou klávesnici ani slovník."; /* Error installing a Keyman package with a version of Keyman that does not support it */ -"kmp-error-unsupported-keyman-version" = "This package requires a newer version of Keyman."; +"kmp-error-unsupported-keyman-version" = "Tento balíček vyžaduje novější verzi Keyman."; /* Error opening a Keyman package - cannot parse contents */ "kmp-error-no-metadata" = "Tento balíček nebyl správně sestaven - obsah není znám."; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/cs.lproj/preferences.strings b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/cs.lproj/preferences.strings index 305368c9ca1..9477b4c6378 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/cs.lproj/preferences.strings +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/cs.lproj/preferences.strings @@ -17,7 +17,7 @@ "JOK-JV-n8w.title" = "Zpět"; /* Keyboards button text */ -"MPN-9N-wWc.label" = "Keyboards"; +"MPN-9N-wWc.label" = "Klávesnice"; /* text to explain verbose Console logging option */ "MrI-GM-7d6.title" = "Když je zapnuta možnost detailního logování, Keyman zaznamená akce, které mohou pomoci Keymanovi diagnostikovat problém. Program konzole může být použit k zobrazení protokolu zpráv od Keymana. V konzoli filtr zobrazuje všechny zprávy z procesu \"Klíčové\". Tento log může být exportován a v případě potřeby odeslán na podporu klíče."; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/cs.lproj/KMInfoWindowController.strings b/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/cs.lproj/KMInfoWindowController.strings index f3fe6a722b1..4c9f26c0f84 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/cs.lproj/KMInfoWindowController.strings +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/cs.lproj/KMInfoWindowController.strings @@ -1,5 +1,5 @@ /* Package Information window title */ -"F0z-JX-Cv5.title" = "Package Information"; +"F0z-JX-Cv5.title" = "Informace o balíčku"; /* button text to show Details */ "Fvy-XJ-s38.label" = "Detaily"; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/cs.lproj/Localizable.strings b/mac/Keyman4MacIM/Keyman4MacIM/cs.lproj/Localizable.strings index f192a323683..31b54577b28 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/cs.lproj/Localizable.strings +++ b/mac/Keyman4MacIM/Keyman4MacIM/cs.lproj/Localizable.strings @@ -26,10 +26,10 @@ "message-keyboard-file-unreadable" = "Nelze číst soubor Keymana '%@'."; /* Message displayed in Configuration window when keyboard cannot be loaded */ -"message-error-loading-keyboard" = "(error loading keyboard)"; +"message-error-loading-keyboard" = "(chyba při načítání klávesnice)"; /* Message displayed in Configuration window when keyboard metadata cannot be loaded */ -"message-error-unknown-metadata" = "unknown"; +"message-error-unknown-metadata" = "neznámé"; /* Button text to acknowledge that .kmp file could not be read */ "button-keyboard-file-unreadable" = "OK"; @@ -50,22 +50,25 @@ "button-download-complete" = "Hotovo"; /* keyboards label in the Package Information window */ -"keyboards-label" = "Keyboards:"; +"keyboards-label" = "Klávesnice:"; /* fonts label in the Package Information window */ -"fonts-label" = "Fonts:"; +"fonts-label" = "Písma:"; /* package version label in the Package Information window */ -"package-version-label" = "Package Version:"; +"package-version-label" = "Verze balíčku:"; /* author label in the Package Information window */ -"author-label" = "Author:"; +"author-label" = "Autor:"; /* website label in the Package Information window */ -"website-label" = "Website:"; +"website-label" = "Webová stránka:"; /* copyright label in the Package Information window */ -"copyright-label" = "Copyright:"; +"copyright-label" = "Autorská práva:"; /* 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."; +"privacy-alert-text" = "Ke správné funkci vyžaduje Keyman zpřístupnění:\n\nPovolte přístup v Předvolbách systému, Zabezpečení a soukromí.\nRestartujte systém."; + +/* Text of menu item in Input Menu when no Keyboards are configured -- include parentheses */ +"no-keyboard-configured-menu-placeholder" = "(Žádná klávesnice nenastavena)"; diff --git a/windows/src/desktop/kmshell/locale/cs-CZ/strings.xml b/windows/src/desktop/kmshell/locale/cs-CZ/strings.xml index 0248e5185b8..d8ae71a33b6 100644 --- a/windows/src/desktop/kmshell/locale/cs-CZ/strings.xml +++ b/windows/src/desktop/kmshell/locale/cs-CZ/strings.xml @@ -47,7 +47,7 @@ - Add/remove language... + Přidat/odebrat jazyk... @@ -71,15 +71,15 @@ - Uninstall + Odinstalovat - Enable + Povolit - Disable + Zakázat @@ -191,7 +191,7 @@ - Add/remove language + Přidat/odebrat jazyk @@ -243,7 +243,7 @@ - Keyboard options... + Možnosti klávesnice... @@ -361,7 +361,7 @@ - (no hotkey) + (žádná klávesová zkratka) @@ -610,13 +610,16 @@ klávesnici, kterou používáte v systému Windows. Klávesnice se automaticky - Klíč Počáteční klíč + + Spustit %1$s + + Ukončit @@ -658,7 +661,6 @@ klávesnici, kterou používáte v systému Windows. Klávesnice se automaticky - Klíč @@ -782,7 +784,6 @@ klávesnici, kterou používáte v systému Windows. Klávesnice se automaticky - Klíč @@ -905,6 +906,10 @@ klávesnici, kterou používáte v systému Windows. Klávesnice se automaticky Vyberte klávesnici klávesnice pro nalezení souvisejících písma. + + + + Pro klávesnici %1$s nebyla nalezena žádná písma. diff --git a/windows/src/desktop/setup/locale/cs-CZ/strings.xml b/windows/src/desktop/setup/locale/cs-CZ/strings.xml index c5b42a648a4..196dc26a818 100644 --- a/windows/src/desktop/setup/locale/cs-CZ/strings.xml +++ b/windows/src/desktop/setup/locale/cs-CZ/strings.xml @@ -72,9 +72,7 @@ Restartovat nyní? Stahování %0:s Stahování %0:s - $APPNAME Instalace se nemohla připojit k keyman.com a stáhnout další zdroje. - -Zkontrolujte, zda jste online, a povolte $APPNAME nastavení přístupu k Internetu v nastavení firewall. - -Kliknutím na tlačítko Zrušit instalaci, zkuste znovu stáhnout zdroje znovu, nebo ignorujte pro pokračování v režimu offline. + $APPNAME Nastavení se nepodařilo připojit ke keyman.com a stáhnout další zdroje. + Zkontrolujte, zda jste online a zda jste v nastavení brány firewall udělili aplikaci $APPNAME Setup oprávnění k přístupu na internet. + Kliknutím na Přerušit ukončíte nastavení, kliknutím na Zkusit znovu se pokusíte znovu stáhnout prostředky nebo kliknutím na Ignorovat budete pokračovat v offline režimu. From dc265debd85252eb132e7279ceee9296dafe992b Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Thu, 29 Aug 2024 15:00:10 +0700 Subject: [PATCH 051/127] docs(web): more adjustments based on review comments --- .../keyman-touch-layout-file.ts | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts index 7ea749906bc..e24fd295c84 100644 --- a/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts +++ b/common/web/types/src/keyman-touch-layout/keyman-touch-layout-file.ts @@ -7,9 +7,9 @@ // writing // -/** - * On screen keyboard description consisting of specific layouts for tablet, phone, - * and desktop. Despite its name, this format is used for both touch layouts and +/** + * On screen keyboard description consisting of specific layouts for tablet, phone, + * and desktop. Despite its name, this format is used for both touch layouts and * hardware-style layouts. */ export interface TouchLayoutFile { @@ -76,8 +76,8 @@ export interface TouchLayoutKey { id?: TouchLayoutKeyId; /** text to display on key cap */ text?: string; - /** - * the modifier combination (not layer) that should be used in key events, + /** + * the modifier combination (not layer) that should be used in key events, * for this key, overriding the layer that the key is a part of. */ layer?: TouchLayoutLayerId; @@ -103,7 +103,7 @@ export interface TouchLayoutKey { hint?: string; }; -/** special keys like framekeys, deadkeys, blank, etc. */ +/** key type like regular key, framekeys, deadkeys, blank, etc. */ export const enum TouchLayoutKeySp { normal=0, /** A 'frame' key, such as Shift or Enter, which is styled accordingly; uses @@ -135,19 +135,22 @@ export type TouchLayoutKeyWidth = number; // 0-100000 /** defines a subkey */ export interface TouchLayoutSubKey { - /** key id: used to find key in VKDictionary */ + /** key id: used to find key in VKDictionary, or a standard key from the K_ enumeration */ id: TouchLayoutKeyId; /** text to display on key cap */ text?: string; - /** current layer */ + /** + * the modifier combination (not layer) that should be used in key events, + * for this key, overriding the layer that the key is a part of. + */ layer?: TouchLayoutLayerId; - /** next layer */ + /** the next layer to switch to after this key is pressed */ nextlayer?: TouchLayoutLayerId; /** font */ font?: TouchLayoutFont; /** fontsize */ fontsize?: TouchLayoutFontSize; - /** special key */ + /** the type of key */ sp?: TouchLayoutKeySp; /** padding */ pad?: TouchLayoutKeyPad; @@ -161,18 +164,18 @@ export interface TouchLayoutSubKey { export interface TouchLayoutFlick { /** flick up (north) */ n?: TouchLayoutSubKey; - /** flick down */ + /** flick down (south) */ s?: TouchLayoutSubKey; - /** flick right */ + /** flick right (east) */ e?: TouchLayoutSubKey; - /** flick left */ + /** flick left (west) */ w?: TouchLayoutSubKey; - /** flick up-right */ + /** flick up-right (north-east) */ ne?: TouchLayoutSubKey; - /** flick up-left */ + /** flick up-left (north-west) */ nw?: TouchLayoutSubKey; - /** flick down-right */ + /** flick down-right (south-east) */ se?: TouchLayoutSubKey; - /** flick down-left */ + /** flick down-left (south-west) */ sw?: TouchLayoutSubKey; }; From 569a8a8a49f14c6153d688dd39787c1780b1b7d3 Mon Sep 17 00:00:00 2001 From: sgschantz Date: Thu, 29 Aug 2024 15:38:00 +0700 Subject: [PATCH 052/127] fix(mac): eliminate all use of deprecated API beginSheetModalForWindow beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: was deprecated in macOS 10.10 and replaced by beginSheetModalForWindow:completionHandler: The newer API automatically closes the sheet. Explicitly closing the sheet also seemed to be causing the parent windows to close. Fixes: #9308 --- .../KMConfigurationWindowController.m | 43 +++++++++++-------- .../KMInfoWindow/KMInfoWindowController.m | 2 - .../Keyman4MacIM/KMInputMethodAppDelegate.m | 4 +- .../Keyman4MacIM/KMPackageReader.m | 7 --- mac/Keyman4MacIM/Keyman4MacIM/KeySender.m | 11 ++--- .../KME/OnScreenKeyboard/KeyView.m | 8 +++- .../KME/OnScreenKeyboard/OSKKey.m | 5 ++- .../KME/OnScreenKeyboard/OSKView.m | 2 +- 8 files changed, 43 insertions(+), 39 deletions(-) diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m index 3e2ffe24100..4a5f194241b 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m @@ -398,8 +398,8 @@ - (void)helpAction:(id)sender { } - (void)removeAction:(id)sender { - NSButton *removeButton = (NSButton *)sender; - NSDictionary *info = [self.tableContents objectAtIndex:removeButton.tag]; + NSButton *deleteButton = (NSButton *)sender; + NSDictionary *info = [self.tableContents objectAtIndex:deleteButton.tag]; NSString *deleteKeyboardMessage = NSLocalizedString(@"message-confirm-delete-keyboard", nil); if ([info objectForKey:@"HeaderTitle"] != nil) @@ -407,10 +407,13 @@ - (void)removeAction:(id)sender { else [self.deleteAlertView setMessageText:[NSString localizedStringWithFormat:deleteKeyboardMessage, [info objectForKey:kKMKeyboardNameKey]]]; - [self.deleteAlertView beginSheetModalForWindow:self.window - modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:(__bridge void *)([NSNumber numberWithInteger:removeButton.tag])]; + [self.deleteAlertView beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { + if (returnCode == NSAlertFirstButtonReturn) { + os_log_debug([KMLogs uiLog], "confirm delete keyboard alert dismissed"); + [self deleteFileAtIndex:[NSNumber numberWithInteger:deleteButton.tag]]; + self.deleteAlertView = nil; + } + }]; } - (IBAction)downloadAction:(id)sender { @@ -438,25 +441,29 @@ - (IBAction)useVerboseLoggingCheckBoxAction:(id)sender { } - (void)handleRequestToInstallPackage:(KMPackage *) package { + os_log_debug([KMLogs dataLog], "handleRequestToInstallPackage"); NSString *keyboardInfoString = NSLocalizedString(@"info-install-keyboard-filename", nil); [self.confirmKmpInstallAlertView setInformativeText:[NSString localizedStringWithFormat:keyboardInfoString, package.getOrigKmpFilename]]; os_log_debug([KMLogs uiLog], "Asking user to confirm installation of %{public}@, KMP - temp file name: %{public}@", package.getOrigKmpFilename, package.getTempKmpFilename); - [self.confirmKmpInstallAlertView beginSheetModalForWindow:self.window - modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:(__bridge void *)(package)]; + [self.confirmKmpInstallAlertView beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { + os_log_debug([KMLogs uiLog], "confirm keyboard installation alert dismissed"); + if (returnCode == NSAlertFirstButtonReturn) { + [self installPackageFile: package.getTempKmpFilename]; + self.confirmKmpInstallAlertView = nil; + } + }]; } - (void)installPackageFile:(NSString *)kmpFile { // kmpFile could be a temp file (in fact, it always is!), so don't display the name. - - os_log_debug([KMLogs dataLog], "KMP - Ready to unzip/install Package File: %{public}@", kmpFile); + os_log_debug([KMLogs dataLog], "kmpFile - ready to unzip/install Package File: %{public}@", kmpFile); BOOL didUnzip = [self.AppDelegate unzipFile:kmpFile]; if (!didUnzip) { + os_log_debug([KMLogs dataLog], "kmpFile, unzipFile failed"); NSAlert *failure = [[NSAlert alloc] init]; [failure addButtonWithTitle:NSLocalizedString(@"button-keyboard-file-unreadable", @"Alert button")]; @@ -465,13 +472,12 @@ - (void)installPackageFile:(NSString *)kmpFile { [failure setIcon:[[NSBundle mainBundle] imageForResource:@"logo.png"]]; [failure setAlertStyle:NSAlertStyleWarning]; - [failure beginSheetModalForWindow:self.window - modalDelegate:self - didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) - contextInfo:nil]; + [failure beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) { + os_log_debug([KMLogs uiLog], "kmpFile, keyboard file unreadable alert dismissed with returnCode: %ld", (long)returnCode); + }]; } else { - os_log_debug([KMLogs dataLog], "Completed installation of KMP file."); + os_log_debug([KMLogs dataLog], "kmpFile, completed installation of KMP file"); } } @@ -547,6 +553,7 @@ - (NSAlert *)confirmKmpInstallAlertView { return _confirmKmpInstallAlertView; } +/* - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { os_log_debug([KMLogs uiLog], "User responded to NSAlert"); if (alert == _deleteAlertView) { @@ -568,7 +575,7 @@ - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInf } // else, just a message - nothing to do. } - +*/ - (void)deleteFileAtIndex:(NSNumber *) n { NSInteger index = [n integerValue]; NSString *path2Remove = nil; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m index 6be446ddd28..32a8377b64d 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m @@ -85,8 +85,6 @@ - (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)ta // TODO: refactor: any reason for this to be HTML? hard to read stringWithFormat applied to template with 16 arguments - (NSString *)detailsHtml { - NSString *errorString = NSLocalizedString(@"message-keyboard-file-unreadable", nil); - @try { NSString *htmlFormat = @"" diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m index 0482f784328..d95982687b3 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m @@ -1340,7 +1340,9 @@ - (BOOL)unzipFile:(NSString *)filePath { NSError *error = nil; NSString *fileName = filePath.lastPathComponent; NSString *folderName = [fileName stringByDeletingPathExtension]; - + + os_log_debug([KMLogs keyboardLog], "unzipFile for filePath: %{public}@", filePath); + // First we unzip into a temp folder, and check kmp.json for the fileVersion // before we continue installation. We don't want to overwrite existing // package if it is there if the files are not compatible with the installed diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m index 7406488a8a0..6ee4402cb9a 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m @@ -251,14 +251,12 @@ - (KMPackageInfo *) loadPackageInfoFromInfFile:(NSString *)path { NSString *s = [line substringFromIndex:kName.length+1]; NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *v1 = [[vs objectAtIndex:0] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *v2 = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; builder.packageName = v1; } else if ([[line lowercaseString] hasPrefix:[kVersion lowercaseString]]) { NSString *s = [line substringFromIndex:kVersion.length+1]; NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *v1 = [[vs objectAtIndex:0] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *v2 = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; builder.packageVersion = v1; } else if ([[line lowercaseString] hasPrefix:[kAuthor lowercaseString]]) { @@ -273,14 +271,12 @@ - (KMPackageInfo *) loadPackageInfoFromInfFile:(NSString *)path { NSString *s = [line substringFromIndex:kCopyright.length+1]; NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *v1 = [[vs objectAtIndex:0] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *v2 = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; builder.copyright = v1; } else if ([[line lowercaseString] hasPrefix:[kWebSite lowercaseString]]) { NSString *s = [line substringFromIndex:kWebSite.length+1]; NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *v1 = [[vs objectAtIndex:0] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *v2 = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; builder.website = v1; } @@ -294,20 +290,17 @@ - (KMPackageInfo *) loadPackageInfoFromInfFile:(NSString *)path { NSString *s = [line substringFromIndex:x+2]; if ([[s lowercaseString] hasPrefix:[kFile lowercaseString]]) { NSArray *vs = [s componentsSeparatedByString:@"\","]; - NSString *v1 = [[[vs objectAtIndex:0] substringFromIndex:kFile.length+1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; NSString *fileName = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; [files addObject:fileName]; } else if ([[s lowercaseString] hasPrefix:[kFont lowercaseString]]) { NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *fontName = [[[vs objectAtIndex:0] substringFromIndex:kFont.length+1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *fontFileName = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; [fontArray addObject:fontName]; } else if ([[s lowercaseString] hasPrefix:[kKeyboard lowercaseString]]) { NSArray *vs = [s componentsSeparatedByString:@"\","]; NSString *keyboardName = [[[vs objectAtIndex:0] substringFromIndex:kKeyboard.length+1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - NSString *keyboardFileName = [[vs objectAtIndex:1] stringByReplacingOccurrencesOfString:@"\"" withString:@""]; KMKeyboardInfoBuilder *builder = [[KMKeyboardInfoBuilder alloc] init]; builder.name = keyboardName; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KeySender.m b/mac/Keyman4MacIM/Keyman4MacIM/KeySender.m index 417475c777d..dc73edc11bd 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/KeySender.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/KeySender.m @@ -1,9 +1,6 @@ /** * Keyman is copyright (C) SIL International. MIT License. * - * KeySender.m - * Keyman - * * Created by Shawn Schantz on 2023-04-17. * * Sends keydown events for the provided keycode to the frontmost application. @@ -56,15 +53,13 @@ - (void)postKeyboardEventWithSource: (CGEventSourceRef)source code:(CGKeyCode) v } /** - sendKeymanKeyCodeForEvent sends the kKeymanEventKeyCode to the - frontmost application to indicate that all the backspaces have been processed - and we can insert the queuedText to the client + * sendKeymanKeyCodeForEvent sends the kKeymanEventKeyCode to the + * frontmost application to indicate that all the backspaces have been processed + * and we can insert the queuedText to the client */ - (void)sendKeymanKeyCodeForEvent:(NSEvent *)event { os_log_debug([KMLogs keyLog], "KeySender sendKeymanKeyCodeForEvent"); - - ProcessSerialNumber psn; // Returns the frontmost app, which is the app that receives key events. NSRunningApplication *app = NSWorkspace.sharedWorkspace.frontmostApplication; diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m index c1dfa75a87a..9dfd39856bc 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m @@ -41,7 +41,10 @@ @implementation KeyView - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { - os_log_debug([KMELogs oskLog], "KeyView initWithFrame: %{public}@, bounds: %{public}@, default clipsToBounds %{public}@", NSStringFromRect(frame), NSStringFromRect(self.bounds), self.clipsToBounds?@"YES":@"NO"); + /* + // usually too much, but uncomment for debugging + os_log_debug([KMELogs oskLog], "KeyView initWithFrame: %{public}@, bounds: %{public}@, default clipsToBounds %{public}@", NSStringFromRect(frame), NSStringFromRect(self.bounds), self.clipsToBounds?@"YES":@"NO"); + */ self.clipsToBounds = true; CGSize size = frame.size; CGFloat x = size.width*0.05; @@ -70,7 +73,10 @@ - (id)initWithFrame:(NSRect)frame { } - (void)drawRect:(NSRect)rect { + /* + // usually too much, but uncomment for debugging os_log_debug([KMELogs uiLog], "KeyView drawRect: %{public}@, bounds: %{public}@, keyCode: 0x%lx, caption: %{public}@, label: %{public}@", NSStringFromRect(rect), NSStringFromRect(self.bounds), self.keyCode, self.caption.stringValue, self.label.stringValue); + */ [[self getOpaqueColorWithRed:241 green:242 blue:242] setFill]; NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m index d81097d3e2f..7ff40ccffea 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m @@ -14,7 +14,10 @@ @implementation OSKKey - (id)initWithKeyCode:(NSUInteger)keyCode caption:(NSString *)caption scale:(CGFloat)scale { self = [super init]; if (self) { - os_log_debug([KMELogs oskLog], "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale); + /* + // usually too much, but uncomment for debugging + os_log_debug([KMELogs oskLog], "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale); + */ _keyCode = keyCode; if (caption == nil) diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m index f5154fa76da..512920e0528 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m @@ -43,7 +43,7 @@ - (id)initWithFrame:(NSRect)frame { } - (void)drawRect:(NSRect)rect { - os_log_debug([KMELogs uiLog], "OSKView drawRect: %{public}@", NSStringFromRect(rect)); + os_log_debug([KMELogs oskLog], "OSKView drawRect: %{public}@", NSStringFromRect(rect)); CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext]; CGContextSetLineJoin(context, kCGLineJoinRound); From c8beeb9ab405fb41b96862bccd103f9cf528644a Mon Sep 17 00:00:00 2001 From: "Dr Mark C. Sinclair" Date: Thu, 29 Aug 2024 10:56:17 +0100 Subject: [PATCH 053/127] fix(developer): add two additional space test cases for index() in GetXStringImpl_type_i test --- .../kmcmplib/tests/gtest-compiler-test.cpp | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp index aab01f8131c..07d08ad156e 100644 --- a/developer/src/kmcmplib/tests/gtest-compiler-test.cpp +++ b/developer/src/kmcmplib/tests/gtest-compiler-test.cpp @@ -1091,34 +1091,45 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b,4)"); EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_index_comma_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; - EXPECT_EQ(0, u16cmp(tstr_index_comma_valid, tstr)); + const KMX_WCHAR tstr_index_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); // index, space before store, comma, valid fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index( b,4)"); EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_index_initial_space_and_comma_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; - EXPECT_EQ(0, u16cmp(tstr_index_initial_space_and_comma_valid, tstr)); + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); + + // index, space after store, comma, valid + fileKeyboard.cxStoreArray = 3u; + fileKeyboard.dpStoreArray = file_store; + u16cpy(str, u"index(b ,4)"); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); // index, comma and space, valid fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; u16cpy(str, u"index(b, 4)"); EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_index_comma_and_space_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; - EXPECT_EQ(0, u16cmp(tstr_index_comma_and_space_valid, tstr)); + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); + + // index, comma, space after offset, valid + fileKeyboard.cxStoreArray = 3u; + fileKeyboard.dpStoreArray = file_store; + u16cpy(str, u"index(b,4 )"); + EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); // index, space, valid ... should not be valid (see issue #11833) u16cpy(str, u"index(b 4)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - const KMX_WCHAR tstr_index_space_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 4, 0 }; - EXPECT_EQ(0, u16cmp(tstr_index_space_valid, tstr)); + EXPECT_EQ(0, u16cmp(tstr_index_valid, tstr)); - // index, two-digit parameter, valid + // index, two-digit offset, valid u16cpy(str, u"index(b,42)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; @@ -1126,25 +1137,25 @@ TEST_F(CompilerTest, GetXStringImpl_type_i_test) { const KMX_WCHAR tstr_index_two_digit_valid[] = { UC_SENTINEL, CODE_INDEX, 2, 42, 0 }; EXPECT_EQ(0, u16cmp(tstr_index_two_digit_valid, tstr)); - // index, comma, non-digit parameter, KmnCompilerMessages::ERROR_InvalidIndex + // index, comma, non-digit offset, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b,g)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, comma, no parameter, KmnCompilerMessages::ERROR_InvalidIndex + // index, comma, no offset, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b,)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, space and comma, no parameter, KmnCompilerMessages::ERROR_InvalidIndex + // index, space and comma, no offset, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b ,)"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidIndex, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE)); - // index, comma, no parameter but space, KmnCompilerMessages::ERROR_InvalidIndex + // index, comma, no offset but space, KmnCompilerMessages::ERROR_InvalidIndex u16cpy(str, u"index(b, )"); fileKeyboard.cxStoreArray = 3u; fileKeyboard.dpStoreArray = file_store; From 028a03c998f1a781816ee9ff71c2415a720457c7 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Thu, 29 Aug 2024 22:22:12 +1000 Subject: [PATCH 054/127] feat(windows): add sil global strings --- oem/firstvoices/windows/src/xml/keyman_support.xsl | 12 ++++++++++-- oem/firstvoices/windows/src/xml/strings.xml | 10 ++++++++++ windows/src/desktop/kmshell/xml/keyman_support.xsl | 12 ++++++++++-- windows/src/desktop/kmshell/xml/strings.xml | 10 ++++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/oem/firstvoices/windows/src/xml/keyman_support.xsl b/oem/firstvoices/windows/src/xml/keyman_support.xsl index dfd8c8445bd..81f72fdb66f 100644 --- a/oem/firstvoices/windows/src/xml/keyman_support.xsl +++ b/oem/firstvoices/windows/src/xml/keyman_support.xsl @@ -32,11 +32,19 @@

- + + + + +
- + + + + +