diff --git a/Sources/OpenKey/engine/Engine.h b/Sources/OpenKey/engine/Engine.h
index f288f8c5..f1e54905 100644
--- a/Sources/OpenKey/engine/Engine.h
+++ b/Sources/OpenKey/engine/Engine.h
@@ -32,12 +32,14 @@
#define HAS_OPTION(data) ((data & 0x200) ? 1 : 0)
#define HAS_COMMAND(data) ((data & 0x400) ? 1 : 0)
#define HAS_SHIFT(data) ((data & 0x800) ? 1 : 0)
+#define HAS_FN(data) ((data & 0x1000) ? 1 : 0)
#define GET_BOOL(data) (data ? 1 : 0)
#define HAS_BEEP(data) (data & 0x8000)
#define SET_SWITCH_KEY(data, key) data = (data & 0xFF) | key
#define SET_CONTROL_KEY(data, val) data|=val<<8;
#define SET_OPTION_KEY(data, val) data|=val<<9;
#define SET_COMMAND_KEY(data, val) data|=val<<10;
+#define SET_FN_KEY(data, val) data|=val<<12;
//define these variable in your application
//API
diff --git a/Sources/OpenKey/macOS/ModernKey/AppDelegate.m b/Sources/OpenKey/macOS/ModernKey/AppDelegate.m
index 011708e2..3216104d 100644
--- a/Sources/OpenKey/macOS/ModernKey/AppDelegate.m
+++ b/Sources/OpenKey/macOS/ModernKey/AppDelegate.m
@@ -111,35 +111,35 @@ -(void)askPermission {
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
appDelegate = self;
-
+
[self registerSupportedNotification];
-
+
//set quick tooltip
[[NSUserDefaults standardUserDefaults] setObject: [NSNumber numberWithInt: 50]
forKey: @"NSInitialToolTipDelay"];
-
+
//check whether this app has been launched before that or not
NSArray* runningApp = [[NSWorkspace sharedWorkspace] runningApplications];
if ([runningApp containsObject:OPENKEY_BUNDLE]) { //if already running -> exit
[NSApp terminate:nil];
return;
}
-
+
// check if user granted Accessabilty permission
if (!MJAccessibilityIsEnabled()) {
[self askPermission];
return;
}
-
+
vShowIconOnDock = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"vShowIconOnDock"];
if (vShowIconOnDock)
[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
-
+
if (vSwitchKeyStatus & 0x8000)
NSBeep();
[self createStatusBarMenu];
-
+
//init
dispatch_async(dispatch_get_main_queue(), ^{
if (![OpenKeyManager initEventTap]) {
@@ -475,12 +475,24 @@ -(void) onControlPanelSelected {
if (_mainWC == nil) {
_mainWC = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"OpenKey"];
}
- //[OpenKeyManager showDockIcon:YES];
if ([_mainWC.window isVisible]) {
+ [NSApp activateIgnoringOtherApps:YES];
return;
}
+ [NSApp activateIgnoringOtherApps:YES];
[_mainWC.window makeKeyAndOrderFront:nil];
[_mainWC.window setLevel:NSFloatingWindowLevel];
+
+ // Center on the primary screen — saved frames from prior multi-display
+ // setups can land the window off-screen.
+ [_mainWC.window setFrameAutosaveName:@""];
+ NSScreen *primary = [NSScreen screens].firstObject ?: [NSScreen mainScreen];
+ NSRect visible = primary.visibleFrame;
+ NSRect frame = _mainWC.window.frame;
+ NSPoint origin = NSMakePoint(
+ visible.origin.x + (visible.size.width - frame.size.width) / 2,
+ visible.origin.y + (visible.size.height - frame.size.height) / 2);
+ [_mainWC.window setFrameOrigin:origin];
}
-(void) onMacroSelected {
@@ -488,9 +500,11 @@ -(void) onMacroSelected {
_macroWC = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"MacroWindow"];
}
//[OpenKeyManager showDockIcon:YES];
- if ([_macroWC.window isVisible])
+ if ([_macroWC.window isVisible]) {
+ [NSApp activateIgnoringOtherApps:YES];
return;
-
+ }
+ [NSApp activateIgnoringOtherApps:YES];
[_macroWC.window makeKeyAndOrderFront:nil];
[_macroWC.window setLevel:NSFloatingWindowLevel];
}
@@ -500,9 +514,11 @@ -(void) onAboutSelected {
_aboutWC = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"AboutWindow"];
}
//[OpenKeyManager showDockIcon:YES];
- if ([_aboutWC.window isVisible])
+ if ([_aboutWC.window isVisible]) {
+ [NSApp activateIgnoringOtherApps:YES];
return;
-
+ }
+ [NSApp activateIgnoringOtherApps:YES];
[_aboutWC.window makeKeyAndOrderFront:nil];
[_aboutWC.window setLevel:NSFloatingWindowLevel];
}
diff --git a/Sources/OpenKey/macOS/ModernKey/Base.lproj/Main.storyboard b/Sources/OpenKey/macOS/ModernKey/Base.lproj/Main.storyboard
index 1ad0aedf..848672a3 100644
--- a/Sources/OpenKey/macOS/ModernKey/Base.lproj/Main.storyboard
+++ b/Sources/OpenKey/macOS/ModernKey/Base.lproj/Main.storyboard
@@ -889,10 +889,10 @@
-
+
-
+
@@ -900,7 +900,7 @@
+
+
+
+
+
+
+
+
+
+
-
+
@@ -967,7 +987,7 @@
-
+
@@ -976,7 +996,7 @@
-
+
@@ -985,7 +1005,7 @@
-
+
@@ -994,7 +1014,7 @@
-
+
@@ -1012,7 +1032,7 @@
-
+
@@ -1692,6 +1712,7 @@
+
diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm
index 4292db2d..18e75a1d 100644
--- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm
+++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm
@@ -500,6 +500,8 @@ bool checkHotKey(int hotKeyData, bool checkKeyCode=true) {
return false;
if (HAS_SHIFT(hotKeyData) ^ GET_BOOL(_lastFlag & kCGEventFlagMaskShift))
return false;
+ if (HAS_FN(hotKeyData) ^ GET_BOOL(_lastFlag & kCGEventFlagMaskSecondaryFn))
+ return false;
if (checkKeyCode) {
if (GET_SWITCH_KEY(hotKeyData) != _keycode)
return false;
diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m b/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m
index 2d1b665b..fbb24b04 100644
--- a/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m
+++ b/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m
@@ -71,12 +71,11 @@ +(BOOL)initEventTap {
// Add to the current run loop.
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
- // Enable the event tap.
+ // Enable the event tap. The source is on the main run loop, which
+ // NSApplication is already running — calling CFRunLoopRun() here would
+ // start a nested loop that blocks AppKit from processing UI events.
CGEventTapEnable(eventTap, true);
-
- // Set it all running.
- CFRunLoopRun();
-
+
return YES;
}
diff --git a/Sources/OpenKey/macOS/ModernKey/ViewController.m b/Sources/OpenKey/macOS/ModernKey/ViewController.m
index d4c5b73c..0f2a00d5 100644
--- a/Sources/OpenKey/macOS/ModernKey/ViewController.m
+++ b/Sources/OpenKey/macOS/ModernKey/ViewController.m
@@ -44,6 +44,7 @@ @implementation ViewController {
__weak IBOutlet NSButton *CustomSwitchOption;
__weak IBOutlet NSButton *CustomSwitchControl;
__weak IBOutlet NSButton *CustomSwitchShift;
+ __weak IBOutlet NSButton *CustomSwitchFn;
__weak IBOutlet MyTextField *CustomSwitchKey;
__weak IBOutlet NSButton *CustomBeepSound;
NSArray* tabviews, *tabbuttons;
@@ -250,6 +251,13 @@ - (IBAction)onShiftSwitchKey:(NSButton *)sender {
[[NSUserDefaults standardUserDefaults] setInteger:vSwitchKeyStatus forKey:@"SwitchKeyStatus"];
}
+- (IBAction)onFnSwitchKey:(NSButton *)sender {
+ NSInteger val = [self setCustomValue:sender keyToSet:nil];
+ vSwitchKeyStatus &= (~0x1000);
+ vSwitchKeyStatus |= val << 12;
+ [[NSUserDefaults standardUserDefaults] setInteger:vSwitchKeyStatus forKey:@"SwitchKeyStatus"];
+}
+
-(void)onMyTextFieldKeyChange:(unsigned short)keyCode character:(unsigned short)character {
vSwitchKeyStatus &= 0xFFFFFF00;
vSwitchKeyStatus |= keyCode;
@@ -467,6 +475,7 @@ -(void)fillData {
CustomSwitchOption.state = (vSwitchKeyStatus & 0x200) ? NSControlStateValueOn : NSControlStateValueOff;
CustomSwitchCommand.state = (vSwitchKeyStatus & 0x400) ? NSControlStateValueOn : NSControlStateValueOff;
CustomSwitchShift.state = (vSwitchKeyStatus & 0x800) ? NSControlStateValueOn : NSControlStateValueOff;
+ CustomSwitchFn.state = (vSwitchKeyStatus & 0x1000) ? NSControlStateValueOn : NSControlStateValueOff;
CustomBeepSound.state = (vSwitchKeyStatus & 0x8000) ? NSControlStateValueOn : NSControlStateValueOff;
[CustomSwitchKey setTextByChar:((vSwitchKeyStatus>>24) & 0xFF)];