fix(mac): added unified logging to Keyman Engine for mac

first draft, need to remove some debug statements and replace
others that would be more useful
This commit is contained in:
sgschantz 2024-05-21 12:45:17 +07:00
parent cc061837d0
commit e4f7f1d1a1
22 changed files with 287 additions and 180 deletions

View file

@ -8,7 +8,6 @@
#import "AppDelegate.h"
#import <KeymanEngine4Mac/KeymanEngine4Mac.h>
#import <os/log.h>
static BOOL debugMode = YES;
@ -68,8 +67,6 @@ NSString *const kKMXFileKey = @"KMXFile";
}
- (void)windowDidResize:(NSNotification *)notification {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "AppDelegate windowDidResize");
[self.oskView resizeOSKLayout];
}

View file

@ -23,6 +23,7 @@
#import "KMPackageInfo.h"
#import "KMKeyboardInfo.h"
#import "PrivacyConsent.h"
#import "KMLogs.h"
@import Sentry;
/** NSUserDefaults keys */
@ -107,7 +108,7 @@ NSString* _keymanDataPath = nil;
}
- (void)initCompletion {
NSLog(@"initCompletionHandler method invoked");
os_log_info([KMLogs startupLog], "initCompletionHandler method invoked");
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
andSelector:@selector(handleURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
@ -124,10 +125,10 @@ NSString* _keymanDataPath = nil;
nil);
if (!self.lowLevelEventTap) {
NSLog(@"Unable to create lowLevelEventTap!");
os_log_error([KMLogs startupLog], "Unable to create lowLevelEventTap!");
}
else {
NSLog(@"Successfully created lowLevelEventTap with CGEventTapCreate.");
os_log([KMLogs startupLog], "Successfully created lowLevelEventTap with CGEventTapCreate.");
CFRelease(self.lowLevelEventTap);
}
@ -140,6 +141,7 @@ NSString* _keymanDataPath = nil;
}
}
// TODO: remove
-(void)logDebugMessage:(NSString *)format, ... {
if (self.debugMode) {
va_list args;
@ -178,6 +180,8 @@ NSString* _keymanDataPath = nil;
KeymanVersionInfo keymanVersionInfo = [self versionInfo];
NSString *releaseName = [NSString stringWithFormat:@"%@", keymanVersionInfo.versionGitTag];
[KMLogs reportLogStatus];
[SentrySDK startWithConfigureOptions:^(SentryOptions *options) {
options.dsn = @"https://960f8b8e574c46e3be385d60ce8e1fea@o1005580.ingest.sentry.io/5983522";
options.releaseName = releaseName;
@ -190,9 +194,9 @@ NSString* _keymanDataPath = nil;
#ifdef USE_ALERT_SHOW_HELP_TO_FORCE_EASTER_EGG_CRASH_FROM_ENGINE
- (BOOL)alertShowHelp:(NSAlert *)alert {
NSLog(@"Sentry - KME: Got call to force crash from engine");
os_log_error([KMLogs startupLog], "Sentry - KME: Got call to force crash from engine");
[SentrySDK crash];
NSLog(@"Sentry - KME: should not have gotten this far!");
os_log_error([KMLogs startupLog], "Sentry - KME: should not have gotten this far!");
return NO;
}
#endif
@ -206,13 +210,11 @@ NSString* _keymanDataPath = nil;
NSMutableString *urlStr = [NSMutableString stringWithString:rawUrl];
[urlStr replaceOccurrencesOfString:@"keyman:" withString:@"keyman/" options:0 range:NSMakeRange(0, 7)];
NSURL *url = [NSURL URLWithString:urlStr];
if (self.debugMode)
NSLog(@"url = %@", url);
os_log_debug([KMLogs keyboardLog], "processURL, url = %{public}@", url);
if ([url.lastPathComponent isEqualToString:@"download"]) {
if (_connection != nil) {
if (self.debugMode)
NSLog(@"Already downloading a keyboard.");
os_log_debug([KMLogs keyboardLog], "Already downloading a keyboard.");
return;
}
@ -236,23 +238,17 @@ NSString* _keymanDataPath = nil;
}
-(void) sleepFollowingDeactivationOfServer:(id)lastServer {
if ([self debugMode]) {
NSLog(@"Keyman no longer active IM.");
}
os_log_debug([KMLogs lifecycleLog], "Keyman no longer active IM.");
self.sleeping = YES;
if ([self.oskWindow.window isVisible]) {
if ([self debugMode]) {
NSLog(@"Hiding OSK.");
}
os_log_debug([KMLogs oskLog], "sleepFollowingDeactivationOfServer, Hiding OSK.");
// Storing this ensures that if the deactivation is temporary, resulting from dropping down a menu,
// the OSK will re-display when that client application re-activates.
_lastServerWithOSKShowing = lastServer;
[self.oskWindow.window setIsVisible:NO];
}
if (self.lowLevelEventTap) {
if ([self debugMode]) {
NSLog(@"Disabling event tap...");
}
os_log_debug([KMLogs lifecycleLog], "sleepFollowingDeactivationOfServer, disabling event tap...");
CGEventTapEnable(self.lowLevelEventTap, NO);
}
}
@ -260,9 +256,7 @@ NSString* _keymanDataPath = nil;
-(void) wakeUpWith:(id)newServer {
self.sleeping = NO;
if (self.lowLevelEventTap && !CGEventTapIsEnabled(self.lowLevelEventTap)) {
if ([self debugMode]) {
NSLog(@"Keyman is now the active IM. Re-enabling event tap...");
}
os_log_debug([KMLogs lifecycleLog], "wakeUpWith, Keyman is now the active IM. Re-enabling event tap...");
CGEventTapEnable(self.lowLevelEventTap, YES);
}
// See note in sleepFollowingDeactivationOfServer.
@ -282,7 +276,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
if (!appDelegate.sleeping) {
// REVIEW: We might need to consider putting in some kind of counter/flag to ensure that the very next
// event is not another disable so we don't end up in an endless cycle.
NSLog(@"Event tap disabled by %@! Attempting to restart...", (type == kCGEventTapDisabledByTimeout ? @"timeout" : @"user"));
os_log([KMLogs eventsLog], "Event tap disabled by %{public}@! Attempting to restart...", (type == kCGEventTapDisabledByTimeout ? @"timeout" : @"user"));
CGEventTapEnable(appDelegate.lowLevelEventTap, YES);
if (!CGEventTapIsEnabled(appDelegate.lowLevelEventTap)) {
if (appDelegate.runLoopEventSrc) { // This should always be true
@ -306,8 +300,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
switch (type) {
case kCGEventFlagsChanged:
if (appDelegate.debugMode)
NSLog(@"eventTapFunction: system event kCGEventFlagsChanged to: %x", (int) sysEvent.modifierFlags);
os_log_debug([KMLogs eventsLog], "eventTapFunction: system event kCGEventFlagsChanged to: %x", (int) sysEvent.modifierFlags);
appDelegate.currentModifierFlags = sysEvent.modifierFlags;
if (appDelegate.currentModifierFlags & NSEventModifierFlagCommand) {
appDelegate.contextChangedByLowLevelEvent = YES;
@ -318,26 +311,26 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
case kCGEventLeftMouseDown:
case kCGEventOtherMouseUp:
case kCGEventOtherMouseDown:
NSLog(@"Event tap context invalidation flagged due to event: %@", event);
os_log_debug([KMLogs eventsLog], "Event tap context invalidation flagged due to event: %{public}@", event);
appDelegate.contextChangedByLowLevelEvent = YES;
break;
case kCGEventKeyDown:
NSLog(@"Event tap keydown event, keyCode: %hu, event: %@", sysEvent.keyCode, event);
os_log_debug([KMLogs eventsLog], "Event tap keydown event, keyCode: %hu, event: %{public}@", sysEvent.keyCode, event);
// Pass back low-level backspace events to the input method event handler
// because some non-compliant apps do not allow us to see backspace events
// that we have generated (and we need to see them, for serialization
// of events)
if(sysEvent.keyCode == kVK_Delete && appDelegate.inputController != nil) {
NSLog(@"Event tap handling kVK_Delete.");
os_log_debug([KMLogs eventsLog], "Event tap handling kVK_Delete.");
[appDelegate.inputController handleBackspace:sysEvent];
} else if(sysEvent.keyCode == kVK_Delete) {
NSLog(@"Event tap not handling kVK_Delete, appDelegate.inputController = %@", appDelegate.inputController);
os_log_debug([KMLogs eventsLog], "Event tap not handling kVK_Delete, appDelegate.inputController = %{public}@", appDelegate.inputController);
}
if(sysEvent.keyCode == 255) {
NSLog(@"*** kKeymanEventKeyCode = 0xFF");
os_log_debug([KMLogs eventsLog], "*** kKeymanEventKeyCode = 0xFF");
} else {
NSLog(@"*** other: %d(%x)", (char) sysEvent.keyCode, sysEvent.keyCode);
os_log_debug([KMLogs eventsLog], "*** other: %d(%x)", (char) sysEvent.keyCode, sysEvent.keyCode);
}
switch(sysEvent.keyCode) {
@ -439,14 +432,14 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
NSDictionary *persistedOptionsForSelectedKeyboard = [allPersistedOptions objectForKey:_selectedKeyboard];
if (!persistedOptionsForSelectedKeyboard) {
NSLog(@"no persisted options found in UserDefaults for keyboard %@ ", _selectedKeyboard);
os_log_info([KMLogs configLog], "no persisted options found in UserDefaults for keyboard %{public}@ ", _selectedKeyboard);
return;
}
// TODO: pass array instead of making repeated calls
for (NSString *key in persistedOptionsForSelectedKeyboard) {
NSString *value = [persistedOptionsForSelectedKeyboard objectForKey:key];
NSLog(@"persisted options found in UserDefaults for keyboard %@, key: %@, value: %@", _selectedKeyboard, key, value);
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];
}
}
@ -495,7 +488,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
- (void)setUseVerboseLogging:(BOOL)useVerboseLogging {
NSLog(@"Turning verbose logging %@", useVerboseLogging ? @"on." : @"off.");
os_log_debug([KMLogs configLog], "Turning verbose logging %{public}@", useVerboseLogging ? @"on." : @"off.");
_debugMode = useVerboseLogging;
if (_kme != nil)
[_kme setUseVerboseLogging:useVerboseLogging];
@ -674,8 +667,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
if (infoDict != nil) {
NSString *name = [infoDict objectForKey:kKMKeyboardNameKey];
if (name != nil && [name length]) {
if (self.debugMode)
NSLog(@"Adding keyboard name: %@", name);
os_log_debug([KMLogs configLog], "Adding keyboard name: %{public}@", name);
[kbNames addObject:name];
}
}
@ -814,9 +806,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
- (void)removeDynamicKeyboardMenuItems {
int numberToRemove = (int) self.menu.numberOfItems - DEFAULT_KEYMAN_MENU_ITEM_COUNT;
if (self.debugMode) {
NSLog(@"*** removeDynamicKeyboardMenuItems, self.menu.numberOfItems = %ld, number of items to remove = %d", (long)self.menu.numberOfItems, numberToRemove);
}
os_log_info([KMLogs keyboardLog], "*** removeDynamicKeyboardMenuItems, self.menu.numberOfItems = %ld, number of items to remove = %d", (long)self.menu.numberOfItems, numberToRemove);
if (numberToRemove > 0) {
for (int i = 0; i < numberToRemove; i++) {
@ -832,7 +822,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
int menuItemIndex = KEYMAN_FIRST_KEYBOARD_MENUITEM_INDEX;
if (self.debugMode) {
NSLog(@"*** populateKeyboardMenuItems, number of active keyboards=%lu", self.activeKeyboards.count);
os_log_info([KMLogs configLog], "*** populateKeyboardMenuItems, number of active keyboards=%lu", self.activeKeyboards.count);
}
// loop through the active keyboards list and add them to the menu
@ -908,7 +898,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
- (void)selectKeyboardFromMenu:(NSInteger)tag {
NSMenuItem *menuItem = [self.menu itemWithTag:tag];
NSString *title = menuItem.title;
NSLog(@"Input Menu, selected Keyboards menu, itag: %lu, title: %@", tag, title);
os_log_info([KMLogs keyboardLog], "Input Menu, selected Keyboards menu, itag: %lu, title: %{public}@", tag, title);
for (NSMenuItem *item in self.menu.itemArray) {
// set the state of the keyboard items in the Keyman menu based on the new selection
if (item.tag >= KEYMAN_FIRST_KEYBOARD_MENUITEM_TAG) {
@ -934,8 +924,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
[self setKvk:kvk];
NSString *keyboardName = [kmxInfo objectForKey:kKMKeyboardNameKey];
if ([self debugMode])
NSLog(@"Selected keyboard from menu: %@", keyboardName);
os_log_info([KMLogs keyboardLog], "Selected keyboard from menu: %{public}@", keyboardName);
[self setKeyboardName:keyboardName];
[self setKeyboardIcon:[kmxInfo objectForKey:kKMKeyboardIconKey]];
[self setContextBuffer:nil];
@ -996,8 +985,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
}
- (void)showConfigurationWindow {
if (self.debugMode)
NSLog(@"Showing config window...");
os_log_debug([KMLogs uiLog], "Showing config window...");
[self.configWindow.window centerInParent];
[self.configWindow.window makeKeyAndOrderFront:nil];
[self.configWindow.window setLevel:NSFloatingWindowLevel];
@ -1027,8 +1015,7 @@ CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef
- (NSWindowController *)configWindow {
if (_configWindow.window == nil) {
if (self.debugMode)
NSLog(@"Creating config window...");
os_log_debug([KMLogs uiLog], "Creating config window...");
_configWindow = [[KMConfigurationWindowController alloc] initWithWindowNibName:@"preferences"];
[self observeCloseFor:_configWindow.window];
}
@ -1289,7 +1276,7 @@ extern const CGKeyCode kProcessPendingBuffer;
CGEventRef ev = CGEventCreateKeyboardEvent (source, virtualKey, true); //down
if (postEvent) {
NSLog(@"postKeyboardEventWithSource, keycode: %d", virtualKey);
os_log_info([KMLogs eventsLog], "postKeyboardEventWithSource, keycode: %d", virtualKey);
postEvent(ev);
}
CFRelease(ev);
@ -1306,7 +1293,7 @@ extern const CGKeyCode kProcessPendingBuffer;
- (BOOL)verifyPackageVersionInTempFolder: (NSString *)tempDestFolder filePath:(NSString *)filePath {
KMPackageInfo *packageInfo = [self loadPackageInfo:tempDestFolder];
if(packageInfo == nil) {
NSLog(@"Could not find kmp.json in %@", filePath);
os_log_info([KMLogs eventsLog], "Could not find kmp.json in %{public}@", filePath);
} else {
NSString* requiredVersion = [packageInfo.fileVersion minimalVersionNumberString];
KeymanVersionInfo keymanVersionInfo = [self versionInfo];
@ -1314,7 +1301,7 @@ extern const CGKeyCode kProcessPendingBuffer;
if ([requiredVersion compare:currentVersion options:NSNumericSearch] == NSOrderedDescending) {
// currentVersion is lower than the requiredVersion
NSLog(@"Package %@ requires a newer version of Keyman: %@", filePath, requiredVersion);
os_log_error([KMLogs keyboardLog], "Package %{public}@ requires a newer version of Keyman: %{public}@", filePath, requiredVersion);
} else {
return YES;
}
@ -1340,10 +1327,9 @@ extern const CGKeyCode kProcessPendingBuffer;
ZipArchive *za = [[ZipArchive alloc] init];
if ([za UnzipOpenFile:filePath]) {
if (self.debugMode) {
NSLog(@"Unzipping %@ to %@", filePath, tempDestFolder);
if ([[NSFileManager defaultManager] fileExistsAtPath:tempDestFolder])
NSLog(@"The temp destination folder already exists. Overwriting...");
os_log_debug([KMLogs keyboardLog], "Unzipping %{public}@ to %{public}@", filePath, tempDestFolder);
if ([[NSFileManager defaultManager] fileExistsAtPath:tempDestFolder]) {
os_log_debug([KMLogs keyboardLog], "The temp destination folder already exists. Overwriting...");
}
didUnzip = [za UnzipFileTo:tempDestFolder overWrite:YES];
@ -1351,25 +1337,22 @@ extern const CGKeyCode kProcessPendingBuffer;
}
if (!didUnzip) {
NSLog(@"Failed to unzip file: %@", filePath);
os_log_error([KMLogs keyboardLog], "Failed to unzip file: %{public}@", filePath);
return NO;
}
if (self.debugMode)
NSLog(@"Unzipped file: %@", filePath);
os_log_debug([KMLogs keyboardLog], "Unzipped file: %{public}@", filePath);
BOOL didInstall = [self verifyPackageVersionInTempFolder:tempDestFolder filePath:filePath];
NSString *destFolder = [self.keyboardsPath stringByAppendingPathComponent:folderName];
// Remove existing package if it exists
if (didInstall && [[NSFileManager defaultManager] fileExistsAtPath:destFolder]) {
if(self.debugMode) {
NSLog(@"The destination folder already exists. Overwriting...");
}
os_log_debug([KMLogs keyboardLog], "The destination folder already exists. Overwriting...");
[[NSFileManager defaultManager] removeItemAtPath:destFolder error:&error];
if (error != nil) {
NSLog(@"Unable to remove destination folder %@", destFolder);
os_log_error([KMLogs keyboardLog], "Unable to remove destination folder %{public}@", destFolder);
didInstall = NO;
}
}
@ -1382,7 +1365,7 @@ extern const CGKeyCode kProcessPendingBuffer;
if(didInstall) {
[[NSFileManager defaultManager] moveItemAtPath:tempDestFolder toPath:destFolder error:&error];
if (error != nil) {
NSLog(@"Unable to move temp folder %@ to dest folder %@", tempDestFolder, destFolder);
os_log_error([KMLogs keyboardLog], "Unable to move temp folder %{public}@ to dest folder %{public}@", tempDestFolder, destFolder);
didInstall = NO;
}
}
@ -1390,7 +1373,7 @@ extern const CGKeyCode kProcessPendingBuffer;
if(!didInstall) {
[[NSFileManager defaultManager] removeItemAtPath:tempDestFolder error:&error];
if (error != nil) {
NSLog(@"Unable to remove temp folder %@", tempDestFolder);
os_log_error([KMLogs keyboardLog], "Unable to remove temp folder %{public}@", tempDestFolder);
}
return NO;
@ -1401,8 +1384,7 @@ extern const CGKeyCode kProcessPendingBuffer;
NSString * keyboardFolderPath = [self.keyboardsPath stringByAppendingPathComponent:folderName];
[self installFontsAtPath:keyboardFolderPath];
for (NSString *kmxFile in [self KMXFilesAtPath:keyboardFolderPath]) {
if (self.debugMode)
NSLog(@"Adding keyboard to list of active keyboards: %@", kmxFile);
os_log_debug([KMLogs keyboardLog], "Adding keyboard to list of active keyboards: %{public}@", kmxFile);
if (![self.activeKeyboards containsObject:kmxFile])
[self.activeKeyboards addObject:kmxFile];
}
@ -1442,7 +1424,7 @@ extern const CGKeyCode kProcessPendingBuffer;
[[NSFileManager defaultManager] copyItemAtPath:srcPath toPath:destPath error:&error];
if (error != nil)
NSLog(@"Error = %@", error);
os_log_error([KMLogs keyboardLog], "installFontsAtPath error = %{public}@", error);
}
}

View file

@ -377,7 +377,7 @@ NSString* const kEasterEggKmxName = @"EnglishSpanish.kmx";
// assume that all non-compliant apps which require backspaces apply an extra backspace if the original event is a backspace
if ((self.apiCompliance.mustBackspaceUsingEvents) && (event.keyCode == kVK_Delete)) {
output.codePointsToDeleteBeforeInsert--;
os_log_with_type(keymanLog, OS_LOG_TYPE_INFO, "isDeleteAndInsertScenario, after delete pressed subtracting one backspace to reach %d and insert text '%{public}@'", output.codePointsToDeleteBeforeInsert, output.textToInsert);
os_log_info(keymanLog, "isDeleteAndInsertScenario, after delete pressed subtracting one backspace to reach %d and insert text '%{public}@'", output.codePointsToDeleteBeforeInsert, output.textToInsert);
if (output.codePointsToDeleteBeforeInsert == 0) {
// no backspace events needed
[self insertAndReplaceTextForOutput:output client:client];

View file

@ -1,12 +1,12 @@
/*
/**
* Keyman is copyright (C) SIL International. MIT License.
*
* KMLogs.h
* CoreTesterApp
* Keyman
*
* Created by Shawn Schantz on 2024-05-16.
*
* Description...
*
* Contains methods to get singleton logger objects and constants for subsystem and category names.
*/
#import <Foundation/Foundation.h>
@ -16,7 +16,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface KMLogs : NSObject
+ (void)reportLogStatus;
+ (os_log_t)startupLog;
+ (os_log_t)lifecycleLog;
+ (os_log_t)configLog;
+ (os_log_t)uiLog;
+ (os_log_t)eventsLog;
+ (os_log_t)keyboardLog;
+ (os_log_t)keyLog;
+ (os_log_t)oskLog;

View file

@ -1,28 +1,69 @@
/*
/**
* Keyman is copyright (C) SIL International. MIT License.
*
* LoggerUtil.m
* CoreTesterApp
*
* KMLogs.m
* Keyman
*
* Created by Shawn Schantz on 2024-05-16.
*
* Description...
* Contains methods to get singleton logger objects and constants for subsystem and category names.
*/
/**
*
* The loggers do not appear to be singletons, but the API which creates them manages
* them as singletons within macOS so that any subsequent call to create a log object
* using the same subsystem and category will return the existing instance.
*
* For any new log categories used anywhere in the Keyman Input method, the name should be defined here.
* Keyman Engine may define and use the same category name but will use a different subsystem name.
*/
#import "KMLogs.h"
#import <os/log.h>
@implementation KMLogs
char *const keymanSubsystem = "org.sil.keyman";
char *const startupCategory = "startup";
char *const lifecycleCategory = "lifecycle";
char *const configCategory = "config";
char *const uiCategory = "ui";
char *const eventsCategory = "events";
char *const keyboardCategory = "keyboard";
char *const keyCategory = "key";
char *const oskCategory = "osk";
+ (void)reportLogStatus {
bool debugLogEnabled = os_log_type_enabled([KMLogs startupLog], OS_LOG_TYPE_DEBUG);
os_log([KMLogs startupLog], "startupLog has debug messages enabled: %@", debugLogEnabled?@"YES":@"NO");
bool infoLogEnabled = os_log_type_enabled([KMLogs startupLog], OS_LOG_TYPE_INFO);
os_log([KMLogs startupLog], "startupLog has info messages enabled: %@", infoLogEnabled?@"YES":@"NO");
}
+ (os_log_t)startupLog {
return os_log_create(keymanSubsystem, startupCategory);
}
+ (os_log_t)lifecycleLog {
return os_log_create(keymanSubsystem, lifecycleCategory);
}
+ (os_log_t)configLog {
return os_log_create(keymanSubsystem, configCategory);
}
+ (os_log_t)uiLog {
return os_log_create(keymanSubsystem, uiCategory);
}
+ (os_log_t)eventsLog {
return os_log_create(keymanSubsystem, eventsCategory);
}
+ (os_log_t)keyboardLog {
return os_log_create(keymanSubsystem, keyboardCategory);
}
+ (os_log_t)keyLog {
return os_log_create(keymanSubsystem, keyCategory);
}

View file

@ -12,6 +12,7 @@
#import <InputMethodKit/InputMethodKit.h>
#import "KeySender.h"
#import "KMInputMethodAppDelegate.h"
#import "KMLogs.h"
const CGKeyCode kKeymanEventKeyCode = 0xFF;
@ -30,8 +31,8 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
}
- (void)sendBackspaceforEventSource:(CGEventSourceRef)eventSource {
[self.appDelegate logDebugMessage:@"KeySender sendBackspaceforEventSource"];
os_log_debug([KMLogs keyLog], "KeySender sendBackspaceforEventSource");
[self postKeyboardEventWithSource:eventSource code:kVK_Delete postCallback:^(CGEventRef eventToPost) {
CGEventPost(kCGHIDEventTap, eventToPost);
}];
@ -40,11 +41,11 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
- (void)postKeyboardEventWithSource: (CGEventSourceRef)source code:(CGKeyCode) virtualKey postCallback:(PostEventCallback)postEvent{
if (!postEvent) {
[self.appDelegate logDebugMessage:@"KeySender postKeyboardEventWithSource callback not specified", virtualKey];
os_log_debug([KMLogs keyLog], "KeySender postKeyboardEventWithSource callback not specified for virtualKey: %u", virtualKey);
return;
}
[self.appDelegate logDebugMessage:@"KeySender postKeyboardEventWithSource for virtualKey: @%", virtualKey];
os_log_debug([KMLogs keyLog], "KeySender postKeyboardEventWithSource for virtualKey: %u", virtualKey);
CGEventRef ev = CGEventCreateKeyboardEvent (source, virtualKey, true); //down
postEvent(ev);
@ -61,8 +62,8 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
*/
- (void)sendKeymanKeyCodeForEvent:(NSEvent *)event {
[self.appDelegate logDebugMessage:@"KeySender sendKeymanKeyCodeForEvent"];
os_log_debug([KMLogs keyLog], "KeySender sendKeymanKeyCodeForEvent");
ProcessSerialNumber psn;
// Returns the frontmost app, which is the app that receives key events.
@ -70,7 +71,7 @@ const CGKeyCode kKeymanEventKeyCode = 0xFF;
pid_t processId = app.processIdentifier;
NSString *bundleId = app.bundleIdentifier;
[self.appDelegate logDebugMessage:@"sendKeymanKeyCodeForEvent keyCode %lu to app %@ with pid %d", (unsigned long)kKeymanEventKeyCode, bundleId, processId];
os_log_debug([KMLogs keyLog], "sendKeymanKeyCodeForEvent keyCode %lu to app %{public}@ with pid %d", (unsigned long)kKeymanEventKeyCode, bundleId, processId);
// use nil as source, as this generated event is not directly tied to the originating event
CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(nil, kKeymanEventKeyCode, true);

View file

@ -8,7 +8,7 @@
#import "OSKWindowController.h"
#import "KMInputMethodAppDelegate.h"
#import <os/log.h>
#import "KMLogs.h"
@interface OSKWindowController ()
@property (nonatomic, strong) NSButton *helpButton;
@ -30,8 +30,7 @@
}
- (void)awakeFromNib {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC awakeFromNib");
os_log_debug([KMLogs oskLog], "OSKWindowController awakeFromNib");
// Keep the aspect ratio constant at its current value
[self.window setAspectRatio:self.window.frame.size];
NSSize size = self.window.frame.size;
@ -54,8 +53,7 @@
}
- (void)windowDidLoad {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidLoad");
os_log_debug([KMLogs oskLog], "OSKWindowController windowDidLoad");
[super windowDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:self.window];
[self.oskView setKvk:[self.AppDelegate kvk]];
@ -64,8 +62,7 @@
}
- (void)windowDidResize:(NSNotification *)notification {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidResize");
os_log_debug([KMLogs oskLog], "OSKWindowController windowDidResize");
[self.oskView resizeOSKLayout];
}
@ -87,8 +84,7 @@
}
- (void)resetOSK {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKWC windowDidLoad");
os_log_debug([KMLogs oskLog], "OSKWindowController windowDidLoad");
[self.oskView setKvk:[self.AppDelegate kvk]];
[self.oskView resetOSK];
if (_helpButton) {

View file

@ -22,7 +22,7 @@ int main(int argc, const char * argv[]) {
BOOL didLoadNib = [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:[NSApplication sharedApplication] topLevelObjects: nil];
os_log_with_type([KMLogs startupLog], OS_LOG_TYPE_INFO, "main Did load MainMenu nib: %@", didLoadNib?@"YES":@"NO");
os_log_info([KMLogs startupLog], "main Did load MainMenu nib: %@", didLoadNib?@"YES":@"NO");
[[NSApplication sharedApplication] run];
}

View file

@ -23,6 +23,8 @@
29A1971E2AF091E600512A37 /* CoreKeyOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 29A1971C2AF091E600512A37 /* CoreKeyOutput.h */; settings = {ATTRIBUTES = (Public, ); }; };
29A1971F2AF091E600512A37 /* CoreKeyOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 29A1971D2AF091E600512A37 /* CoreKeyOutput.m */; };
29A658C82AF394560038DCFE /* armenian_mnemonic.kmx in Resources */ = {isa = PBXBuildFile; fileRef = 29A658C72AF394560038DCFE /* armenian_mnemonic.kmx */; };
29B4A0D82BFAE8A400682049 /* KMELogs.h in Headers */ = {isa = PBXBuildFile; fileRef = 29B4A0D62BFAE8A400682049 /* KMELogs.h */; };
29B4A0D92BFAE8A400682049 /* KMELogs.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B4A0D72BFAE8A400682049 /* KMELogs.m */; };
378568D122FCCF0A00B481B5 /* sil_ipa.kmx in Resources */ = {isa = PBXBuildFile; fileRef = 378568D022FCCF0A00B481B5 /* sil_ipa.kmx */; };
378568D322FCD93300B481B5 /* indexoffset1892.kmx in Resources */ = {isa = PBXBuildFile; fileRef = 378568D222FCD93300B481B5 /* indexoffset1892.kmx */; };
980053351B37C9B50088DDDD /* NFont.h in Headers */ = {isa = PBXBuildFile; fileRef = 980053311B37C9B50088DDDD /* NFont.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -97,6 +99,8 @@
29A205D82AC2E446000750C0 /* libsicuuc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsicuuc.a; path = "../../core/build/mac-arm64/release/subprojects/icu/source/common/libsicuuc.a"; sourceTree = "<group>"; };
29A205DA2AC2E46A000750C0 /* libsicui18n.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsicui18n.a; path = "../../core/build/mac-arm64/release/subprojects/icu/source/i18n/libsicui18n.a"; sourceTree = "<group>"; };
29A658C72AF394560038DCFE /* armenian_mnemonic.kmx */ = {isa = PBXFileReference; lastKnownFileType = file; path = armenian_mnemonic.kmx; sourceTree = "<group>"; };
29B4A0D62BFAE8A400682049 /* KMELogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMELogs.h; sourceTree = "<group>"; };
29B4A0D72BFAE8A400682049 /* KMELogs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMELogs.m; sourceTree = "<group>"; };
378568D022FCCF0A00B481B5 /* sil_ipa.kmx */ = {isa = PBXFileReference; lastKnownFileType = file; path = sil_ipa.kmx; sourceTree = "<group>"; };
378568D222FCD93300B481B5 /* indexoffset1892.kmx */ = {isa = PBXFileReference; lastKnownFileType = file; path = indexoffset1892.kmx; sourceTree = "<group>"; };
980053311B37C9B50088DDDD /* NFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFont.h; sourceTree = "<group>"; };
@ -286,6 +290,8 @@
984C2AEE1A79CA4F0023F89D /* KME */ = {
isa = PBXGroup;
children = (
29B4A0D62BFAE8A400682049 /* KMELogs.h */,
29B4A0D72BFAE8A400682049 /* KMELogs.m */,
981880641BC1EA5800A1FBA5 /* OnScreenKeyboard */,
984C2AEF1A79CA4F0023F89D /* Categories */,
984C2AF51A79CA4F0023F89D /* KMBinaryFileFormat.h */,
@ -351,6 +357,7 @@
2993C33229B1D92E00FB5E95 /* CoreWrapper.h in Headers */,
9818806F1BC1EA5800A1FBA5 /* KeyLabel.h in Headers */,
981880751BC1EA5800A1FBA5 /* OSKKey.h in Headers */,
29B4A0D82BFAE8A400682049 /* KMELogs.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -501,6 +508,7 @@
980053381B37C9B50088DDDD /* NKey.m in Sources */,
981880701BC1EA5800A1FBA5 /* KeyLabel.m in Sources */,
981880721BC1EA5800A1FBA5 /* KeyLabelCell.m in Sources */,
29B4A0D92BFAE8A400682049 /* KMELogs.m in Sources */,
981880781BC1EA5800A1FBA5 /* OSKView.m in Sources */,
2993C32E29B1D92E00FB5E95 /* CoreWrapper.m in Sources */,
984C2B0F1A79CA4F0023F89D /* KMCompKey.m in Sources */,

View file

@ -23,7 +23,6 @@ extern UInt32 VirtualKeyMap[0x80];
-(unsigned long long) unicharStringLength:(unichar const *)string;
-(instancetype)initWithDebugMode:(BOOL)debugMode;
-(void)logDebugMessage:(NSString *)format, ...;
-(unsigned short) macVirtualKeyToWindowsVirtualKey:(unsigned short) keyCode;
-(UTF32Char)macToKeymanModifier:(NSEventModifierFlags)modifiers;
-(NSString*)utf32ValueToString:(UTF32Char)scalarValue;

View file

@ -19,6 +19,7 @@
#import "keyman_core_api.h"
#import "MacVKCodes.h"
#import "WindowsVKCodes.h"
#import "KMELogs.h"
const int VIRTUAL_KEY_ARRAY_SIZE = 0x80;
UInt32 VirtualKeyMap[VIRTUAL_KEY_ARRAY_SIZE];
@ -32,7 +33,7 @@ UInt32 VirtualKeyMap[VIRTUAL_KEY_ARRAY_SIZE];
-(unichar const *) createUnicharStringFromNSString:(NSString *)string {
NSString *nullTerminatedString = [string stringByAppendingString:@"\0"];
if (![nullTerminatedString canBeConvertedToEncoding:NSUTF16LittleEndianStringEncoding]) {
[self logDebugMessage:@"createUnicharStringFromNSString, canBeConvertedToEncoding false for NSUTF16LittleEndianStringEncoding"];
os_log_debug([KMELogs coreLog], "createUnicharStringFromNSString, canBeConvertedToEncoding false for NSUTF16LittleEndianStringEncoding");
return nil;
}
@ -77,15 +78,6 @@ UInt32 VirtualKeyMap[VIRTUAL_KEY_ARRAY_SIZE];
return self;
}
-(void)logDebugMessage:(NSString *)format, ... {
if (self.debugMode) {
va_list args;
va_start(args, format);
NSLogv(format, args);
va_end(args);
}
}
-(unsigned short) macVirtualKeyToWindowsVirtualKey:(unsigned short) keyCode {
if ((keyCode<0) || (keyCode>=VIRTUAL_KEY_ARRAY_SIZE)) {
return 0;
@ -125,7 +117,7 @@ UInt32 VirtualKeyMap[VIRTUAL_KEY_ARRAY_SIZE];
keymanModifiers |= KM_CORE_MODIFIER_NOCAPS;
}*/
[self logDebugMessage:@"macToKeymanModifier result = %u", (unsigned int)keymanModifiers];
os_log_debug([KMELogs coreLog], "macToKeymanModifier result = %u", (unsigned int)keymanModifiers);
return keymanModifiers;
}
@ -169,7 +161,7 @@ UInt32 VirtualKeyMap[VIRTUAL_KEY_ARRAY_SIZE];
NSData * characterData = [[NSData alloc] initWithBytes:&scalarValue length:sizeof(scalarValue)];
NSString *characterString=[[NSString alloc] initWithBytes:[characterData bytes] length:[characterData length] encoding:NSUTF32LittleEndianStringEncoding];
[self logDebugMessage:@"utf32ValueToString data: '%@', string: %@", characterData, characterString];
os_log_debug([KMELogs coreLog], "utf32ValueToString data: '%@', string: %@", characterData, characterString);
return characterString;
}

View file

@ -15,6 +15,7 @@
#import "CoreWrapper.h"
#import "keyman_core_api.h"
#import "keyman_core_api_consts.h"
#import "KMELogs.h"
@interface CoreWrapper()
@ -73,7 +74,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
if (self.coreKeyboard) {
km_core_keyboard_dispose(self.coreKeyboard);
}
[self.coreHelper logDebugMessage:@"CoreWrapper dealloc called."];
os_log_debug([KMELogs coreLog], "CoreWrapper dealloc called.");
}
-(void)loadKeyboardUsingCore:(NSString*) path {
@ -94,9 +95,9 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
if (result==KM_CORE_STATUS_OK) {
_keyboardVersion = [self.coreHelper createNSStringFromUnicharString:keyboardAttributes->version_string];
_keyboardId = [self.coreHelper createNSStringFromUnicharString:keyboardAttributes->id];
[self.coreHelper logDebugMessage:@"keyboardVersion = %@\n, keyboardId = %@\n", _keyboardVersion, _keyboardId];
os_log_debug([KMELogs coreLog], "keyboardVersion = %{public}@\n, keyboardId = %{public}@\n", _keyboardVersion, _keyboardId);
} else {
NSLog(@"km_core_keyboard_get_attrs() failed with result = %u\n", result );
os_log_error([KMELogs coreLog], "km_core_keyboard_get_attrs() failed with result = %u\n", result);
}
}
}
@ -117,7 +118,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
[NSException raise:@"CreateKeyboardStateException" format:@"%@", message];
}
} else {
NSLog(@"CoreWrapper, Unable to set environment options for keyboard" );
os_log_error([KMELogs coreLog], "CoreWrapper, Unable to set environment options for keyboard");
}
}
@ -160,7 +161,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
km_core_status result = km_core_process_event(self.coreState, keyCode, modifierState, isKeyDown, KM_CORE_EVENT_FLAG_DEFAULT);
if (result!=KM_CORE_STATUS_OK) {
[self.coreHelper logDebugMessage:@"km_core_process_event() result = %u\n", result];
os_log_error([KMELogs coreLog], "km_core_process_event() result = %u\n", result);
}
return (result==KM_CORE_STATUS_OK);
@ -171,7 +172,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
}
-(CoreKeyOutput*)loadActionStructUsingCore {
[self.coreHelper logDebugMessage:@"CoreWrapper loadActionStructUsingCore"];
os_log_debug([KMELogs coreLog], "CoreWrapper loadActionStructUsingCore");
km_core_actions * actions = km_core_state_get_actions(self.coreState);
CoreKeyOutput *output = [self createCoreKeyOutputForActionsStruct:actions];
return output;
@ -225,13 +226,13 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
-(void)clearContextUsingCore {
km_core_state_context_clear(self.coreState);
[self.coreHelper logDebugMessage:@"km_core_state_context_clear called"];
os_log_debug([KMELogs coreLog], "km_core_state_context_clear called");
}
-(void)setContextIfNeeded:(NSString*)context {
unichar const * unicharContext = [self.coreHelper createUnicharStringFromNSString:context];
km_core_status result = km_core_state_context_set_if_needed(self.coreState, unicharContext);
[self.coreHelper logDebugMessage:@"CoreWrapper setContextIfNeeded, context=%@, km_core_state_context_set_if_needed result=%i", context, result];
os_log_debug([KMELogs coreLog], "CoreWrapper setContextIfNeeded, context=%{public}@, km_core_state_context_set_if_needed result=%d", context, result);
}
-(NSString*)contextDebug {
@ -239,7 +240,7 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
NSString *debugString = [self.coreHelper createNSStringFromUnicharString:context];
km_core_cu_dispose(context);
[self.coreHelper logDebugMessage:@"CoreWrapper contextDebug = %@", debugString];
os_log_debug([KMELogs coreLog], "CoreWrapper contextDebug = %{public}@", debugString);
return debugString;
}
@ -271,8 +272,8 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
}
-(BOOL)setOptionsForCore: (NSString *) key value:(NSString *) value {
[self.coreHelper logDebugMessage:@"setOptionsForCore, key = %@, value = %@", key, value];
os_log_debug([KMELogs coreLog], "setOptionsForCore, key = %@, value = %@", key, value);
// array of length 2, second item is terminating null struct
km_core_option_item option[2] = {0};
option[0].key = [self.coreHelper createUnicharStringFromNSString: key];
@ -280,8 +281,8 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
option[0].scope = KM_CORE_OPT_KEYBOARD;
km_core_status result = km_core_state_options_update(self.coreState, &option[0]);
[self.coreHelper logDebugMessage:@"setOptionsForCore, km_core_state_options_update result = %d", result];
os_log_debug([KMELogs coreLog], "setOptionsForCore, km_core_state_options_update result = %d", result);
return (result==KM_CORE_STATUS_OK);
}
@ -294,15 +295,15 @@ const int CORE_ENVIRONMENT_ARRAY_LENGTH = 6;
&valueFromCore);
if (result == KM_CORE_STATUS_OK) {
if (valueFromCore) {
[self.coreHelper logDebugMessage:@"km_core_state_option_lookup successful, current value set in core= %@", [self.coreHelper createNSStringFromUnicharString:valueFromCore]];
os_log_debug([KMELogs coreLog], "km_core_state_option_lookup successful, current value set in core= %@", [self.coreHelper createNSStringFromUnicharString:valueFromCore]);
} else {
[self.coreHelper logDebugMessage:@"km_core_state_option_lookup returned nil"];
os_log_debug([KMELogs coreLog], "km_core_state_option_lookup returned nil");
}
} else {
if (valueFromCore) {
[self.coreHelper logDebugMessage:@"km_core_state_option_lookup failed, result = %d", result];
os_log_debug([KMELogs coreLog], "km_core_state_option_lookup failed, result = %d", result);
} else {
[self.coreHelper logDebugMessage:@"km_core_state_option_lookup returned nil, result = %d", result];
os_log_debug([KMELogs coreLog], "km_core_state_option_lookup returned nil, result = %d", result);
}
}

View file

@ -0,0 +1,29 @@
/**
* Keyman is copyright (C) SIL International. MIT License.
*
* KMELogs.h
* KeymanEngine4Mac
*
* Created by Shawn Schantz on 2024-05-16.
*
* Contains methods to get singleton logger objects and constants for subsystem and category names.
*/
#import <Foundation/Foundation.h>
#import <os/log.h>
NS_ASSUME_NONNULL_BEGIN
@interface KMELogs : NSObject
+ (os_log_t)startupLog;
+ (os_log_t)configLog;
+ (os_log_t)keyLog;
+ (os_log_t)coreLog;
+ (os_log_t)oskLog;
+ (os_log_t)uiLog;
+ (os_log_t)testLog;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,63 @@
/**
* Keyman is copyright (C) SIL International. MIT License.
*
* KMELogs.m
* KeymanEngine4Mac
*
* Created by Shawn Schantz on 2024-05-16.
*
* Contains methods to get singleton logger objects and constants for subsystem and category names.
*/
/**
* The loggers do not appear to be singletons, but the API which creates them manages
* them as singletons within macOS so that any subsequent call to create a log object
* using the same subsystem and category will return the existing instance.
*
* For any new log categories used anywhere in the Keyman Engine for Mac, the name should be defined here.
* The Keyman Input Method may define and use the same category name but will use a different subsystem name.
*/
#import "KMELogs.h"
#import <os/log.h>
@implementation KMELogs
char *const keymanEngineSubsystem = "org.sil.keymanengine";
char *const startupCategory = "startup";
char *const configCategory = "config";
char *const keyCategory = "key";
char *const coreCategory = "core";
char *const oskCategory = "osk";
char *const uiCategory = "ui";
char *const testCategory = "test";
+ (os_log_t)startupLog {
return os_log_create(keymanEngineSubsystem, startupCategory);
}
+ (os_log_t)configLog {
return os_log_create(keymanEngineSubsystem, configCategory);
}
+ (os_log_t)keyLog {
return os_log_create(keymanEngineSubsystem, keyCategory);
}
+ (os_log_t)coreLog {
return os_log_create(keymanEngineSubsystem, coreCategory);
}
+ (os_log_t)oskLog {
return os_log_create(keymanEngineSubsystem, oskCategory);
}
+ (os_log_t)uiLog {
return os_log_create(keymanEngineSubsystem, uiCategory);
}
+ (os_log_t)testLog {
return os_log_create(keymanEngineSubsystem, testCategory);
}
@end

View file

@ -15,6 +15,7 @@
#import "WindowsVKCodes.h"
#import "MacVKCodes.h"
#import "CoreWrapper.h"
#import "KMELogs.h"
@import Carbon;
@interface KMEngine ()
@ -47,10 +48,10 @@ const NSString* kEasterEggKmxName = @"EnglishSpanish.kmx";
-(void)loadCoreWrapperFromKmxFile:(NSString *)kmxFilePath {
@try {
_coreWrapper = [[CoreWrapper alloc] initWithHelper:_coreHelper kmxFilePath:kmxFilePath];
[self.coreHelper logDebugMessage:@"loadCoreWrapperFromKmxFile, keyboardId = %@", [self.coreWrapper keyboardId]];
os_log([KMELogs coreLog], "loadCoreWrapperFromKmxFile, keyboardId = %{public}@", [self.coreWrapper keyboardId]);
}
@catch (NSException *exception) {
NSLog(@"loadCoreWrapperFromKmxFile, failed to create keyboard for path '%@' with exception: %@", kmxFilePath, exception.description);
os_log_error([KMELogs coreLog], "loadCoreWrapperFromKmxFile, failed to create keyboard for path '%{public}@' with exception: %{public}@", kmxFilePath, exception.description);
}
}
@ -71,20 +72,21 @@ const NSString* kEasterEggKmxName = @"EnglishSpanish.kmx";
}
if (useVerboseLogging) {
NSLog(@"KMEngine - Turning verbose logging on");
os_log_debug([KMELogs keyLog], "KMEngine - Turning verbose logging on");
// In Keyman Engine if "debugMode" is turned on (explicitly) with "English plus Spanish" as the current keyboard and you type "Sentrycrash#KME",
// it will force a simulated crash to test reporting to sentry.keyman.com.
NSString * kmxName = [[_kmx filePath] lastPathComponent];
NSLog(@"Sentry - KME: _kmx name = %@", kmxName);
os_log_debug([KMELogs keyLog], "Sentry - KME: _kmx name = %{public}@", kmxName);
if ([kEasterEggKmxName isEqualToString:kmxName]) {
NSLog(@"Sentry - KME: Preparing to detect Easter egg.");
os_log_debug([KMELogs keyLog], "Sentry - KME: Preparing to detect Easter egg.");
_easterEggForSentry = [[NSMutableString alloc] init];
}
else
_easterEggForSentry = nil;
}
else
NSLog(@"KMEngine - Turning verbose logging off");
else {
os_log_debug([KMELogs keyLog], "KMEngine - Turning verbose logging off");
}
}
- (NSString *)getCoreContextDebug {
@ -101,7 +103,7 @@ const NSString* kEasterEggKmxName = @"EnglishSpanish.kmx";
- (void)setCoreOptions:(NSString *)key withValue:(NSString *)value {
BOOL success = [self.coreWrapper setOptionsForCore:key value:value];
[self.coreHelper logDebugMessage:@"setCoreOptions for key: %@, value: %@ succeeded = %@", key, value, success ? @"YES" : @"NO"];
os_log_debug([KMELogs coreLog], "setCoreOptions for key: %{public}@, value: %{public}@ succeeded = %{public}@", key, value, success ? @"YES" : @"NO");
}
/*
@ -116,13 +118,13 @@ const NSString* kEasterEggKmxName = @"EnglishSpanish.kmx";
- (void) processPossibleEasterEggCharacterFrom:(NSString *)characters {
NSUInteger len = [_easterEggForSentry length];
NSLog(@"Sentry - KME: Processing character(s): %@", characters);
os_log_debug([KMELogs keyLog], "Sentry - KME: Processing character(s): %{public}@", characters);
if ([characters length] == 1 && [characters characterAtIndex:0] == [kEasterEggText characterAtIndex:len]) {
NSString *characterToAdd = [kEasterEggText substringWithRange:NSMakeRange(len, 1)];
NSLog(@"Sentry - KME: Adding character to Easter Egg code string: %@", characterToAdd);
os_log_debug([KMELogs keyLog], "Sentry - KME: Adding character to Easter Egg code string: %{public}@", characterToAdd);
[_easterEggForSentry appendString:characterToAdd];
if ([kEasterEggText isEqualToString:_easterEggForSentry]) {
NSLog(@"Sentry - KME: Forcing crash now!");
os_log_debug([KMELogs keyLog], "Sentry - KME: Forcing crash now!");
// Both of the following approaches do throw an exception that causes control to exit this method,
// but at least in my debug builds locally, neither one seems to get picked up by Sentry in a
// way that results in a new report on sentry.keyman.com
@ -143,12 +145,10 @@ const NSString* kEasterEggKmxName = @"EnglishSpanish.kmx";
// purpose of enabling the engine to force a crash.
[(NSObject <NSAlertDelegate> *)[NSApp delegate] alertShowHelp:[NSAlert alertWithMessageText:@"Forcing an error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"Forcing an Easter egg error from KME!"]];
#endif
NSLog(@"Sentry - KME: You should not be seeing this line!");
}
}
else if (len > 0) {
NSLog(@"Sentry - KME: Clearing Easter Egg code string.");
os_log_debug([KMELogs keyLog], "Sentry - KME: Clearing Easter Egg code string.");
[_easterEggForSentry setString:@""];
}
}

View file

@ -11,6 +11,7 @@
#import "KMCompGroup.h"
#import "KMCompKey.h"
#import "NSString+XString.h"
#import "KMELogs.h"
NSString *const kKMKeyboardNameKey = @"KMKeyboardNameKey";
NSString *const kKMKeyboardVersionKey = @"KMKeyboardVersionKey";
@ -31,7 +32,7 @@ NSString *const kKMVisualKeyboardKey = @"KMVisualKeyboardKey";
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
if (file == nil) {
//NSLog(@"Failed to open kmx file");
os_log_error([KMELogs configLog], "Failed to open kmx file");
_filePath = nil;
return nil;
}
@ -162,7 +163,7 @@ NSString *const kKMVisualKeyboardKey = @"KMVisualKeyboardKey";
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
if (file == nil) {
//NSLog(@"Failed to open file");
os_log_error([KMELogs configLog], "Failed to open file");
return nil;
}

View file

@ -8,6 +8,7 @@
#import "KVKFile.h"
#import "NKey.h"
#import "KMELogs.h"
@implementation KVKFile
@ -21,7 +22,7 @@
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
if (file == nil) {
//NSLog(@"Failed to open kvk file");
os_log_error([KMELogs configLog], "Failed to open kmx file");
_filePath = nil;
return nil;
}

View file

@ -10,7 +10,7 @@
#import "KeyLabel.h"
#import "MacVKCodes.h"
#import "TimerTarget.h"
#import <os/log.h>
#import "KMELogs.h"
CGFloat lw = 1.0;
CGFloat r = 7.0;
@ -39,10 +39,9 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
@synthesize bgColorRegularKey, bgColorSpecialKey;
- (id)initWithFrame:(NSRect)frame {
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
self = [super initWithFrame:frame];
if (self) {
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "KeyView initWithFrame: %{public}@, bounds: %{public}@, default clipsToBounds %{public}@", NSStringFromRect(frame), NSStringFromRect(self.bounds), self.clipsToBounds?@"YES":@"NO");
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;
@ -71,8 +70,7 @@ static CGFloat const kRelativeModifierLabelHeight = 0.30f;
}
- (void)drawRect:(NSRect)rect {
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "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);
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);

View file

@ -7,15 +7,14 @@
//
#import "OSKKey.h"
#import <os/log.h>
#import "KMELogs.h"
@implementation OSKKey
- (id)initWithKeyCode:(NSUInteger)keyCode caption:(NSString *)caption scale:(CGFloat)scale {
self = [super init];
if (self) {
os_log_t oskKeyLog = os_log_create("org.sil.keyman", "osk-key");
os_log_with_type(oskKeyLog, OS_LOG_TYPE_DEBUG, "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale);
os_log_debug([KMELogs oskLog], "OSKKey initWithKeyCode: 0x%lx, caption: %{public}@, scale: %f", keyCode, caption, scale);
_keyCode = keyCode;
if (caption == nil)

View file

@ -15,7 +15,7 @@
#import "CoreHelper.h"
#include <Carbon/Carbon.h>
#import <os/log.h>
#import "KMELogs.h"
@interface OSKView()
@property (nonatomic, strong) NSArray *oskLayout;
@ -32,8 +32,7 @@
@synthesize tag;
- (id)initWithFrame:(NSRect)frame {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView initWithFrame: %{public}@", NSStringFromRect(frame));
os_log_debug([KMELogs oskLog], "OSKView initWithFrame: %{public}@", NSStringFromRect(frame));
self = [super initWithFrame:frame];
if (self) {
// Custom initialization
@ -44,8 +43,7 @@
}
- (void)drawRect:(NSRect)rect {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView drawRect: %{public}@", NSStringFromRect(rect));
os_log_debug([KMELogs uiLog], "OSKView drawRect: %{public}@", NSStringFromRect(rect));
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContext];
CGContextSetLineJoin(context, kCGLineJoinRound);
@ -103,8 +101,7 @@
}
- (void)setKvk:(KVKFile *)kvk {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView setKvk, forces keyboard to re-layout");
os_log_debug([KMELogs oskLog], "OSKView setKvk, forces keyboard to re-layout");
_kvk = kvk;
// Force the keyboard to re-layout
@ -115,8 +112,7 @@
}
- (void)initOSKKeys {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView initOSKKeys");
os_log_debug([KMELogs oskLog], "OSKView initOSKKeys");
CGFloat viewWidth = self.frame.size.width;
CGFloat viewHeight = self.frame.size.height;
CGFloat margin = 2.0;
@ -151,8 +147,7 @@
- (NSArray *)oskLayout {
if (_oskLayout == nil) {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "oskLayout -> creating new arrays of OSKKey objects");
os_log_debug([KMELogs oskLog], "oskLayout -> creating new arrays of OSKKey objects");
NSArray *row1 = [NSArray arrayWithObjects:
[[OSKKey alloc] initWithKeyCode:MVK_GRAVE caption:@"`" scale:1.0],
[[OSKKey alloc] initWithKeyCode:MVK_1 caption:@"1" scale:1.0],
@ -237,8 +232,7 @@
- (NSArray *)oskDefaultNKeys {
if (_oskDefaultNKeys == nil) {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "oskDefaultNKeys -> creating new arrays of default number OSKKey objects");
os_log_debug([KMELogs oskLog], "oskDefaultNKeys -> creating new arrays of default number OSKKey objects");
NSMutableArray *defNKeys = [[NSMutableArray alloc] initWithCapacity:0];
// row 1
@ -409,8 +403,7 @@
}
- (void)resizeOSKLayout {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView resizeOSKLayout, removing all superviews");
os_log_debug([KMELogs oskLog], "OSKView resizeOSKLayout, removing all superviews");
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self initOSKKeys];
}
@ -418,8 +411,7 @@
- (void)keyAction:(id)sender {
KeyView *keyView = (KeyView *)sender;
NSUInteger keyCode = [keyView.key keyCode];
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView keyAction keyCode: 0x%lx", keyCode);
os_log_debug([KMELogs oskLog], "OSKView keyAction keyCode: 0x%lx", keyCode);
if (keyCode < 0x100) {
NSRunningApplication *app = NSWorkspace.sharedWorkspace.frontmostApplication;
pid_t processId = app.processIdentifier;
@ -458,8 +450,7 @@
}
- (void)handleKeyEvent:(NSEvent *)event {
os_log_t oskLog = os_log_create("org.sil.keyman", "osk");
os_log_with_type(oskLog, OS_LOG_TYPE_DEBUG, "OSKView handleKeyEvent event.type: %lu", event.type);
os_log_debug([KMELogs oskLog], "OSKView handleKeyEvent event.type: %lu", event.type);
NSView *view = [self viewWithTag:event.keyCode|0x1000];
if (view == nil || ![view isKindOfClass:[KeyView class]])
return;

View file

@ -15,6 +15,7 @@
#import "CoreTestStaticHelperMethods.h"
#import "CoreAction.h"
#import "MacVKCodes.h"
#import "KMELogs.h"
@interface CoreWrapperTests : XCTestCase
@ -28,8 +29,8 @@ CoreWrapper *mockWrapper;
+ (void)setUp {
NSString *khmerKeyboardPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"khmer_angkor.kmx"];
NSLog(@"mockKmxFilePath = %@\n", mockKmxFilePath);
os_log_debug([KMELogs testLog], "mockKmxFilePath = %@\n", mockKmxFilePath);
mockWrapper = [[CoreWrapper alloc] initWithHelper: [CoreTestStaticHelperMethods helper] kmxFilePath:mockKmxFilePath];
}

View file

@ -11,6 +11,7 @@
#import "KeymanEngineTestsStaticHelperMethods.h"
#import "KMEngine.h"
#import "CoreAction.h"
#import "KMELogs.h"
@interface KMEngineTests : XCTestCase
@end
@ -106,7 +107,7 @@ NSString * names[nCombinations];
KMEngine *engine = [[KMEngine alloc] initWithKMX:kmxFile context:@"" verboseLogging:YES];
NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0 windowNumber:0 context:nil characters:@"a" charactersIgnoringModifiers:@"a" isARepeat:NO keyCode:kVK_ANSI_A];
CoreKeyOutput *output = [engine processEvent:event];
NSLog(@"output = %@", output);
os_log_debug([KMELogs testLog], "output = %{public}@", output);
XCTAssert(output.hasTextToInsert, @"output has text to insert");
XCTAssert([output.textToInsert isEqualToString:@"\u00C7"], @"Expected capital C cedille (U+00C7)");
}
@ -287,14 +288,14 @@ NSString * names[nCombinations];
if (modifiers[i] & (LEFT_ALT_FLAG | RIGHT_ALT_FLAG))
characters = [characters stringByAppendingString:@"\u030A"];
NSLog(@"Test case: %lu", (NSUInteger)modifiers[i]);
os_log_debug([KMELogs testLog], "Test case: %lu", (NSUInteger)modifiers[i]);
// NOTE: 'a' happens to be keyCode 0 (see initVirtualKeyMapping in CoreHelper)
NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown location:NSMakePoint(0, 0) modifierFlags:modifiers[i] timestamp:0 windowNumber:0 context:nil characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:0];
NSString * keyCombination = [names[i] stringByAppendingFormat:@" %@", charactersIgnoringModifiers];
CoreKeyOutput *coreKeyOutput = [engine processEvent:event];
XCTAssert(coreKeyOutput.hasTextToInsert, @"hasTextToInsert for %@", keyCombination);
NSString *output = coreKeyOutput.textToInsert;
NSLog(@"output = %@", output);
os_log_debug([KMELogs testLog], "output = %{public}@", output);
switch (modifiers[i]) {
case LEFT_SHIFT_FLAG:
case RIGHT_SHIFT_FLAG:
@ -358,13 +359,13 @@ NSString * names[nCombinations];
characters = @"ß";
}
NSLog(@"Test case: %lu", (NSUInteger)modifiers[i]);
os_log_debug([KMELogs testLog], "Test case: %lu", (NSUInteger)modifiers[i]);
// NOTE: 's' happens to be keyCode 1 (see initVirtualKeyMapping in CoreHelper)
NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown location:NSMakePoint(0, 0) modifierFlags:modifiers[i] timestamp:0 windowNumber:0 context:nil characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:1];
NSString * keyCombination = [names[i] stringByAppendingFormat:@" %@", charactersIgnoringModifiers];
CoreKeyOutput *coreKeyOutput = [engine processEvent:event];
NSString *output = coreKeyOutput.textToInsert;
NSLog(@"output = %@", output);
os_log_debug([KMELogs testLog], "output = %@", output);
switch (modifiers[i]) {
case LEFT_SHIFT_FLAG:
case RIGHT_SHIFT_FLAG:
@ -548,7 +549,7 @@ NSString * names[nCombinations];
KMEngine *engine = [[KMEngine alloc] initWithKMX:kmxFile context:@"" verboseLogging:YES];
NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0 windowNumber:0 context:nil characters:@"\b" charactersIgnoringModifiers:@"\b" isARepeat:NO keyCode:kVK_Delete];
CoreKeyOutput *output = [engine processEvent:event];
NSLog(@"output: %@", output);
os_log_debug([KMELogs testLog], "output = %{public}@", output);
XCTAssert(!output.hasTextToInsert, @"expected to insert nothing");
XCTAssert(!output.hasCodePointsToDelete, @"expected to delete nothing");
XCTAssert(output.emitKeystroke, @"expected to emit key");
@ -559,7 +560,7 @@ NSString * names[nCombinations];
KMEngine *engine = [[KMEngine alloc] initWithKMX:kmxFile context:@"ɣ" verboseLogging:YES];
NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0 windowNumber:0 context:nil characters:@"\b" charactersIgnoringModifiers:@"\b" isARepeat:NO keyCode:kVK_Delete];
CoreKeyOutput *output = [engine processEvent:event];
NSLog(@"output: %@", output);
os_log_debug([KMELogs testLog], "output = %{public}@", output);
XCTAssert(output.codePointsToDeleteBeforeInsert == 1, @"Expected output to delete one code point");
XCTAssert(!output.hasTextToInsert, @"expected to insert nothing");
NSString *context = engine.getCoreContextDebug;