Compare commits

..
85 Commits
Author SHA1 Message Date
Anton Palgunov 91a4e5bded Fix HapticFeedback for new MacBook models (#187)
Fix HapticFeedback for new MacBook models
2019-07-11 17:40:37 +01:00
bobrosoft 68dfcddb29 Fix HapticFeedback for new MacBook models 2019-07-11 20:16:34 +04:00
Anton Palgunov 82ec231700 README: add more details on how to setup "weather" plugin (#186)
README: add more details on how to setup "weather" plugin
2019-07-09 19:27:42 +01:00
Vladimir Tolstikov ed261c2349 README: add more details on how to setup "weather" plugin 2019-07-09 22:25:00 +04:00
Anton Palgunov f06d1f4329 Create FUNDING.yml 2019-05-23 14:16:25 +01:00
toxblh 3dabd598f4 upd Readme 2019-05-22 22:52:49 +01:00
Anton Palgunov 0a09ea7117 Merge pull request #169 from FinHorsley:patch-1
improved readme
2019-05-22 22:48:51 +01:00
toxblh 02cf911336 move ss.png to Resources 2019-05-22 22:47:58 +01:00
toxblh d831069025 Merge remote-tracking branch 'origin/master' into pr/FinHorsley/169-2 2019-05-22 22:44:57 +01:00
toxblh 33206ab457 update standart preset for first install 2019-05-22 22:44:21 +01:00
toxblh c6c808369f Edited Readme. Also updated paths 2019-05-22 22:44:01 +01:00
toxblh cbad06ac07 Move files to correct folder. 2019-05-22 22:43:44 +01:00
toxblh 64171d5c51 merge 2019-05-22 18:26:24 +01:00
toxblh 5504e5d640 #171 Added DarkMode button v0.21 2019-05-22 18:25:18 +01:00
Anton Palgunov 164295820b Merge pull request #167 from willsunnn:master
Added an additional option for the dock to automatically resize
2019-05-15 17:04:52 +01:00
toxblh ae469bb92a add Readme info 2019-05-15 17:01:06 +01:00
toxblh 57b5129135 info.plist 2019-05-15 16:57:40 +01:00
toxblh 7cc72de66f merge master 2019-05-15 16:56:53 +01:00
toxblh 2e5db4ffa0 revert project settings 2019-05-15 16:55:44 +01:00
toxblh 8a73fe01e4 Revert "#154 .cghidEventTap -> .cgAnnotatedSessionEventTap"
This reverts commit 5a8117ac7f.
2019-05-15 16:40:09 +01:00
toxblh 5fbb2bafc6 Revert "Fix #164"
This reverts commit 40fa61fcb5.
2019-05-15 16:39:52 +01:00
toxblh 5b6b6dfa56 Revert "fixed tests"
This reverts commit 7c9dd26eb0.
2019-05-15 16:39:32 +01:00
FinHorsley 65e5a52383 shadow to images 2019-05-15 14:44:15 +01:00
FinHorsley 03304bd030 Add files via upload 2019-05-15 14:43:17 +01:00
FinHorsley f264425ba7 Update README.md 2019-05-13 20:56:21 +01:00
FinHorsley c377b9494c Update README.md 2019-05-13 20:54:43 +01:00
FinHorsley f5b36ec012 Update README.md 2019-05-13 20:48:01 +01:00
FinHorsley 999c4cf6e2 Update README.md 2019-05-13 20:38:30 +01:00
FinHorsley b8d5d0a8a5 Update README.md 2019-05-13 20:35:36 +01:00
FinHorsley 6bb5aade07 Update README.md 2019-05-13 20:35:17 +01:00
FinHorsley b6bcc31456 Update README.md 2019-05-13 20:34:01 +01:00
FinHorsley 9d09646742 Update README.md 2019-05-13 20:32:53 +01:00
FinHorsley 55f988e393 Update README.md 2019-05-13 20:32:26 +01:00
FinHorsley 2f4cf9e5f6 Update README.md 2019-05-13 20:31:46 +01:00
FinHorsley 327d38e47d Update README.md 2019-05-13 20:30:35 +01:00
FinHorsley cd380b289d Update README.md 2019-05-13 20:26:41 +01:00
FinHorsley 6a26b2f5ca Update README.md 2019-05-13 20:24:31 +01:00
FinHorsley d7186aac18 Update README.md 2019-05-13 20:23:43 +01:00
FinHorsley cef07dc965 Update README.md 2019-05-13 20:22:45 +01:00
FinHorsley 471c0c5d57 Update README.md 2019-05-13 20:16:56 +01:00
FinHorsley 5b93525806 Add files via upload 2019-05-13 20:00:31 +01:00
FinHorsley b87bc632ab Delete some.png 2019-05-13 20:00:10 +01:00
FinHorsley 1763a24942 Add files via upload 2019-05-13 19:57:41 +01:00
FinHorsley 627e6951c1 Update README.md 2019-05-13 18:20:28 +01:00
FinHorsley 918054df78 Update README.md 2019-05-13 18:17:17 +01:00
FinHorsley 25fb0d4f04 center things 2019-05-13 18:06:21 +01:00
FinHorsley 61a357ffc3 Update README.md 2019-05-13 18:01:41 +01:00
FinHorsley f4116a95df Update README.md 2019-05-13 18:00:03 +01:00
FinHorsley c952505c1c Update README.md 2019-05-13 17:57:50 +01:00
FinHorsley f10b58b996 Update README.md 2019-05-13 17:56:34 +01:00
FinHorsley 88a8ae3ae8 Add files via upload 2019-05-13 17:55:43 +01:00
FinHorsley d783448567 Update README.md 2019-05-13 17:36:55 +01:00
FinHorsley 595ae165d3 Update README.md 2019-05-13 17:32:55 +01:00
FinHorsley da406713dd Update README.md 2019-05-13 17:32:01 +01:00
FinHorsley 938b83f37e Update README.md 2019-05-13 17:31:40 +01:00
FinHorsley a8a085df1e Update README.md 2019-05-13 17:30:43 +01:00
FinHorsley b188f45c8e Update README.md 2019-05-13 17:30:14 +01:00
FinHorsley 3319c5d45a Update README.md 2019-05-13 17:27:51 +01:00
FinHorsley 6174d14925 Update README.md 2019-05-13 17:27:06 +01:00
FinHorsley c8197239d7 Update README.md 2019-05-13 17:25:51 +01:00
FinHorsley d2854e3dae Update README.md 2019-05-13 17:24:28 +01:00
FinHorsley 4f9c3258ae Add files via upload 2019-05-13 17:22:26 +01:00
FinHorsley dfeda1e874 Update README.md 2019-05-13 17:20:40 +01:00
FinHorsley 82f82039ae Update readme
Bit of a refresh
2019-05-13 17:19:39 +01:00
willsunnn 324c3f711e Fixed a bug where the dock would not change size after the first time due to conflicting constraints 2019-05-09 22:39:47 -07:00
willsunnn a81d6fc595 Made the dock resize when Apps are removed 2019-05-09 22:20:45 -07:00
willsunnn 3bde1fe4b1 Created and passed the autoResize parameter to the dock widget 2019-05-09 22:04:10 -07:00
toxblh 7c9dd26eb0 fixed tests 2019-05-09 22:19:21 +01:00
toxblh 40fa61fcb5 Fix #164 2019-05-09 22:14:48 +01:00
toxblh 5a8117ac7f #154 .cghidEventTap -> .cgAnnotatedSessionEventTap 2019-05-07 10:37:29 +01:00
toxblh a606767ddc Revert "migration to swift 5"
This reverts commit 4497c7102c.
2019-04-02 17:10:18 +01:00
toxblh 6badc37dc3 Merge branch 'master' of https://github.com/Toxblh/MTMR 2019-04-02 17:07:27 +01:00
toxblh 4497c7102c migration to swift 5 2019-04-02 17:07:23 +01:00
Anton Palgunov b6c6bb945b Update README.md 2019-03-28 13:30:16 +00:00
Anton Palgunov 3e399d14c2 Update README.md 2019-03-27 10:58:41 +00:00
toxblh 624c8ac6d8 upd readme 2019-03-21 21:52:55 +00:00
toxblh ea68ce33c1 Merge branch 'master' of https://github.com/Toxblh/MTMR 2019-03-21 21:52:01 +00:00
toxblh 744ea067db v0.20.1 2019-03-21 21:51:05 +00:00
toxblh 8064ab759c test old build type. try resolve #155 2019-03-21 21:50:38 +00:00
toxblh 556c28df85 flip param for network 2019-03-21 21:49:34 +00:00
Anton Palgunov e68f930efa Update README.md 2019-03-21 12:26:29 +00:00
Anton Palgunov 647ac0ba20 Update README.md 2019-03-03 14:37:56 +00:00
Anton Palgunov 780a8ba81e Update README.md 2019-02-25 09:20:08 +00:00
Anton Palgunov 71f5030fa6 spellchecking 2019-02-24 23:37:58 +00:00
Anton Palgunov f435c0b530 Troubleshooting in Readme 2019-02-24 23:34:56 +00:00
21 changed files with 422 additions and 221 deletions
+4
View File
@@ -0,0 +1,4 @@
# These are supported funding model platforms
patreon: toxblh
ko_fi: toxblh
+4
View File
@@ -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"
}
}
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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()
}
}
}
+10 -6
View File
@@ -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 {
+27 -4
View File
@@ -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
+57
View File
@@ -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
}
+40 -22
View File
@@ -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
View File
@@ -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"]
}
]
+105 -95
View File
@@ -1,38 +1,67 @@
<p align="center"><img src="Resources/logo.png" width="120"></p>
# My touchbar. My rules. [![GitHub release](https://img.shields.io/github/release/toxblh/MTMR.svg)](https://github.com/Toxblh/MTMR/releases) [![license](https://img.shields.io/github/license/Toxblh/MTMR.svg)](https://github.com/Toxblh/MTMR/blob/master/LICENSE)![minimal system requirements](https://img.shields.io/badge/required-macOS%2010.12.2-blue.svg) ![travis](https://travis-ci.org/Toxblh/MTMR.svg?branch=master)
# 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_
[![GitHub release](https://img.shields.io/github/release/toxblh/MTMR.svg)](https://github.com/Toxblh/MTMR/releases)
[![license](https://img.shields.io/github/license/Toxblh/MTMR.svg)](https://github.com/Toxblh/MTMR/blob/master/LICENSE) [![Total downloads](https://img.shields.io/github/downloads/Toxblh/MTMR/total.svg)](https://github.com/Toxblh/MTMR/releases/latest) ![minimal system requirements](https://img.shields.io/badge/required-macOS%2010.12.2-blue.svg) ![travis](https://travis-ci.org/Toxblh/MTMR.svg?branch=master)
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)
![](Resources/luongvo209.png)
[aadi_vs_anand preset](Resources/aadi_vs_anand.json)
![](Resources/aadi_vs_anand1.png)
![](Resources/aadi_vs_anand2.png)
- [ ] 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

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB