From e58c78374f4b367c8322c30f914ec18cb84805f3 Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Wed, 8 Jan 2025 11:01:27 +0700 Subject: [PATCH 01/11] Ignore Spotlight --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 30 +++++++++++++++--- .../macOS/OpenKey.xcodeproj/project.pbxproj | 6 ++-- .../UserInterfaceState.xcuserstate | Bin 0 -> 18869 bytes 3 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 4292db2d..26b566a0 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -3,7 +3,7 @@ // OpenKey // // Created by Tuyen on 1/18/19. -// Copyright © 2019 Tuyen Mai. All rights reserved. +// Copyright 2019 Tuyen Mai. All rights reserved. // #import #import @@ -53,6 +53,8 @@ @"com.sublimetext.2", ]; + NSString* const SPOTLIGHT_BUNDLE = @"com.apple.Spotlight"; + //app which error with unicode Compound NSArray* _unicodeCompoundApp = @[@"com.apple.", @"com.google.Chrome", @"com.brave.Browser", @@ -575,6 +577,25 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod * MAIN HOOK entry, very important function. * MAIN Callback. */ + NSString* getFocusedAppBundleId() { + AXUIElementRef systemWide = AXUIElementCreateSystemWide(); + AXUIElementRef focusedApp = NULL; + AXError result = AXUIElementCopyAttributeValue(systemWide, kAXFocusedApplicationAttribute, (CFTypeRef*)&focusedApp); + + if (result == kAXErrorSuccess && focusedApp) { + pid_t pid = 0; + AXUIElementGetPid(focusedApp, &pid); + NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; + CFRelease(focusedApp); + CFRelease(systemWide); + return app.bundleIdentifier; + } + + if (focusedApp) CFRelease(focusedApp); + CFRelease(systemWide); + return nil; + } + CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { //dont handle my event if (CGEventGetIntegerValueField(event, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource)) { @@ -645,8 +666,9 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e _proxy = proxy; - //If is in english mode - if (vLanguage == 0) { + //If is in english mode or typing in Spotlight + NSString *focusedAppId = getFocusedAppBundleId(); + if (vLanguage == 0 || [focusedAppId isEqualToString:SPOTLIGHT_BUNDLE]) { if (vUseMacro && vUseMacroInEnglishMode && type == kCGEventKeyDown) { vEnglishMode((type == kCGEventKeyDown ? vKeyEventState::KeyDown : vKeyEventState::MouseDown), _keycode, @@ -732,7 +754,7 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e //send backspace if (pData->backspaceCount > 0 && pData->backspaceCount < MAX_BUFF) { - for (_i = 0; _i < pData->backspaceCount; _i++) { + for (int i = 0; i < pData->backspaceCount; i++) { SendBackspace(); } } diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.pbxproj b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.pbxproj index 8434abed..596497d5 100644 --- a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.pbxproj +++ b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.pbxproj @@ -570,6 +570,7 @@ buildSettings = { CLANG_ENABLE_MODULES = NO; CODE_SIGN_IDENTITY = "Mac Developer"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 48; @@ -580,7 +581,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 11.5; MARKETING_VERSION = 2.0.4; OTHER_LDFLAGS = ( "-lc++\n-lc++", @@ -596,6 +597,7 @@ buildSettings = { CLANG_ENABLE_MODULES = NO; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 48; @@ -606,7 +608,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 11.5; MARKETING_VERSION = 2.0.4; OTHER_LDFLAGS = ( "-lc++\n-lc++", diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..24bb7101adeed8e590d9903d2d312217a466735e GIT binary patch literal 18869 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 gZ Date: Wed, 8 Jan 2025 11:01:34 +0700 Subject: [PATCH 02/11] Ignore Spotlight --- .../UserInterfaceState.xcuserstate | Bin 18869 -> 18869 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate index 24bb7101adeed8e590d9903d2d312217a466735e..2566a9309996530e1b8df72f49a6a2c52e1e9ce9 100644 GIT binary patch delta 39 scmdlwnQ`l6#trBASvX!lJG=Q3e;$bS;oD{x`CoiM)+w#cPI|@C0Bk=IasU7T delta 39 scmdlwnQ`l6#trBASy=Wc-Q9eNKM%xGbKC49|BDaEl9{~ONv~KM05h)+W&i*H From 0f1bd4d8192725688dda21312709fc41f846a839 Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Wed, 8 Jan 2025 21:46:40 +0700 Subject: [PATCH 03/11] optimize detecting focus app --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 22 +++++++++++++----- .../UserInterfaceState.xcuserstate | Bin 18869 -> 44321 bytes 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 26b566a0..3630753e 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -87,6 +87,9 @@ NSString* _frontMostApp = @"UnknownApp"; + static NSString *lastFocusedAppBundleId = nil; + static pid_t lastFocusedAppPid = -1; + void OpenKeyInit() { //load saved data vFreeMark = 0;//(int)[[NSUserDefaults standardUserDefaults] integerForKey:@"FreeMark"]; @@ -573,10 +576,6 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod fallbackKeyCode); } - /** - * MAIN HOOK entry, very important function. - * MAIN Callback. - */ NSString* getFocusedAppBundleId() { AXUIElementRef systemWide = AXUIElementCreateSystemWide(); AXUIElementRef focusedApp = NULL; @@ -585,17 +584,28 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod if (result == kAXErrorSuccess && focusedApp) { pid_t pid = 0; AXUIElementGetPid(focusedApp, &pid); + + // Check if the focused app has changed + if (pid != lastFocusedAppPid) { NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; + lastFocusedAppBundleId = app.bundleIdentifier; + lastFocusedAppPid = pid; + } + CFRelease(focusedApp); CFRelease(systemWide); - return app.bundleIdentifier; + return lastFocusedAppBundleId; } if (focusedApp) CFRelease(focusedApp); CFRelease(systemWide); return nil; } - + + /** + * MAIN HOOK entry, very important function. + * MAIN Callback. + */ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { //dont handle my event if (CGEventGetIntegerValueField(event, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource)) { diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate index 2566a9309996530e1b8df72f49a6a2c52e1e9ce9..8252ec75d5199724ea49ad52becf25def65fe6c2 100644 GIT binary patch literal 44321 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 delta 9382 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 From 2508ee11e86e6396f1a5c0839dcd76118775d256 Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Wed, 8 Jan 2025 23:22:19 +0700 Subject: [PATCH 04/11] optimize detecting focus app --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 3630753e..d106984f 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -89,6 +89,17 @@ static NSString *lastFocusedAppBundleId = nil; static pid_t lastFocusedAppPid = -1; + + // Global AX variables + static AXUIElementRef g_systemWide = NULL; + + // Cleanup function for AX variables + static void cleanupAXVariables() { + if (g_systemWide) { + CFRelease(g_systemWide); + g_systemWide = NULL; + } + } void OpenKeyInit() { //load saved data @@ -148,6 +159,11 @@ void OpenKeyInit() { } } + void OpenKeyCleanup() { + cleanupAXVariables(); + // ... other cleanup code ... + } + void RequestNewSession() { //send event signal to Engine vKeyHandleEvent(vKeyEvent::Mouse, vKeyEventState::MouseDown, 0); @@ -577,9 +593,12 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod } NSString* getFocusedAppBundleId() { - AXUIElementRef systemWide = AXUIElementCreateSystemWide(); + if (!g_systemWide) { + g_systemWide = AXUIElementCreateSystemWide(); + } + AXUIElementRef focusedApp = NULL; - AXError result = AXUIElementCopyAttributeValue(systemWide, kAXFocusedApplicationAttribute, (CFTypeRef*)&focusedApp); + AXError result = AXUIElementCopyAttributeValue(g_systemWide, kAXFocusedApplicationAttribute, (CFTypeRef*)&focusedApp); if (result == kAXErrorSuccess && focusedApp) { pid_t pid = 0; @@ -587,18 +606,18 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod // Check if the focused app has changed if (pid != lastFocusedAppPid) { - NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; + NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; lastFocusedAppBundleId = app.bundleIdentifier; lastFocusedAppPid = pid; } CFRelease(focusedApp); - CFRelease(systemWide); return lastFocusedAppBundleId; } - if (focusedApp) CFRelease(focusedApp); - CFRelease(systemWide); + if (focusedApp) { + CFRelease(focusedApp); + } return nil; } From 803879745e9e13c0ecb5ce5754d15daa825ef38e Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Thu, 9 Jan 2025 10:43:16 +0700 Subject: [PATCH 05/11] optimize detecting focus app --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 37 ++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index d106984f..6d482839 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -52,8 +52,11 @@ NSArray* _niceSpaceApp = @[@"com.sublimetext.3", @"com.sublimetext.2", ]; - - NSString* const SPOTLIGHT_BUNDLE = @"com.apple.Spotlight"; + + // Array of bundle IDs for apps that should be ignored + static NSArray* const IGNORED_BUNDLES = @[ + @"com.apple.Spotlight" // Spotlight search + ]; //app which error with unicode Compound NSArray* _unicodeCompoundApp = @[@"com.apple.", @@ -89,6 +92,7 @@ static NSString *lastFocusedAppBundleId = nil; static pid_t lastFocusedAppPid = -1; + static bool _willUpdateFocusedApp = false; // Global AX variables static AXUIElementRef g_systemWide = NULL; @@ -203,6 +207,7 @@ void saveSmartSwitchKeyData() { } void OnActiveAppChanged() { //use for smart switch key; improved on Sep 28th, 2019 + _willUpdateFocusedApp = true; queryFrontMostApp(); _languageTemp = getAppInputMethodStatus(string(_frontMostApp.UTF8String), vLanguage | (vCodeTable << 1)); if ((_languageTemp & 0x01) != vLanguage) { //for input method @@ -592,7 +597,7 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod fallbackKeyCode); } - NSString* getFocusedAppBundleId() { + void updateFocusedAppBundleId() { if (!g_systemWide) { g_systemWide = AXUIElementCreateSystemWide(); } @@ -603,7 +608,6 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod if (result == kAXErrorSuccess && focusedApp) { pid_t pid = 0; AXUIElementGetPid(focusedApp, &pid); - // Check if the focused app has changed if (pid != lastFocusedAppPid) { NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; @@ -612,13 +616,12 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod } CFRelease(focusedApp); - return lastFocusedAppBundleId; + return; } if (focusedApp) { CFRelease(focusedApp); } - return nil; } /** @@ -695,9 +698,8 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e _proxy = proxy; - //If is in english mode or typing in Spotlight - NSString *focusedAppId = getFocusedAppBundleId(); - if (vLanguage == 0 || [focusedAppId isEqualToString:SPOTLIGHT_BUNDLE]) { + //If is in english mode + if (vLanguage == 0) { if (vUseMacro && vUseMacroInEnglishMode && type == kCGEventKeyDown) { vEnglishMode((type == kCGEventKeyDown ? vKeyEventState::KeyDown : vKeyEventState::MouseDown), _keycode, @@ -714,6 +716,7 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e //handle mouse if (type == kCGEventLeftMouseDown || type == kCGEventRightMouseDown || type == kCGEventLeftMouseDragged || type == kCGEventRightMouseDragged) { + _willUpdateFocusedApp = true; RequestNewSession(); return event; } @@ -739,6 +742,21 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e //handle keyboard if (type == kCGEventKeyDown) { + + //update focused app + if (_willUpdateFocusedApp) { + updateFocusedAppBundleId(); + _willUpdateFocusedApp = false; + } + if (OTHER_CONTROL_KEY) { + _willUpdateFocusedApp = true; + } + + //ignore some apps + if (lastFocusedAppBundleId && [IGNORED_BUNDLES containsObject:lastFocusedAppBundleId]) { + return event; + } + //send event signal to Engine vKeyHandleEvent(vKeyEvent::Keyboard, vKeyEventState::KeyDown, @@ -758,7 +776,6 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e } _syncKey.pop_back(); } - } else if (pData->extCode == 3) { //normal key InsertKeyLength(1); } From 21bcb6918ecee698fe1dbebe0b6f34ec63b1b3bd Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Thu, 9 Jan 2025 21:23:05 +0700 Subject: [PATCH 06/11] optimize detecting focus app --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 6d482839..eace09a9 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -608,6 +608,7 @@ void updateFocusedAppBundleId() { if (result == kAXErrorSuccess && focusedApp) { pid_t pid = 0; AXUIElementGetPid(focusedApp, &pid); + // Check if the focused app has changed if (pid != lastFocusedAppPid) { NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:pid]; @@ -617,6 +618,13 @@ void updateFocusedAppBundleId() { CFRelease(focusedApp); return; + } else { + // Fallback to NSWorkspace when AX API fails + NSRunningApplication *frontApp = [[NSWorkspace sharedWorkspace] frontmostApplication]; + if (frontApp && frontApp.processIdentifier != lastFocusedAppPid) { + lastFocusedAppBundleId = frontApp.bundleIdentifier; + lastFocusedAppPid = frontApp.processIdentifier; + } } if (focusedApp) { @@ -751,7 +759,7 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e if (OTHER_CONTROL_KEY) { _willUpdateFocusedApp = true; } - + //ignore some apps if (lastFocusedAppBundleId && [IGNORED_BUNDLES containsObject:lastFocusedAppBundleId]) { return event; From 94efae9c4b57ee7c589cd0b8e341e0d63833d08a Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Thu, 9 Jan 2025 21:44:36 +0700 Subject: [PATCH 07/11] turn off Vietnamese when in other language: accept unicode hex input --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index eace09a9..6dbe1e24 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -739,9 +739,9 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e if (CFArrayGetCount(languages) > 0) { CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); NSString *currentLanguage = (__bridge NSString *)langRef; - if(![currentLanguage isLike:@"en"]){ + if(![currentLanguage isLike:@"en"] && ![currentLanguage isLike:@""]){ // empty for "unicode hex input" return event; - } + }a CFRelease(langRef); CFRelease(isource); } From 7c843bc2c70d2404006ce0b9b828d7585a1fba3d Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Thu, 9 Jan 2025 21:49:54 +0700 Subject: [PATCH 08/11] turn off Vietnamese when in other language: accept unicode hex input --- .../UserInterfaceState.xcuserstate | Bin 44321 -> 49510 bytes .../xcdebugger/Expressions.xcexplist | 14 ++ .../xcdebugger/Breakpoints_v2.xcbkptlist | 132 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/xcdebugger/Expressions.xcexplist create mode 100644 Sources/OpenKey/macOS/OpenKey.xcodeproj/xcuserdata/irix.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/UserInterfaceState.xcuserstate index 8252ec75d5199724ea49ad52becf25def65fe6c2..e02c4fce3f61384e7163fb79011c1fb58062ec71 100644 GIT binary patch literal 49510 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 diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/xcdebugger/Expressions.xcexplist b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/xcdebugger/Expressions.xcexplist new file mode 100644 index 00000000..b873cab8 --- /dev/null +++ b/Sources/OpenKey/macOS/OpenKey.xcodeproj/project.xcworkspace/xcuserdata/irix.xcuserdatad/xcdebugger/Expressions.xcexplist @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/Sources/OpenKey/macOS/OpenKey.xcodeproj/xcuserdata/irix.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Sources/OpenKey/macOS/OpenKey.xcodeproj/xcuserdata/irix.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000..1ece9ca1 --- /dev/null +++ b/Sources/OpenKey/macOS/OpenKey.xcodeproj/xcuserdata/irix.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From dc9ae1d8c8dc560bf66f125c30293f696db90fdb Mon Sep 17 00:00:00 2001 From: "Son. Pham The" <> Date: Thu, 9 Jan 2025 21:50:02 +0700 Subject: [PATCH 09/11] turn off Vietnamese when in other language: accept unicode hex input --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 6dbe1e24..fd5d43e8 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -741,7 +741,7 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e NSString *currentLanguage = (__bridge NSString *)langRef; if(![currentLanguage isLike:@"en"] && ![currentLanguage isLike:@""]){ // empty for "unicode hex input" return event; - }a + } CFRelease(langRef); CFRelease(isource); } From 29c3ec2865e40917c80e8bcbca0bde557c7558e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 06:25:32 +0000 Subject: [PATCH 10/11] Initial plan From 0eb40f7f3063ce9943845338a8ed5230e2c39663 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 06:38:56 +0000 Subject: [PATCH 11/11] Fix CFRelease memory safety issues in OpenKey.mm Co-authored-by: sonthepham-dev <46697168+sonthepham-dev@users.noreply.github.com> --- Sources/OpenKey/macOS/ModernKey/OpenKey.mm | 170 ++++++++++++--------- 1 file changed, 96 insertions(+), 74 deletions(-) diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index fd5d43e8..23ad879d 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -256,12 +256,14 @@ void InsertKeyLength(const Uint8& len) { void SendPureCharacter(const Uint16& ch) { _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, 1, &ch); - CGEventKeyboardSetUnicodeString(_newEventUp, 1, &ch); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); - CFRelease(_newEventDown); - CFRelease(_newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, 1, &ch); + CGEventKeyboardSetUnicodeString(_newEventUp, 1, &ch); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } + if (_newEventDown) CFRelease(_newEventDown); + if (_newEventUp) CFRelease(_newEventUp); if (IS_DOUBLE_CODE(vCodeTable)) { InsertKeyLength(1); } @@ -302,21 +304,25 @@ void SendKeyCode(Uint32 data) { _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newChar); - CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newChar); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newChar); + CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newChar); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } if (_newCharHi > 32) { if (vCodeTable == 2) //VNI InsertKeyLength(2); - CFRelease(_newEventDown); - CFRelease(_newEventUp); + if (_newEventDown) CFRelease(_newEventDown); + if (_newEventUp) CFRelease(_newEventUp); _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newCharHi); - CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newCharHi); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newCharHi); + CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newCharHi); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } } else { if (vCodeTable == 2) //VNI InsertKeyLength(1); @@ -329,14 +335,16 @@ void SendKeyCode(Uint32 data) { InsertKeyLength(_newCharHi > 0 ? 2 : 1); _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, (_newCharHi > 0 ? 2 : 1), _uniChar); - CGEventKeyboardSetUnicodeString(_newEventUp, (_newCharHi > 0 ? 2 : 1), _uniChar); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, (_newCharHi > 0 ? 2 : 1), _uniChar); + CGEventKeyboardSetUnicodeString(_newEventUp, (_newCharHi > 0 ? 2 : 1), _uniChar); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } } } - CFRelease(_newEventDown); - CFRelease(_newEventUp); + if (_newEventDown) CFRelease(_newEventDown); + if (_newEventUp) CFRelease(_newEventUp); } void SendEmptyCharacter() { @@ -350,77 +358,89 @@ void SendEmptyCharacter() { _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newChar); - CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newChar); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); - CFRelease(_newEventDown); - CFRelease(_newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, 1, &_newChar); + CGEventKeyboardSetUnicodeString(_newEventUp, 1, &_newChar); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } + if (_newEventDown) CFRelease(_newEventDown); + if (_newEventUp) CFRelease(_newEventUp); } void SendVirtualKey(const Byte& vKey) { CGEventRef eventVkeyDown = CGEventCreateKeyboardEvent (myEventSource, vKey, true); CGEventRef eventVkeyUp = CGEventCreateKeyboardEvent (myEventSource, vKey, false); - CGEventTapPostEvent(_proxy, eventVkeyDown); - CGEventTapPostEvent(_proxy, eventVkeyUp); + if (eventVkeyDown && eventVkeyUp) { + CGEventTapPostEvent(_proxy, eventVkeyDown); + CGEventTapPostEvent(_proxy, eventVkeyUp); + } - CFRelease(eventVkeyDown); - CFRelease(eventVkeyUp); + if (eventVkeyDown) CFRelease(eventVkeyDown); + if (eventVkeyUp) CFRelease(eventVkeyUp); } void SendBackspace() { - CGEventTapPostEvent(_proxy, eventBackSpaceDown); - CGEventTapPostEvent(_proxy, eventBackSpaceUp); - - if (IS_DOUBLE_CODE(vCodeTable)) { //VNI or Unicode Compound - if (_syncKey.back() > 1) { - if (!(vCodeTable == 3 && containUnicodeCompoundApp(FRONT_APP))) { - CGEventTapPostEvent(_proxy, eventBackSpaceDown); - CGEventTapPostEvent(_proxy, eventBackSpaceUp); + if (eventBackSpaceDown && eventBackSpaceUp) { + CGEventTapPostEvent(_proxy, eventBackSpaceDown); + CGEventTapPostEvent(_proxy, eventBackSpaceUp); + + if (IS_DOUBLE_CODE(vCodeTable)) { //VNI or Unicode Compound + if (_syncKey.back() > 1) { + if (!(vCodeTable == 3 && containUnicodeCompoundApp(FRONT_APP))) { + CGEventTapPostEvent(_proxy, eventBackSpaceDown); + CGEventTapPostEvent(_proxy, eventBackSpaceUp); + } } + _syncKey.pop_back(); } - _syncKey.pop_back(); } } void SendShiftAndLeftArrow() { CGEventRef eventVkeyDown = CGEventCreateKeyboardEvent (myEventSource, KEY_LEFT, true); CGEventRef eventVkeyUp = CGEventCreateKeyboardEvent (myEventSource, KEY_LEFT, false); - _privateFlag = CGEventGetFlags(eventVkeyDown); - _privateFlag |= kCGEventFlagMaskShift; - CGEventSetFlags(eventVkeyDown, _privateFlag); - CGEventSetFlags(eventVkeyUp, _privateFlag); - - CGEventTapPostEvent(_proxy, eventVkeyDown); - CGEventTapPostEvent(_proxy, eventVkeyUp); - - if (IS_DOUBLE_CODE(vCodeTable)) { //VNI or Unicode Compound - if (_syncKey.back() > 1) { - if (!(vCodeTable == 3 && containUnicodeCompoundApp(FRONT_APP))) { - CGEventTapPostEvent(_proxy, eventVkeyDown); - CGEventTapPostEvent(_proxy, eventVkeyUp); + + if (eventVkeyDown && eventVkeyUp) { + _privateFlag = CGEventGetFlags(eventVkeyDown); + _privateFlag |= kCGEventFlagMaskShift; + CGEventSetFlags(eventVkeyDown, _privateFlag); + CGEventSetFlags(eventVkeyUp, _privateFlag); + + CGEventTapPostEvent(_proxy, eventVkeyDown); + CGEventTapPostEvent(_proxy, eventVkeyUp); + + if (IS_DOUBLE_CODE(vCodeTable)) { //VNI or Unicode Compound + if (_syncKey.back() > 1) { + if (!(vCodeTable == 3 && containUnicodeCompoundApp(FRONT_APP))) { + CGEventTapPostEvent(_proxy, eventVkeyDown); + CGEventTapPostEvent(_proxy, eventVkeyUp); + } } + _syncKey.pop_back(); } - _syncKey.pop_back(); } - CFRelease(eventVkeyDown); - CFRelease(eventVkeyUp); + if (eventVkeyDown) CFRelease(eventVkeyDown); + if (eventVkeyUp) CFRelease(eventVkeyUp); } void SendCutKey() { CGEventRef eventVkeyDown = CGEventCreateKeyboardEvent (myEventSource, KEY_X, true); CGEventRef eventVkeyUp = CGEventCreateKeyboardEvent (myEventSource, KEY_X, false); - _privateFlag = CGEventGetFlags(eventVkeyDown); - _privateFlag |= NX_COMMANDMASK; - CGEventSetFlags(eventVkeyDown, _privateFlag); - CGEventSetFlags(eventVkeyUp, _privateFlag); - CGEventTapPostEvent(_proxy, eventVkeyDown); - CGEventTapPostEvent(_proxy, eventVkeyUp); + if (eventVkeyDown && eventVkeyUp) { + _privateFlag = CGEventGetFlags(eventVkeyDown); + _privateFlag |= NX_COMMANDMASK; + CGEventSetFlags(eventVkeyDown, _privateFlag); + CGEventSetFlags(eventVkeyUp, _privateFlag); + + CGEventTapPostEvent(_proxy, eventVkeyDown); + CGEventTapPostEvent(_proxy, eventVkeyUp); + } - CFRelease(eventVkeyDown); - CFRelease(eventVkeyUp); + if (eventVkeyDown) CFRelease(eventVkeyDown); + if (eventVkeyUp) CFRelease(eventVkeyUp); } void SendNewCharString(const bool& dataFromMacro=false, const Uint16& offset=0) { @@ -498,12 +518,14 @@ void SendNewCharString(const bool& dataFromMacro=false, const Uint16& offset=0) _newEventDown = CGEventCreateKeyboardEvent(myEventSource, 0, true); _newEventUp = CGEventCreateKeyboardEvent(myEventSource, 0, false); - CGEventKeyboardSetUnicodeString(_newEventDown, _willContinuteSending ? 16 : _newCharSize - offset, _newCharString); - CGEventKeyboardSetUnicodeString(_newEventUp, _willContinuteSending ? 16 : _newCharSize - offset, _newCharString); - CGEventTapPostEvent(_proxy, _newEventDown); - CGEventTapPostEvent(_proxy, _newEventUp); - CFRelease(_newEventDown); - CFRelease(_newEventUp); + if (_newEventDown && _newEventUp) { + CGEventKeyboardSetUnicodeString(_newEventDown, _willContinuteSending ? 16 : _newCharSize - offset, _newCharString); + CGEventKeyboardSetUnicodeString(_newEventUp, _willContinuteSending ? 16 : _newCharSize - offset, _newCharString); + CGEventTapPostEvent(_proxy, _newEventDown); + CGEventTapPostEvent(_proxy, _newEventUp); + } + if (_newEventDown) CFRelease(_newEventDown); + if (_newEventUp) CFRelease(_newEventUp); if (_willContinuteSending) { SendNewCharString(dataFromMacro, dataFromMacro ? _k : 16); @@ -740,11 +762,11 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e CFStringRef langRef = (CFStringRef)CFArrayGetValueAtIndex(languages, 0); NSString *currentLanguage = (__bridge NSString *)langRef; if(![currentLanguage isLike:@"en"] && ![currentLanguage isLike:@""]){ // empty for "unicode hex input" + CFRelease(isource); return event; } - CFRelease(langRef); - CFRelease(isource); } + CFRelease(isource); } } @@ -777,7 +799,7 @@ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef e _syncKey.clear(); } else if (pData->extCode == 2) { //delete key if (_syncKey.size() > 0) { - if (_syncKey.back() > 1 && (vCodeTable == 2 || !containUnicodeCompoundApp(FRONT_APP))) { + if (_syncKey.back() > 1 && (vCodeTable == 2 || !containUnicodeCompoundApp(FRONT_APP)) && eventBackSpaceDown && eventBackSpaceUp) { //send one more backspace CGEventTapPostEvent(_proxy, eventBackSpaceDown); CGEventTapPostEvent(_proxy, eventBackSpaceUp);