From 435439ecd207ea02fd68c490e8fe6efd1ef4d4b8 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Mon, 9 Apr 2018 22:59:02 +0100 Subject: [PATCH] Added Haptic feddback on click all buttons --- MTMR.xcodeproj/project.pbxproj | 8 +++++ MTMR/HapticFeedback.swift | 57 ++++++++++++++++++++++++++++++ MTMR/TouchBarItems.swift | 18 +++++----- MTMR/TouchBarPrivateApi-Bridging.h | 10 ++++++ 4 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 MTMR/HapticFeedback.swift diff --git a/MTMR.xcodeproj/project.pbxproj b/MTMR.xcodeproj/project.pbxproj index 8f337d8..ed288e9 100644 --- a/MTMR.xcodeproj/project.pbxproj +++ b/MTMR.xcodeproj/project.pbxproj @@ -18,6 +18,8 @@ B082B25A205C7D8000BC04DC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B082B258205C7D8000BC04DC /* Main.storyboard */; }; B082B266205C7D8000BC04DC /* MTMRTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B082B265205C7D8000BC04DC /* MTMRTests.swift */; }; B082B271205C7D8000BC04DC /* MTMRUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B082B270205C7D8000BC04DC /* MTMRUITests.swift */; }; + B09EB1E4207C082000D5C1E0 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09EB1E3207C082000D5C1E0 /* HapticFeedback.swift */; }; + B09EB1E6207C0F8E00D5C1E0 /* MultitouchSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B09EB1E5207C0F8E00D5C1E0 /* MultitouchSupport.framework */; }; B0A7E9AA205D6AA400EEF070 /* KeyPress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0A7E9A9205D6AA400EEF070 /* KeyPress.swift */; }; B0A8BF9E207B84160086F74D /* weather.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B0A8BF9D207B84160086F74D /* weather.scpt */; }; B0C1CFCA205C97D30021C862 /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C1CFC9205C97D30021C862 /* WindowController.swift */; }; @@ -64,6 +66,8 @@ B082B26C205C7D8000BC04DC /* MTMRUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MTMRUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B082B270205C7D8000BC04DC /* MTMRUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MTMRUITests.swift; sourceTree = ""; }; B082B272205C7D8000BC04DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B09EB1E3207C082000D5C1E0 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticFeedback.swift; sourceTree = ""; }; + B09EB1E5207C0F8E00D5C1E0 /* MultitouchSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MultitouchSupport.framework; path = ../../../../../System/Library/PrivateFrameworks/MultitouchSupport.framework; sourceTree = ""; }; B0A7E9A9205D6AA400EEF070 /* KeyPress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPress.swift; sourceTree = ""; }; B0A8BF9D207B84160086F74D /* weather.scpt */ = {isa = PBXFileReference; lastKnownFileType = text; path = weather.scpt; sourceTree = ""; }; B0C1CFC9205C97D30021C862 /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; @@ -78,6 +82,7 @@ buildActionMask = 2147483647; files = ( B059D62D205F11E8006E6B86 /* DFRFoundation.framework in Frameworks */, + B09EB1E6207C0F8E00D5C1E0 /* MultitouchSupport.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -101,6 +106,7 @@ B059D62B205F11E8006E6B86 /* Frameworks */ = { isa = PBXGroup; children = ( + B09EB1E5207C0F8E00D5C1E0 /* MultitouchSupport.framework */, B059D62C205F11E8006E6B86 /* DFRFoundation.framework */, ); name = Frameworks; @@ -149,6 +155,7 @@ B0F8771B207AC92700D6E430 /* TouchBarSupport.h */, B0F8771C207AD35400D6E430 /* battery.scpt */, B0A8BF9D207B84160086F74D /* weather.scpt */, + B09EB1E3207C082000D5C1E0 /* HapticFeedback.swift */, ); path = MTMR; sourceTree = ""; @@ -318,6 +325,7 @@ B0F8771A207AC1EA00D6E430 /* TouchBarSupport.m in Sources */, B082B253205C7D8000BC04DC /* AppDelegate.swift in Sources */, B059D624205E04F3006E6B86 /* TouchBarItems.swift in Sources */, + B09EB1E4207C082000D5C1E0 /* HapticFeedback.swift in Sources */, B0A7E9AA205D6AA400EEF070 /* KeyPress.swift in Sources */, 36C2ECD7207B6DAE003CDA33 /* TimeTouchBarItem.swift in Sources */, ); diff --git a/MTMR/HapticFeedback.swift b/MTMR/HapticFeedback.swift new file mode 100644 index 0000000..573b350 --- /dev/null +++ b/MTMR/HapticFeedback.swift @@ -0,0 +1,57 @@ +// +// HapticFeedback.swift +// MTMR +// +// Created by Anton Palgunov on 09/04/2018. +// Copyright © 2018 Anton Palgunov. All rights reserved. +// + +import IOKit + +class HapticFeedback { + private var actuatorRef: CFTypeRef? + private var deviceID: UInt64 = 0x200000001000000 + private var error: IOReturn = 0 + + // Don't know how to do strong is enum one of + // 1 like backClick + // 2 (like Click) + // 3 (week) + // 4 (medium) + // 5 (week medium) + // 6 (strong) + // 15 (nothing) + // 16 (nothing) + + func tap(strong:Int32) -> Void { + let actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue() + + // TODO: Need to fix warning + guard actuatorRef != nil else { + print("guard actuatorRef == nil") + return + } + + error = MTActuatorOpen(actuatorRef) + guard error == kIOReturnSuccess else { + print("guard MTActuatorOpen") + return + } + + error = MTActuatorActuate(actuatorRef, strong, 0, 0.0, 0.0) + guard error == kIOReturnSuccess else { + print("guard MTActuatorActuate") + return + } + + error = MTActuatorClose(actuatorRef) + guard error == kIOReturnSuccess else { + print("guard MTActuatorClose") + return + } + + return + } +} + + diff --git a/MTMR/TouchBarItems.swift b/MTMR/TouchBarItems.swift index af2ffcd..2f93810 100644 --- a/MTMR/TouchBarItems.swift +++ b/MTMR/TouchBarItems.swift @@ -11,45 +11,47 @@ import Cocoa extension NSTouchBarItem.Identifier { static let escButton = NSTouchBarItem.Identifier("com.toxblh.mtmr.escButton") static let dismissButton = NSTouchBarItem.Identifier("com.toxblh.mtmr.dismissButton") - + // Volume static let volumeUp = NSTouchBarItem.Identifier("com.toxblh.mtmr.volumeUp") static let volumeDown = NSTouchBarItem.Identifier("com.toxblh.mtmr.volumeDown") - + // Brightness static let brightUp = NSTouchBarItem.Identifier("com.toxblh.mtmr.brightUp") static let brightDown = NSTouchBarItem.Identifier("com.toxblh.mtmr.brightDown") - + // Music static let prev = NSTouchBarItem.Identifier("com.toxblh.mtmr.prev") static let next = NSTouchBarItem.Identifier("com.toxblh.mtmr.next") static let play = NSTouchBarItem.Identifier("com.toxblh.mtmr.play") - + // Plugins static let sleep = NSTouchBarItem.Identifier("com.toxblh.mtmr.sleep") static let weather = NSTouchBarItem.Identifier("com.toxblh.mtmr.weather") static let time = NSTouchBarItem.Identifier("com.toxblh.mtmr.time") static let battery = NSTouchBarItem.Identifier("com.toxblh.mtmr.battery") static let nowPlaying = NSTouchBarItem.Identifier("com.toxblh.mtmr.nowPlaying") - + static let controlStripItem = NSTouchBarItem.Identifier("com.toxblh.mtmr.controlStrip") } class CustomButtonTouchBarItem: NSCustomTouchBarItem { let tapClosure: (NSCustomTouchBarItem) -> () - + init(identifier: NSTouchBarItem.Identifier, title: String, onTap callback: @escaping (NSCustomTouchBarItem) -> ()) { self.tapClosure = callback super.init(identifier: identifier) self.view = NSButton(title: title, target: self, action: #selector(didTapped)) } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + @objc func didTapped() { self.tapClosure(self) + let hf: HapticFeedback = HapticFeedback() + hf.tap(strong: 6) } } diff --git a/MTMR/TouchBarPrivateApi-Bridging.h b/MTMR/TouchBarPrivateApi-Bridging.h index 28ea5b2..8c25a7d 100644 --- a/MTMR/TouchBarPrivateApi-Bridging.h +++ b/MTMR/TouchBarPrivateApi-Bridging.h @@ -8,3 +8,13 @@ #import "TouchBarPrivateApi.h" #import "TouchBarSupport.h" + +NS_ASSUME_NONNULL_BEGIN + +CF_EXPORT CFTypeRef MTActuatorCreateFromDeviceID(UInt64 deviceID); +CF_EXPORT IOReturn MTActuatorOpen(CFTypeRef actuatorRef); +CF_EXPORT IOReturn MTActuatorClose(CFTypeRef actuatorRef); +CF_EXPORT IOReturn MTActuatorActuate(CFTypeRef actuatorRef, SInt32 actuationID, UInt32 arg1, Float32 arg2, Float32 arg3); +CF_EXPORT bool MTActuatorIsOpen(CFTypeRef actuatorRef); + +NS_ASSUME_NONNULL_END