mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-01-10 17:08:39 +00:00
Merge remote-tracking branch 'origin/master' into pr/FinHorsley/169-2
This commit is contained in:
commit
d831069025
@ -61,6 +61,7 @@
|
|||||||
B0B17439207D6B590004B740 /* Vox.nowPlaying.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B0B1742F207D6B590004B740 /* Vox.nowPlaying.scpt */; };
|
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 */; };
|
B0B1743A207D6B590004B740 /* iTunes.nowPlaying.scpt in Resources */ = {isa = PBXBuildFile; fileRef = B0B17430207D6B590004B740 /* iTunes.nowPlaying.scpt */; };
|
||||||
B0F3112520C9E35F0076BB88 /* SupportNSTouchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F3112420C9E35F0076BB88 /* SupportNSTouchBar.swift */; };
|
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 */; };
|
B0F8771A207AC1EA00D6E430 /* TouchBarSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F87719207AC1EA00D6E430 /* TouchBarSupport.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -142,6 +143,7 @@
|
|||||||
B0B1742F207D6B590004B740 /* Vox.nowPlaying.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Vox.nowPlaying.scpt; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
B0F8771B207AC92700D6E430 /* TouchBarSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TouchBarSupport.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@ -293,6 +295,7 @@
|
|||||||
6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */,
|
6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */,
|
||||||
607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */,
|
607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */,
|
||||||
B08126F0217BE19000A98970 /* WidgetProtocol.swift */,
|
B08126F0217BE19000A98970 /* WidgetProtocol.swift */,
|
||||||
|
B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */,
|
||||||
);
|
);
|
||||||
path = Widgets;
|
path = Widgets;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -446,6 +449,7 @@
|
|||||||
B0008E552080286C003AD4DD /* SupportHelpers.swift in Sources */,
|
B0008E552080286C003AD4DD /* SupportHelpers.swift in Sources */,
|
||||||
6042B6A72083E03A00C525C8 /* AppScrubberTouchBarItem.swift in Sources */,
|
6042B6A72083E03A00C525C8 /* AppScrubberTouchBarItem.swift in Sources */,
|
||||||
B082B253205C7D8000BC04DC /* AppDelegate.swift in Sources */,
|
B082B253205C7D8000BC04DC /* AppDelegate.swift in Sources */,
|
||||||
|
B0F54A7A2295AC7D00B4C509 /* DarkModeBarItem.swift in Sources */,
|
||||||
B08126EF217BD0B900A98970 /* PomodoroBarItem.swift in Sources */,
|
B08126EF217BD0B900A98970 /* PomodoroBarItem.swift in Sources */,
|
||||||
B081732C213739FE005D4908 /* DnDBarItem.swift in Sources */,
|
B081732C213739FE005D4908 /* DnDBarItem.swift in Sources */,
|
||||||
60C44AFD20A373A100C0EC91 /* MusicBarItem.swift in Sources */,
|
60C44AFD20A373A100C0EC91 /* MusicBarItem.swift in Sources */,
|
||||||
|
|||||||
24
MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json
vendored
Normal file
24
MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json
vendored
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
MTMR/Assets.xcassets/dark-mode-off.imageset/sun-icon-256.png
vendored
Normal file
BIN
MTMR/Assets.xcassets/dark-mode-off.imageset/sun-icon-256.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
MTMR/Assets.xcassets/dark-mode-on.imageset/39857.png
vendored
Normal file
BIN
MTMR/Assets.xcassets/dark-mode-on.imageset/39857.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
24
MTMR/Assets.xcassets/dark-mode-on.imageset/Contents.json
vendored
Normal file
24
MTMR/Assets.xcassets/dark-mode-on.imageset/Contents.json
vendored
Normal file
@ -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"?>
|
<?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>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Application-->
|
<!--Application-->
|
||||||
@ -619,7 +619,7 @@
|
|||||||
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
|
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleSourceList:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
|
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
||||||
|
|||||||
@ -17,9 +17,9 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.20.3</string>
|
<string>0.21</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>201</string>
|
<string>252</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|||||||
@ -51,7 +51,7 @@ class SupportedTypesHolder {
|
|||||||
private var supportedTypes: [String: ParametersDecoder] = [
|
private var supportedTypes: [String: ParametersDecoder] = [
|
||||||
"escape": { _ in (
|
"escape": { _ in (
|
||||||
item: .staticButton(title: "esc"),
|
item: .staticButton(title: "esc"),
|
||||||
action: .keyPressSession(keycode: 53),
|
action: .keyPress(keycode: 53),
|
||||||
longAction: .none,
|
longAction: .none,
|
||||||
parameters: [.align: .align(.left)]
|
parameters: [.align: .align(.left)]
|
||||||
) },
|
) },
|
||||||
@ -197,9 +197,12 @@ class SupportedTypesHolder {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
"dock": { _ in
|
"dock": { decoder in
|
||||||
(
|
enum CodingKeys: String, CodingKey { case autoResize }
|
||||||
item: .dock(),
|
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,
|
action: .none,
|
||||||
longAction: .none,
|
longAction: .none,
|
||||||
parameters: [:]
|
parameters: [:]
|
||||||
@ -327,7 +330,7 @@ enum ItemType: Decodable {
|
|||||||
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
|
case appleScriptTitledButton(source: SourceProtocol, refreshInterval: Double)
|
||||||
case timeButton(formatTemplate: String, timeZone: String?)
|
case timeButton(formatTemplate: String, timeZone: String?)
|
||||||
case battery()
|
case battery()
|
||||||
case dock()
|
case dock(autoResize: Bool)
|
||||||
case volume()
|
case volume()
|
||||||
case brightness(refreshInterval: Double)
|
case brightness(refreshInterval: Double)
|
||||||
case weather(interval: Double, units: String, api_key: String, icon_type: String)
|
case weather(interval: Double, units: String, api_key: String, icon_type: String)
|
||||||
@ -339,6 +342,7 @@ enum ItemType: Decodable {
|
|||||||
case dnd()
|
case dnd()
|
||||||
case pomodoro(workTime: Double, restTime: Double)
|
case pomodoro(workTime: Double, restTime: Double)
|
||||||
case network(flip: Bool)
|
case network(flip: Bool)
|
||||||
|
case darkMode()
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case type
|
case type
|
||||||
@ -360,6 +364,7 @@ enum ItemType: Decodable {
|
|||||||
case workTime
|
case workTime
|
||||||
case restTime
|
case restTime
|
||||||
case flip
|
case flip
|
||||||
|
case autoResize
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ItemTypeRaw: String, Decodable {
|
enum ItemTypeRaw: String, Decodable {
|
||||||
@ -379,6 +384,7 @@ enum ItemType: Decodable {
|
|||||||
case dnd
|
case dnd
|
||||||
case pomodoro
|
case pomodoro
|
||||||
case network
|
case network
|
||||||
|
case darkMode
|
||||||
}
|
}
|
||||||
|
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
@ -403,7 +409,8 @@ enum ItemType: Decodable {
|
|||||||
self = .battery()
|
self = .battery()
|
||||||
|
|
||||||
case .dock:
|
case .dock:
|
||||||
self = .dock()
|
let autoResize = try container.decodeIfPresent(Bool.self, forKey: .autoResize) ?? false
|
||||||
|
self = .dock(autoResize: autoResize)
|
||||||
|
|
||||||
case .volume:
|
case .volume:
|
||||||
self = .volume()
|
self = .volume()
|
||||||
@ -451,6 +458,9 @@ enum ItemType: Decodable {
|
|||||||
case .network:
|
case .network:
|
||||||
let flip = try container.decodeIfPresent(Bool.self, forKey: .flip) ?? false
|
let flip = try container.decodeIfPresent(Bool.self, forKey: .flip) ?? false
|
||||||
self = .network(flip: flip)
|
self = .network(flip: flip)
|
||||||
|
|
||||||
|
case .darkMode:
|
||||||
|
self = .darkMode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,7 +469,6 @@ enum ActionType: Decodable {
|
|||||||
case none
|
case none
|
||||||
case hidKey(keycode: Int32)
|
case hidKey(keycode: Int32)
|
||||||
case keyPress(keycode: Int)
|
case keyPress(keycode: Int)
|
||||||
case keyPressSession(keycode: Int)
|
|
||||||
case appleScript(source: SourceProtocol)
|
case appleScript(source: SourceProtocol)
|
||||||
case shellScript(executable: String, parameters: [String])
|
case shellScript(executable: String, parameters: [String])
|
||||||
case custom(closure: () -> Void)
|
case custom(closure: () -> Void)
|
||||||
|
|||||||
@ -27,16 +27,6 @@ extension KeyPress {
|
|||||||
keyDown?.post(tap: loc)
|
keyDown?.post(tap: loc)
|
||||||
keyUp?.post(tap: loc)
|
keyUp?.post(tap: loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendSession() {
|
|
||||||
let src = CGEventSource(stateID: .hidSystemState)
|
|
||||||
let keyDown = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: true)
|
|
||||||
let keyUp = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: false)
|
|
||||||
|
|
||||||
let loc: CGEventTapLocation = .cgAnnotatedSessionEventTap
|
|
||||||
keyDown?.post(tap: loc)
|
|
||||||
keyUp?.post(tap: loc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func HIDPostAuxKey(_ key: Int32) {
|
func HIDPostAuxKey(_ key: Int32) {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ extension ItemType {
|
|||||||
return "com.toxblh.mtmr.timeButton."
|
return "com.toxblh.mtmr.timeButton."
|
||||||
case .battery():
|
case .battery():
|
||||||
return "com.toxblh.mtmr.battery."
|
return "com.toxblh.mtmr.battery."
|
||||||
case .dock():
|
case .dock(autoResize: _):
|
||||||
return "com.toxblh.mtmr.dock"
|
return "com.toxblh.mtmr.dock"
|
||||||
case .volume():
|
case .volume():
|
||||||
return "com.toxblh.mtmr.volume"
|
return "com.toxblh.mtmr.volume"
|
||||||
@ -51,6 +51,8 @@ extension ItemType {
|
|||||||
return PomodoroBarItem.identifier
|
return PomodoroBarItem.identifier
|
||||||
case .network(flip: _):
|
case .network(flip: _):
|
||||||
return NetworkBarItem.identifier
|
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)
|
barItem = TimeTouchBarItem(identifier: identifier, formatTemplate: template, timeZone: timeZone)
|
||||||
case .battery():
|
case .battery():
|
||||||
barItem = BatteryBarItem(identifier: identifier)
|
barItem = BatteryBarItem(identifier: identifier)
|
||||||
case .dock:
|
case let .dock(autoResize: autoResize):
|
||||||
barItem = AppScrubberTouchBarItem(identifier: identifier)
|
barItem = AppScrubberTouchBarItem(identifier: identifier, autoResize: autoResize)
|
||||||
case .volume:
|
case .volume:
|
||||||
if case let .image(source)? = item.additionalParameters[.image] {
|
if case let .image(source)? = item.additionalParameters[.image] {
|
||||||
barItem = VolumeViewController(identifier: identifier, image: source.image)
|
barItem = VolumeViewController(identifier: identifier, image: source.image)
|
||||||
@ -283,6 +285,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
barItem = PomodoroBarItem(identifier: identifier, workTime: workTime, restTime: restTime)
|
barItem = PomodoroBarItem(identifier: identifier, workTime: workTime, restTime: restTime)
|
||||||
case let .network(flip: flip):
|
case let .network(flip: flip):
|
||||||
barItem = NetworkBarItem(identifier: identifier, 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 {
|
if let action = self.action(forItem: item), let item = barItem as? CustomButtonTouchBarItem {
|
||||||
@ -319,8 +323,6 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
return { HIDPostAuxKey(keycode) }
|
return { HIDPostAuxKey(keycode) }
|
||||||
case let .keyPress(keycode: keycode):
|
case let .keyPress(keycode: keycode):
|
||||||
return { GenericKeyPress(keyCode: CGKeyCode(keycode)).send() }
|
return { GenericKeyPress(keyCode: CGKeyCode(keycode)).send() }
|
||||||
case let .keyPressSession(keycode: keycode):
|
|
||||||
return { GenericKeyPress(keyCode: CGKeyCode(keycode)).sendSession() }
|
|
||||||
case let .appleScript(source: source):
|
case let .appleScript(source: source):
|
||||||
guard let appleScript = source.appleScript else {
|
guard let appleScript = source.appleScript else {
|
||||||
print("cannot create apple script for item \(item)")
|
print("cannot create apple script for item \(item)")
|
||||||
|
|||||||
@ -17,6 +17,8 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
|||||||
private let minTicks: Int = 5
|
private let minTicks: Int = 5
|
||||||
private let maxTicks: Int = 20
|
private let maxTicks: Int = 20
|
||||||
private var lastSelected: Int = 0
|
private var lastSelected: Int = 0
|
||||||
|
private var autoResize: Bool = false
|
||||||
|
private var widthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
private var persistentAppIdentifiers: [String] = []
|
private var persistentAppIdentifiers: [String] = []
|
||||||
private var runningAppsIdentifiers: [String] = []
|
private var runningAppsIdentifiers: [String] = []
|
||||||
@ -27,17 +29,25 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var applications: [DockItem] = []
|
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)
|
super.init(identifier: identifier)
|
||||||
|
self.autoResize = autoResize
|
||||||
|
|
||||||
scrubber = NSScrubber()
|
scrubber = NSScrubber()
|
||||||
scrubber.delegate = self
|
scrubber.delegate = self
|
||||||
scrubber.dataSource = self
|
scrubber.dataSource = self
|
||||||
scrubber.mode = .free // .fixed
|
scrubber.mode = .free // .fixed
|
||||||
let layout = NSScrubberFlowLayout()
|
let layout = NSScrubberFlowLayout()
|
||||||
layout.itemSize = NSSize(width: 36, height: 32)
|
layout.itemSize = NSSize(width: AppScrubberTouchBarItem.iconWidth, height: 32)
|
||||||
layout.itemSpacing = 2
|
layout.itemSpacing = CGFloat(AppScrubberTouchBarItem.spacingWidth)
|
||||||
scrubber.scrubberLayout = layout
|
scrubber.scrubberLayout = layout
|
||||||
scrubber.selectionBackgroundStyle = .roundedBackground
|
scrubber.selectionBackgroundStyle = .roundedBackground
|
||||||
scrubber.showsAdditionalContentIndicators = true
|
scrubber.showsAdditionalContentIndicators = true
|
||||||
@ -79,9 +89,22 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub
|
|||||||
applications = newApplications
|
applications = newApplications
|
||||||
applications += getDockPersistentAppsList()
|
applications += getDockPersistentAppsList()
|
||||||
scrubber.reloadData()
|
scrubber.reloadData()
|
||||||
|
updateSize()
|
||||||
|
|
||||||
scrubber.selectedIndex = index ?? 0
|
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 {
|
public func numberOfItems(for _: NSScrubber) -> Int {
|
||||||
return applications.count
|
return applications.count
|
||||||
|
|||||||
57
MTMR/Widgets/DarkModeBarItem.swift
Normal file
57
MTMR/Widgets/DarkModeBarItem.swift
Normal 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,7 +40,7 @@ class ParseConfig: XCTestCase {
|
|||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard case .keyPressSession(keycode: 53)? = result?.first?.action else {
|
guard case .keyPress(keycode: 53)? = result?.first?.action else {
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ class ParseConfig: XCTestCase {
|
|||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard case .keyPressSession(keycode: 53)? = result?.first?.action else {
|
guard case .keyPress(keycode: 53)? = result?.first?.action else {
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
10
README.md
10
README.md
@ -76,6 +76,7 @@ The pre-installed configuration contains less or more than you'll probably want,
|
|||||||
- dock (half-long click to open app, full-long click to kill app)
|
- dock (half-long click to open app, full-long click to kill app)
|
||||||
- nightShift
|
- nightShift
|
||||||
- dnd (Don't disturb)
|
- dnd (Don't disturb)
|
||||||
|
- darkMode
|
||||||
- pomodoro
|
- pomodoro
|
||||||
- network
|
- network
|
||||||
|
|
||||||
@ -205,6 +206,15 @@ To close a group, use the button:
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `dock`
|
||||||
|
> Dock plugin
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"type": "dock",
|
||||||
|
"autoResize": true
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
## Actions:
|
## Actions:
|
||||||
- `hidKey`
|
- `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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user