Date: Thu, 29 Aug 2024 15:38:00 +0700
Subject: [PATCH 06/22] 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 3e2ffe2410..4a5f194241 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m
@@ -398,8 +398,8 @@
}
- (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 @@
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 @@
}
- (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 @@
[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 @@
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 @@
}
// 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 6be446ddd2..32a8377b64 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInfoWindow/KMInfoWindowController.m
@@ -85,8 +85,6 @@
// 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 0482f78432..d95982687b 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m
@@ -1340,7 +1340,9 @@ extern const CGKeyCode kProcessPendingBuffer;
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 7406488a8a..6ee4402cb9 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMPackageReader.m
@@ -251,14 +251,12 @@ typedef enum {
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 @@ typedef enum {
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 @@ typedef enum {
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 417475c777..dc73edc11b 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 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
}
/**
- 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 c1dfa75a87..9dfd39856b 100644
--- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m
+++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m
@@ -41,7 +41,10 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
- (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 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
}
- (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 d81097d3e2..7ff40ccffe 100644
--- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m
+++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m
@@ -14,7 +14,10 @@
- (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 f5154fa76d..512920e052 100644
--- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m
+++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKView.m
@@ -43,7 +43,7 @@
}
- (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 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 07/22] 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 dfd8c8445b..81f72fdb66 100644
--- a/oem/firstvoices/windows/src/xml/keyman_support.xsl
+++ b/oem/firstvoices/windows/src/xml/keyman_support.xsl
@@ -32,11 +32,19 @@
-
+
+
+
+
+
-
+
+
+
+
+
diff --git a/oem/firstvoices/windows/src/xml/strings.xml b/oem/firstvoices/windows/src/xml/strings.xml
index d0708d2b4c..e71f4b2c90 100644
--- a/oem/firstvoices/windows/src/xml/strings.xml
+++ b/oem/firstvoices/windows/src/xml/strings.xml
@@ -512,6 +512,16 @@
Copyright © SIL International. All Rights Reserved.
+
+
+
+ Created by %1$s
+
+
+
+
+ Copyright © %1$s. All Rights Reserved.
+
diff --git a/windows/src/desktop/kmshell/xml/keyman_support.xsl b/windows/src/desktop/kmshell/xml/keyman_support.xsl
index d472f88155..4bf93f89bd 100644
--- a/windows/src/desktop/kmshell/xml/keyman_support.xsl
+++ b/windows/src/desktop/kmshell/xml/keyman_support.xsl
@@ -29,11 +29,19 @@
-
+
+
+
+
+
-
+
+
+
+
+
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml
index 774a4d5e42..9f9a8b105f 100644
--- a/windows/src/desktop/kmshell/xml/strings.xml
+++ b/windows/src/desktop/kmshell/xml/strings.xml
@@ -536,6 +536,16 @@
Copyright © SIL International. All Rights Reserved.
+
+
+
+
Created by %1$s
+
+
+
+
+
Copyright © %1$s. All Rights Reserved.
+
From 19cb236fe5cedb47bc152eb1ebc6facf636c3625 Mon Sep 17 00:00:00 2001
From: sgschantz
Date: Fri, 30 Aug 2024 15:05:58 +0700
Subject: [PATCH 08/22] fix(mac): open download info sheet from config window
Rather than opening from the keyboard download window
which is supposed to be closed by the download info
sheet. This prevents the download info sheet from
closing its own parent on which it depends.
---
.../Keyman4MacIM/KMInputMethodAppDelegate.m | 19 ++++++++++++++++---
.../Keyman4MacIM/KMSettingsRepository.m | 5 ++---
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m
index d0c7e808d5..78c6362de9 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMInputMethodAppDelegate.m
@@ -983,6 +983,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
return _configWindow;
}
+// TODO: rewrite confusing pattern, multiple methods differing only by underscore
- (NSWindowController *)aboutWindow_ {
return _aboutWindow;
}
@@ -1073,6 +1074,9 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
else if (returnCode == NSModalResponseOK) {
os_log_debug([KMLogs uiLog], "downloadComplete, returnCode == NSModalResponseOK");
+
+ [_downloadKBWindow close];
+
if (self.configWindow.window != nil) {
os_log_debug([KMLogs uiLog], "downloadComplete, self.configWindow.window != nil");
[self.configWindow.window makeKeyAndOrderFront:nil];
@@ -1135,6 +1139,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
[self downloadKeyboardFromURL:url];
}
+
- (void)downloadKeyboardFromURL:(NSURL *)url {
NSURL* downloadUrl = url;
os_log_debug([KMLogs uiLog], "downloadKeyboardFromURL, url.path: %{public}@", url.path);
@@ -1153,7 +1158,13 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
[self.downloadKBWindow.window centerInParent];
[self.downloadKBWindow.window makeKeyAndOrderFront:nil];
- [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window completionHandler:^(NSModalResponse returnCode) {
+
+ /*
+ Open sheet off of config window, not the download window.
+ This is because, if the download is successful,
+ the download window will be closed by the sheet.
+ */
+ [self.downloadInfoView beginSheetModalForWindow:self.configWindow.window completionHandler:^(NSModalResponse returnCode) {
[self downloadComplete:returnCode];
}];
}
@@ -1162,7 +1173,10 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
[self.downloadKBWindow.window centerInParent];
[self.downloadKBWindow.window makeKeyAndOrderFront:nil];
[self.downloadKBWindow.window setLevel:NSFloatingWindowLevel];
- [self.downloadInfoView beginSheetModalForWindow:self.downloadKBWindow.window completionHandler:^(NSModalResponse returnCode) {
+ /*
+ Open sheet off of config window, same as above.
+ */
+ [self.downloadInfoView beginSheetModalForWindow:self.configWindow.window completionHandler:^(NSModalResponse returnCode) {
[self downloadComplete:returnCode];
}];
}
@@ -1178,7 +1192,6 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
_receivedData = [[NSMutableData alloc] initWithLength:0];
_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
-
}
}
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m
index d8cca25f94..bbd87a40ec 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.m
@@ -251,7 +251,6 @@ NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInLibraryDirec
}
- (void)convertActiveKeyboardArrayForMigration {
- NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
NSMutableArray *keyboards = [self activeKeyboards];
NSMutableArray *convertedActiveKeyboards = [[NSMutableArray alloc] initWithCapacity:0];
BOOL didConvert = NO;
@@ -269,9 +268,9 @@ NSInteger const kCurrentDataModelVersionNumber = kVersionStoreDataInLibraryDirec
}
}
- // only update array in UserDefaults if we actually converted something
+ // only write array to UserDefaults if we actually converted something
if (didConvert) {
- [[NSUserDefaults standardUserDefaults] setObject:convertedActiveKeyboards forKey:kActiveKeyboardsKey];
+ [self writeActiveKeyboards:convertedActiveKeyboards];
}
}
From b38700cb19d5535a8c56259e629605a4a689046c Mon Sep 17 00:00:00 2001
From: sgschantz
Date: Mon, 2 Sep 2024 09:34:31 +0700
Subject: [PATCH 09/22] fix(mac): comment cleanup
---
mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h | 2 +-
.../KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m | 4 ++--
.../KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h
index 5a7f920c9f..8d7b114f2b 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMSettingsRepository.h
@@ -1,4 +1,4 @@
-/**
+/*
* Keyman is copyright (C) SIL International. MIT License.
*
* KMSettingsRepository.h
diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m
index 9dfd39856b..5b31cf8ffa 100644
--- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m
+++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/KeyView.m
@@ -42,7 +42,7 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
self = [super initWithFrame:frame];
if (self) {
/*
- // usually too much, but uncomment for debugging
+ // usually too much logging, 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;
@@ -74,7 +74,7 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
- (void)drawRect:(NSRect)rect {
/*
- // usually too much, but uncomment for debugging
+ // usually too much logging, 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);
*/
diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m
index 7ff40ccffe..b1144a17fa 100644
--- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m
+++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/KME/OnScreenKeyboard/OSKKey.m
@@ -15,7 +15,7 @@
self = [super init];
if (self) {
/*
- // usually too much, but uncomment for debugging
+ // usually too much logging, uncomment for debugging
os_log_debug([KMELogs oskLog], "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale);
*/
_keyCode = keyCode;
From 10c343fc432641b1df11fa73e0e852fde2c6c7cf Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Mon, 2 Sep 2024 13:31:21 +1000
Subject: [PATCH 10/22] feat(windows): change verb use to allow for clarity
---
common/windows/delphi/general/RegistryKeys.pas | 8 ++++----
windows/src/desktop/kmshell/xml/strings.xml | 2 +-
.../keyman32/k32_lowlevelkeyboardhook.cpp | 18 +++++++++---------
.../engine/kmcomapi/util/utilkeymanoption.pas | 2 +-
4 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/common/windows/delphi/general/RegistryKeys.pas b/common/windows/delphi/general/RegistryKeys.pas
index 0553b82306..e351b3860f 100644
--- a/common/windows/delphi/general/RegistryKeys.pas
+++ b/common/windows/delphi/general/RegistryKeys.pas
@@ -113,11 +113,11 @@ const
SRegValue_ShowWelcome = 'show welcome'; // CU
SRegValue_UseAdvancedInstall = 'use advanced install'; // CU
- SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU
- SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU
- SRegValue_UseRightModifierHotKey = 'use right modifier for hotkey'; // CU
+ SRegValue_AltGrCtrlAlt = 'simulate altgr'; // CU
+ SRegValue_KeyboardHotKeysAreToggle = 'hotkeys are toggles'; // CU
+ SRegValue_AllowRightModifierHotKey = 'allow right modifier for hotkey'; // CU
SRegValue_ReleaseShiftKeysAfterKeyPress = 'release shift keys after key press'; // CU
- SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true
+ SRegValue_TestKeymanFunctioning = 'test keyman functioning'; // CU, default true
SRegValue_CreateStartMenuAsSubfolders = 'create start menu as subfolders'; // CU
SRegValue_CreateUninstallEntries = 'create uninstall entries'; // CU
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml
index 9409d6d8c1..8b6c37c55c 100644
--- a/windows/src/desktop/kmshell/xml/strings.xml
+++ b/windows/src/desktop/kmshell/xml/strings.xml
@@ -380,7 +380,7 @@
- Right-side modifier keys trigger hotkeys
+ Allow right modifier for hotkeys
diff --git a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
index efd5d158bb..a6a84faf44 100644
--- a/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
+++ b/windows/src/engine/keyman32/k32_lowlevelkeyboardhook.cpp
@@ -130,22 +130,22 @@ BOOL IsTouchPanelVisible() {
}
/*
- Cache UseRightModifierHotKey for this session
+ Cache AllowRightModifierHotKey for this session
*/
-BOOL UseRightModifierHotKey() {
- static BOOL flag_UseRightModifierHotKey = FALSE;
+BOOL AllowRightModifierHotKey() {
+ static BOOL flag_AllowRightModifierHotKey = FALSE;
static BOOL loaded = FALSE;
if (!loaded) {
RegistryReadOnly reg(HKEY_CURRENT_USER);
if (reg.OpenKeyReadOnly(REGSZ_KeymanCU)) {
if (reg.ValueExists(REGSZ_AllowRightModifierHotKey)) {
- flag_UseRightModifierHotKey = !!reg.ReadInteger(REGSZ_AllowRightModifierHotKey);
+ flag_AllowRightModifierHotKey = !!reg.ReadInteger(REGSZ_AllowRightModifierHotKey);
}
}
loaded = TRUE; // Set loaded to TRUE whether or not the key exists
}
- return flag_UseRightModifierHotKey;
+ return flag_AllowRightModifierHotKey;
}
LRESULT _kmnLowLevelKeyboardProc(
@@ -176,7 +176,7 @@ LRESULT _kmnLowLevelKeyboardProc(
}
if (GetKeyState(VK_RCONTROL) < 0) {
- FHotkeyShiftState |= UseRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID;
+ FHotkeyShiftState |= AllowRightModifierHotKey() ? HK_CTRL : HK_RCTRL_INVALID;
}
if (GetKeyState(VK_LMENU) < 0) {
@@ -184,18 +184,18 @@ LRESULT _kmnLowLevelKeyboardProc(
}
if (GetKeyState(VK_RMENU) < 0) {
- FHotkeyShiftState |= UseRightModifierHotKey() ? HK_ALT : HK_RALT_INVALID;
+ FHotkeyShiftState |= AllowRightModifierHotKey() ? 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 |= AllowRightModifierHotKey() ? HK_SHIFT : HK_RSHIFT_INVALID;
}
//TODO: #8064. Can remove debug message once issue #8064 is resolved
- SendDebugMessageFormat("!UseCachedHotkeyModifierState [FHotkeyShiftState:%x]", FHotkeyShiftState);
+ SendDebugMessageFormat("[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,
diff --git a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
index 2df38b5c82..906e121f07 100644
--- a/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
+++ b/windows/src/engine/kmcomapi/util/utilkeymanoption.pas
@@ -127,7 +127,7 @@ const KeymanOptionInfo: array[0..16] of TKeymanOptionInfo = ( // I3331 // I36
(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: koRightModifierHK; RegistryName: SRegValue_AllowRightModifierHotKey; 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'),
From cad009acc2627c72fa572f5cbcdbf5b6eb6d4ea4 Mon Sep 17 00:00:00 2001
From: rc-swag <58423624+rc-swag@users.noreply.github.com>
Date: Mon, 2 Sep 2024 17:03:37 +1000
Subject: [PATCH 11/22] feat(windows): Fix string id name
---
oem/firstvoices/windows/src/xml/strings.xml | 2 +-
windows/src/desktop/kmshell/xml/strings.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/oem/firstvoices/windows/src/xml/strings.xml b/oem/firstvoices/windows/src/xml/strings.xml
index e71f4b2c90..fbd099c8c7 100644
--- a/oem/firstvoices/windows/src/xml/strings.xml
+++ b/oem/firstvoices/windows/src/xml/strings.xml
@@ -520,7 +520,7 @@
- Copyright © %1$s. All Rights Reserved.
+ Copyright © %1$s. All Rights Reserved.
diff --git a/windows/src/desktop/kmshell/xml/strings.xml b/windows/src/desktop/kmshell/xml/strings.xml
index 9f9a8b105f..bf4cccc117 100644
--- a/windows/src/desktop/kmshell/xml/strings.xml
+++ b/windows/src/desktop/kmshell/xml/strings.xml
@@ -544,7 +544,7 @@
- Copyright © %1$s. All Rights Reserved.
+ Copyright © %1$s. All Rights Reserved.
From cc2c917bc2babfa1a316fec81bd8637d786eec02 Mon Sep 17 00:00:00 2001
From: sgschantz
Date: Mon, 2 Sep 2024 15:56:50 +0700
Subject: [PATCH 12/22] fix(mac): nil window references after dismissing
dialogs
also delete commented code
---
.../KMConfigurationWindowController.m | 28 ++-----------------
1 file changed, 3 insertions(+), 25 deletions(-)
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m
index 027e4f9bc2..c99d632665 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/KMConfiguration/KMConfigurationWindowController.m
@@ -422,8 +422,8 @@
if (returnCode == NSAlertFirstButtonReturn) {
os_log_debug([KMLogs uiLog], "confirm delete keyboard alert dismissed");
[self deleteFileAtIndex:[NSNumber numberWithInteger:deleteButton.tag]];
- self.deleteAlertView = nil;
}
+ self.deleteAlertView = nil;
}];
}
@@ -462,8 +462,9 @@
os_log_debug([KMLogs uiLog], "confirm keyboard installation alert dismissed");
if (returnCode == NSAlertFirstButtonReturn) {
[self installPackageFile: package.getTempKmpFilename];
- self.confirmKmpInstallAlertView = nil;
}
+ [package releaseTempKMPFile];
+ self.confirmKmpInstallAlertView = nil;
}];
}
@@ -564,29 +565,6 @@
return _confirmKmpInstallAlertView;
}
-/*
-- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
- os_log_debug([KMLogs uiLog], "User responded to NSAlert");
- if (alert == _deleteAlertView) {
- if (returnCode == NSAlertFirstButtonReturn) { // Delete
- [self deleteFileAtIndex:(__bridge NSNumber *)contextInfo];
- }
-
- _deleteAlertView = nil;
- }
- else if (alert == _confirmKmpInstallAlertView) {
- KMPackage *package = (__bridge KMPackage *)contextInfo;
- os_log_debug([KMLogs uiLog], "KMP - Temp file: %{public}@", package.getTempKmpFilename);
- if (returnCode == NSAlertFirstButtonReturn) { // Install
- [self installPackageFile: package.getTempKmpFilename];
- }
-
- [package releaseTempKMPFile];
- _confirmKmpInstallAlertView = nil;
- }
- // else, just a message - nothing to do.
-}
-*/
- (void)deleteFileAtIndex:(NSNumber *) n {
NSInteger index = [n integerValue];
NSString *path2Remove = nil;
From 33715a0b389fa77ff52463c16eb574860c89250a Mon Sep 17 00:00:00 2001
From: Keyman Build Agent
Date: Mon, 2 Sep 2024 14:02:38 -0400
Subject: [PATCH 13/22] auto: increment master version to 18.0.104
---
HISTORY.md | 5 +++++
VERSION.md | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/HISTORY.md b/HISTORY.md
index a99386923b..6a45fe68ea 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,5 +1,10 @@
# Keyman Version History
+## 18.0.103 alpha 2024-09-02
+
+* feat(windows): Remove hotkey related feature flags (#12252)
+* feat(windows): update SIL logo for Windows UI (#12250)
+
## 18.0.102 alpha 2024-08-30
* docs(web): add documentation comments for touch layout interfaces (#12314)
diff --git a/VERSION.md b/VERSION.md
index 237f3b532e..6451a36310 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-18.0.103
\ No newline at end of file
+18.0.104
\ No newline at end of file
From 99adf9c7e1db99e88d01d489889a9248a2239997 Mon Sep 17 00:00:00 2001
From: Darcy Wong
Date: Tue, 3 Sep 2024 11:05:13 +0700
Subject: [PATCH 14/22] chore(common): Fix missing entries in HISTORY.md
---
HISTORY.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/HISTORY.md b/HISTORY.md
index 6a45fe68ea..2bc57835ac 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -25,7 +25,7 @@
* fix(android): Prioritize certain actions over multi-line for ENTER key (#12315)
* fix(linux): add `keymanFacename` to .ldml file (#12277)
* chore(common): Update crowdin strings for Czech (#12316)
-* (#12313)
+* fix(web): prevent unintuitive space-output blocking for mid-context suggestions (#12313)
## 18.0.100 alpha 2024-08-28
@@ -35,8 +35,8 @@
* feat(web): import the generator for the pred-text wordbreaker's Unicode-property data-table (#10690)
* feat(web): optimize the wordbreaker data table for filesize and ease of first-load parsing (#10692)
-* (#12297)
-* (#12115)
+* fix(web): fixes wordbreaker test import path (#12297)
+* feat(web): enable utf8 charset encoding for the build artifacts (#12115)
## 18.0.98 alpha 2024-08-26
@@ -81,11 +81,11 @@
## 18.0.93 alpha 2024-08-20
-* (#12188)
+* refactor(web): remove engine/interfaces dependency on engine/js-processor (#12188)
* fix(web): fix malformed reversion display strings (#12201)
* feat(android): Add menu to specify long-press delay (#12170)
* feat(android): Pass longpress delay to KeymanWeb (#12185)
-* (#12223)
+* fix(core): set mac build version for meson cli build to 10.13 (#12223)
## 18.0.92 alpha 2024-08-19
From f5677782b0157ce2b5faa1d107df9068471238fd Mon Sep 17 00:00:00 2001
From: sgschantz
Date: Tue, 3 Sep 2024 13:07:25 +0700
Subject: [PATCH 15/22] fix(mac): check for macOS 11 for PostEvent access
CGPreflightPostEventAccess API should be available
with macOS 10.5 (Catalina) but that does not appear
to be true in experience. Changing to check for 11.0
(Big Sur) before using that API instead.
Fixes: #12295
---
.../Keyman4MacIM/Privacy/PrivacyConsent.m | 58 ++++++++++---------
1 file changed, 31 insertions(+), 27 deletions(-)
diff --git a/mac/Keyman4MacIM/Keyman4MacIM/Privacy/PrivacyConsent.m b/mac/Keyman4MacIM/Keyman4MacIM/Privacy/PrivacyConsent.m
index 057f401cbe..89e6338852 100644
--- a/mac/Keyman4MacIM/Keyman4MacIM/Privacy/PrivacyConsent.m
+++ b/mac/Keyman4MacIM/Keyman4MacIM/Privacy/PrivacyConsent.m
@@ -1,4 +1,4 @@
-/**
+/*
* Keyman is copyright (C) SIL International. MIT License.
*
* PrivacyConsent.m
@@ -7,8 +7,8 @@
* Created by Shawn Schantz on 2022-09-22.
*
* Used to determine if the user has provided consent to the services it needs
- * and, if not, to request that consent. For versions of macOS prior to 10.15,
- * Keyman requires Accessibility access. For 10.15 and later, Keyman requires
+ * and, if not, to request that consent. For versions of macOS prior to 11.0,
+ * Keyman requires Accessibility access. For 11.0 and later, Keyman requires
* PostEvent access. Both are presented to the user as a need for Accessibility
* when prompted by the system and are listed under Accessibility in the Privacy
* tab in System Preferences, Security & Privacy. Both Accessibility and
@@ -16,7 +16,11 @@
* that access is not explicitly needed as long as one of the others is provided
* first.
*
- * Access this functionality through the shared instance. Call
+ * Note that Apple's documentation states that the PostEvent access APIs are
+ * available with macOS 10.15 (Catalina) but testing showed that it was only
+ * available with macOS 11.0 (Big Sur). This is documented with issue #12295.
+ *
+ * To access this functionality, used the shared instance. Call
* requestPrivacyAccess which will check whether access has been granted. If
* not, then a dialog will be presented to the user to inform them that
* Accessibility is required. Dismissing this dialog will trigger the API call
@@ -24,7 +28,7 @@
* only happen once. If the user was prompted earlier and did not grant access,
* they can still go to System Preferences and enable it there. So it is useful
* to prompt with a dialog from Keyman at startup. Without Accessibility, the
- * shift layer and the OSK do not work -- so Keyman is basically useless.
+ * shift layer and the OSK do not work.
*/
#import "PrivacyConsent.h"
@@ -43,7 +47,7 @@
}
/**
- * For macOS earlier than 10.15: check for Accessibility access.
+ * For macOS earlier than 11.0: check for Accessibility access.
*/
- (BOOL)checkAccessibility
{
@@ -66,7 +70,7 @@
BOOL hasAccessibility = NO;
// check if we already have accessibility
- if (@available(macOS 10.15, *)) {
+ if (@available(macOS 11.0, *)) {
hasAccessibility = [self checkPostEventAccess];
} else {
hasAccessibility = [self checkAccessibility];
@@ -85,7 +89,7 @@
}
/**
- * For macOS earlier than 10.15: request Accessibility access.
+ * For macOS earlier than 11.0: request Accessibility access.
*/
- (void)requestAccessibility
{
@@ -113,18 +117,18 @@
*/
- (void)configureDialogForOsVersion {
- if (@available(macOS 10.15, *)) {
- [self configureDialogForCatalinaAndLater];
+ if (@available(macOS 11.0, *)) {
+ [self configureDialogForBigSurAndLater];
} else {
- [self configureDialogForPreCatalina];
+ [self configureDialogForPreBigSur];
}
}
/**
- * Initialize privacy dialog for macOS versions prior to Catalina (10.15).
+ * Initialize privacy dialog for macOS versions prior to Big Sur (11.0).
* In this case, request Accessibility access, not PostEvent.
*/
-- (void)configureDialogForPreCatalina {
+- (void)configureDialogForPreBigSur {
void (^consentPrompt)(void) = ^(void) {
[self requestAccessibility];
@@ -136,10 +140,10 @@
}
/**
- * Initialize privacy dialog for macOS versions of Catalina (10.15) or later.
+ * Initialize privacy dialog for macOS versions of Big Sur (11.0) or later.
* In this case, request PostEvent access, not Accessibility.
*/
-- (void)configureDialogForCatalinaAndLater {
+- (void)configureDialogForBigSurAndLater {
void (^consentPrompt)(void) = ^(void) {
[self requestPostEventAccess];
@@ -160,7 +164,7 @@
/**
* Check whether the user has allowed ListenEvent access.
- * Only available with macOS Catalina (10.15) or later.
+ * Only available with macOS Big Sur (11.0) or later.
*
* If user has granted Accessibility or PostEvent access, then
* ListenEvent access is also granted.
@@ -170,18 +174,18 @@
BOOL hasAccess = NO;
// below checks for ListenEvent access
- if (@available(macOS 10.15, *)) {
+ if (@available(macOS 11.0, *)) {
hasAccess = CGPreflightListenEventAccess();
os_log([KMLogs privacyLog], "CGPreflightListenEventAccess() returned %@", hasAccess ? @"YES" : @"NO");
} else {
- os_log([KMLogs privacyLog], "CGPreflightListenEventAccess not available before macOS version 10.15");
+ os_log([KMLogs privacyLog], "CGPreflightListenEventAccess not available before macOS version 11.0");
}
return hasAccess;
}
/**
* Check whether the user has allowed PostEvent access.
- * Only available with macOS Catalina (10.15) or later.
+ * Only available with macOS Big Sur (11.0) or later.
*
* If user has granted Accessibility, then PostEvent access is also granted.
*/
@@ -190,46 +194,46 @@
BOOL hasAccess = NO;
// below checks for PostEvent access
- if (@available(macOS 10.15, *)) {
+ if (@available(macOS 11.0, *)) {
hasAccess = CGPreflightPostEventAccess();
os_log([KMLogs privacyLog], "CGPreflightPostEventAccess() returned %@", hasAccess ? @"YES" : @"NO");
} else {
- os_log([KMLogs privacyLog], "CGPreflightPostEventAccess not available before macOS version 10.15");
+ os_log([KMLogs privacyLog], "CGPreflightPostEventAccess not available before macOS version 11.0");
}
return hasAccess;
}
/**
* Request ListenEvent access.
- * Only available with macOS Catalina (10.15) or later.
+ * Only available with macOS Big Sur (11.0) or later.
*/
- (BOOL)requestListenEventAccess
{
BOOL granted = NO;
- if (@available(macOS 10.15, *)) {
+ if (@available(macOS 11.0, *)) {
granted = CGRequestListenEventAccess();
os_log([KMLogs privacyLog], "CGRequestListenEventAccess() returned %@", granted ? @"YES" : @"NO");
} else {
- os_log([KMLogs privacyLog], "CGRequestListenEventAccess not available before macOS version 10.15");
+ os_log([KMLogs privacyLog], "CGRequestListenEventAccess not available before macOS version 11.0");
}
return granted;
}
/**
* Request PostEvent access.
- * Only available with macOS Catalina (10.15) or later.
+ * Only available with macOS Big Sur (11.0) or later.
*/
- (BOOL)requestPostEventAccess
{
BOOL granted = NO;
- if (@available(macOS 10.15, *)) {
+ if (@available(macOS 11.0, *)) {
granted = CGRequestPostEventAccess();
os_log([KMLogs privacyLog], "CGRequestPostEventAccess() returned %@", granted ? @"YES" : @"NO");
} else {
- os_log([KMLogs privacyLog], "CGRequestPostEventAccess not available before macOS version 10.15");
+ os_log([KMLogs privacyLog], "CGRequestPostEventAccess not available before macOS version 11.0");
}
return granted;
}
From ca48f44065b9b067c5afbd38721f83d60d7977b8 Mon Sep 17 00:00:00 2001
From: Keyman Build Agent
Date: Tue, 3 Sep 2024 14:02:35 -0400
Subject: [PATCH 16/22] auto: increment master version to 18.0.105
---
HISTORY.md | 4 ++++
VERSION.md | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/HISTORY.md b/HISTORY.md
index 6a45fe68ea..bbf7e3960b 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,5 +1,9 @@
# Keyman Version History
+## 18.0.104 alpha 2024-09-03
+
+* fix(mac): display package info after keyboard installation (#12326)
+
## 18.0.103 alpha 2024-09-02
* feat(windows): Remove hotkey related feature flags (#12252)
diff --git a/VERSION.md b/VERSION.md
index 6451a36310..65cb0d73ef 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-18.0.104
\ No newline at end of file
+18.0.105
\ No newline at end of file
From 0a42e5bba60a4e5f54774975697d5e78ea08cbb9 Mon Sep 17 00:00:00 2001
From: Darcy Wong
Date: Wed, 4 Sep 2024 12:54:55 +0700
Subject: [PATCH 17/22] docs(android): Add in-app help for adjusting longpress
delay
---
android/help/android_images/ic_timelapse.png | Bin 0 -> 2943 bytes
.../help/android_images/longpress-slider.png | Bin 0 -> 6054 bytes
.../android_images/settings-screen-ap.png | Bin 28237 -> 38196 bytes
.../basic/config/adjust-longpress-delay.md | 13 +++++++++++++
android/help/basic/config/index.md | 5 +++++
5 files changed, 18 insertions(+)
create mode 100644 android/help/android_images/ic_timelapse.png
create mode 100644 android/help/android_images/longpress-slider.png
create mode 100644 android/help/basic/config/adjust-longpress-delay.md
diff --git a/android/help/android_images/ic_timelapse.png b/android/help/android_images/ic_timelapse.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f948825b2c55ccd2048dc1f2158ce52635b44d7
GIT binary patch
literal 2943
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
literal 28237
zcmb@t1zc3!)-Zk$kd}~cX{Dr5VhAY_3F#qJq#OrC8U{vCxCiq+3d)yFmm*8ipP~
z8fH*ngaN+eeeQklbHDF>fB)RWX4db_j#Yc@wb$C`V)|kUpt-B5qX`fY5C9Ls4{)&z
z$ZGgFI{<*59&iHy08-!*0UbaHLImIkAdmnqfiMYJ1;7euxw<+&vj_X3FA3?WtJ@kF
z>1*oT(*OqqfJ@AOT3n(50Jw|C3nMKxZgUGu?my4|RUX;7KmQl}-+Y5(98Lb26#&LW
z|C`_cuO5*-v3Iuv8)3le@dBJ2#QzBh(>wkJ`}~0){{=_?fnOLKse^5@Kv>A}Z}8*4
z!QLLvJ-{|!{5GwR>Z__6?i`ZWO54nKeN;?X~lAp-wjasVZMPzV52
z765SdI{=VF|Apwk`~F)N{{yYuU>|mnPFL{b2s{Jq0d7DCZ~^Q9F%XgjZUPd3?8Pjg
z4(b%apTB<=LSn){@kDGBMH7XQ!6MLR%CO7Ig{CM4hiF3}PY(h^*B16-i|h{5&nXG#3C5L_Z8
zBEAfwL{0%VsG$MTCnUTCB1=pJGLIkt{2d^oC8oP3p?dkM;Uf|rH+spS_-s;MwaN|#
zqY(_B)Z-VyWaNxY%q*<@0)j%
zx_fwfdHeYKy?PxI8WtWAnUMH4DLLic`_!D=y!?W~qT-LAtEy{i>*^aCJG;7jdi%cg
ze;pkgpO~DQoq5z+z>AfZlrKeTbOYf;|1wu&-w
z16-wx>+Qp7nyUyFWrlwbob69G!o~YimBNDTMxKo9rRunv?wxNfn$U1)n6zro+!HY|
zlq2qXsNi}n+yJ6kJebmmOpzz|@%?IRk(88Pw^-1BE^E4_!`0D7r;E%%^%VBGc~{J7
zIXV)_8T1Q&!1mqfh;CYlbVqlUlc6vlYUt#
z+O-LSo!+-`PJj-;@;3t!(Vw5{y;$&Dl&=e(uNC|L&@}cEDRIQlJhsR;x#8IRtqa0f
z<@}G*642UwPtlP`NCS(vXiY%qbK%=BiWXaA2frmlnFWK>-d2=NCVxJ#TsX#y)p$r~
z3gy%)8uT#dL;@0#LIo^uxtiP30p-ZJVcY${YTxa%HT>pG5I+M~M%%)f)6bOCf!`wz
zL~o4){Vo9i!(6bH_`1eBIzz+X+aUAel#pO|#)mo@TI&_ZZI+6M=LhE=7D4&Tu9OQt
zV?DP6;|kTr7PnH!V6M!j@NcUG$ExxiIvwpqlWmc$G}{^EW95S5*>$zaU-yLBnq1|j
zj~?`|Kfd+WjfGQv-HoF%GtEUV1Yw61-)BYv;LMV82yQ($0Oq^Zq|1>
z{mPVneO=|0s7JqPfaIc)V|~ro>d$0N`=GS154Si-Z^$Rbx*Ou8(1XgPn4L*kl-`Fi
z>l+b!3orQIM1{P2Xh&WjD~*!>Eoa9!-ZOD`h}E<($>amS=KT-PekV4kPwApiZ3&k9
zIoa8W+mniV%ReSW;6^YLUt0P(&8ly9wAHOv8g*Z2bXgw1457*h3Lm=wLKx7_{64!o
z@cnd}+h?&y6!DOK!MJA*au4@7CzlwkGUu;;5l&s8!Bw~|T>!*SQ6eyo?%R2;mzo-p
zIebNxbH7!x?S1X;sC5J{Ynp@`HLkCewPvoQ!J#@Mk1Idb*6H$(I=0El7C-xZ`M`j5
zjNJGO*&FSif&`;`VF6c69>{i$^`{HntzOM9l-$|dn`#`p+rK~KO-*z@#3_r5!t9%4
z9b&SF0ca%p%j+fgTGg{^>_Rszkk+T0ByqO^hmpz
z3t%|C;_SCAri7srZ;e|iz~5{d`&Ci13BkO9amkc29rruB5~(cjImU<2&>a9Q&dhLw
z`*%+g)*_oAW!GN4UKDxQy6R;+eT4kE4!ZyX&G16!eN`7grh@J1LEEx1USY+Wsn>Au
zM65C&Mmzh-!t(2ZLJ;k(_Q%oB?^D~VTfWLSjeDd^rKcb-USDw*=Xe1qd$k>}Av@##
zhAM;fsIOtw3$N%U@ACaVBr#<9N@JYRky0l9H|hddOu7Kb
zw=ekNxyYW%>yrtJ&^WPRWQXh$xwBmZM2NafB2u>Ni8
z9AAMm-Z&kZgR}i
z_CF435-GH%dgy2SwRP3(@4E1xJO~i|7Z0Mi|GVjON)5IC$sF!-M>JO#
z49Tt(v-$w(u-$kkR1acko^1MBR<4JKlRsGHCN@E;>$;hV=dTK!(Yf>mkge5y0pM0~R9{u&Q|F><9{CD*qi|W_-ERAC
z>JQ|yuFvp!2p2ta=_B%7;0>M$`~CuWuhql#7YU`pXQnkRd5LwI_^Txphj^KJW*xby
z6x-I`g$ir|hpEE0j)