Skip to content

Commit 660edbe

Browse files
committed
set CapsLockDelayOverride to 0
1 parent 24239a0 commit 660edbe

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

CapsLockSwitcher.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@
285285
"$(inherited)",
286286
"@executable_path/../Frameworks",
287287
);
288-
MARKETING_VERSION = 1.0;
288+
MARKETING_VERSION = 1.1;
289289
PRODUCT_BUNDLE_IDENTIFIER = com.doasync.CapsLockSwitcher;
290290
PRODUCT_NAME = "$(TARGET_NAME)";
291291
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -315,7 +315,7 @@
315315
"$(inherited)",
316316
"@executable_path/../Frameworks",
317317
);
318-
MARKETING_VERSION = 1.0;
318+
MARKETING_VERSION = 1.1;
319319
PRODUCT_BUNDLE_IDENTIFIER = com.doasync.CapsLockSwitcher;
320320
PRODUCT_NAME = "$(TARGET_NAME)";
321321
SWIFT_EMIT_LOC_STRINGS = YES;

CapsLockSwitcher/AppDelegate.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
6363

6464
func applicationDidFinishLaunching(_ aNotification: Notification) {
6565
print("CapsLockSwitcher: Did Finish Launching")
66+
67+
// Set the override
68+
manageCapsLockDelayOverride(setOverride: true)
69+
6670
// Check permissions initially - prompt might not work on modern OS anyway
6771
let hasPermissions = checkAccessibilityPermissions(promptUserIfNeeded: false)
6872

@@ -100,6 +104,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
100104

101105
func applicationWillTerminate(_ aNotification: Notification) {
102106
print("CapsLockSwitcher: Will Terminate")
107+
manageCapsLockDelayOverride(setOverride: false) // Reset the override
103108
destroyEventTap() // Clean up the event tap
104109
// Remove status item (optional, system usually does it)
105110
if let item = statusItem {
@@ -739,7 +744,48 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
739744

740745

741746
// MARK: - Helper Functions
747+
/// Manages the system-level CapsLockDelayOverride using hidutil.
748+
/// - Parameter setOverride: If true, sets the delay override to 0. If false, attempts to reset the override
749+
private func manageCapsLockDelayOverride(setOverride: Bool) {
750+
// Use "0" to set the override, "200" to reset it to default.
751+
let propertyValue = setOverride ? "0" : "200"
752+
let jsonString = "{\"CapsLockDelayOverride\":\(propertyValue)}"
753+
let actionDescription = setOverride ? "set CapsLockDelayOverride to 0" : "reset CapsLockDelayOverride"
754+
755+
print("CapsLockSwitcher: Attempting to \(actionDescription)...")
756+
757+
let process = Process()
758+
// Ensure the path to hidutil is correct. /usr/bin/ is standard.
759+
process.executableURL = URL(fileURLWithPath: "/usr/bin/hidutil")
760+
process.arguments = ["property", "--set", jsonString]
761+
762+
// Optional: Capture output/errors for debugging
763+
let pipe = Pipe()
764+
process.standardOutput = pipe
765+
process.standardError = pipe
766+
767+
do {
768+
try process.run()
769+
process.waitUntilExit() // Wait for the command to complete
770+
771+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
772+
if let output = String(data: data, encoding: .utf8), !output.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
773+
// Log output only if it's not empty to avoid noise
774+
print("hidutil output: \(output.trimmingCharacters(in: .whitespacesAndNewlines))")
775+
}
742776

777+
if process.terminationStatus == 0 {
778+
print("CapsLockSwitcher: Successfully \(actionDescription).")
779+
} else {
780+
// Log a warning if the command finished with an error status
781+
print("Warning: hidutil command finished with status \(process.terminationStatus). \(actionDescription) might have failed.")
782+
}
783+
} catch {
784+
// Log an error if process.run() itself throws (e.g., command not found)
785+
print("Error executing hidutil to \(actionDescription): \(error.localizedDescription)")
786+
}
787+
}
788+
743789
/// Handles cleanup and UI update when permission loss is detected, run on main thread.
744790
private func handleSuspectedPermissionLoss() {
745791
// Ensure we are on the main thread for UI updates and state changes

0 commit comments

Comments
 (0)