mirror of
https://github.com/Toxblh/MTMR.git
synced 2026-01-11 09:28:38 +00:00
Compare commits
3 Commits
d199bbd852
...
36bf749a46
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36bf749a46 | ||
|
|
ac0e44db4d | ||
|
|
26ad83be70 |
@ -19,6 +19,7 @@ class HapticFeedback {
|
|||||||
0x200_0000_0100_0000, // MacBook Pro 2016/2017
|
0x200_0000_0100_0000, // MacBook Pro 2016/2017
|
||||||
0x300_0000_8050_0000, // MacBook Pro 2019/2018
|
0x300_0000_8050_0000, // MacBook Pro 2019/2018
|
||||||
0x200_0000_0000_0024, // MacBook Pro (13-inch, M1, 2020)
|
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`
|
// 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`
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.27</string>
|
<string>0.27</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>434</string>
|
<string>448</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>
|
||||||
|
|||||||
@ -658,6 +658,7 @@ enum GeneralParameter {
|
|||||||
case bordered(_: Bool)
|
case bordered(_: Bool)
|
||||||
case background(_: NSColor)
|
case background(_: NSColor)
|
||||||
case title(_: String)
|
case title(_: String)
|
||||||
|
case matchAppId(_: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GeneralParameters: Decodable {
|
struct GeneralParameters: Decodable {
|
||||||
@ -670,6 +671,7 @@ struct GeneralParameters: Decodable {
|
|||||||
case bordered
|
case bordered
|
||||||
case background
|
case background
|
||||||
case title
|
case title
|
||||||
|
case matchAppId
|
||||||
}
|
}
|
||||||
|
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
@ -699,6 +701,10 @@ struct GeneralParameters: Decodable {
|
|||||||
result[.title] = .title(title)
|
result[.title] = .title(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let matchAppId = try container.decodeIfPresent(String.self, forKey: .matchAppId) {
|
||||||
|
result[.matchAppId] = .matchAppId(matchAppId)
|
||||||
|
}
|
||||||
|
|
||||||
parameters = result
|
parameters = result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,11 @@ class ShellScriptTouchBarItem: CustomButtonTouchBarItem {
|
|||||||
|
|
||||||
func execute(_ command: String) -> String {
|
func execute(_ command: String) -> String {
|
||||||
let task = Process()
|
let task = Process()
|
||||||
task.launchPath = "/bin/bash"
|
if let shell = getenv("SHELL") {
|
||||||
|
task.launchPath = String.init(cString: shell)
|
||||||
|
} else {
|
||||||
|
task.launchPath = "/bin/bash"
|
||||||
|
}
|
||||||
task.arguments = ["-c", command]
|
task.arguments = ["-c", command]
|
||||||
|
|
||||||
let pipe = Pipe()
|
let pipe = Pipe()
|
||||||
|
|||||||
@ -51,7 +51,11 @@ class SwipeItem: NSCustomTouchBarItem {
|
|||||||
if scriptBash != nil {
|
if scriptBash != nil {
|
||||||
DispatchQueue.shellScriptQueue.async {
|
DispatchQueue.shellScriptQueue.async {
|
||||||
let task = Process()
|
let task = Process()
|
||||||
task.launchPath = "/bin/bash"
|
if let shell = getenv("SHELL") {
|
||||||
|
task.launchPath = String.init(cString: shell)
|
||||||
|
} else {
|
||||||
|
task.launchPath = "/bin/bash"
|
||||||
|
}
|
||||||
task.arguments = ["-c", self.scriptBash!]
|
task.arguments = ["-c", self.scriptBash!]
|
||||||
task.launch()
|
task.launch()
|
||||||
task.waitUntilExit()
|
task.waitUntilExit()
|
||||||
@ -63,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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,11 +134,48 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
touchBar = NSTouchBar()
|
touchBar = NSTouchBar()
|
||||||
jsonItems = newJsonItems
|
jsonItems = newJsonItems
|
||||||
itemDefinitions = [:]
|
itemDefinitions = [:]
|
||||||
items = [:]
|
|
||||||
|
|
||||||
loadItemDefinitions(jsonItems: jsonItems)
|
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()
|
createItems()
|
||||||
|
|
||||||
|
let changed = didItemsChange(prevItems: prevItems, prevSwipeItems: prevSwipeItems)
|
||||||
|
|
||||||
|
if !changed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let centerItems = centerIdentifiers.compactMap({ (identifier) -> NSTouchBarItem? in
|
let centerItems = centerIdentifiers.compactMap({ (identifier) -> NSTouchBarItem? in
|
||||||
items[identifier]
|
items[identifier]
|
||||||
})
|
})
|
||||||
@ -146,6 +183,8 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
let centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea.".appending(UUID().uuidString))
|
let centerScrollArea = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollArea.".appending(UUID().uuidString))
|
||||||
let scrollArea = ScrollViewItem(identifier: centerScrollArea, items: centerItems)
|
let scrollArea = ScrollViewItem(identifier: centerScrollArea, items: centerItems)
|
||||||
|
|
||||||
|
basicViewIdentifier = NSTouchBarItem.Identifier("com.toxblh.mtmr.scrollView.".appending(UUID().uuidString))
|
||||||
|
|
||||||
touchBar.delegate = self
|
touchBar.delegate = self
|
||||||
touchBar.defaultItemIdentifiers = [basicViewIdentifier]
|
touchBar.defaultItemIdentifiers = [basicViewIdentifier]
|
||||||
|
|
||||||
@ -158,8 +197,6 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
|
|
||||||
basicView = BasicView(identifier: basicViewIdentifier, items:leftItems + [scrollArea] + rightItems, swipeItems: swipeItems)
|
basicView = BasicView(identifier: basicViewIdentifier, items:leftItems + [scrollArea] + rightItems, swipeItems: swipeItems)
|
||||||
basicView?.legacyGesturesEnabled = AppSettings.multitouchGestures
|
basicView?.legacyGesturesEnabled = AppSettings.multitouchGestures
|
||||||
|
|
||||||
updateActiveApp()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func activeApplicationChanged(_: Notification) {
|
@objc func activeApplicationChanged(_: Notification) {
|
||||||
@ -170,10 +207,19 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
if frontmostApplicationIdentifier != nil && blacklistAppIdentifiers.firstIndex(of: frontmostApplicationIdentifier!) != nil {
|
if frontmostApplicationIdentifier != nil && blacklistAppIdentifiers.firstIndex(of: frontmostApplicationIdentifier!) != nil {
|
||||||
dismissTouchBar()
|
dismissTouchBar()
|
||||||
} else {
|
} else {
|
||||||
presentTouchBar()
|
prepareTouchBar()
|
||||||
|
if touchBarContainsAnyItems() {
|
||||||
|
presentTouchBar()
|
||||||
|
} else {
|
||||||
|
dismissTouchBar()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func touchBarContainsAnyItems() -> Bool {
|
||||||
|
return items.count != 0 || swipeItems.count != 0
|
||||||
|
}
|
||||||
|
|
||||||
func reloadStandardConfig() {
|
func reloadStandardConfig() {
|
||||||
let presetPath = standardConfigPath
|
let presetPath = standardConfigPath
|
||||||
if !FileManager.default.fileExists(atPath: presetPath),
|
if !FileManager.default.fileExists(atPath: presetPath),
|
||||||
@ -212,12 +258,29 @@ class TouchBarController: NSObject, NSTouchBarDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createItems() {
|
func createItems() {
|
||||||
|
items = [:]
|
||||||
|
swipeItems = []
|
||||||
|
|
||||||
for (identifier, definition) in itemDefinitions {
|
for (identifier, definition) in itemDefinitions {
|
||||||
let item = createItem(forIdentifier: identifier, definition: definition)
|
var show = true
|
||||||
if item is SwipeItem {
|
|
||||||
swipeItems.append(item as! SwipeItem)
|
if let frontApp = frontmostApplicationIdentifier {
|
||||||
} else {
|
if case let .matchAppId(regexString)? = definition.additionalParameters[.matchAppId] {
|
||||||
items[identifier] = item
|
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() {
|
func updateControlStripPresence() {
|
||||||
DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, true)
|
let showMtmrButtonOnControlStrip = touchBarContainsAnyItems()
|
||||||
|
DFRElementSetControlStripPresenceForIdentifier(.controlStripItem, showMtmrButtonOnControlStrip)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func presentTouchBar() {
|
@objc private func presentTouchBar() {
|
||||||
if AppSettings.showControlStripState {
|
if AppSettings.showControlStripState {
|
||||||
updateControlStripPresence()
|
|
||||||
presentSystemModal(touchBar, systemTrayItemIdentifier: .controlStripItem)
|
presentSystemModal(touchBar, systemTrayItemIdentifier: .controlStripItem)
|
||||||
} else {
|
} else {
|
||||||
presentSystemModal(touchBar, placement: 1, systemTrayItemIdentifier: .controlStripItem)
|
presentSystemModal(touchBar, placement: 1, systemTrayItemIdentifier: .controlStripItem)
|
||||||
}
|
}
|
||||||
|
updateControlStripPresence()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func dismissTouchBar() {
|
@objc private func dismissTouchBar() {
|
||||||
minimizeSystemModal(touchBar)
|
if touchBarContainsAnyItems() {
|
||||||
|
minimizeSystemModal(touchBar)
|
||||||
|
}
|
||||||
updateControlStripPresence()
|
updateControlStripPresence()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func resetControlStrip() {
|
@objc func resetControlStrip() {
|
||||||
dismissTouchBar()
|
dismissTouchBar()
|
||||||
presentTouchBar()
|
updateActiveApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
func touchBar(_: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
|
func touchBar(_: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ class VolumeViewController: NSCustomTouchBarItem {
|
|||||||
super.init(identifier: identifier)
|
super.init(identifier: identifier)
|
||||||
|
|
||||||
var forPropertyAddress = AudioObjectPropertyAddress(
|
var forPropertyAddress = AudioObjectPropertyAddress(
|
||||||
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
|
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMainVolume,
|
||||||
mScope: kAudioDevicePropertyScopeOutput,
|
mScope: kAudioDevicePropertyScopeOutput,
|
||||||
mElement: kAudioObjectPropertyElementMaster
|
mElement: kAudioObjectPropertyElementMaster
|
||||||
)
|
)
|
||||||
@ -66,7 +66,7 @@ class VolumeViewController: NSCustomTouchBarItem {
|
|||||||
var volume: Float32 = 0.5
|
var volume: Float32 = 0.5
|
||||||
var size: UInt32 = UInt32(MemoryLayout.size(ofValue: volume))
|
var size: UInt32 = UInt32(MemoryLayout.size(ofValue: volume))
|
||||||
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
|
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
|
||||||
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMasterVolume)
|
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMainVolume)
|
||||||
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
|
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
|
||||||
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
|
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
|
||||||
AudioObjectGetPropertyData(defaultDeviceID, &address, 0, nil, &size, &volume)
|
AudioObjectGetPropertyData(defaultDeviceID, &address, 0, nil, &size, &volume)
|
||||||
@ -86,7 +86,7 @@ class VolumeViewController: NSCustomTouchBarItem {
|
|||||||
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
|
var address: AudioObjectPropertyAddress = AudioObjectPropertyAddress()
|
||||||
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
|
address.mScope = AudioObjectPropertyScope(kAudioDevicePropertyScopeOutput)
|
||||||
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
|
address.mElement = AudioObjectPropertyElement(kAudioObjectPropertyElementMaster)
|
||||||
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMasterVolume)
|
address.mSelector = AudioObjectPropertySelector(kAudioHardwareServiceDeviceProperty_VirtualMainVolume)
|
||||||
return AudioObjectSetPropertyData(defaultDeviceID, &address, 0, nil, size, &inputVolume)
|
return AudioObjectSetPropertyData(defaultDeviceID, &address, 0, nil, size, &inputVolume)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
README.md
37
README.md
@ -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`
|
- 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
|
- [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">
|
<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">
|
<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
|
## Customization
|
||||||
|
|
||||||
MTMR preferences are stored under `~/Library/Application\ Support/MTMR/items.json`.
|
MTMR preferences are stored in `~/Library/Application\ Support/MTMR/items.json`.
|
||||||
|
|
||||||
The pre-installed configuration contains less or more than you'll probably want, try to configure:
|
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: appleScriptTitledButton can change its icon. To do it, you need to do the following things:
|
> Note: You can change appleScriptTitledButton's icon by following these steps:
|
||||||
1. Declare dictionary of icons in `alternativeImages` field
|
1. Declare dictionary of icons in `alternativeImages` field
|
||||||
2. Make you script return array of two values - `{"TITLE", "IMAGE_LABEL"}`
|
2. Make you script return array of two values - `{"TITLE", "IMAGE_LABEL"}`
|
||||||
3. Make sure that your `IMAGE_LABEL` is declared in `alternativeImages` field
|
3. Make sure that your `IMAGE_LABEL` is declared in `alternativeImages` field
|
||||||
@ -187,10 +187,10 @@ Example:
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### `shellScriptTitledButton`
|
#### `shellScriptTitledButton`
|
||||||
> Note: script may return also colors using escape sequences (read more here https://misc.flogisoft.com/bash/tip_colors_and_formatting)
|
> Note: script may also use escape sequences to return colors (read https://misc.flogisoft.com/bash/tip_colors_and_formatting for more information)
|
||||||
> Only "16 Colors" mode supported atm. If background color returned, button will pick it up as own background color.
|
> "16 Colors" is the only mode supported presently. Buttons will set their own background color to the color returned.
|
||||||
|
|
||||||
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):
|
Example of "CPU load" button which also changes color based on load value (Note: The native `cpu` plugin runs runs better):
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
"type": "shellScriptTitledButton",
|
"type": "shellScriptTitledButton",
|
||||||
@ -249,8 +249,8 @@ To close a group, use the button:
|
|||||||
|
|
||||||
#### `cpu`
|
#### `cpu`
|
||||||
|
|
||||||
> Shows current CPU load in percents, changes color based on load value.
|
> Shows current CPU load in percent, changes color based on load value.
|
||||||
> Has lower power consumption and more stable in comparison to shell-based solution.
|
> Has lower power consumption and higher stability than the shell-based solution.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
@ -262,7 +262,7 @@ To close a group, use the button:
|
|||||||
|
|
||||||
#### `timeButton`
|
#### `timeButton`
|
||||||
|
|
||||||
> Attention! Works not all: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
|
> NOTE: Some values don't work properly: https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
|
||||||
|
|
||||||
> formatTemplate examples: https://www.datetimeformatter.com/how-to-format-date-time-in-swift/
|
> 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`
|
#### `weather`
|
||||||
|
|
||||||
> Provider: https://openweathermap.org \
|
> Provider: https://openweathermap.org \
|
||||||
> Note: you need to register on https://openweathermap.org to get your API key \
|
> Note: Register at 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: Wait for 20 minutes or so for Openweathermap to activate your API key.\
|
||||||
> Note: you need to allow using "Location Services" in your Mac OS "Security & Privacy" settings for MTMR
|
> Note: Enable MTMR in "Location Services" in the "Security & Privacy" System Preferences pane
|
||||||
|
|
||||||
```js
|
```js
|
||||||
"type": "weather",
|
"type": "weather",
|
||||||
@ -295,7 +295,7 @@ To close a group, use the button:
|
|||||||
#### `yandexWeather` (experimental)
|
#### `yandexWeather` (experimental)
|
||||||
|
|
||||||
> Provider: https://yandex.ru/pogoda. One click to open up weather forecast in your browser. \
|
> Provider: https://yandex.ru/pogoda. One click to open up weather forecast in your browser. \
|
||||||
> Note: you need to allow using "Location Services" in your Mac OS "Security & Privacy" settings for MTMR
|
> Note: Enable MTMR in "Location Services" in the "Security & Privacy" System Preferences pane
|
||||||
|
|
||||||
```js
|
```js
|
||||||
"type": "yandexWeather",
|
"type": "yandexWeather",
|
||||||
@ -330,7 +330,7 @@ To close a group, use the button:
|
|||||||
|
|
||||||
#### `pomodoro`
|
#### `pomodoro`
|
||||||
|
|
||||||
> Pomodoro plugin. One click to start the work timer, longclick to start the rest timer. Click in progress for reset.
|
> Pomodoro plugin. One tap starts the work timer, long-press to start the rest timer. Tap an in-progress timer to reset.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
@ -342,7 +342,7 @@ To close a group, use the button:
|
|||||||
|
|
||||||
#### `network`
|
#### `network`
|
||||||
|
|
||||||
> Network plugin. The plugin to show usage a network
|
> Network plugin. The plugin to show network usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
@ -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
|
## Troubleshooting
|
||||||
|
|
||||||
#### If you can't open preferences:
|
#### If you can't open preferences:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user