From 3bde1fe4b1224e74163de5f62aac53ce14cd7659 Mon Sep 17 00:00:00 2001 From: willsunnn Date: Thu, 9 May 2019 22:04:10 -0700 Subject: [PATCH 01/10] Created and passed the autoResize parameter to the dock widget --- MTMR.xcodeproj/project.pbxproj | 4 ++-- MTMR/Base.lproj/Main.storyboard | 6 +++--- MTMR/Info.plist | 2 +- MTMR/ItemsParsing.swift | 15 ++++++++++----- MTMR/TouchBarController.swift | 6 +++--- MTMR/Widgets/AppScrubberTouchBarItem.swift | 10 ++++++++-- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/MTMR.xcodeproj/project.pbxproj b/MTMR.xcodeproj/project.pbxproj index 4251a02..5ea5b1e 100644 --- a/MTMR.xcodeproj/project.pbxproj +++ b/MTMR.xcodeproj/project.pbxproj @@ -283,7 +283,6 @@ 6027D1B72080E52A004FFDC7 /* BrightnessViewController.swift */, 607EEA4C2087A8DA009DA5F0 /* CurrencyBarItem.swift */, B081732B213739FE005D4908 /* DnDBarItem.swift */, - 60669B4220AD8FA80074E817 /* GroupBarItem.swift */, 60F7D453208CC31400ABF5D2 /* InputSourceBarItem.swift */, 60C44AFC20A373A100C0EC91 /* MusicBarItem.swift */, B0846A742220C968000288A7 /* NetworkBarItem.swift */, @@ -293,6 +292,7 @@ 6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */, 607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */, B08126F0217BE19000A98970 /* WidgetProtocol.swift */, + 60669B4220AD8FA80074E817 /* GroupBarItem.swift */, ); path = Widgets; sourceTree = ""; @@ -633,7 +633,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = D6D8BR2QNB; + DEVELOPMENT_TEAM = P5KK92AA97; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", diff --git a/MTMR/Base.lproj/Main.storyboard b/MTMR/Base.lproj/Main.storyboard index 925123a..3f295b2 100644 --- a/MTMR/Base.lproj/Main.storyboard +++ b/MTMR/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -619,7 +619,7 @@ - + diff --git a/MTMR/Info.plist b/MTMR/Info.plist index df5f206..71da62c 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 0.20.3 CFBundleVersion - 201 + 220 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index 01095de..0adf2a5 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -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) @@ -360,6 +363,7 @@ enum ItemType: Decodable { case workTime case restTime case flip + case autoResize } enum ItemTypeRaw: String, Decodable { @@ -403,7 +407,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() diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index 43776a9..1384a81 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -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" @@ -251,8 +251,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) diff --git a/MTMR/Widgets/AppScrubberTouchBarItem.swift b/MTMR/Widgets/AppScrubberTouchBarItem.swift index 8d15966..e9fb8ac 100644 --- a/MTMR/Widgets/AppScrubberTouchBarItem.swift +++ b/MTMR/Widgets/AppScrubberTouchBarItem.swift @@ -17,6 +17,7 @@ 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 persistentAppIdentifiers: [String] = [] private var runningAppsIdentifiers: [String] = [] @@ -27,10 +28,15 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub } private var applications: [DockItem] = [] + + convenience override init(identifier: NSTouchBarItem.Identifier) { + self.init(identifier: identifier, autoResize: false) + } - 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 From a81d6fc595c8f9ea8aede6f2a42698b4c7008156 Mon Sep 17 00:00:00 2001 From: willsunnn Date: Thu, 9 May 2019 22:20:45 -0700 Subject: [PATCH 02/10] Made the dock resize when Apps are removed --- MTMR/Info.plist | 2 +- MTMR/Widgets/AppScrubberTouchBarItem.swift | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index 71da62c..86379f7 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 0.20.3 CFBundleVersion - 220 + 223 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMR/Widgets/AppScrubberTouchBarItem.swift b/MTMR/Widgets/AppScrubberTouchBarItem.swift index e9fb8ac..7b28da4 100644 --- a/MTMR/Widgets/AppScrubberTouchBarItem.swift +++ b/MTMR/Widgets/AppScrubberTouchBarItem.swift @@ -32,6 +32,9 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub convenience override init(identifier: NSTouchBarItem.Identifier) { self.init(identifier: identifier, autoResize: false) } + + static var iconWidth = 36 + static var spacingWidth = 2 init(identifier: NSTouchBarItem.Identifier, autoResize: Bool) { super.init(identifier: identifier) @@ -42,8 +45,8 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub 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 @@ -84,10 +87,18 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub applications = newApplications applications += getDockPersistentAppsList() + updateSize() scrubber.reloadData() scrubber.selectedIndex = index ?? 0 } + + func updateSize() { + if self.autoResize { + let width = (AppScrubberTouchBarItem.iconWidth + AppScrubberTouchBarItem.spacingWidth) * self.applications.count - AppScrubberTouchBarItem.spacingWidth + self.setWidth(value: CGFloat(width)) + } + } public func numberOfItems(for _: NSScrubber) -> Int { return applications.count From 324c3f711e1614c2b772f1ee1da4068512af042a Mon Sep 17 00:00:00 2001 From: willsunnn Date: Thu, 9 May 2019 22:39:47 -0700 Subject: [PATCH 03/10] Fixed a bug where the dock would not change size after the first time due to conflicting constraints --- MTMR/Info.plist | 2 +- MTMR/Widgets/AppScrubberTouchBarItem.swift | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index 86379f7..950d24c 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 0.20.3 CFBundleVersion - 223 + 226 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMR/Widgets/AppScrubberTouchBarItem.swift b/MTMR/Widgets/AppScrubberTouchBarItem.swift index 7b28da4..7c5cd39 100644 --- a/MTMR/Widgets/AppScrubberTouchBarItem.swift +++ b/MTMR/Widgets/AppScrubberTouchBarItem.swift @@ -18,6 +18,7 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub 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] = [] @@ -87,16 +88,21 @@ class AppScrubberTouchBarItem: NSCustomTouchBarItem, NSScrubberDelegate, NSScrub applications = newApplications applications += getDockPersistentAppsList() - updateSize() 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.setWidth(value: CGFloat(width)) + self.widthConstraint = self.scrubber.widthAnchor.constraint(equalToConstant: CGFloat(width)) + self.widthConstraint!.isActive = true } } From 5b6b6dfa56314d65fc6c58ae0690f81a1735ca01 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 16:39:32 +0100 Subject: [PATCH 04/10] Revert "fixed tests" This reverts commit 7c9dd26eb074577959e0f95e0be409d9b9ebf5fb. --- MTMR/Info.plist | 2 +- MTMRTests/ParseConfigTests.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index df5f206..3f8a189 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 0.20.3 CFBundleVersion - 201 + 197 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMRTests/ParseConfigTests.swift b/MTMRTests/ParseConfigTests.swift index ebea8a5..a3321cc 100644 --- a/MTMRTests/ParseConfigTests.swift +++ b/MTMRTests/ParseConfigTests.swift @@ -40,7 +40,7 @@ class ParseConfig: XCTestCase { XCTFail() return } - guard case .keyPressSession(keycode: 53)? = result?.first?.action else { + guard case .keyPress(keycode: 53)? = result?.first?.action else { XCTFail() return } @@ -55,7 +55,7 @@ class ParseConfig: XCTestCase { XCTFail() return } - guard case .keyPressSession(keycode: 53)? = result?.first?.action else { + guard case .keyPress(keycode: 53)? = result?.first?.action else { XCTFail() return } From 5fbb2bafc62c6381caee3d574fdf43611225a64a Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 16:39:52 +0100 Subject: [PATCH 05/10] Revert "Fix #164" This reverts commit 40fa61fcb5e82a58481c5ca9e8607d74ecbe0e1b. --- MTMR/Info.plist | 2 +- MTMR/ItemsParsing.swift | 5 ++--- MTMR/KeyPress.swift | 10 ---------- MTMR/TouchBarController.swift | 2 -- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index 3f8a189..06505cc 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.20.3 + 0.20.2 CFBundleVersion 197 LSApplicationCategoryType diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index 01095de..8fa1413 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -51,7 +51,7 @@ class SupportedTypesHolder { private var supportedTypes: [String: ParametersDecoder] = [ "escape": { _ in ( item: .staticButton(title: "esc"), - action: .keyPressSession(keycode: 53), + action: .keyPress(keycode: 53), longAction: .none, parameters: [.align: .align(.left)] ) }, @@ -447,7 +447,7 @@ 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: let flip = try container.decodeIfPresent(Bool.self, forKey: .flip) ?? false self = .network(flip: flip) @@ -459,7 +459,6 @@ enum ActionType: Decodable { case none case hidKey(keycode: Int32) case keyPress(keycode: Int) - case keyPressSession(keycode: Int) case appleScript(source: SourceProtocol) case shellScript(executable: String, parameters: [String]) case custom(closure: () -> Void) diff --git a/MTMR/KeyPress.swift b/MTMR/KeyPress.swift index c88b49f..a4afe2b 100644 --- a/MTMR/KeyPress.swift +++ b/MTMR/KeyPress.swift @@ -23,16 +23,6 @@ extension KeyPress { let keyDown = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: true) let keyUp = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: false) - let loc: CGEventTapLocation = .cghidEventTap - keyDown?.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) diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index 43776a9..a23ebe8 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -319,8 +319,6 @@ class TouchBarController: NSObject, NSTouchBarDelegate { return { HIDPostAuxKey(keycode) } case let .keyPress(keycode: keycode): return { GenericKeyPress(keyCode: CGKeyCode(keycode)).send() } - case let .keyPressSession(keycode: keycode): - return { GenericKeyPress(keyCode: CGKeyCode(keycode)).sendSession() } case let .appleScript(source: source): guard let appleScript = source.appleScript else { print("cannot create apple script for item \(item)") From 8a73fe01e42c6ce90494a2c749a6312e2069d8ae Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 16:40:09 +0100 Subject: [PATCH 06/10] Revert "#154 .cghidEventTap -> .cgAnnotatedSessionEventTap" This reverts commit 5a8117ac7f0e5ab3898cf5a60699adcaa74733ea. --- MTMR/Info.plist | 4 ++-- MTMR/KeyPress.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index 06505cc..1180dfc 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.20.2 + 0.20.1 CFBundleVersion - 197 + 185 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMR/KeyPress.swift b/MTMR/KeyPress.swift index a4afe2b..1f68768 100644 --- a/MTMR/KeyPress.swift +++ b/MTMR/KeyPress.swift @@ -23,7 +23,7 @@ extension KeyPress { let keyDown = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: true) let keyUp = CGEvent(keyboardEventSource: src, virtualKey: keyCode, keyDown: false) - let loc: CGEventTapLocation = .cgAnnotatedSessionEventTap + let loc: CGEventTapLocation = .cghidEventTap keyDown?.post(tap: loc) keyUp?.post(tap: loc) } From 2e5db4ffa0d8a5c66223c6742d03208fb9bb09b3 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 16:55:44 +0100 Subject: [PATCH 07/10] revert project settings --- MTMR.xcodeproj/project.pbxproj | 4 ++-- MTMR/Info.plist | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MTMR.xcodeproj/project.pbxproj b/MTMR.xcodeproj/project.pbxproj index 5ea5b1e..4251a02 100644 --- a/MTMR.xcodeproj/project.pbxproj +++ b/MTMR.xcodeproj/project.pbxproj @@ -283,6 +283,7 @@ 6027D1B72080E52A004FFDC7 /* BrightnessViewController.swift */, 607EEA4C2087A8DA009DA5F0 /* CurrencyBarItem.swift */, B081732B213739FE005D4908 /* DnDBarItem.swift */, + 60669B4220AD8FA80074E817 /* GroupBarItem.swift */, 60F7D453208CC31400ABF5D2 /* InputSourceBarItem.swift */, 60C44AFC20A373A100C0EC91 /* MusicBarItem.swift */, B0846A742220C968000288A7 /* NetworkBarItem.swift */, @@ -292,7 +293,6 @@ 6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */, 607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */, B08126F0217BE19000A98970 /* WidgetProtocol.swift */, - 60669B4220AD8FA80074E817 /* GroupBarItem.swift */, ); path = Widgets; sourceTree = ""; @@ -633,7 +633,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = P5KK92AA97; + DEVELOPMENT_TEAM = D6D8BR2QNB; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", diff --git a/MTMR/Info.plist b/MTMR/Info.plist index 950d24c..dccd38a 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 0.20.3 CFBundleVersion - 226 + 250 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion From 57b51291359fe19b1326eb0d325be42e677b1022 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 16:57:40 +0100 Subject: [PATCH 08/10] info.plist --- MTMR/Info.plist | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MTMR/Info.plist b/MTMR/Info.plist index a27c2b9..ddd4823 100644 --- a/MTMR/Info.plist +++ b/MTMR/Info.plist @@ -19,11 +19,7 @@ CFBundleShortVersionString 0.20.1 CFBundleVersion -<<<<<<< HEAD 250 -======= - 185 ->>>>>>> origin/master LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion From ae469bb92a37fe731125cd37d065b71e7b5e2cd7 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 15 May 2019 17:01:06 +0100 Subject: [PATCH 09/10] add Readme info --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 43341e8..6188b72 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,15 @@ To close a group, use the button: }, ``` +#### `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 From 5504e5d640916a78b99c95ff0b79542b65877f80 Mon Sep 17 00:00:00 2001 From: Toxblh Date: Wed, 22 May 2019 18:25:18 +0100 Subject: [PATCH 10/10] #171 Added DarkMode button v0.21 --- MTMR.xcodeproj/project.pbxproj | 4 ++ .../dark-mode-off.imageset/Contents.json | 24 ++++++++ .../dark-mode-off.imageset/sun-icon-256.png | Bin 0 -> 16444 bytes .../dark-mode-on.imageset/39857.png | Bin 0 -> 8308 bytes .../dark-mode-on.imageset/Contents.json | 24 ++++++++ MTMR/Info.plist | 4 +- MTMR/ItemsParsing.swift | 7 ++- MTMR/TouchBarController.swift | 4 ++ MTMR/Widgets/DarkModeBarItem.swift | 57 ++++++++++++++++++ README.md | 1 + 10 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json create mode 100644 MTMR/Assets.xcassets/dark-mode-off.imageset/sun-icon-256.png create mode 100644 MTMR/Assets.xcassets/dark-mode-on.imageset/39857.png create mode 100644 MTMR/Assets.xcassets/dark-mode-on.imageset/Contents.json create mode 100644 MTMR/Widgets/DarkModeBarItem.swift diff --git a/MTMR.xcodeproj/project.pbxproj b/MTMR.xcodeproj/project.pbxproj index 4251a02..8830654 100644 --- a/MTMR.xcodeproj/project.pbxproj +++ b/MTMR.xcodeproj/project.pbxproj @@ -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 = ""; }; B0B17430207D6B590004B740 /* iTunes.nowPlaying.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = iTunes.nowPlaying.scpt; sourceTree = ""; }; B0F3112420C9E35F0076BB88 /* SupportNSTouchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportNSTouchBar.swift; sourceTree = ""; }; + B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DarkModeBarItem.swift; sourceTree = ""; }; B0F87719207AC1EA00D6E430 /* TouchBarSupport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TouchBarSupport.m; sourceTree = ""; }; B0F8771B207AC92700D6E430 /* TouchBarSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TouchBarSupport.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -293,6 +295,7 @@ 6027D1B82080E52A004FFDC7 /* VolumeViewController.swift */, 607EEA4A2087835F009DA5F0 /* WeatherBarItem.swift */, B08126F0217BE19000A98970 /* WidgetProtocol.swift */, + B0F54A792295AC7D00B4C509 /* DarkModeBarItem.swift */, ); path = Widgets; sourceTree = ""; @@ -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 */, diff --git a/MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json b/MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json new file mode 100644 index 0000000..f185c89 --- /dev/null +++ b/MTMR/Assets.xcassets/dark-mode-off.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/MTMR/Assets.xcassets/dark-mode-off.imageset/sun-icon-256.png b/MTMR/Assets.xcassets/dark-mode-off.imageset/sun-icon-256.png new file mode 100644 index 0000000000000000000000000000000000000000..ddec2cd1d2dd27d3f09692b2e7b2651b7dbb6f99 GIT binary patch literal 16444 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 literal 0 HcmV?d00001 diff --git a/MTMR/Assets.xcassets/dark-mode-on.imageset/39857.png b/MTMR/Assets.xcassets/dark-mode-on.imageset/39857.png new file mode 100644 index 0000000000000000000000000000000000000000..4c127cc991868549e84517688986422291f8bde8 GIT binary patch literal 8308 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 APPL CFBundleShortVersionString - 0.20.1 + 0.21 CFBundleVersion - 185 + 207 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index 8fa1413..fabc858 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -339,6 +339,7 @@ enum ItemType: Decodable { case dnd() case pomodoro(workTime: Double, restTime: Double) case network(flip: Bool) + case darkMode() private enum CodingKeys: String, CodingKey { case type @@ -379,6 +380,7 @@ enum ItemType: Decodable { case dnd case pomodoro case network + case darkMode } init(from decoder: Decoder) throws { @@ -447,10 +449,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: let flip = try container.decodeIfPresent(Bool.self, forKey: .flip) ?? false self = .network(flip: flip) + + case .darkMode: + self = .darkMode() } } } diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index a23ebe8..eab726f 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -51,6 +51,8 @@ extension ItemType { return PomodoroBarItem.identifier case .network(flip: _): return NetworkBarItem.identifier + case .darkMode(items: _): + return DarkModeBarItem.identifier } } } @@ -283,6 +285,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate { barItem = PomodoroBarItem(identifier: identifier, workTime: workTime, restTime: restTime) 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 { diff --git a/MTMR/Widgets/DarkModeBarItem.swift b/MTMR/Widgets/DarkModeBarItem.swift new file mode 100644 index 0000000..60fecb6 --- /dev/null +++ b/MTMR/Widgets/DarkModeBarItem.swift @@ -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 +} + diff --git a/README.md b/README.md index 43341e8..b0b10c2 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Re-tick or check a tick for access 🍏→ System Preferences → Security and P - dock (half-long click to open app, full-long click to kill app) - nightShift - dnd (Don't disturb) +- darkMode - pomodoro - network