mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-01-10 17:08:39 +00:00
Fix HapticFeedback; Add MBP 13, M1 2020 (#408)
* Fix HapticFeedback; Add MBP 13, M1 2020 * Fix warnings Co-authored-by: Sergey Ryazanov <sergey.ryazanov@rightperception.company>
This commit is contained in:
parent
44732e8ad6
commit
d270a7bbcd
@ -25,7 +25,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true] as NSDictionary)
|
AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true] as NSDictionary)
|
||||||
|
|
||||||
TouchBarController.shared.setupControlStripPresence()
|
TouchBarController.shared.setupControlStripPresence()
|
||||||
HapticFeedbackUpdate()
|
|
||||||
|
|
||||||
if let button = statusItem.button {
|
if let button = statusItem.button {
|
||||||
button.image = #imageLiteral(resourceName: "StatusImage")
|
button.image = #imageLiteral(resourceName: "StatusImage")
|
||||||
@ -41,10 +40,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
|
|
||||||
func applicationWillTerminate(_: Notification) {}
|
func applicationWillTerminate(_: Notification) {}
|
||||||
|
|
||||||
func HapticFeedbackUpdate() {
|
|
||||||
HapticFeedback.shared = AppSettings.hapticFeedbackState ? HapticFeedback() : nil
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func updateIsBlockedApp() {
|
@objc func updateIsBlockedApp() {
|
||||||
if let frontmostAppId = TouchBarController.shared.frontmostApplicationIdentifier {
|
if let frontmostAppId = TouchBarController.shared.frontmostApplicationIdentifier {
|
||||||
isBlockedApp = AppSettings.blacklistedAppIds.firstIndex(of: frontmostAppId) != nil
|
isBlockedApp = AppSettings.blacklistedAppIds.firstIndex(of: frontmostAppId) != nil
|
||||||
@ -86,7 +81,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
@objc func toggleHapticFeedback(_ item: NSMenuItem) {
|
@objc func toggleHapticFeedback(_ item: NSMenuItem) {
|
||||||
item.state = item.state == .on ? .off : .on
|
item.state = item.state == .on ? .off : .on
|
||||||
AppSettings.hapticFeedbackState = item.state == .on
|
AppSettings.hapticFeedbackState = item.state == .on
|
||||||
HapticFeedbackUpdate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func toggleMultitouch(_ item: NSMenuItem) {
|
@objc func toggleMultitouch(_ item: NSMenuItem) {
|
||||||
|
|||||||
@ -240,12 +240,12 @@ final class MultiClickGestureRecognizer: NSClickGestureRecognizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func touchesBegan(with event: NSEvent) {
|
override func touchesBegan(with event: NSEvent) {
|
||||||
HapticFeedback.shared?.tap(strong: 2)
|
HapticFeedback.instance.tap(type: .click)
|
||||||
super.touchesBegan(with: event)
|
super.touchesBegan(with: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func touchesEnded(with event: NSEvent) {
|
override func touchesEnded(with event: NSEvent) {
|
||||||
HapticFeedback.shared?.tap(strong: 1)
|
HapticFeedback.instance.tap(type: .back)
|
||||||
super.touchesEnded(with: event)
|
super.touchesEnded(with: event)
|
||||||
_clickCount += 1
|
_clickCount += 1
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ class LongPressGestureRecognizer: NSPressGestureRecognizer {
|
|||||||
@objc private func onTimer() {
|
@objc private func onTimer() {
|
||||||
if let target = self.target, let action = self.action {
|
if let target = self.target, let action = self.action {
|
||||||
target.performSelector(onMainThread: action, with: self, waitUntilDone: false)
|
target.performSelector(onMainThread: action, with: self, waitUntilDone: false)
|
||||||
HapticFeedback.shared?.tap(strong: 6)
|
HapticFeedback.instance.tap(type: .strong)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
import IOKit
|
import IOKit
|
||||||
|
|
||||||
class HapticFeedback {
|
class HapticFeedback {
|
||||||
static var shared: HapticFeedback?
|
|
||||||
|
|
||||||
// Here we have list of possible IDs for Haptic Generator Device. They are not constant
|
// Here we have list of possible IDs for Haptic Generator Device. They are not constant
|
||||||
// To find deviceID, you will need IORegistryExplorer app from Additional Tools for Xcode dmg
|
// To find deviceID, you will need IORegistryExplorer app from Additional Tools for Xcode dmg
|
||||||
@ -17,73 +16,82 @@ class HapticFeedback {
|
|||||||
// Open IORegistryExplorer app, search for AppleMultitouchDevice and get "Multitouch ID"
|
// Open IORegistryExplorer app, search for AppleMultitouchDevice and get "Multitouch ID"
|
||||||
// There should be programmatic way to get it but I can't find, no docs for macOS :(
|
// There should be programmatic way to get it but I can't find, no docs for macOS :(
|
||||||
private let possibleDeviceIDs: [UInt64] = [
|
private let possibleDeviceIDs: [UInt64] = [
|
||||||
0x200_0000_0100_0000, // MacBook Pro 2016/2017
|
0x200_0000_0100_0000, // MacBook Pro 2016/2017
|
||||||
0x300000080500000 // MacBook Pro 2019 (possibly 2018 as well)
|
0x300_0000_8050_0000, // MacBook Pro 2019/2018
|
||||||
|
0x200_0000_0000_0024, // MacBook Pro (13-inch, M1, 2020)
|
||||||
]
|
]
|
||||||
private var correctDeviceID: UInt64?
|
|
||||||
private var actuatorRef: CFTypeRef?
|
|
||||||
|
|
||||||
init() {
|
// you can get a plist `otool -s __TEXT __tpad_act_plist /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/Current/MultitouchSupport|tail -n +3|awk -F'\t' '{print $2}'|xxd -r -p`
|
||||||
recreateDevice()
|
enum HapticType: Int32, CaseIterable {
|
||||||
|
case back = 1
|
||||||
|
case click = 2
|
||||||
|
case weak = 3
|
||||||
|
case medium = 4
|
||||||
|
case weakMedium = 5
|
||||||
|
case strong = 6
|
||||||
|
case reserved1 = 15
|
||||||
|
case reserved2 = 16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't know how to do strong is enum one of
|
private var actuatorRef: CFTypeRef?
|
||||||
// 1 like back Click
|
|
||||||
// 2 like Click
|
|
||||||
// 3 week
|
|
||||||
// 4 medium
|
|
||||||
// 5 week medium
|
|
||||||
// 6 strong
|
|
||||||
// 15 nothing
|
|
||||||
// 16 nothing
|
|
||||||
// you can get a plist `otool -s __TEXT __tpad_act_plist /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/Current/MultitouchSupport|tail -n +3|awk -F'\t' '{print $2}'|xxd -r -p`
|
|
||||||
|
|
||||||
func tap(strong: Int32) {
|
static var instance = HapticFeedback()
|
||||||
guard correctDeviceID != nil, actuatorRef != nil else {
|
|
||||||
print("guard actuatorRef == nil (no haptic device found?)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var result: IOReturn
|
// MARK: - Init
|
||||||
|
|
||||||
result = MTActuatorOpen(actuatorRef!)
|
private init() {
|
||||||
guard result == kIOReturnSuccess else {
|
self.recreateDevice()
|
||||||
print("guard MTActuatorOpen")
|
|
||||||
recreateDevice()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result = MTActuatorActuate(actuatorRef!, strong, 0, 0, 0)
|
|
||||||
guard result == kIOReturnSuccess else {
|
|
||||||
print("guard MTActuatorActuate")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result = MTActuatorClose(actuatorRef!)
|
|
||||||
guard result == kIOReturnSuccess else {
|
|
||||||
print("guard MTActuatorClose")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func recreateDevice() {
|
private func recreateDevice() {
|
||||||
if let actuatorRef = actuatorRef {
|
if let actuatorRef = self.actuatorRef {
|
||||||
MTActuatorClose(actuatorRef)
|
MTActuatorClose(actuatorRef)
|
||||||
self.actuatorRef = nil // just in case %)
|
self.actuatorRef = nil // just in case %)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let correctDeviceID = correctDeviceID {
|
guard self.actuatorRef == nil else {
|
||||||
actuatorRef = MTActuatorCreateFromDeviceID(correctDeviceID).takeRetainedValue()
|
return
|
||||||
} else {
|
}
|
||||||
// Let's find our Haptic device
|
|
||||||
possibleDeviceIDs.forEach {(deviceID) in
|
|
||||||
guard correctDeviceID == nil else {return}
|
|
||||||
actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
|
|
||||||
|
|
||||||
if actuatorRef != nil {
|
// Let's find our Haptic device
|
||||||
correctDeviceID = deviceID
|
self.possibleDeviceIDs.forEach {(deviceID) in
|
||||||
}
|
let actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
|
||||||
|
|
||||||
|
if actuatorRef != nil {
|
||||||
|
self.actuatorRef = actuatorRef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Tap action
|
||||||
|
|
||||||
|
private func getActuatorIfPosible() -> CFTypeRef? {
|
||||||
|
guard AppSettings.hapticFeedbackState else { return nil }
|
||||||
|
guard let actuatorRef = self.actuatorRef else {
|
||||||
|
print("guard actuatorRef == nil (no haptic device found?)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard MTActuatorOpen(actuatorRef) == kIOReturnSuccess else {
|
||||||
|
print("guard MTActuatorOpen")
|
||||||
|
self.recreateDevice()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return actuatorRef
|
||||||
|
}
|
||||||
|
|
||||||
|
func tap(type: HapticType) {
|
||||||
|
guard let actuator = getActuatorIfPosible() else { return }
|
||||||
|
|
||||||
|
guard MTActuatorActuate(actuator, type.rawValue, 0, 0, 0) == kIOReturnSuccess else {
|
||||||
|
print("guard MTActuatorActuate")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard MTActuatorClose(actuator) == kIOReturnSuccess else {
|
||||||
|
print("guard MTActuatorClose")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user