Toxblh / MTMR

🌟 [My TouchBar My rules]. The Touch Bar Customisation App for your MacBook Pro
https://mtmr.app
MIT License
4.22k stars 220 forks source link
applescript bar custom-touchbar customization customization-app dock macbook macos statusbar touch touch-bar-customization touch-bar-customization-app touchbar

My touchbar. My rules. GitHub release license minimal system requirements travis

<img src="Resources/logo.png" align="right" title="MTMR by Toxblh" width="110" height="110">

The TouchBar Customization App for your MacBook Pro

My idea is to create a platform for creating plugins to customize the TouchBar. I very much like BTT and having a full custom TouchBar (my BTT preset), and I wanted to create it. It's my first Swift project for MacOS :)

Share your presets here

Mackbook with touchbar

Discord Telegram

PayPal donate button Buy Me A Coffee My TouchBar My Rules (MTMR)

Installation

On first install you need to allow access for MTMR in Accessibility otherwise buttons like Esc, Volume, Brightness and other system keys won't work.

screenshot 2019-02-24 at 23 19 20

πŸβ†’ System Preferences β†’ Security and Privacy β†’ tab Privacy β†’ Accessibility β†’ MTMR

Examples

MTMR presets

Presets for touchbar

Customization

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:

Built-in button types:

Buttons

Native Plugins

Media Keys

AppleScript plugins

Custom buttons

Gestures

By default you can enable basic gestures from application menu (status bar -> MTMR icon -> Volume/Brightness gestures):

Custom gestures

You can add custom actions for two/three/four finger swipes. To do it, you need to use swipe type:

    "type": "swipe",
    "fingers": 2,            // number of fingers required (2,3 or 4)
    "direction": "right",    // direction of swipe (right/left)
    "minOffset": 10,          // optional: minimal required offset for gesture to emit event
    "sourceApple": {         // optional: apple script to run
        "inline": "beep"
    },
    "sourceBash": {          // optional: bash script to run
        "inline": "touch /Users/lobster/test"
    }

You may create as many swipe objects in the preset as you want.

Built-in slider types:

You can also make custom buttons using these types

staticButton

 "type": "staticButton",
 "title": "esc",

appleScriptTitledButton

  {
    "type": "appleScriptTitledButton",
    "refreshInterval": 60, //optional
    "source": {
      "filePath": "~/Library/Application Support/MTMR/iTunes.nowPlaying.scpt",
      // or
      "inline": "tell application \"Finder\"\rif not (exists window 1) then\rmake new Finder window\rset target of front window to path to home folder as string\rend if\ractivate\rend tell",
      // or
      "base64": "StringInbase64"
    },
  }

Note: You can change appleScriptTitledButton's icon by following these steps:

  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

Example:

  {
    "type": "appleScriptTitledButton",
    "source": {
      "inline": "if (random number from 1 to 2) = 1 then\n\tset val to {\"title\", \"play\"}\nelse\n\tset val to {\"title\", \"pause\"}\nend if\nreturn val"
    },
    "refreshInterval": 1,
    "image": {
      "base64": "iVBORw0KGgoAAAANSUhEUgA..."
    },
    "alternativeImages": {
      "play": {
        "base64": "iVBORw0KGgoAAAANSUhEUgAAAAAA..."
      },
      "pause": {
        "base64": "iVBORw0KGgoAAAANSUhEUgAAAIAA..."
      }
    }
  },

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.

Example of "CPU load" button which also changes color based on load value (Note: The native cpu plugin runs runs better):

{
  "type": "shellScriptTitledButton",
  "width": 80,
  "refreshInterval": 2,
  "source": {
    "inline": "top -l 2 -n 0 -F | egrep -o ' \\d*\\.\\d+% idle' | tail -1 | awk -F% '{p = 100 - $1; if (p > 30) c = \"\\033[33m\"; if (p > 70) c = \"\\033[30;43m\"; printf \"%s%4.1f%%\\n\", c, p}'"
  },
  "actions": [
    {
      "trigger": "singleTap",
      "action": "appleScript",
      "actionAppleScript": {
        "inline": "activate application \"Activity Monitor\"\rtell application \"System Events\"\r\ttell process \"Activity Monitor\"\r\t\ttell radio button \"CPU\" of radio group 1 of group 2 of toolbar 1 of window 1 to perform action \"AXPress\"\r\tend tell\rend tell"
      }
    }
  ],
  "align": "right",
  "image": {
    // Or you can specify a filePath here.
    // Images will be resized to 24x24.
    // "filePath": "~/myproject/myimage.jpg" // or "/fixed/path/to/the.png"
    "base64":
    "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA/1BMVEUAAADaACbYACfYACfjABzXACjYACfXACjYACfYACfYACfYACfdACLYACfXACjYACfVACv/AADXACjYACfYACfXACjYACfXACjaACXYACfYACfVACvYACfYACfZACbZACbYACfYACfZACb/AADYACfYACfVACrXACjVACu/AEDYACfYACfYACfXACjXACjYACfXACjYACfYACfYACfXACjYACfXACjYACfYACfZACbYACfYACfMADPYACfYACfYACfYACfYACfZACbXACjYACfYACfRAC7XACjYACfZACbWACnXACjXACjYACfTACzZACb/AADYACfYACfYACcAAAA+zneGAAAAU3RSTlMAItK+CVPjh3xUxPwPiGDQGAMtSKmN3Vk+wPQG/e26oIJBnwJCdiuAHgTmw+6BX+IgfaqLUvKOW8VKnagK+vBwYrhlc/urCznvhSyUbOEXPAFjGh/ektAAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4ggWETQWgEDcSgAAAqVJREFUWMPtl4ly2jAQhsUNNlcw5r4SICEHLSQhCQRyX73T/u//LpUlLIyxbMAznWmn/0ywo5U+27tr7ZoQuwLBUJidRKIxPhKLRtgxHAoGiLfiQIKdKFCTxjGpQmEDCSC+BiAFpNlJBsgaxyyQYQNpIPUf8AcAOzktD+iaoQJQNI5FoMAGdCCv5XZclpfKFXiqUi5Jllf1mvdyQzW96gigd4h6o+mhRp1O0x3vvwa1VSWeqrZU1Jyeogy01ggSVQsoO/i/gjq9/u6u+2LDXq2jshqLHNCgdsCVwO0NILdi0oDmuoAmoImhQDzFRPNnb36L7U43NVfc2EH2D9h5t9OePyIF5IU9uIhvkyN7iiXmQUIOj8x/lB6f0bTaQ3ZA+9iaNCH2Lpg6btsBIRJOpJl0E9ABTvof5kqEGeCjMaN/AnRMgM5XJcI2J1J1gf6S48Tb2Ae6JkAjdgmAeJ1XAOJ1Xg8wGJ6elXwAzkeGjy62BgxG3MuXnoCIkmEq8EQyAUPgajyhPxJAga9SIiRqzwMOuAbGZDrDjQRgKkpiqiPgFphM74B7d4BKy2cyy1RcBvSodUb/HiSAIl+VlEfh8cm4wvPL9nnw+gbc+kkkUVioO95etwe8PBuP8vQoBzg7UQAe5t7syZwoCaMA3AN30wlzh3MYJYkkADeYTckYuJYlkiSVBeCKZtSY/gxlqezlxEt+pdFg6zBesPXn1ih8Aj5vkAels9PhYCkPsl++kg0AQu4dyuqmugIQm+qS5Nv6N+D7wm7d1skPc4xu666Fhd6BxU6r+jub8tNaWNxK29EhsdpR/sVn7FlLm0txPdgni+JrFNd3p+K67MQtyrsp3w2G7xbHd5Plv83z3Wj6b3V9N9ssFv7afaa//ZPn3wD4/vje8PP/N7TebS0hgZhEAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTIyVDE3OjUyOjIyKzAyOjAwc2qUYAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0yMlQxNzo1MjoyMiswMjowMAI3LNwAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC"
  },
  "bordered": false
}

Groups

{
  "type": "group",
  "align": "center",
  "bordered": true,
  "title": "stats",
  "items": [
    { "type": "play" },
    { "type": "mute" },
    ...
  ]
}

To close a group, use the button:

{
  "type": "close",
  "width": 64
},

Native plugins

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.

{
  "type": "cpu",
  "refreshInterval": 3,
  "width": 80
}

timeButton

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/

locale examples: https://gist.github.com/jacobbubu/1836273

{
  "type": "timeButton",
  "formatTemplate": "dd HH:mm",
  "locale": "en_GB",
  "timeZone": "UTC"
}

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

  "type": "weather",
  "refreshInterval": 600, // in seconds
  "units": "metric", // or imperial
  "icon_type": "text", // or images
  "api_key": "" // you can get the key on openweather

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

  "type": "yandexWeather",
  "refreshInterval": 600 // in seconds

currency

Provider: https://coinbase.com

  "type": "currency",
  "refreshInterval": 600, // in seconds
  "align": "right",
  "from": "BTC",
  "to": "USD",
  "full": true // Β£β€£1.29$

music

{
  "type": "music",
  "align": "center",
  "width": 80, // Optional
  "bordered": false, // Optional
  "refreshInterval": 2, // in seconds. Optional. Default 5 seconds
  "disableMarquee": true // to disable marquee effect. Optional. Default false
},

pomodoro

Pomodoro plugin. One tap starts the work timer, long-press to start the rest timer. Tap an in-progress timer to reset.

{
  "type": "pomodoro",
  "workTime": 1200, // set time work in seconds. Default 1500 (25 min)
  "restTime": 600 // set time rest in seconds. Default 300 (5 min)
},

network

Network plugin. The plugin to show network usage

{
  "type": "network",
  "flip": true,
  "units": "dynamic" // or B/s, KB/s, MB/s, GB/s
},

dock

Dock plugin

{
  "type": "dock",
  "filter": "(^Xcode$)|(Safari)|(.*player)",
  "autoResize": true
},

upnext

Calendar next event plugin Displays upcoming events from macOS Calendar. Does not display current event.

{
  "type": "upnext",
  "from": 0, // Lower bound of search range for next event in hours.        Default 0 (current time)(can be negative to view events in the past)
  "to": 12, // Upper bounds of search range for next event in hours.        Default 12 (12 hours in the future)
  "maxToShow": 3, // Limits the maximum number of events displayed.          Default 3 (the first 3 upcoming events)
  "autoResize": false // If true, widget will expand to display all events. Default false (scrollable view within "width")
},

Actions:

Example:

"actions": [
  {
    "trigger": "singleTap",
    "action": "hidKey",
    "keycode": 53
  }
]

Triggers:

Types

 "action": "hidKey",
 "keycode": 53,
 "action": "keyPress",
 "keycode": 1,
 "action": "appleScript",
 "actionAppleScript": {
      "inline": "tell application \"Finder\"\rif not (exists window 1) then\rmake new Finder window\rset target of front window to path to home folder as string\rend if\ractivate\rend tell",
    // "filePath" or "base64" will work as well
 },
 "action": "shellScript",
 "executablePath": "/usr/bin/pmset",
 "shellArguments": ["sleepnow"], // optional
 "action": "openUrl",
 "url": "https://google.com",

Additional parameters:

  "width": 34
  "align": "left" // "left", "right" or "center"
  "bordered": "false" // "true" or "false"
  "background": "#FF0000",

by using background with color "#000000" and bordered == false you can create button without gray background but with background when the button is pressed

  "title": "hello"
  "image": {
    //Can be either of those
    "base64": "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAABGdB...."
    //or
    "filePath": "~/img.png"
  }
  "matchAppId": "Safari"

Troubleshooting

If you can't open preferences:

Buttons or gestures doesn't work:

Re-tick or check a tick for access πŸβ†’ System Preferences β†’ Security and Privacy β†’ tab Privacy β†’ Accessibility β†’ MTMR

Credits

Built by @Toxblh and @ReDetection.

Analytics