Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment the next line to define a global platform for your project
platform :osx, '10.12'
platform :osx, '10.13'

target 'Unshaky' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
Expand Down
6 changes: 3 additions & 3 deletions Unshaky.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "LOCATION=\"${BUILT_PRODUCTS_DIR}\"/\"${FRAMEWORKS_FOLDER_PATH}\"\n\n# By default, use the configured code signing identity for the project/target\nIDENTITY=\"${CODE_SIGN_IDENTITY}\"\nIDENTITY=\"Apple Development: Xinhong Liu (32BU6UVQ76)\"\nif [ \"$IDENTITY\" == \"\" ]\nthen\n# If a code signing identity is not specified, use ad hoc signing\nIDENTITY=\"-\"\nfi\nif [ \"$DONT_CODE_SIGN\" == \"YES\" ]\nthen\n# If a code signing identity is not specified, use ad hoc signing\nIDENTITY=\"-\"\nfi\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Sparkle.framework/Versions/A/Resources/AutoUpdate.app\"\ncodesign --verbose --force -o runtime --sign \"$IDENTITY\" \"$LOCATION/Sparkle.framework/Versions/A\"\n";
shellScript = "LOCATION=\"${BUILT_PRODUCTS_DIR}\"/\"${FRAMEWORKS_FOLDER_PATH}\"\n\n# By default, use the configured code signing identity for the project/target\nIDENTITY=\"${CODE_SIGN_IDENTITY}\"\nif [ \"$IDENTITY\" == \"\" ]\nthen\n# If a code signing identity is not specified, use ad hoc signing\nIDENTITY=\"-\"\nfi\nif [ \"$DONT_CODE_SIGN\" == \"YES\" ]\nthen\n# If a code signing identity is not specified, use ad hoc signing\nIDENTITY=\"-\"\nfi\ncodesign --verbose --force --deep -o runtime --sign \"$IDENTITY\" \"$LOCATION/Sparkle.framework/Versions/A/Resources/AutoUpdate.app\"\ncodesign --verbose --force -o runtime --sign \"$IDENTITY\" \"$LOCATION/Sparkle.framework/Versions/A\"\n";
};
63A7B0E478BADB58754CFBEC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
Expand Down Expand Up @@ -792,7 +792,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.12;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 0.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nestederror.Unshaky;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -821,7 +821,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.12;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MARKETING_VERSION = 0.7.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nestederror.Unshaky;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
34 changes: 33 additions & 1 deletion Unshaky/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Cocoa
import ServiceManagement
import IOKit.hid

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
Expand Down Expand Up @@ -88,17 +89,48 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// Basic
//
func setup() {
// Since macOS 10.15 (and strictly enforced in 10.15.6+), CGEventTap requires
// BOTH Accessibility AND Input Monitoring permission. Trigger the Input
// Monitoring prompt up-front so the user lands in the right pane.
let inputMonitoringGranted = requestInputMonitoringIfNeeded()

// this following lines will add Unshaky.app to privacy->accessibility panel, unchecked
let checkOptPrompt = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString
let accessEnabled = AXIsProcessTrustedWithOptions([checkOptPrompt: false] as CFDictionary?)

if (!shakyPressPreventer.setupEventTap() || !accessEnabled) {
let eventTapOK = shakyPressPreventer.setupEventTap()

if !accessEnabled || !eventTapOK {
let alert = NSAlert()
alert.messageText = NSLocalizedString("Accessibility Help", comment: "")
alert.runModal()
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)
NSApplication.shared.terminate(self)
return
}

if !inputMonitoringGranted {
let alert = NSAlert()
alert.messageText = NSLocalizedString("Input Monitoring Help", comment: "")
alert.runModal()
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent")!)
NSApplication.shared.terminate(self)
}
}

/// Returns true if Input Monitoring is granted (or can't be queried on this OS).
/// On macOS 10.15+, also triggers the system prompt the first time it's needed.
private func requestInputMonitoringIfNeeded() -> Bool {
if #available(macOS 10.15, *) {
let access = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent)
if access == kIOHIDAccessTypeGranted {
return true
}
// Fires the TCC prompt on first call; subsequent calls just return the
// current state without re-prompting.
return IOHIDRequestAccess(kIOHIDRequestTypeListenEvent)
}
return true
}

func recover() {
Expand Down
2 changes: 2 additions & 0 deletions Unshaky/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

"Accessibility Help" = "Unshaky needs accessibility permission to work. Right now, Unshaky will attempt to open this panel for you. If it does not open automatically, you have to go to: System Preferences -> Security & Privacy -> Privacy (Tab) -> Accessibility (Left panel). \n\nWhen you have the panel open, add and check the Unshaky.app. \n\nOn Big Sur, you will need to do the same for Privacy (Tab) -> Input Monitoring (Left panel).";

"Input Monitoring Help" = "Unshaky also needs Input Monitoring permission on macOS 10.15.6 and later. Unshaky will attempt to open this panel for you. If it does not open automatically, go to: System Settings -> Privacy & Security -> Input Monitoring, then add and enable Unshaky.app. \n\nAfter enabling it, relaunch Unshaky.";

"Invalid Delay" = "\"%@\" is not a valid delay. Please input an integer value.";

"Paste the configuration here" = "Paste the configuration here";
Expand Down