10

I can choose in Syst Prefs to have the menubar show always or hide with auto-show (auto-show being show on hover or show on focus-by-keyboard-shortcut).

But when I'm working, I want the menubar always visible. And when I'm recreating, I want it usually hidden.

I like that with the dock I can hit commandoptiond to show or hide the dock, and it stays shown or hidden until I press the same shortcut again.

I wish the menubar worked this way too. Can such a shortcut be created somehow?

1
  • 1
    Just an FYI, I downloaded and tested FastScripts under macOS 10.12.3 with my code as a .scpt and gave it a keyboard shortcut of ⌃⌘M and it works great! Much better then as an Automator Service and System Preferences key binding. Commented May 17, 2017 at 2:06

7 Answers 7

3

You asked, "Can a shortcut be created to toggle menubar visibility (that would persist, as the dock's does)?" and the short answer is, yes.

However, the longer answer is, while it's technically and natively possible to create an Automator Service workflow that gets assigned a keyboard shortcut to hide/unhide the Menu bar in OS X 10.11 and later, including the current macOS, it's not without its issues.

  • You'd have to assign the Automator Service a keyboard shortcut that does not interfere with an existing shortcut in every app that might have focus when you triggered the service's keyboard shortcut.
  • Every app that has focus when the service's keyboard shortcut is triggered would have to be added to System Preferences > Security & Privacy > Privacy > Accessibility, in order for the service's keyboard shortcut to work.

A possible workaround to the second point above would be if there's a third-party app that can be globally set to trigger the Automator Service work flow (or the AppleScript code as an AppleScript script or app not using an Automator Service). This might include apps like Alfred, FastScripts, Karabiner, Karabiner-Elements, Keyboard Maestro, etc., and having not tested these third party apps under this particular scenario I can only offer that as something to look into.

So, how about an AppleScript app you could place in the Dock, so it's readily available to click on, that will toggle the state of the Menu bar? You'd only have to add that AppleScript app to System Preferences > Security & Privacy > Privacy > Accessibility, in order for it to work.

In lieu of a third-party app or as an Automator Service and just as a plain AppleScript app, you do have a keyboard shortcut built in by way of Spotlight, in that you press space and the first character or two of the name you gave to the AppleScript app and then press enter. As an example, name it tmb.app for toggle menu bar, the you'd press spacetmenter to trigger the AppleScript App. After all, I double you already have an app named tm installed.

However, that said, it too is not without possible issues in that it relies on UI Scripting, meaning, it has to open System Preferences to the General settings and click the "Automatically hide and show the menu bar" checkbox and close System Preferences. This means once you triggered the app, you have to let it run and not manually steal focus from System Preferences while the UI Scripting events take place. In other words, you have to stop multitasking for a couple of seconds.

In part, one of the issues using AppleScript and or UI Scripting to hide/unhide the Menu bar is it's just not as graceful as hiding the Dock with its built-in keyboard shortcut, but it's at least doable.

That all said, here's the AppleScript code, that can be used in either an AppleScript script/app, Automator Service, or possibly a third party app, that will toggle the state of the Menu bar in OS X 10.11 and later via UI Scripting.


tell application "System Preferences"
    reveal pane id "com.apple.preference.general"
    delay 1
    tell application "System Events"
        click checkbox "Automatically hide and show the menu bar" of window "General" of process "System Preferences"
    end tell
    quit
end tell

Note there is no error checking to ensure this code in run under OS X 10.11 and later so don't try using it in versions of OS X prior to 10.11. Also note that the value of the delay command may need to be adjusted as necessary under the working conditions of your system.

9
  • @jaepage, How about if you don't see the System Preferences window? In other words, it opens off screen, checks/un-checks the checkbox and closes? Then the state of the Menu bar is toggled, but you don't have to watch the UI events take place. That is other then if System Preferences is in the Dock it will bounce once and the dot will be under its icon until is closes. Commented May 15, 2017 at 19:58
  • @user3439894 you deserve the credit for the accepted answer. Is there any way I can post my revision as just a comment to your answer?
    – wch1zpink
    Commented May 15, 2017 at 20:05
  • @jaepage, I updated the code to hide System Preferences windows while making the change to hide/show the Menu bar. I replaced activate for set bounds of window 1 to {0, 0, 0, 0} and so you do not see the System Preferences window but it makes the change. You actually could just leave both those out and you should't see the UI. Commented May 15, 2017 at 20:22
  • @jaepage, I named the app tmb.app for testing and after searching for it once in Spotlight by tmb then subsequent searches for just tm show tmb before Time Machine. That said, you could name it something else that wouldn't near match anything else. I just suggested tmb as it makes it easy to remember for Toggle Menu Bar, which the full name like that wouldn't bring up Time Machine but to might catch on other things too. You'll have to figure what naming convention works best for you to only have to type one or two characters after ⌘space. Commented May 17, 2017 at 1:06
  • @jaepage, I do not recommend using Automator and binding it to a shortcut key sequence in System Preferences for reasons I explained in my answer and also because it's not reliable. This is why I suggested third-party apps to trigger or use just the AppleScript app method in the Dock and or from Spotlight as the AppleScript app it all that has to be authorized and that method has never failed me! Commented May 17, 2017 at 1:29
3
  1. Made an app with Automator using this AppleScript code by "@user3439894". You can try setting the delay to 0.1 which worked for me.
    tell application "System Preferences"
        reveal pane id "com.apple.preference.general"
        delay 1
        tell application "System Events"
            click checkbox "Automatically hide and show the menu bar" of window "General" of process "System Preferences"
        end tell
        quit
    end tell
  1. Made a keyboard shortcut for the app and mapped it to cmd-ctrl-9 Works great.

Instructions here: https://appleinsider.com/articles/18/03/14/how-to-create-keyboard-shortcuts-to-launch-apps-in-macos-using-automator

1
  • 1
    Answers on Ask Different need to be self contained, since if your link goes down, your answer will be useless. Paraphrasing the source and including any relevant information in the answer will ensure it stays relevant
    – nohillside
    Commented Mar 16, 2019 at 14:10
1

Making some minor adjustments to the original code from user3439894’s answer. Running this revised code will not bring system preferences app to the front.

tell application "System Preferences"
    reveal pane id "com.apple.preference.general"
end tell
tell application "System Events" to tell process "System Preferences" to tell window "General"
    click checkbox "Automatically hide and show the menu bar" 
end tell
delay 1
quit application "System Preferences"

In some comments to my answer, it has been pointed out where I have the delay command in my script, makes the script fail. On my system this script works.

enter image description here

However this script on my system will not work if I put the delay command before the system event.

enter image description here

6
  • @jaepage, wch1zpink's code will fail at times because of where he placed the delay! In this case, there has to be a delay before System Events click the checkbox, so as to allow the element to be available to act upon, and doesn't need to be there before quit especially when nested as how mine is written. Commented May 17, 2017 at 1:22
  • @user3439894 I deemed it necessary to put the delay before the quit command because on my system, for some reason, System preferences kept quitting before the checkbox got selected in the previous command
    – wch1zpink
    Commented May 17, 2017 at 1:59
  • Your code without the delay before the System Events call will fail if the checkbox isn't yet available to be clicked and does constantly fail on my system without the delay as in my code. This is a part of why UI Scripting is not the preferred way to go! I only use UI Scripting if I have no other choice. Commented May 17, 2017 at 2:02
  • @user3439894 Please look at the edits I've made to my original answer. Do you have any insight as to why my version of the script works for me and not for you? I'm using operating system Sierra.
    – wch1zpink
    Commented May 17, 2017 at 2:35
  • Let me try to clarify things... There is nothing wrong with having the delay where you have it, however while your code, as written, fails on my system, and not yours is why some UI Scripting isn't always reliable on each individual system. Purely from a programatic standpoint, the checkbox has to be available before it can be acted upon, for the same reason you can't close the app before it's acted upon and why a delay is actually appropriate anywhere as needed (or wanted for some reasons) and may need different values depending on the individual system and its overall usage. Commented May 17, 2017 at 2:48
1

I'm posting this as a second answer instead of editing my original answer as this new version of the example AppleScript code accommodates issues raised with the use of the delay command and where it was placed in the code presented by wch1zpink and myself between our versions of the code.

The new code wraps a much smaller value for the delay command in a repeat loop, thus making the over all code run faster while accommodating the timing differential based on the system specifications of the computer it's been run on. Additionally, because of the use of UI Scripting, the two repeat loops ensures that the UI Elements are available and or have been changed respectively before proceeding within the code.

This code was tested under macOS High Sierra and worked as an AppleScript application, Automator service, as described in my original answer, and as an AppleScript .scpt file triggered by FastScripts with an assigned keyboard shortcut, as with the Automator service.

Example AppleScript code:

if running of application "System Preferences" then
    try
        tell application "System Preferences" to quit
    on error
        do shell script "killall 'System Preferences'"
    end try
end if

repeat while running of application "System Preferences" is true
    delay 0.01
end repeat

tell application "System Preferences" to ¬
    reveal pane id "com.apple.preference.general"

tell application "System Events"

    repeat until exists checkbox ¬
        "Automatically hide and show the menu bar" of ¬
        window "General" of process "System Preferences"
        delay 0.01
    end repeat

    set cbVal to value of checkbox ¬
        "Automatically hide and show the menu bar" of ¬
        window "General" of process "System Preferences"

    click checkbox "Automatically hide and show the menu bar" of ¬
        window "General" of process "System Preferences"

    repeat until cbVal is not (value of checkbox ¬
        "Automatically hide and show the menu bar" of ¬
        window "General" of process "System Preferences")
        delay 0.01
    end repeat

end tell

tell application "System Preferences" to quit

    Scroll as necessary to view full code.

 


Note: The example AppleScript code is just that and, other then included error handling, does not contain any additional error handling as may be appropriate. The onus is upon the used 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.

Also note that I am not affiliated with Red Sweater Software, the developer of FastScripts, just a satisfied user of their product.

1

There are 2 Apple Scripts

To show the menu bar:

tell application "System Events"
    tell dock preferences
       set autohide menu bar to false
    end tell
end tell

To hide the menu bar:

tell application "System Events"
    tell dock preferences
       set autohide menu bar to true
    end tell
end tell

Save them as quick actions in Automator and assign the hot keys. Here is the guide how to do it.

  1. Open the Automator app on your Mac.
  2. Click "New Document" and select "Quick Action" from the list of templates.
  3. In the "Workflow receives current" dropdown, select "no input" and "any application".
  4. In the search bar, type "Run AppleScript" and drag the "Run AppleScript" action to the right side of the window.
  5. Paste your AppleScript code into the "Run AppleScript" action.
  6. Save the workflow with a name that describes what it does.
  7. Open "System Preferences" and click "Keyboard".
  8. Click "Shortcuts" and then "Services" in the left sidebar.
  9. Scroll down to the "General" section and find your saved Automator workflow.
  10. Click the "Add Shortcut" button next to your workflow and press the keys that you want to use as the hotkey.
  11. Once you have assigned a hotkey to your Automator workflow, you can use that hotkey to run your custom AppleScript application from anywhere on your Mac.

The specific steps and options may vary depending on the version of macOS you are running.

There is no other way to access the dock preferences settings without using the System Events application. This is because the dock preferences settings are a part of the system settings, and can only be accessed through the System Events application.

Here are some additional scripts:

The script to hide the dock together with the menu bar:

tell application "System Events"
  tell dock preferences
    set autohide menu bar to true
    set dockAutohide to get autohide
    set autohide to true
  end tell
end tell

The script to show the dock together with the menu bar:

tell application "System Events"
  tell dock preferences
    set autohide menu bar to false
    set dockAutohide to get autohide
    set autohide to false
  end tell
end tell

I combined the scripts, so this script will change the state of the menu bar - if it is hidden, then shown, or otherwise. It can be used with a single hot key.

tell application "System Events"
    tell dock preferences
        set currentStatus to autohide menu bar
        set autohide menu bar to not currentStatus
    end tell
end tell

And the following script will show or hide both menu bar and the dock - it can be used with a single hot key.

tell application "System Events"
 tell dock preferences
    set currentStatus to get autohide menu bar
    if currentStatus then
        set autohide menu bar to false
        set dockAutohide to get autohide
        set autohide to false
    else
        set autohide menu bar to true
        set dockAutohide to get autohide
        set autohide to true
    end if
  end tell
end tell
0

I have made some changes to the previous scripts so that it works in 2022 as the location of the checkbox appears to have changed with the MacOS update. For anyone who wants to put the script to use, you can do so via the shortcut app by clicking the '+' icon and typing in "run AppleScript". This way, you can have the shortcut appear in the menu bar. You can also create a service with the Automator.app and define a keyboard shortcut for the service in system preferences.

tell application "System Preferences"
    reveal pane id "com.apple.preference.dock"
    delay 1
    tell application "System Events"
        click checkbox "Automatically hide and show the menu bar in full screen" of window "Dock & Menu Bar" of process "System Preferences"
    end tell
    delay 1
    quit
end tell
0

They moved the show / hide menu bar option to a pull down menu in Sonoma (10.14.2). This Shortcut (using embedded script) toggles between "always show" / "hide on full screen only" which are the two modes that I use:

on run {input, parameters}
## This script toggles the hide menu item setting from "Never" to "In Full Screen Only"
## Used the great UI Browser https://pfiddlesoft.com/ app (now no longer operational) to write
## confirmed to work for MacOS 14.2.1, but they are changing the control center layout quickly
## Archon Fung on December 22, 2023

##open the system settings app in background
do shell script "open -j x-apple.systempreferences:com.apple.ControlCenter-Settings.extension"

tell application "System Events"
    
    tell application process "System Settings"
        ## set CurrentShowStr to "Never"
        ##get value of pop up button 1 of group 9 of scroll area 1 of group 1 of group 2 of splitter group 1 of group 1 of window "Control Center"
        delay 1
        set CurrentShowStr to value of pop up button 1 of group 9 of scroll area 1 of group 1 of group 2 of splitter group 1 of group 1 of window "Control Center"
        if (CurrentShowStr is "Never") then
            set NewShowStr to "In Full Screen Only" ##In Full Screen Only 
        else
            set NewShowStr to "Never" ##Never
        end if
        tell pop up button 1 of group 9 of scroll area 1 of group 1 of group 2 of splitter group 1 of group 1 of window "Control Center"
            click
            ##need delays to allow the menu items to populate
            delay 0.5
            click menu item NewShowStr of menu 1
            delay 0.5
        end tell
    end tell
end tell
quit application "System Settings"
return input
end run

You must log in to answer this question.