1
0
mirror of https://github.com/Toxblh/MTMR.git synced 2026-01-10 17:08:39 +00:00

HapticFeedback: fix broken haptic for Release builds + refactori… (#198)

HapticFeedback: fix broken haptic for Release builds + refactoring
This commit is contained in:
Anton Palgunov 2019-07-28 00:17:18 +01:00 committed by GitHub
commit 95271dba0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 33 deletions

View File

@ -12,7 +12,6 @@ class CustomButtonTouchBarItem: NSCustomTouchBarItem, NSGestureRecognizerDelegat
var tapClosure: (() -> Void)? var tapClosure: (() -> Void)?
var longTapClosure: (() -> Void)? var longTapClosure: (() -> Void)?
private let hf: HapticFeedback = HapticFeedback()
private var button: NSButton! private var button: NSButton!
private var singleClick: HapticClickGestureRecognizer! private var singleClick: HapticClickGestureRecognizer!
private var longClick: NSPressGestureRecognizer! private var longClick: NSPressGestureRecognizer!
@ -118,10 +117,10 @@ class CustomButtonTouchBarItem: NSCustomTouchBarItem, NSGestureRecognizerDelegat
switch gr.state { switch gr.state {
case .began: case .began:
if let closure = self.longTapClosure { if let closure = self.longTapClosure {
hf.tap(strong: 2) HapticFeedback.shared.tap(strong: 2)
closure() closure()
} else if let closure = self.tapClosure { } else if let closure = self.tapClosure {
hf.tap(strong: 6) HapticFeedback.shared.tap(strong: 6)
closure() closure()
print("long click") print("long click")
} }
@ -171,15 +170,13 @@ class CustomButtonCell: NSButtonCell {
} }
class HapticClickGestureRecognizer: NSClickGestureRecognizer { class HapticClickGestureRecognizer: NSClickGestureRecognizer {
let hf: HapticFeedback = HapticFeedback()
override func touchesBegan(with event: NSEvent) { override func touchesBegan(with event: NSEvent) {
hf.tap(strong: 2) HapticFeedback.shared.tap(strong: 2)
super.touchesBegan(with: event) super.touchesBegan(with: event)
} }
override func touchesEnded(with event: NSEvent) { override func touchesEnded(with event: NSEvent) {
hf.tap(strong: 1) HapticFeedback.shared.tap(strong: 1)
super.touchesEnded(with: event) super.touchesEnded(with: event)
} }
} }

View File

@ -9,7 +9,7 @@
import IOKit import IOKit
class HapticFeedback { class HapticFeedback {
private var correctDeviceId: UInt64? static let 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
@ -20,16 +20,11 @@ class HapticFeedback {
0x200_0000_0100_0000, // MacBook Pro 2016/2017 0x200_0000_0100_0000, // MacBook Pro 2016/2017
0x300000080500000 // MacBook Pro 2019 (possibly 2018 as well) 0x300000080500000 // MacBook Pro 2019 (possibly 2018 as well)
] ]
private var correctDeviceID: UInt64?
private var actuatorRef: CFTypeRef?
init() { init() {
// Let's find our Haptic device recreateDevice()
possibleDeviceIDs.forEach {(deviceID) in
guard correctDeviceId == nil else {return}
let actuatorRef: CFTypeRef? = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
if actuatorRef != nil {
correctDeviceId = deviceID
}
}
} }
// Don't know how to do strong is enum one of // Don't know how to do strong is enum one of
@ -44,15 +39,8 @@ class HapticFeedback {
// 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` // 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) { func tap(strong: Int32) {
guard correctDeviceId != nil else { guard correctDeviceID != nil, actuatorRef != nil else {
print("guard correctDeviceId == nil (no haptic device found?)") print("guard actuatorRef == nil (no haptic device found?)")
return
}
let actuatorRef: CFTypeRef? = MTActuatorCreateFromDeviceID(correctDeviceId!).takeRetainedValue()
guard actuatorRef != nil else {
print("guard actuatorRef == nil")
return return
} }
@ -61,10 +49,11 @@ class HapticFeedback {
result = MTActuatorOpen(actuatorRef!) result = MTActuatorOpen(actuatorRef!)
guard result == kIOReturnSuccess else { guard result == kIOReturnSuccess else {
print("guard MTActuatorOpen") print("guard MTActuatorOpen")
recreateDevice()
return return
} }
result = MTActuatorActuate(actuatorRef!, strong, 0, 0.0, 0.0) result = MTActuatorActuate(actuatorRef!, strong, 0, 0, 0)
guard result == kIOReturnSuccess else { guard result == kIOReturnSuccess else {
print("guard MTActuatorActuate") print("guard MTActuatorActuate")
return return
@ -76,4 +65,25 @@ class HapticFeedback {
return return
} }
} }
private func recreateDevice() {
if let actuatorRef = actuatorRef {
MTActuatorClose(actuatorRef)
self.actuatorRef = nil // just in case %)
}
if let correctDeviceID = correctDeviceID {
actuatorRef = MTActuatorCreateFromDeviceID(correctDeviceID).takeRetainedValue()
} else {
// Let's find our Haptic device
possibleDeviceIDs.forEach {(deviceID) in
guard correctDeviceID == nil else {return}
actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
if actuatorRef != nil {
correctDeviceID = deviceID
}
}
}
}
} }

View File

@ -10,8 +10,6 @@ import Cocoa
class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrubberDataSource { class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrubberDataSource {
private var scrubber: NSScrubber! private var scrubber: NSScrubber!
private let hf: HapticFeedback = HapticFeedback()
private var timer: Timer! private var timer: Timer!
private var ticks: Int = 0 private var ticks: Int = 0
private let minTicks: Int = 5 private let minTicks: Int = 5
@ -148,12 +146,12 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
ticks += 1 ticks += 1
if ticks == minTicks { if ticks == minTicks {
hf.tap(strong: 2) HapticFeedback.shared.tap(strong: 2)
} }
if ticks > maxTicks { if ticks > maxTicks {
stopTimer() stopTimer()
hf.tap(strong: 6) HapticFeedback.shared.tap(strong: 6)
} }
} }
@ -184,7 +182,7 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
NSWorkspace.shared.openFile(bundleIdentifier!.replacingOccurrences(of: "file://", with: "")) NSWorkspace.shared.openFile(bundleIdentifier!.replacingOccurrences(of: "file://", with: ""))
} else { } else {
NSWorkspace.shared.launchApplication(withBundleIdentifier: bundleIdentifier!, options: [.default], additionalEventParamDescriptor: nil, launchIdentifier: nil) NSWorkspace.shared.launchApplication(withBundleIdentifier: bundleIdentifier!, options: [.default], additionalEventParamDescriptor: nil, launchIdentifier: nil)
hf.tap(strong: 6) HapticFeedback.shared.tap(strong: 6)
} }
updateRunningApplication() updateRunningApplication()
@ -203,7 +201,7 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
} }
} }
} else { } else {
hf.tap(strong: 6) HapticFeedback.shared.tap(strong: 6)
if let index = self.persistentAppIdentifiers.index(of: bundleIdentifier!) { if let index = self.persistentAppIdentifiers.index(of: bundleIdentifier!) {
persistentAppIdentifiers.remove(at: index) persistentAppIdentifiers.remove(at: index)
} else { } else {

View File

@ -123,7 +123,7 @@ class CurrencyBarItem: CustomButtonTouchBarItem {
} }
let regularFont = attributedTitle.attribute(.font, at: 0, effectiveRange: nil) as? NSFont ?? NSFont.systemFont(ofSize: 15) let regularFont = attributedTitle.attribute(.font, at: 0, effectiveRange: nil) as? NSFont ?? NSFont.systemFont(ofSize: 15)
let newTitle = NSMutableAttributedString(string: title as String, attributes: [.foregroundColor: color, .font: regularFont]) let newTitle = NSMutableAttributedString(string: title as String, attributes: [.foregroundColor: color, .font: regularFont, .baselineOffset: 1])
newTitle.setAlignment(.center, range: NSRange(location: 0, length: title.count)) newTitle.setAlignment(.center, range: NSRange(location: 0, length: title.count))
attributedTitle = newTitle attributedTitle = newTitle
} }