1
0
mirror of https://github.com/Toxblh/MTMR.git synced 2026-01-11 09:28:38 +00:00

Compare commits

..

No commits in common. "36bf749a46e10de760711ebaddeeb2236266c1a7" and "d199bbd8528a697b4ad3cd48d2e3c8acbe9cca83" have entirely different histories.

8 changed files with 34 additions and 130 deletions

View File

@ -19,7 +19,6 @@ class HapticFeedback {
0x200_0000_0100_0000, // MacBook Pro 2016/2017
0x300_0000_8050_0000, // MacBook Pro 2019/2018
0x200_0000_0000_0024, // MacBook Pro (13-inch, M1, 2020)
0x200_0000_0000_0023 // MacBook Pro M1 13-Inch 2020 with 1tb
]
// 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`

View File

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>0.27</string>
<key>CFBundleVersion</key>
<string>448</string>
<string>434</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>

View File

@ -658,7 +658,6 @@ enum GeneralParameter {
case bordered(_: Bool)
case background(_: NSColor)
case title(_: String)
case matchAppId(_: String)
}
struct GeneralParameters: Decodable {
@ -671,7 +670,6 @@ struct GeneralParameters: Decodable {
case bordered
case background
case title
case matchAppId
}
init(from decoder: Decoder) throws {
@ -701,10 +699,6 @@ struct GeneralParameters: Decodable {
result[.title] = .title(title)
}
if let matchAppId = try container.decodeIfPresent(String.self, forKey: .matchAppId) {
result[.matchAppId] = .matchAppId(matchAppId)
}
parameters = result
}
}

View File

@ -78,11 +78,7 @@ class ShellScriptTouchBarItem: CustomButtonTouchBarItem {
func execute(_ command: String) -> String {
let task = Process()
if let shell = getenv("SHELL") {
task.launchPath = String.init(cString: shell)
} else {
task.launchPath = "/bin/bash"
}
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()

View File

@ -51,11 +51,7 @@ class SwipeItem: NSCustomTouchBarItem {
if scriptBash != nil {
DispatchQueue.shellScriptQueue.async {
let task = Process()
if let shell = getenv("SHELL") {
task.launchPath = String.init(cString: shell)
} else {
task.launchPath = "/bin/bash"
}
task.launchPath = "/bin/bash"
task.arguments = ["-c", self.scriptBash!]
task.launch()
task.waitUntilExit()
@ -67,12 +63,4 @@ 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
}
}
}

View File

@ -134,56 +134,17 @@ 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]
@ -197,6 +158,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
basicView = BasicView(identifier: basicViewIdentifier, items:leftItems + [scrollArea] + rightItems, swipeItems: swipeItems)
basicView?.legacyGesturesEnabled = AppSettings.multitouchGestures
updateActiveApp()
}
@objc func activeApplicationChanged(_: Notification) {
@ -207,18 +170,9 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
if frontmostApplicationIdentifier != nil && blacklistAppIdentifiers.firstIndex(of: frontmostApplicationIdentifier!) != nil {
dismissTouchBar()
} else {
prepareTouchBar()
if touchBarContainsAnyItems() {
presentTouchBar()
} else {
dismissTouchBar()
}
presentTouchBar()
}
}
func touchBarContainsAnyItems() -> Bool {
return items.count != 0 || swipeItems.count != 0
}
func reloadStandardConfig() {
let presetPath = standardConfigPath
@ -258,29 +212,12 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
}
func createItems() {
items = [:]
swipeItems = []
for (identifier, definition) in itemDefinitions {
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
}
let item = createItem(forIdentifier: identifier, definition: definition)
if item is SwipeItem {
swipeItems.append(item as! SwipeItem)
} else {
items[identifier] = item
}
}
}
@ -294,29 +231,26 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
}
func updateControlStripPresence() {
let showMtmrButtonOnControlStrip = touchBarContainsAnyItems()
DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, showMtmrButtonOnControlStrip)
DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, true)
}
@objc private func presentTouchBar() {
if AppSettings.showControlStripState {
updateControlStripPresence()
presentSystemModal(touchBar, systemTrayItemIdentifier: .controlStripItem)
} else {
presentSystemModal(touchBar, placement: 1, systemTrayItemIdentifier: .controlStripItem)
}
updateControlStripPresence()
}
@objc private func dismissTouchBar() {
if touchBarContainsAnyItems() {
minimizeSystemModal(touchBar)
}
minimizeSystemModal(touchBar)
updateControlStripPresence()
}
@objc func resetControlStrip() {
dismissTouchBar()
updateActiveApp()
presentTouchBar()
}
func touchBar(_: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {

View File

@ -10,7 +10,7 @@ class VolumeViewController: NSCustomTouchBarItem {
super.init(identifier: identifier)
var forPropertyAddress = AudioObjectPropertyAddress(
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMainVolume,
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
mScope: kAudioDevicePropertyScopeOutput,
mElement: kAudioObjectPropertyElementMaster
)
@ -66,7 +66,7 @@ class VolumeViewController: NSCustomTouchBarItem {
var volume: Float32 = 0.5
var size: UInt32 = UInt32(MemoryLayout.size(ofValue: volume))
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMainVolume)
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMasterVolume)
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
AudioObjectGetPropertyData(defaultDeviceID, &address, 0, nil, &size, &volume)
@ -86,7 +86,7 @@ class VolumeViewController: NSCustomTouchBarItem {
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMainVolume)
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMasterVolume)
return AudioObjectSetPropertyData(defaultDeviceID, &address, 0, nil, size, &inputVolume)
}

View File

@ -31,7 +31,7 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
- Or via Homebrew `brew install --cask 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.
**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">
@ -51,7 +51,7 @@ My idea is to create a platform for creating plugins to customize the TouchBar.
## Customization
MTMR preferences are stored in `~/Library/Application\ Support/MTMR/items.json`.
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:
@ -159,7 +159,7 @@ You may create as many `swipe` objects in the preset as you want.
}
```
> Note: You can change appleScriptTitledButton's icon by following these steps:
> Note: appleScriptTitledButton can change its icon. To do it, you need to do the following things:
1. Declare dictionary of icons in `alternativeImages` field
2. Make you script return array of two values - `{"TITLE", "IMAGE_LABEL"}`
3. Make sure that your `IMAGE_LABEL` is declared in `alternativeImages` field
@ -187,10 +187,10 @@ Example:
```
#### `shellScriptTitledButton`
> Note: script may also use escape sequences to return colors (read https://misc.flogisoft.com/bash/tip_colors_and_formatting for more information)
> "16 Colors" is the only mode supported presently. Buttons will set their own background color to the color returned.
> Note: script may return also colors using escape sequences (read more here https://misc.flogisoft.com/bash/tip_colors_and_formatting)
> Only "16 Colors" mode supported atm. If background color returned, button will pick it up as own background color.
Example of "CPU load" button which also changes color based on load value (Note: The native `cpu` plugin runs runs better):
Example of "CPU load" button which also changes color based on load value (Note: you can use native `cpu` plugin for that purpose which runs better):
```js
{
"type": "shellScriptTitledButton",
@ -249,8 +249,8 @@ To close a group, use the button:
#### `cpu`
> Shows current CPU load in percent, changes color based on load value.
> Has lower power consumption and higher stability than the shell-based solution.
> Shows current CPU load in percents, changes color based on load value.
> Has lower power consumption and more stable in comparison to shell-based solution.
```js
{
@ -262,7 +262,7 @@ To close a group, use the button:
#### `timeButton`
> NOTE: Some values don't work properly: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
> Attention! Works not all: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
> formatTemplate examples: https://www.datetimeformatter.com/how-to-format-date-time-in-swift/
@ -280,9 +280,9 @@ To close a group, use the button:
#### `weather`
> Provider: https://openweathermap.org \
> Note: Register at https://openweathermap.org to get your API key \
> Note: Wait for 20 minutes or so for Openweathermap to activate your API key.\
> Note: Enable MTMR in "Location Services" in the "Security & Privacy" System Preferences pane
> 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",
@ -295,7 +295,7 @@ To close a group, use the button:
#### `yandexWeather` (experimental)
> Provider: https://yandex.ru/pogoda. One click to open up weather forecast in your browser. \
> Note: Enable MTMR in "Location Services" in the "Security & Privacy" System Preferences pane
> Note: you need to allow using "Location Services" in your Mac OS "Security & Privacy" settings for MTMR
```js
"type": "yandexWeather",
@ -330,7 +330,7 @@ To close a group, use the button:
#### `pomodoro`
> Pomodoro plugin. One tap starts the work timer, long-press to start the rest timer. Tap an in-progress timer to reset.
> Pomodoro plugin. One click to start the work timer, longclick to start the rest timer. Click in progress for reset.
```js
{
@ -342,7 +342,7 @@ To close a group, use the button:
#### `network`
> Network plugin. The plugin to show network usage
> Network plugin. The plugin to show usage a network
```js
{
@ -488,13 +488,6 @@ 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: