mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-10-31 18:38:35 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91a4e5bded | ||
|
|
68dfcddb29 | ||
|
|
82ec231700 | ||
|
|
ed261c2349 | ||
|
|
f06d1f4329 | ||
|
|
3dabd598f4 | ||
|
|
0a09ea7117 | ||
|
|
02cf911336 | ||
|
|
d831069025 | ||
|
|
33206ab457 | ||
|
|
c6c808369f | ||
|
|
cbad06ac07 | ||
|
|
64171d5c51 | ||
|
|
5504e5d640 | ||
|
|
164295820b | ||
|
|
ae469bb92a | ||
|
|
57b5129135 | ||
|
|
7cc72de66f | ||
|
|
2e5db4ffa0 | ||
|
|
8a73fe01e4 | ||
|
|
5fbb2bafc6 | ||
|
|
5b6b6dfa56 | ||
|
|
65e5a52383 | ||
|
|
03304bd030 | ||
|
|
f264425ba7 | ||
|
|
c377b9494c | ||
|
|
f5b36ec012 | ||
|
|
999c4cf6e2 | ||
|
|
b8d5d0a8a5 | ||
|
|
6bb5aade07 | ||
|
|
b6bcc31456 | ||
|
|
9d09646742 | ||
|
|
55f988e393 | ||
|
|
2f4cf9e5f6 | ||
|
|
327d38e47d | ||
|
|
cd380b289d | ||
|
|
6a26b2f5ca | ||
|
|
d7186aac18 | ||
|
|
cef07dc965 | ||
|
|
471c0c5d57 | ||
|
|
5b93525806 | ||
|
|
b87bc632ab | ||
|
|
1763a24942 | ||
|
|
627e6951c1 | ||
|
|
918054df78 | ||
|
|
25fb0d4f04 | ||
|
|
61a357ffc3 | ||
|
|
f4116a95df | ||
|
|
c952505c1c | ||
|
|
f10b58b996 | ||
|
|
88a8ae3ae8 | ||
|
|
d783448567 | ||
|
|
595ae165d3 | ||
|
|
da406713dd | ||
|
|
938b83f37e | ||
|
|
a8a085df1e | ||
|
|
b188f45c8e | ||
|
|
3319c5d45a | ||
|
|
6174d14925 | ||
|
|
c8197239d7 | ||
|
|
d2854e3dae | ||
|
|
4f9c3258ae | ||
|
|
dfeda1e874 | ||
|
|
82f82039ae | ||
|
|
324c3f711e | ||
|
|
a81d6fc595 | ||
|
|
3bde1fe4b1 | ||
|
|
7c9dd26eb0 | ||
|
|
40fa61fcb5 | ||
|
|
5a8117ac7f | ||
|
|
a606767ddc | ||
|
|
6badc37dc3 | ||
|
|
4497c7102c | ||
|
|
b6c6bb945b | ||
|
|
3e399d14c2 | ||
|
|
624c8ac6d8 | ||
|
|
ea68ce33c1 | ||
|
|
744ea067db | ||
|
|
8064ab759c | ||
|
|
556c28df85 | ||
|
|
e68f930efa | ||
|
|
647ac0ba20 | ||
|
|
780a8ba81e | ||
|
|
71f5030fa6 | ||
|
|
f435c0b530 |
@@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: toxblh
|
||||
ko_fi: toxblh
|
||||
@@ -61,6 +61,7 @@
|
||||
B0B17439207D6B590004B740 /* Vox.nowPlaying.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B0B1742F207D6B590004B740 /* Vox.nowPlaying.scpt */; };
|
||||
B0B1743A207D6B590004B740 /* iTunes.nowPlaying.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B0B17430207D6B590004B740 /* iTunes.nowPlaying.scpt */; };
|
||||
B0F3112520C9E35F0076BB88 /* SupportNSTouchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F3112420C9E35F0076BB88 /* SupportNSTouchBar.swift */; };
|
||||
B0F54A7A2295AC7D00B4C509 /* DarkModeBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */; };
|
||||
B0F8771A207AC1EA00D6E430 /* TouchBarSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F87719207AC1EA00D6E430 /* TouchBarSupport.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -142,6 +143,7 @@
|
||||
B0B1742F207D6B590004B740 /* Vox.nowPlaying.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Vox.nowPlaying.scpt; sourceTree = "<group>"; };
|
||||
B0B17430207D6B590004B740 /* iTunes.nowPlaying.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = iTunes.nowPlaying.scpt; sourceTree = "<group>"; };
|
||||
B0F3112420C9E35F0076BB88 /* SupportNSTouchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportNSTouchBar.swift; sourceTree = "<group>"; };
|
||||
B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DarkModeBarItem.swift; sourceTree = "<group>"; };
|
||||
B0F87719207AC1EA00D6E430 /* TouchBarSupport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TouchBarSupport.m; sourceTree = "<group>"; };
|
||||
B0F8771B207AC92700D6E430 /* TouchBarSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TouchBarSupport.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -293,6 +295,7 @@
|
||||
6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */,
|
||||
607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */,
|
||||
B08126F0217BE19000A98970 /* WidgetProtocol.swift */,
|
||||
B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */,
|
||||
);
|
||||
path = Widgets;
|
||||
sourceTree = "<group>";
|
||||
@@ -446,6 +449,7 @@
|
||||
B0008E552080286C003AD4DD /* SupportHelpers.swift in Sources */,
|
||||
6042B6A72083E03A00C525C8 /* AppScrubberTouchBarItem.swift in Sources */,
|
||||
B082B253205C7D8000BC04DC /* AppDelegate.swift in Sources */,
|
||||
B0F54A7A2295AC7D00B4C509 /* DarkModeBarItem.swift in Sources */,
|
||||
B08126EF217BD0B900A98970 /* PomodoroBarItem.swift in Sources */,
|
||||
B081732C213739FE005D4908 /* DnDBarItem.swift in Sources */,
|
||||
60C44AFD20A373A100C0EC91 /* MusicBarItem.swift in Sources */,
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Latest</string>
|
||||
<string>Original</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "sun-icon-256.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "39857.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
@@ -619,7 +619,7 @@
|
||||
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleSourceList:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
|
||||
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||
|
||||
+27
-13
@@ -10,8 +10,24 @@ import IOKit
|
||||
|
||||
class HapticFeedback {
|
||||
private var actuatorRef: CFTypeRef?
|
||||
private var deviceID: UInt64 = 0x200_0000_0100_0000
|
||||
private var error: IOReturn = 0
|
||||
|
||||
// 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
|
||||
// which you can download from https://developer.apple.com/download/more/?=Additional%20Tools
|
||||
// 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 :(
|
||||
private var possibleDeviceIDs: [UInt64] = [
|
||||
0x200_0000_0100_0000, // MacBook Pro 2016/2017
|
||||
0x300000080500000 // MacBook Pro 2019 (possibly 2018 as well)
|
||||
]
|
||||
|
||||
init() {
|
||||
// Let's find and init Haptic device
|
||||
possibleDeviceIDs.forEach {(deviceID) in
|
||||
guard actuatorRef == nil else {return}
|
||||
actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
|
||||
}
|
||||
}
|
||||
|
||||
// Don't know how to do strong is enum one of
|
||||
// 1 like back Click
|
||||
@@ -25,31 +41,29 @@ 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`
|
||||
|
||||
func tap(strong: Int32) {
|
||||
actuatorRef = MTActuatorCreateFromDeviceID(deviceID).takeRetainedValue()
|
||||
|
||||
guard actuatorRef != nil else {
|
||||
print("guard actuatorRef == nil")
|
||||
print("guard actuatorRef == nil (can't find proper haptic device?)")
|
||||
return
|
||||
}
|
||||
|
||||
error = MTActuatorOpen(actuatorRef!)
|
||||
guard error == kIOReturnSuccess else {
|
||||
var result: IOReturn
|
||||
|
||||
result = MTActuatorOpen(actuatorRef!)
|
||||
guard result == kIOReturnSuccess else {
|
||||
print("guard MTActuatorOpen")
|
||||
return
|
||||
}
|
||||
|
||||
error = MTActuatorActuate(actuatorRef!, strong, 0, 0.0, 0.0)
|
||||
guard error == kIOReturnSuccess else {
|
||||
result = MTActuatorActuate(actuatorRef!, strong, 0, 0.0, 0.0)
|
||||
guard result == kIOReturnSuccess else {
|
||||
print("guard MTActuatorActuate")
|
||||
return
|
||||
}
|
||||
|
||||
error = MTActuatorClose(actuatorRef!)
|
||||
guard error == kIOReturnSuccess else {
|
||||
result = MTActuatorClose(actuatorRef!)
|
||||
guard result == kIOReturnSuccess else {
|
||||
print("guard MTActuatorClose")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.20</string>
|
||||
<string>0.21</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>178</string>
|
||||
<string>252</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
+20
-8
@@ -197,9 +197,12 @@ class SupportedTypesHolder {
|
||||
)
|
||||
},
|
||||
|
||||
"dock": { _ in
|
||||
(
|
||||
item: .dock(),
|
||||
"dock": { decoder in
|
||||
enum CodingKeys: String, CodingKey { case autoResize }
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let autoResize = try container.decodeIfPresent(Bool.self, forKey: .autoResize) ?? false
|
||||
return (
|
||||
item: .dock(autoResize: autoResize),
|
||||
action: .none,
|
||||
longAction: .none,
|
||||
parameters: [:]
|
||||
@@ -327,7 +330,7 @@ enum ItemType: Decodable {
|
||||
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
|
||||
case timeButton(formatTemplate: String, timeZone: String?)
|
||||
case battery()
|
||||
case dock()
|
||||
case dock(autoResize: Bool)
|
||||
case volume()
|
||||
case brightness(refreshInterval: Double)
|
||||
case weather(interval: Double, units: String, api_key: String, icon_type: String)
|
||||
@@ -338,7 +341,8 @@ enum ItemType: Decodable {
|
||||
case nightShift()
|
||||
case dnd()
|
||||
case pomodoro(workTime: Double, restTime: Double)
|
||||
case network()
|
||||
case network(flip: Bool)
|
||||
case darkMode()
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type
|
||||
@@ -359,6 +363,8 @@ enum ItemType: Decodable {
|
||||
case items
|
||||
case workTime
|
||||
case restTime
|
||||
case flip
|
||||
case autoResize
|
||||
}
|
||||
|
||||
enum ItemTypeRaw: String, Decodable {
|
||||
@@ -378,6 +384,7 @@ enum ItemType: Decodable {
|
||||
case dnd
|
||||
case pomodoro
|
||||
case network
|
||||
case darkMode
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
@@ -402,7 +409,8 @@ enum ItemType: Decodable {
|
||||
self = .battery()
|
||||
|
||||
case .dock:
|
||||
self = .dock()
|
||||
let autoResize = try container.decodeIfPresent(Bool.self, forKey: .autoResize) ?? false
|
||||
self = .dock(autoResize: autoResize)
|
||||
|
||||
case .volume:
|
||||
self = .volume()
|
||||
@@ -446,9 +454,13 @@ enum ItemType: Decodable {
|
||||
let workTime = try container.decodeIfPresent(Double.self, forKey: .workTime) ?? 1500.0
|
||||
let restTime = try container.decodeIfPresent(Double.self, forKey: .restTime) ?? 600.0
|
||||
self = .pomodoro(workTime: workTime, restTime: restTime)
|
||||
|
||||
|
||||
case .network:
|
||||
self = .network()
|
||||
let flip = try container.decodeIfPresent(Bool.self, forKey: .flip) ?? false
|
||||
self = .network(flip: flip)
|
||||
|
||||
case .darkMode:
|
||||
self = .darkMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ extension ItemType {
|
||||
return "com.toxblh.mtmr.timeButton."
|
||||
case .battery():
|
||||
return "com.toxblh.mtmr.battery."
|
||||
case .dock():
|
||||
case .dock(autoResize: _):
|
||||
return "com.toxblh.mtmr.dock"
|
||||
case .volume():
|
||||
return "com.toxblh.mtmr.volume"
|
||||
@@ -49,8 +49,10 @@ extension ItemType {
|
||||
return "com.toxblh.mtmr.dnd."
|
||||
case .pomodoro(interval: _):
|
||||
return PomodoroBarItem.identifier
|
||||
case .network():
|
||||
case .network(flip: _):
|
||||
return NetworkBarItem.identifier
|
||||
case .darkMode(items: _):
|
||||
return DarkModeBarItem.identifier
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,8 +253,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template, timeZone: timeZone)
|
||||
case .battery():
|
||||
barItem = BatteryBarItem(identifier: identifier)
|
||||
case .dock:
|
||||
barItem = AppScrubberTouchBarItem(identifier: identifier)
|
||||
case let .dock(autoResize: autoResize):
|
||||
barItem = AppScrubberTouchBarItem(identifier: identifier, autoResize: autoResize)
|
||||
case .volume:
|
||||
if case let .image(source)? = item.additionalParameters[.image] {
|
||||
barItem = VolumeViewController(identifier: identifier, image: source.image)
|
||||
@@ -281,8 +283,10 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
||||
barItem = DnDBarItem(identifier: identifier)
|
||||
case let .pomodoro(workTime: workTime, restTime: restTime):
|
||||
barItem = PomodoroBarItem(identifier: identifier, workTime: workTime, restTime: restTime)
|
||||
case .network():
|
||||
barItem = NetworkBarItem(identifier: identifier)
|
||||
case let .network(flip: flip):
|
||||
barItem = NetworkBarItem(identifier: identifier, flip: flip)
|
||||
case .darkMode():
|
||||
barItem = DarkModeBarItem(identifier: identifier)
|
||||
}
|
||||
|
||||
if let action = self.action(forItem: item), let item = barItem as? CustomButtonTouchBarItem {
|
||||
|
||||
@@ -17,6 +17,8 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
||||
private let minTicks: Int = 5
|
||||
private let maxTicks: Int = 20
|
||||
private var lastSelected: Int = 0
|
||||
private var autoResize: Bool = false
|
||||
private var widthConstraint: NSLayoutConstraint?
|
||||
|
||||
private var persistentAppIdentifiers: [String] = []
|
||||
private var runningAppsIdentifiers: [String] = []
|
||||
@@ -27,17 +29,25 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
||||
}
|
||||
|
||||
private var applications: [DockItem] = []
|
||||
|
||||
convenience override init(identifier: NSTouchBarItem.Identifier) {
|
||||
self.init(identifier: identifier, autoResize: false)
|
||||
}
|
||||
|
||||
static var iconWidth = 36
|
||||
static var spacingWidth = 2
|
||||
|
||||
override init(identifier: NSTouchBarItem.Identifier) {
|
||||
init(identifier: NSTouchBarItem.Identifier, autoResize: Bool) {
|
||||
super.init(identifier: identifier)
|
||||
|
||||
self.autoResize = autoResize
|
||||
|
||||
scrubber = NSScrubber()
|
||||
scrubber.delegate = self
|
||||
scrubber.dataSource = self
|
||||
scrubber.mode = .free // .fixed
|
||||
let layout = NSScrubberFlowLayout()
|
||||
layout.itemSize = NSSize(width: 36, height: 32)
|
||||
layout.itemSpacing = 2
|
||||
layout.itemSize = NSSize(width: AppScrubberTouchBarItem.iconWidth, height: 32)
|
||||
layout.itemSpacing = CGFloat(AppScrubberTouchBarItem.spacingWidth)
|
||||
scrubber.scrubberLayout = layout
|
||||
scrubber.selectionBackgroundStyle = .roundedBackground
|
||||
scrubber.showsAdditionalContentIndicators = true
|
||||
@@ -79,9 +89,22 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
||||
applications = newApplications
|
||||
applications += getDockPersistentAppsList()
|
||||
scrubber.reloadData()
|
||||
updateSize()
|
||||
|
||||
scrubber.selectedIndex = index ?? 0
|
||||
}
|
||||
|
||||
func updateSize() {
|
||||
if self.autoResize {
|
||||
if let constraint: NSLayoutConstraint = self.widthConstraint {
|
||||
constraint.isActive = false
|
||||
self.scrubber.removeConstraint(constraint)
|
||||
}
|
||||
let width = (AppScrubberTouchBarItem.iconWidth + AppScrubberTouchBarItem.spacingWidth) * self.applications.count - AppScrubberTouchBarItem.spacingWidth
|
||||
self.widthConstraint = self.scrubber.widthAnchor.constraint(equalToConstant: CGFloat(width))
|
||||
self.widthConstraint!.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
public func numberOfItems(for _: NSScrubber) -> Int {
|
||||
return applications.count
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import Foundation
|
||||
|
||||
class DarkModeBarItem: CustomButtonTouchBarItem, Widget {
|
||||
static var name: String = "darkmode"
|
||||
static var identifier: String = "com.toxblh.mtmr.darkmode"
|
||||
|
||||
private var timer: Timer!
|
||||
|
||||
init(identifier: NSTouchBarItem.Identifier) {
|
||||
super.init(identifier: identifier, title: "")
|
||||
isBordered = false
|
||||
setWidth(value: 24)
|
||||
|
||||
tapClosure = { [weak self] in self?.DarkModeToggle() }
|
||||
|
||||
timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(refresh), userInfo: nil, repeats: true)
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func DarkModeToggle() {
|
||||
DarkMode.isEnabled = !DarkMode.isEnabled
|
||||
refresh()
|
||||
}
|
||||
|
||||
@objc func refresh() {
|
||||
image = DarkMode.isEnabled ? #imageLiteral(resourceName: "dark-mode-on") : #imageLiteral(resourceName: "dark-mode-off")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct DarkMode {
|
||||
private static let prefix = "tell application \"System Events\" to tell appearance preferences to"
|
||||
|
||||
static var isEnabled: Bool {
|
||||
get {
|
||||
return UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark"
|
||||
}
|
||||
set {
|
||||
toggle(force: newValue)
|
||||
}
|
||||
}
|
||||
|
||||
static func toggle(force: Bool? = nil) {
|
||||
let value = force.map(String.init) ?? "not dark mode"
|
||||
runAppleScript("\(prefix) set dark mode to \(value)")
|
||||
}
|
||||
}
|
||||
|
||||
func runAppleScript(_ source: String) -> String? {
|
||||
return NSAppleScript(source: source)?.executeAndReturnError(nil).stringValue
|
||||
}
|
||||
|
||||
@@ -12,7 +12,10 @@ class NetworkBarItem: CustomButtonTouchBarItem, Widget {
|
||||
static var name: String = "network"
|
||||
static var identifier: String = "com.toxblh.mtmr.network"
|
||||
|
||||
init(identifier: NSTouchBarItem.Identifier) {
|
||||
private let flip: Bool
|
||||
|
||||
init(identifier: NSTouchBarItem.Identifier, flip: Bool = false) {
|
||||
self.flip = flip
|
||||
super.init(identifier: identifier, title: " ")
|
||||
startMonitoringProcess()
|
||||
}
|
||||
@@ -95,34 +98,49 @@ class NetworkBarItem: CustomButtonTouchBarItem, Widget {
|
||||
return humanText
|
||||
}
|
||||
|
||||
func setTitle(up: String, down: String) {
|
||||
let titleFont = NSFont.monospacedDigitSystemFont(ofSize: 12, weight: NSFont.Weight.light)
|
||||
|
||||
let newTitle = NSMutableAttributedString(
|
||||
string: "↓",
|
||||
attributes: [
|
||||
NSAttributedString.Key.foregroundColor: NSColor.red,
|
||||
NSAttributedString.Key.font: titleFont,
|
||||
])
|
||||
|
||||
newTitle.append(NSMutableAttributedString(
|
||||
string: down,
|
||||
attributes: [
|
||||
NSAttributedString.Key.font: titleFont
|
||||
]))
|
||||
|
||||
newTitle.append(NSMutableAttributedString(
|
||||
string: "\n↑",
|
||||
func appendUpSpeed(appendString: NSMutableAttributedString, up: String, titleFont: NSFont, newStr: Bool = false) {
|
||||
appendString.append(NSMutableAttributedString(
|
||||
string: newStr ? "\n↑" : "↑",
|
||||
attributes: [
|
||||
NSAttributedString.Key.foregroundColor: NSColor.blue,
|
||||
NSAttributedString.Key.font: titleFont,
|
||||
]))
|
||||
]))
|
||||
|
||||
newTitle.append(NSMutableAttributedString(
|
||||
appendString.append(NSMutableAttributedString(
|
||||
string: up,
|
||||
attributes: [
|
||||
NSAttributedString.Key.font: titleFont,
|
||||
]))
|
||||
]))
|
||||
}
|
||||
|
||||
func appendDownSpeed(appendString: NSMutableAttributedString, down: String, titleFont: NSFont, newStr: Bool = false) {
|
||||
appendString.append(NSMutableAttributedString(
|
||||
string: newStr ? "\n↓" : "↓",
|
||||
attributes: [
|
||||
NSAttributedString.Key.foregroundColor: NSColor.red,
|
||||
NSAttributedString.Key.font: titleFont,
|
||||
]))
|
||||
|
||||
appendString.append(NSMutableAttributedString(
|
||||
string: down,
|
||||
attributes: [
|
||||
NSAttributedString.Key.font: titleFont
|
||||
]))
|
||||
}
|
||||
|
||||
func setTitle(up: String, down: String) {
|
||||
let titleFont = NSFont.monospacedDigitSystemFont(ofSize: 12, weight: NSFont.Weight.light)
|
||||
|
||||
let newTitle: NSMutableAttributedString = NSMutableAttributedString(string: "")
|
||||
|
||||
if (self.flip) {
|
||||
appendUpSpeed(appendString: newTitle, up: up, titleFont: titleFont)
|
||||
appendDownSpeed(appendString: newTitle, down: down, titleFont: titleFont, newStr: true)
|
||||
} else {
|
||||
appendDownSpeed(appendString: newTitle, down: down, titleFont: titleFont)
|
||||
appendUpSpeed(appendString: newTitle, up: up, titleFont: titleFont, newStr: true)
|
||||
}
|
||||
|
||||
|
||||
self.attributedTitle = newTitle
|
||||
}
|
||||
|
||||
+74
-67
@@ -1,82 +1,89 @@
|
||||
[
|
||||
{ "type": "escape", "align": "left" },
|
||||
{ "type": "exitTouchbar", "width": 44, "align": "left" },
|
||||
{ "type": "brightnessDown", "width": 44, "align": "left" },
|
||||
{
|
||||
"type": "brightness",
|
||||
"width": 60,
|
||||
"align": "left",
|
||||
"image": {
|
||||
"base64":
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAQMAAAD58POIAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAGUExURffLOPfLNyaSVzUAAAACdFJOU/kBxOqnWgAAAbJJREFUSMfVljtyhDAQBVulQCFH4CgcDR1NR9ERFBKoeA5GfGddtkNvwFINFKP5tED22+Zxwviv6QVKfIEc/iNoF5gkpLIeYI8SUp4PsAUJiekADQntF6isQjvxCTrhAJlFqMMBeIH9BMsD7DAb2BhvYbIyNAOCZIWqYKGTpDZJFQu9EKVd44RxQRq3IrULWD62C8wSssWUZEsR0k6wcDOrJZmoBpMKI+s5qkBQCQOUJADVOECdOsDS0gDbsgHMfT4rVwHSrZQFIN5ABka8BgDgAeZ+BztBgvUEnSgVlhNsTFJjvoF5HAZorBpdYKAiSRbqNyBIUr6AjZMdPwO72R40MElS+wZUWA+wQ6LAYkFvdIhkmA+wQSDDdIAGAZ6A34H0x0fca11gBZZsIHSIfnE/5+NjCn/OuiuUB+/aunZwDeNayjXdTpDN0wlY+r1PfWu75nfj8RogN2JuCN2Y5qgMwTI0wGPUnQw6Qarx0sVNKA5Mn6VUL22lIbZoYitDbPmlvocc9Umfl2D7adz1reC3pF8av4m+DCenp/ndZuG3E7fhuC3pH2+vnz8V3MfE+bnxBTXuuIMTrLWHAAAAAElFTkSuQmCC"
|
||||
}
|
||||
"type": "escape",
|
||||
"width": 64,
|
||||
"align": "left"
|
||||
},
|
||||
{ "type": "brightnessUp", "width": 44, "align": "left" },
|
||||
// --- iTunes ---
|
||||
{
|
||||
"type": "dnd",
|
||||
"align": "left",
|
||||
"width": 38
|
||||
},
|
||||
{ "type": "brightnessDown", "width": 32, "bordered": false, "align": "left" },
|
||||
{ "type": "brightnessUp", "width": 32, "bordered": false, "align": "left" },
|
||||
|
||||
// Spotify
|
||||
{
|
||||
"type": "appleScriptTitledButton",
|
||||
"source": {
|
||||
"inline":
|
||||
"if application \"iTunes\" is running then\rtell application \"iTunes\"\rif player state is playing then\rreturn (get artist of current track) & \" – \" & (get name of current track)\relse\rreturn \"\"\rend if\rend tell\rend if\rreturn \"\"\r"
|
||||
"inline": "if application \"Spotify\" is running then\rtell application \"Spotify\"\rif player state is playing then\rreturn (get artist of current track) & \" – \" & (get name of current track)\relse\rreturn \"\"\rend if\rend tell\rend if\rreturn \"\"\r"
|
||||
},
|
||||
"action": "appleScript",
|
||||
"actionAppleScript": {
|
||||
"inline":
|
||||
"if application \"iTunes\" is running then\rtell application \"iTunes\"\rif player state is playing then\rnext track\rend if\rend tell\rend if\r"
|
||||
"inline": "if application \"Spotify\" is running then\rtell application \"Spotify\"\rif player state is playing then\rnext track\rend if\rend tell\rend if\r"
|
||||
},
|
||||
"refreshInterval": 1,
|
||||
"image": {
|
||||
"base64":
|
||||
"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"
|
||||
"base64": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAYUExURUdwTB3WXx3UXh3VXx7XYBkXFRpVLRyURmIaeAQAAAAEdFJOUwDDO3fSqUUkAAABbklEQVRIx61VbW6DMAztoAeYNA7ApB6gkzhAWS24wIAL0HABaK6/pHFNEhy8TXu/kPzkPD/8cTj8K7KPAqB+K5NhQPCUrABCXe7HOUYYZxgVRLiG8RfY4DUgFFtC7cffAfZTFBwBdhWEKfgEq4ocEjgj4ZQifO6/QG9kkETp1dDeVWfRKx3XYSW0LoqY5kCElXDrQkyeCCuh6WL0M4nIWQIyzqixdfKU1koFDKvyCA8NJMzU4xiD+b4kfHRpsIyKc6hBwjVptFHVY51EMAINNDFGJITKDNQcdpX74Hz0CQ3rY5qwMp4EIxrlafzrsYZ2Veb0DkRgfNCUok4Y1fqEijfyi2b8RE9beWqa48Y/uvCNMcH9btfUi+/CGLR1vhL6Zz9N/vBlaCU+7lwY/cmJ67Ryen/2tj23PLqJBodZH8vgj544vOL4pxfI5acrSFxi8hrkU9TSKr78ZpnL50A8KPJJEo+afBblwyqf5j/iGys5j6ScrST2AAAAAElFTkSuQmCC"
|
||||
}
|
||||
},
|
||||
// --- Spotify ---
|
||||
// {
|
||||
// "type": "appleScriptTitledButton",
|
||||
// "source": {
|
||||
// "inline":
|
||||
// "if application \"Spotify\" is running then\rtell application \"Spotify\"\rif player state is playing then\rreturn (get artist of current track) & \" – \" & (get name of current track)\relse\rreturn \"\"\rend if\rend tell\rend if\rreturn \"\"\r"
|
||||
// },
|
||||
// "action": "appleScript",
|
||||
// "actionAppleScript": {
|
||||
// "inline":
|
||||
// "if application \"Spotify\" is running then\rtell application \"Spotify\"\rif player state is playing then\rnext track\rend if\rend tell\rend if\r"
|
||||
// },
|
||||
// "refreshInterval": 1,
|
||||
// "image": {
|
||||
// "base64":
|
||||
// "iVBORw0KGgoAAAANSUhEUgAAAEAAAABABAMAAABYR2ztAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAYUExURUdwTB3WXx3UXh3VXx7XYBkXFRpVLRyURmIaeAQAAAAEdFJOUwDDO3fSqUUkAAABbklEQVRIx61VbW6DMAztoAeYNA7ApB6gkzhAWS24wIAL0HABaK6/pHFNEhy8TXu/kPzkPD/8cTj8K7KPAqB+K5NhQPCUrABCXe7HOUYYZxgVRLiG8RfY4DUgFFtC7cffAfZTFBwBdhWEKfgEq4ocEjgj4ZQifO6/QG9kkETp1dDeVWfRKx3XYSW0LoqY5kCElXDrQkyeCCuh6WL0M4nIWQIyzqixdfKU1koFDKvyCA8NJMzU4xiD+b4kfHRpsIyKc6hBwjVptFHVY51EMAINNDFGJITKDNQcdpX74Hz0CQ3rY5qwMp4EIxrlafzrsYZ2Veb0DkRgfNCUok4Y1fqEijfyi2b8RE9beWqa48Y/uvCNMcH9btfUi+/CGLR1vhL6Zz9N/vBlaCU+7lwY/cmJ67Ryen/2tj23PLqJBodZH8vgj544vOL4pxfI5acrSFxi8hrkU9TSKr78ZpnL50A8KPJJEo+afBblwyqf5j/iGys5j6ScrST2AAAAAElFTkSuQmCC"
|
||||
// }
|
||||
// },
|
||||
// --- VOX ---
|
||||
// {
|
||||
// "type": "appleScriptTitledButton",
|
||||
// "source": {
|
||||
// "inline":
|
||||
// "if application \"VOX\" is running then\rtell application \"VOX\"\rif player state is 1 then\rreturn (get artist) & \" – \" & (get track)\relse\rreturn \"\"\rend if\rend tell\rend if\rreturn \"\"\r"
|
||||
// },
|
||||
// "action": "appleScript",
|
||||
// "actionAppleScript": {
|
||||
// "inline":
|
||||
// "if application \"VOX\" is running then\rtell application \"VOX\"\rif player state is 1 then\rnext\rend if\rend tell\rend if\r"
|
||||
// },
|
||||
// "refreshInterval": 1,
|
||||
// "image": {
|
||||
// "base64":
|
||||
// "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"
|
||||
// }
|
||||
// },
|
||||
{ "type": "previous", "width": 44 },
|
||||
{ "type": "play", "width": 44 },
|
||||
{ "type": "next", "width": 44 },
|
||||
{ "type": "weather", "icon_type": "images", "units": "metric" },
|
||||
{ "type": "currency", "from": "BTC", "to": "USD" },
|
||||
{ "type": "sleep", "width": 44 },
|
||||
{ "type": "mute", "width": 40, "align": "right" },
|
||||
{ "type": "volumeDown", "width": 34, "align": "right" },
|
||||
{ "type": "volume", "width": 60, "align": "right" },
|
||||
{ "type": "volumeUp", "width": 34, "align": "right" },
|
||||
{ "type": "inputsource", "align": "right" },
|
||||
{ "type": "battery", "align": "right", "bordered": false },
|
||||
{ "type": "timeButton", "align": "right", "bordered": false }
|
||||
|
||||
// iTunes
|
||||
{
|
||||
"type": "appleScriptTitledButton",
|
||||
"source": {
|
||||
"inline": "if application \"iTunes\" is running then\rtell application \"iTunes\"\rif player state is playing then\rreturn (get artist of current track) & \" – \" & (get name of current track)\relse\rreturn \"\"\rend if\rend tell\rend if\rreturn \"\"\r"
|
||||
},
|
||||
"action": "appleScript",
|
||||
"actionAppleScript": {
|
||||
"inline": "if application \"iTunes\" is running then\rtell application \"iTunes\"\rif player state is playing then\rnext track\rend if\rend tell\rend if\r"
|
||||
},
|
||||
"longAction": "appleScript",
|
||||
"longActionAppleScript": {
|
||||
"inline": "if application \"iTunes\" is running then\rtell application \"iTunes\"\rif player state is playing then\rprev track\rend if\rend tell\rend if\r"
|
||||
},
|
||||
"refreshInterval": 2,
|
||||
"image": {
|
||||
"base64": "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"
|
||||
}
|
||||
},
|
||||
{ "type": "displaySleep", "width": 40, "align": "right", "bordered": false },
|
||||
{
|
||||
"type": "weather",
|
||||
"align": "right",
|
||||
"icon_type": "images",
|
||||
"api_key": "ca93a0bb8cdb428552660d83249e4bc9",
|
||||
"bordered": false
|
||||
},
|
||||
{
|
||||
"type": "volumeDown",
|
||||
"bordered": false,
|
||||
"align": "right",
|
||||
"width": 28
|
||||
},
|
||||
{
|
||||
"type": "volumeUp",
|
||||
"bordered": false,
|
||||
"align": "right",
|
||||
"width": 28
|
||||
},
|
||||
{
|
||||
"type": "play",
|
||||
"align": "right",
|
||||
"width": 38
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"align": "right",
|
||||
"bordered": false
|
||||
},
|
||||
{
|
||||
"type": "timeButton",
|
||||
"formatTemplate": "HH:mm",
|
||||
"align": "right",
|
||||
"bordered": false,
|
||||
"longAction": "shellScript",
|
||||
"longExecutablePath": "/usr/bin/pmset",
|
||||
"longShellArguments": ["sleepnow"]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,38 +1,67 @@
|
||||
<p align="center"><img src="Resources/logo.png" width="120"></p>
|
||||
# My touchbar. My rules. [](https://github.com/Toxblh/MTMR/releases) [](https://github.com/Toxblh/MTMR/blob/master/LICENSE) 
|
||||
|
||||
# My TouchBar. My rules
|
||||
<img src="Resources/logo.png" align="right"
|
||||
title="MTMR by Toxblh" width="110" height="110">
|
||||
|
||||
*The TouchBar Customization App for your MacBook Pro*
|
||||
_The TouchBar Customization App for your MacBook Pro_
|
||||
|
||||
[](https://github.com/Toxblh/MTMR/releases)
|
||||
[](https://github.com/Toxblh/MTMR/blob/master/LICENSE) [](https://github.com/Toxblh/MTMR/releases/latest)  
|
||||
My idea is to create a platform for creating plugins to customize the TouchBar. I very much like BTT and having a full custom TouchBar (my BTT preset), and I wanted to create it. It's my first Swift project for MacOS :)
|
||||
|
||||
**Share your presets [here](https://github.com/Toxblh/MTMR-presets)**
|
||||
|
||||
<p align="center">
|
||||
<img src="Resources/TouchBar-v0.8.1.png">
|
||||
<img src="./Resources/aaaaa-acc6-17fee7572ed0.png" alt="Mackbook with touchbar" width="800">
|
||||
</p>
|
||||
|
||||
**MTMR** Community:
|
||||
[<img height="24px" src="https://github.com/discourse/DiscourseMobile/raw/master/icon.png" /> Discourse](https://forum.mtmr.app)
|
||||
[<img height="24px" src="https://camo.githubusercontent.com/88f53948f291c54736bf08f5fd7b037a848dfc62/68747470733a2f2f646973636f72646170702e636f6d2f6173736574732f30376463613830613130326434313439653937333664346231363263666636662e69636f"> Discord](https://discord.gg/CmNcDuQ)
|
||||
[<img height="24px" src="https://telegram.org/img/t_logo.png" /> Telegram](https://t.me/joinchat/AmVYGg8vW38c13_3MxdE_g)
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/CmNcDuQ"><img height="20px" src="https://camo.githubusercontent.com/88f53948f291c54736bf08f5fd7b037a848dfc62/68747470733a2f2f646973636f72646170702e636f6d2f6173736574732f30376463613830613130326434313439653937333664346231363263666636662e69636f"> Discord</a>
|
||||
<a href="https://t.me/joinchat/AmVYGg8vW38c13_3MxdE_g"><img height="20px" src="https://telegram.org/img/t_logo.png" /> Telegram</a>
|
||||
</p>
|
||||
|
||||
<a href="https://www.paypal.me/toxblh/10" title="Donate via Paypal"><img height="32px" src="Resources/support_paypal.svg" alt="PayPal donate button" /></a>
|
||||
<a href="https://www.buymeacoffee.com/toxblh" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" height="32px" ></a>
|
||||
<a href="https://www.patreon.com/bePatron?u=9900748"><img height="32px" src="https://c5.patreon.com/external/logo/become_a_patron_button.png" srcset="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png 2x"></a>
|
||||
[<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/854859-e299e139ab7f79855c0bc589f10b0ec6-medium_jpg.jpg?buster=1453074480" height="32px" /> Become a backer](https://opencollective.com/MTMR#backer)
|
||||
[<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/854859-e299e139ab7f79855c0bc589f10b0ec6-medium_jpg.jpg?buster=1453074480" height="32px" /> Become a sponsor](https://opencollective.com/MTMR#sponsor)
|
||||
|
||||
|
||||
My idea is to create a platform for creating plugins to customize the TouchBar. I very much like BTT and having a full custom TouchBar (my [BTT preset](https://github.com/Toxblh/btt-touchbar-preset)), and I wanted to create it. It's my first Swift project for MacOS :)
|
||||
|
||||
#### Share your presets [here](https://github.com/Toxblh/MTMR-presets)
|
||||
<p align="center"><a href="https://www.paypal.me/toxblh/10" title="Donate via Paypal"><img height="36px" src="Resources/support_paypal.svg" alt="PayPal donate button" /></a>
|
||||
<a href="https://www.buymeacoffee.com/toxblh" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" height="36px" ></a>
|
||||
<a href="https://www.patreon.com/bePatron?u=9900748"><img height="36px" src="https://c5.patreon.com/external/logo/become_a_patron_button.png" srcset="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png 2x"></a>
|
||||
<a href="https://www.producthunt.com/posts/my-touchbar-my-rules-mtmr">
|
||||
<img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=my-touchbar-my-rules-mtmr&theme=light" alt="My TouchBar My Rules (MTMR)" height="36px" style="max-width:100%">
|
||||
</a></p>
|
||||
|
||||
## Installation
|
||||
- Download lastest [release](https://github.com/Toxblh/MTMR/releases) from github
|
||||
|
||||
- Download lastest [release](https://github.com/Toxblh/MTMR/releases) (.dmg) from github
|
||||
- Or via Homebrew `brew cask install mtmr`
|
||||
- [Dario Prski](https://medium.com/@urdigitalpulse) has written a [fantastic article on medium](https://medium.com/@urdigitalpulse/customise-your-macbook-pro-touch-bar-966998e606b5) that goes into more detail on installing MTMR
|
||||
|
||||
**On first install** you need to allow access for MTMR in Accessibility otherwise buttons like <kbd>Esc</kbd>, <kbd>Volume</kbd>, <kbd>Brightness</kbd> and other system keys won't work
|
||||
|
||||
<p align="center">
|
||||
<img width="450" alt="screenshot 2019-02-24 at 23 19 20" src="https://user-images.githubusercontent.com/2198153/53307057-2b078200-388c-11e9-8212-8c2b1aff0aa6.png">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
🍏→ System Preferences → Security and Privacy → tab Privacy → Accessibility → MTMR
|
||||
</p>
|
||||
|
||||
## Examples
|
||||
|
||||
- [@Toxblh preset](Resources/toxblh.json)
|
||||
- [@ReDetection preset](Resources/ReDetection.json)
|
||||
- [@luongvo209 preset](Resources/luongvo209.json)
|
||||
- [aadi_vs_anand preset](Resources/aadi_vs_anand.json)
|
||||
|
||||
<p align="center">
|
||||
<img src="./Resources/Artboard.png" alt="Presets for touchbar" width="800">
|
||||
</p>
|
||||
|
||||
## Customization
|
||||
|
||||
MTMR preferences are stored under `~/Library/Application\ Support/MTMR/items.json`.
|
||||
|
||||
The pre-installed configuration contains less or more than you'll probably want, try to configure:
|
||||
|
||||
## Built-in button types:
|
||||
|
||||
> Buttons
|
||||
|
||||
- escape
|
||||
- exitTouchbar
|
||||
- brightnessUp
|
||||
@@ -44,6 +73,7 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
|
||||
- mute
|
||||
|
||||
> Native Plugins
|
||||
|
||||
- battery
|
||||
- currency
|
||||
- weather
|
||||
@@ -52,19 +82,23 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
|
||||
- dock (half-long click to open app, full-long click to kill app)
|
||||
- nightShift
|
||||
- dnd (Don't disturb)
|
||||
- darkMode
|
||||
- pomodoro
|
||||
- network
|
||||
|
||||
> Media Keys
|
||||
|
||||
- previous
|
||||
- play
|
||||
- next
|
||||
|
||||
> AppleScript plugins
|
||||
|
||||
- sleep
|
||||
- displaySleep
|
||||
|
||||
## Gestures on central part:
|
||||
|
||||
- two finger slide: change you Volume
|
||||
- three finger slide: change you Brightness
|
||||
|
||||
@@ -74,13 +108,16 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
|
||||
- volume
|
||||
|
||||
### You can also make custom buttons using these types
|
||||
|
||||
- `staticButton`
|
||||
|
||||
```json
|
||||
"type": "staticButton",
|
||||
"title": "esc",
|
||||
```
|
||||
|
||||
- `appleScriptTitledButton`
|
||||
|
||||
```js
|
||||
"type": "appleScriptTitledButton",
|
||||
"refreshInterval": 60, //optional
|
||||
@@ -94,12 +131,14 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
|
||||
```
|
||||
|
||||
- `timeButton`
|
||||
|
||||
```js
|
||||
"type": "timeButton",
|
||||
"formatTemplate": "HH:mm" //optional
|
||||
```
|
||||
|
||||
## Groups
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "group",
|
||||
@@ -112,6 +151,7 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
|
||||
```
|
||||
|
||||
To close a group, use the button:
|
||||
|
||||
```
|
||||
{
|
||||
"type": "close",
|
||||
@@ -120,8 +160,11 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
## Native plugins
|
||||
|
||||
#### `timeButton`
|
||||
|
||||
> Attention! Works not all: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "timeButton",
|
||||
@@ -131,7 +174,12 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
#### `weather`
|
||||
> Provider: https://openweathermap.org Need allowance location service
|
||||
|
||||
> Provider: https://openweathermap.org \
|
||||
> Note: you need to register on https://openweathermap.org to get your API key \
|
||||
> Note: you may need to wait for near 20 mins until your API key will be activated by Openweathermap \
|
||||
> Note: you need to allow using "Location Services" in your Mac OS "Security & Privacy" settings for MTMR
|
||||
|
||||
```js
|
||||
"type": "weather",
|
||||
"refreshInterval": 600, // in seconds
|
||||
@@ -141,7 +189,9 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
#### `currency`
|
||||
|
||||
> Provider: https://coinbase.com
|
||||
|
||||
```js
|
||||
"type": "currency",
|
||||
"refreshInterval": 600, // in seconds
|
||||
@@ -152,6 +202,7 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
#### `music`
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "music",
|
||||
@@ -163,38 +214,58 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
#### `pomodoro`
|
||||
|
||||
> Pomodoro plugin. One click to start the work timer, longclick to start the rest timer. Click in progress for reset.
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "pomodoro",
|
||||
"workTime": 1200, // set time work in seconds. Default 1500 (25 min)
|
||||
"restTime": 600, // set time rest in seconds. Default 300 (5 min)
|
||||
"restTime": 600 // set time rest in seconds. Default 300 (5 min)
|
||||
},
|
||||
```
|
||||
|
||||
#### `network`
|
||||
|
||||
> Network plugin. The plugin to show usage a network
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "network",
|
||||
"flip": true
|
||||
},
|
||||
```
|
||||
|
||||
#### `dock`
|
||||
|
||||
> Dock plugin
|
||||
|
||||
```js
|
||||
{
|
||||
"type": "dock",
|
||||
"autoResize": true
|
||||
},
|
||||
```
|
||||
|
||||
## Actions:
|
||||
|
||||
- `hidKey`
|
||||
> https://github.com/aosm/IOHIDFamily/blob/master/IOHIDSystem/IOKit/hidsystem/ev_keymap.h use only numbers
|
||||
> https://github.com/aosm/IOHIDFamily/blob/master/IOHIDSystem/IOKit/hidsystem/ev_keymap.h use only numbers
|
||||
|
||||
```json
|
||||
"action": "hidKey",
|
||||
"keycode": 53,
|
||||
```
|
||||
|
||||
- `keyPress`
|
||||
|
||||
```json
|
||||
"action": "keyPress",
|
||||
"keycode": 1,
|
||||
```
|
||||
|
||||
- `appleScript`
|
||||
|
||||
```js
|
||||
"action": "appleScript",
|
||||
"actionAppleScript": {
|
||||
@@ -204,6 +275,7 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
- `shellScript`
|
||||
|
||||
```js
|
||||
"action": "shellScript",
|
||||
"executablePath": "/usr/bin/pmset",
|
||||
@@ -212,13 +284,16 @@ To close a group, use the button:
|
||||
```
|
||||
|
||||
- `openUrl`
|
||||
|
||||
```js
|
||||
"action": "openUrl",
|
||||
"url": "https://google.com",
|
||||
```
|
||||
|
||||
## LongActions
|
||||
|
||||
If you want to longPress for some operations, it is similar to the configuration for Actions but with additional parameters, for example:
|
||||
|
||||
```js
|
||||
"longAction": "hidKey",
|
||||
"longKeycode": 53,
|
||||
@@ -234,79 +309,25 @@ If you want to longPress for some operations, it is similar to the configuration
|
||||
## Additional parameters:
|
||||
|
||||
- `width` restrict how much room a particular button will take
|
||||
|
||||
```json
|
||||
"width": 34
|
||||
```
|
||||
|
||||
- `align` can stick the item to the side. default is center
|
||||
|
||||
```js
|
||||
"align": "left" // "left", "right" or "center"
|
||||
```
|
||||
|
||||
- `bordered` you can do button without border
|
||||
|
||||
```js
|
||||
"bordered": "false" // "true" or "false"
|
||||
```
|
||||
|
||||
## Example configuration:
|
||||
```json
|
||||
[
|
||||
{ "type": "escape", "width": 110 },
|
||||
{ "type": "exitTouchbar", "align": "left" },
|
||||
{
|
||||
"type": "brightnessUp",
|
||||
"align": "left",
|
||||
"width": 36
|
||||
},
|
||||
{
|
||||
"type": "staticButton",
|
||||
"align": "left",
|
||||
"title": "🔆",
|
||||
"action": "keyPress",
|
||||
"keycode": 113,
|
||||
"width": 36
|
||||
},
|
||||
|
||||
{
|
||||
"type": "appleScriptTitledButton",
|
||||
"source": {
|
||||
"filePath": "/Users/toxblh/Library/Application Support/MTMR/iTunes.nowPlaying.scpt"
|
||||
},
|
||||
"refreshInterval": 1
|
||||
},
|
||||
{
|
||||
"type": "staticButton",
|
||||
"align": "left",
|
||||
"image": { "base64" : "%base64Finder%"},
|
||||
"action": "appleScript",
|
||||
"actionAppleScript": {
|
||||
"inline": "tell application \"Finder\"\rmake new Finder window\rset target of front window to path to home folder as string\ractivate\rend tell"
|
||||
},
|
||||
"width": 36
|
||||
},
|
||||
{
|
||||
"type": "appleScriptTitledButton",
|
||||
"source": {
|
||||
"inline": "if application \"Safari\" is running then\r\ttell application \"Safari\"\r\t\trepeat with t in tabs of windows\r\t\t\ttell t\r\t\t\t\tif URL starts with \"https:\/\/music.yandex.ru\" and name does not end with \"на Яндекс.Музыке\" then\r\t\t\t\t\treturn name of t as text\r\t\t\t\tend if\r\t\t\tend tell\r\t\tend repeat\r\tend tell\rend if\rreturn \"\""
|
||||
},
|
||||
"refreshInterval": 1
|
||||
},
|
||||
{ "type": "previous", "width": 36, "align": "right" },
|
||||
{ "type": "play", "width": 36, "align": "right" },
|
||||
{ "type": "next", "width": 36, "align": "right" },
|
||||
{ "type": "sleep", "width": 36 , "align": "right"},
|
||||
{ "type": "displaySleep", "align": "right" },
|
||||
{ "type": "weather", "refreshInterval": 1800, "width": 70, "align": "right" },
|
||||
{ "type": "volumeDown", "width": 36 , "align": "right"},
|
||||
{ "type": "volumeUp", "width": 36 , "align": "right"},
|
||||
{ "type": "battery", "refreshInterval": 60 , "align": "right"},
|
||||
{ "type": "appleScriptTitledButton", "refreshInterval": 1800, "source": { "filePath": "/Users/redetection/Library/Application Support/MTMR/Weather.scpt"} , "align": "right"},
|
||||
{ "type": "timeButton", "formatTemplate": "HH:mm", "width": 64, "align": "right" }
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
### Roadmap
|
||||
|
||||
- [x] Create the first prototype with TouchBar in Storyboard
|
||||
- [x] Put in stripe menu on startup the application
|
||||
- [x] Find how to simulate real buttons like brightness, volume, night shift and etc.
|
||||
@@ -328,6 +349,7 @@ If you want to longPress for some operations, it is similar to the configuration
|
||||
- [ ] Import config from BTT
|
||||
|
||||
Settings:
|
||||
|
||||
- [ ] Interface for plugins and export like presets
|
||||
- [x] Startup at login
|
||||
- [ ] Show on/off in Dock
|
||||
@@ -335,20 +357,8 @@ Settings:
|
||||
- [ ] On/off Haptic Feedback
|
||||
|
||||
Maybe:
|
||||
- [ ] Refactoring the application on packages (AppleScript, JavaScript? and Swift?)
|
||||
|
||||
### Author's presets
|
||||
[@Toxblh preset](Resources/toxblh.json)
|
||||
|
||||
[@ReDetection preset](Resources/ReDetection.json)
|
||||
|
||||
### User's presets
|
||||
[@luongvo209 preset](Resources/luongvo209.json)
|
||||

|
||||
|
||||
[aadi_vs_anand preset](Resources/aadi_vs_anand.json)
|
||||

|
||||

|
||||
- [ ] Refactoring the application into packages (AppleScript, JavaScript? and Swift?)
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 259 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 583 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Reference in New Issue
Block a user