0

System

M1 MacBook Pro

MacOS Big Sur

Problem

I like the default Mac touchbar layout for everyday use, but I prefer the F1-F12 keys at my fingertips when programming. I also don't like holding down the fn key. That's why I wrote two AppleScripts to switch the layouts (included below).

The scripts work, but they are buggy. This is because they rely on opening the System Preferences app and navigating through the menus. I made a couple "apps" with Automator that simply run the scripts and then assigned them to keyboard shortcuts.

This is an ok solution, but I'd like to do something more elegant. Ideally, my script should run behind the scenes and instantly change the touchbar layout instead of opening System Preferences, selecting items from drop-down-lists, and then finally closing System Preferences.

I messed around with the shell for quite awhile with no success before resorting to using Automator. Any suggestions from those who are more savvy with sort of thing?

Code

This one makes the F1-F12 keys the default touchbar layout:

tell application "System Preferences"
    set the current pane to pane id "com.apple.preference.keyboard"
    delay 0.25
    reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell

tell application "System Events"
    tell process "System Preferences"
        click pop up button 2 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click menu item "F1, F2, etc. Keys" of menu 1 of pop up button 2 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click pop up button 4 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click menu item "Show App Controls" of menu 1 of pop up button 4 of tab group 1 of window "Keyboard"
    end tell
end tell

quit application "System Preferences"

And this one does the reverse (makes app controls the default touchbar layout):

tell application "System Preferences"
    set the current pane to pane id "com.apple.preference.keyboard"
    delay 0.25
    reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell


tell application "System Events"
    tell process "System Preferences"
        click pop up button 2 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click menu item "App Controls" of menu 1 of pop up button 2 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click pop up button 4 of tab group 1 of window "Keyboard"
    end tell
end tell

tell application "System Events"
    tell process "System Preferences"
        click menu item "Show F1, F2, etc. Keys" of menu 1 of pop up button 4 of tab group 1 of window "Keyboard"
    end tell
end tell

quit application "System Preferences"
  • In **macOS Catalina** if I change the setting for **Touch Bar shows** it automatically toggles the setting for **Press Fn key to**, does it not do that in **macOS Big Sur**, do you have to set each one individually? – user3439894 Sep 25 '21 at 06:05
  • @user3439894 Yes, Big Sur has the same behavior. That's just my programming style - explicit and verbose. – Johnny Rocketfingers Sep 25 '21 at 06:24
  • RE: "That's just my programming style - explicit and verbose." -- Have a look at this _example_ **AppleScript** _code_ as it does the same thing as both your script combined to toggle the target setting: [https://paste.ee/p/qeMFk](https://paste.ee/p/qeMFk). I tested it under **macOS Catalina** and it works without the need to be so verbose. – user3439894 Sep 25 '21 at 06:34
  • @user3439894 Yes, that does the trick. I remember now, I wrote it that way as a placeholder, since I was trying out different combinations of settings. I was considering using more than two different layouts, each of which would have its own dedicated keyboard shortcut. This is also why I wrote two separate scripts instead of one with conditional logic. These were my first-ever AppleScripts, and I never got around to refining them until now. Regardless, I think your shell script is the cleanest solution of all. – Johnny Rocketfingers Sep 25 '21 at 06:57
  • Yes absolutely the _shell script_ is the way to go. I was just trying to point out what is considered a poor coding practice in the coding style exhibited in your question. – user3439894 Sep 25 '21 at 07:06

1 Answers1

2

On macOS Catalina when toggling the target setting it changes the value of the PresentationModeGlobal key in ~/Library/Preferences/com.apple.touchbar.agent.plist from appWithControlStrip to functionKeys or vise versa for those two choices. However, toggling it programmatically using the defaults command while it changes it in the UI it does not change it on the Touch Bar without also restarting the ControlStrip process.

The following example shell script code is what I use with a single keyboard shortcut to toggle between between Show App Controls and F1, F2, etc. Keys as that is what they are set to respectively in System Preferences > Keyboard > Keyboard on my system.

Example shell script code:

#!/bin/zsh

pmg="$(defaults read com.apple.touchbar.agent 'PresentationModeGlobal')"

if [[ $pmg == "appWithControlStrip" ]]; then
    defaults write com.apple.touchbar.agent 'PresentationModeGlobal' 'functionKeys'
    killall "ControlStrip"
else
    defaults write com.apple.touchbar.agent 'PresentationModeGlobal' 'appWithControlStrip'
    killall 'ControlStrip'
fi

Notes:

Other versions of macOS may require additional settings to be changed and or additional processes to be restarted, e.g., pkill 'Touch Bar agent' if applicable.

In Terminal you can use the read verb of the defaults command to examine changes to com.apple.touchbar.agent.plist as you make them in the UI to see if the value for additional keys needs to be changed too.




Side Note

As to your AppleScript code, here is how I'd do it based on your code as a single script to toggle between the two choices.

You didn't say what version of macOS are you running and since I do not have a pop up button 4 I cannot test the example AppleScript code shown below, however, this should eliminate having two separate scripts and it just toggles between the two with a single keyboard shortcut.

Example AppleScript code:

tell application "System Preferences"
    set the current pane to pane id "com.apple.preference.keyboard"
    delay 0.25
    reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell

tell application "System Events"
    tell tab group 1 of window 1 of process "System Preferences"
        if value of pop up button 2 is "Show App Controls" then
            click pop up button 2
            click menu item "F1, F2, etc. Keys" of menu 1 of pop up button 2
            click pop up button 4
            click menu item "Show App Controls" of menu 1 of pop up button 4
        else
            click pop up button 2
            click menu item "Show App Controls" of menu 1 of pop up button 2
            click pop up button 4
            click menu item "F1, F2, etc. Keys" of menu 1 of pop up button 4
        end if
    end tell
end tell

quit application "System Preferences"


Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.

user3439894
  • 7,266
  • 3
  • 17
  • 28
  • Thank you for your thorough and thoughtful answer. I will definitely make use of the shell script. My quick and dirty script also looks better with the logic you added. How did you assign it to a keyboard shortcut? Did you use Automator for that, or is there a simpler method? Also, how did you get AppleScript syntax highlighting in your Markdown? I tried \`\`\`applescript with no luck, and couldn't seem to find the correct keyword. – Johnny Rocketfingers Sep 25 '21 at 05:02
  • 1
    @Johnny Rocketfingers, While it can be done with an **Automator** _Service/Quick Action_ and a _keyboard shortcut_ in **System Preferences** > **Keyboard** > **Shortcuts** > **Services**, nonetheless, I prefer to use [**Hammerspoon**](https://www.hammerspoon.org) for some of my _global keyboard shortcuts_ and I did for this one. I also use [**FastScripts**](https://redsweater.com/fastscripts/) for some as well. I use `` because I use indented _code_ not the \`\`\` method, however you can use: ```lang-applescript – user3439894 Sep 25 '21 at 05:20
  • 1
    @Johnny Rocketfingers, In my `~/.hammerspoon/init.lua` _file_ for **Hammerspoon** I have this set for **⌘F6** to trigger the _shell script_. _Example_ **Lua** _code_: [https://paste.ee/p/aUY0Z](https://paste.ee/p/aUY0Z) – user3439894 Sep 25 '21 at 05:34