From 36bf749a46e10de760711ebaddeeb2236266c1a7 Mon Sep 17 00:00:00 2001 From: Wiktor Latanowicz Date: Wed, 16 Feb 2022 20:01:09 +0100 Subject: [PATCH] App id matching (#432) * Add app id matching for buttons * Hide MT button from control strip when touch bar is empty Co-authored-by: Wiktor Latanowicz Co-authored-by: Anton Palgunov --- MTMR/ItemsParsing.swift | 6 +++ MTMR/SwipeItem.swift | 8 +++ MTMR/TouchBarController.swift | 92 ++++++++++++++++++++++++++++++----- README.md | 7 +++ 4 files changed, 100 insertions(+), 13 deletions(-) diff --git a/MTMR/ItemsParsing.swift b/MTMR/ItemsParsing.swift index c7bcb78..ca8305a 100644 --- a/MTMR/ItemsParsing.swift +++ b/MTMR/ItemsParsing.swift @@ -658,6 +658,7 @@ enum GeneralParameter { case bordered(_: Bool) case background(_: NSColor) case title(_: String) + case matchAppId(_: String) } struct GeneralParameters: Decodable { @@ -670,6 +671,7 @@ struct GeneralParameters: Decodable { case bordered case background case title + case matchAppId } init(from decoder: Decoder) throws { @@ -699,6 +701,10 @@ struct GeneralParameters: Decodable { result[.title] = .title(title) } + if let matchAppId = try container.decodeIfPresent(String.self, forKey: .matchAppId) { + result[.matchAppId] = .matchAppId(matchAppId) + } + parameters = result } } diff --git a/MTMR/SwipeItem.swift b/MTMR/SwipeItem.swift index 3142eca..6aa3a24 100644 --- a/MTMR/SwipeItem.swift +++ b/MTMR/SwipeItem.swift @@ -67,4 +67,12 @@ class SwipeItem: NSCustomTouchBarItem { } } } + + func isEqual(_ object: AnyObject?) -> Bool { + if let object = object as? SwipeItem { + return self.scriptApple?.source as String? == object.scriptApple?.source as String? && self.scriptBash == object.scriptBash && self.direction == object.direction && self.fingers == object.fingers && self.minOffset == object.minOffset + } else { + return false + } + } } diff --git a/MTMR/TouchBarController.swift b/MTMR/TouchBarController.swift index cbf8b95..155b028 100644 --- a/MTMR/TouchBarController.swift +++ b/MTMR/TouchBarController.swift @@ -134,17 +134,56 @@ class TouchBarController: NSObject, NSTouchBarDelegate { touchBar = NSTouchBar() jsonItems = newJsonItems itemDefinitions = [:] - items = [:] loadItemDefinitions(jsonItems: jsonItems) + + updateActiveApp() + } + + func didItemsChange(prevItems: [NSTouchBarItem.Identifier: NSTouchBarItem], prevSwipeItems: [SwipeItem]) -> Bool { + var changed = items.count != prevItems.count || swipeItems.count != prevSwipeItems.count + + if !changed { + for (item, prevItem) in zip(items, prevItems) { + if item.key != prevItem.key { + changed = true + break + } + } + } + + if !changed { + for (swipeItem, prevSwipeItem) in zip(swipeItems, prevSwipeItems) { + if !swipeItem.isEqual(prevSwipeItem) { + changed = true + break + } + } + } + + return changed + } + + func prepareTouchBar() { + let prevItems = items + let prevSwipeItems = swipeItems + createItems() + let changed = didItemsChange(prevItems: prevItems, prevSwipeItems: prevSwipeItems) + + if !changed { + return + } + let centerItems = centerIdentifiers.compactMap({ (identifier) -> NSTouchBarItem? in items[identifier] }) let centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea.".appending(UUID().uuidString)) let scrollArea = ScrollViewItem(identifier: centerScrollArea, items: centerItems) + + basicViewIdentifier = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollView.".appending(UUID().uuidString)) touchBar.delegate = self touchBar.defaultItemIdentifiers = [basicViewIdentifier] @@ -158,8 +197,6 @@ class TouchBarController: NSObject, NSTouchBarDelegate { basicView = BasicView(identifier: basicViewIdentifier, items:leftItems + [scrollArea] + rightItems, swipeItems: swipeItems) basicView?.legacyGesturesEnabled = AppSettings.multitouchGestures - - updateActiveApp() } @objc func activeApplicationChanged(_: Notification) { @@ -170,9 +207,18 @@ class TouchBarController: NSObject, NSTouchBarDelegate { if frontmostApplicationIdentifier != nil && blacklistAppIdentifiers.firstIndex(of: frontmostApplicationIdentifier!) != nil { dismissTouchBar() } else { - presentTouchBar() + prepareTouchBar() + if touchBarContainsAnyItems() { + presentTouchBar() + } else { + dismissTouchBar() + } } } + + func touchBarContainsAnyItems() -> Bool { + return items.count != 0 || swipeItems.count != 0 + } func reloadStandardConfig() { let presetPath = standardConfigPath @@ -212,12 +258,29 @@ class TouchBarController: NSObject, NSTouchBarDelegate { } func createItems() { + items = [:] + swipeItems = [] + for (identifier, definition) in itemDefinitions { - let item = createItem(forIdentifier: identifier, definition: definition) - if item is SwipeItem { - swipeItems.append(item as! SwipeItem) - } else { - items[identifier] = item + var show = true + + if let frontApp = frontmostApplicationIdentifier { + if case let .matchAppId(regexString)? = definition.additionalParameters[.matchAppId] { + let regex = try! NSRegularExpression(pattern: regexString) + let range = NSRange(location: 0, length: frontApp.count) + if regex.firstMatch(in: frontApp, range: range) == nil { + show = false + } + } + } + + if show { + let item = createItem(forIdentifier: identifier, definition: definition) + if item is SwipeItem { + swipeItems.append(item as! SwipeItem) + } else { + items[identifier] = item + } } } } @@ -231,26 +294,29 @@ class TouchBarController: NSObject, NSTouchBarDelegate { } func updateControlStripPresence() { - DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, true) + let showMtmrButtonOnControlStrip = touchBarContainsAnyItems() + DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, showMtmrButtonOnControlStrip) } @objc private func presentTouchBar() { if AppSettings.showControlStripState { - updateControlStripPresence() presentSystemModal(touchBar, systemTrayItemIdentifier: .controlStripItem) } else { presentSystemModal(touchBar, placement: 1, systemTrayItemIdentifier: .controlStripItem) } + updateControlStripPresence() } @objc private func dismissTouchBar() { - minimizeSystemModal(touchBar) + if touchBarContainsAnyItems() { + minimizeSystemModal(touchBar) + } updateControlStripPresence() } @objc func resetControlStrip() { dismissTouchBar() - presentTouchBar() + updateActiveApp() } func touchBar(_: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? { diff --git a/README.md b/README.md index 4840b1c..996f419 100644 --- a/README.md +++ b/README.md @@ -488,6 +488,13 @@ by using background with color "#000000" and bordered == false you can create bu } ``` +- `matchAppId` displays the button only when active app's id matches given regexp + +```json + "matchAppId": "Safari" +``` + + ## Troubleshooting #### If you can't open preferences: