118

Pretty much every application I use in full-screen (including Firefox, MacVim and the Terminal) have tabs on the top of the screen.

The problem is that when I move my mouse to reach the tabs I'll often accidentally touch the top of the screen, bringing in the OS menu OVER the tabs:

Illustration - moving mouse to top of screen in fullscreen apps makes menu bar appear

Is there any way to change this behavior? I'd prefer it if the menu bar would stay hidden when I'm using a full-screen app, even if my mouse does touch the top of the screen.

16
  • 9
    Yeah, this is really annoying. I wish there where a defaults write variable one could edit. But so far I've not heard about anything like that. It is especially annoying when using a VM in full screen. Ubuntu has the menubar at the top and I like it that way. But I'm constantly triggering the OSX menu bar to appear. :(
    – gentmatt
    Nov 8, 2012 at 15:25
  • 5
    Ok further info: what 'PresentYourApps' does is basically set the LSUIPresentationMode or 'Application UI Presentation Mode' value in the Info.plist for the app in question: documentation here and a guide at Lifehacker here. Instead of '4', use numeric value '3' for 'All hidden' mode, which is what my above comment's steps do in that easier GUI - but again, 'All hidden' annoyingly disables ALL access to the menu bar when in that app, while 'All suppressed' DOES hide the menu but the mouse invokes it when hit top of the screen, which we don't want.
    – user46942
    May 10, 2014 at 9:57
  • 9
    if only we could specify a bigger delay... this is really annoying Mar 10, 2017 at 17:15
  • 2
    As a workaround solution, someone could write an app that makes a "wall" to prevent the mouse from ever hitting the top row of pixels on the screen (unless a key is held to "release" the mouse.). Something like this would be an acceptable first step and the reason for my bounty.
    – cloneman
    Jan 29, 2018 at 14:13
  • 2
    I spent so long trying to find a way to force menu bar to stay hidden, I can't stand this behaviour at all.
    – Avamander
    Jul 10, 2022 at 15:35

9 Answers 9

6

Inspired by the answer of @Alpine with Hammerspoon, I extended the script so that the menu bar will not be completely hidden and will drop if you place your mouse at the top of the screen for a while. I also make sure this only applys to the fullscreen window.

block = true

mouseEventTap = hs.eventtap.new({hs.eventtap.event.types.mouseMoved}, function(event)
    local rel = hs.mouse.getRelativePosition()
    -- the 5 pixel menu bar threshold, adjust it for different screens
    local th = 5
    if(hs.window.focusedWindow():isFullScreen()) then
        if(rel.y < th and block) then
            hs.mouse.setRelativePosition(hs.geometry.point(rel.x, th + 1))
            -- set a timer to check mouse position after 0.5 seconds; if it's still at the top, set block to false
            -- I found th + 10 works more smoothly for me; adjust it for yourself
            blockTimer = hs.timer.doAfter(0.5, function()
                block = hs.mouse.getRelativePosition().y > th + 10
            end)
            return true
        end
    end
end)
mouseEventTap:start()


mouseEventTap2 = hs.eventtap.new({hs.eventtap.event.types.mouseMoved}, function(event)
    local rel = hs.mouse.getRelativePosition()
    local th = 5
    if(hs.window.focusedWindow():isFullScreen()) then
        -- set block back to true when the mouse returns from the menu bar
        -- use th + 20 so that the mouse will not be easily blocked when moving around in the menu, adjust it for yourself
        if(rel.y > th + 20 and block == false) then
            block = true
            return true
        end
    end
end)
mouseEventTap2:start()

This script allows the menu bar to drop with 0.5s delay. You can adjust the number yourself. Put the code in ~/.hammerspoon/init.lua, and load the configuration.

There are some disadvantages. For example,when moving your mouse on a long drop down menu from the menu bar (like the one in the image), you'll also experience the 0.5 second blocking.

Like this

1
  • This is the game changer, I can't explain the frustration I had because of that annoying title-bar/menu bar in full screen mode. Thank you very much. This solves everything. For my liking, I've set the pixel wall to be at 15, and the delay to be of 1 second. Aug 19, 2023 at 7:07
19
+250
  • Save the following AppleScript to a file named fullscreen.scpt:

    use framework "AppKit"
    use scripting additions
    
    repeat with runningApp in current application's NSWorkspace's sharedWorkspace's runningApplications()
        if runningApp's isActive()
            set frontApp to (localizedName of runningApp) as text
            exit repeat
        end if
    end repeat
    
    tell application "System Events"
        tell process frontApp to set isFullScreen to value of attribute "AXFullScreen" of first window
        if frontApp = "Finder"
            tell process frontApp to set value of attribute "AXFullScreen" of first window to not isFullScreen
        else if isFullScreen
            do shell script "lsappinfo setinfo -app " & quoted form of frontApp & " ApplicationType=Foreground"
            tell process frontApp to set value of attribute "AXFullScreen" of first window to false
    
            (*fix to make sure the menu bar is not stuck*)
            delay 0.42
            tell application "Finder" to activate
            tell process frontApp to set frontmost to true
        else
            do shell script "lsappinfo setinfo -app " & quoted form of frontApp & " ApplicationType=UIElement"
            tell process frontApp to set value of attribute "AXFullScreen" of first window to true
        end if
    end tell
    
  • From terminal, compile it to an application with the following command:

    osacompile -o "/Applications/Full Screen.app" fullscreen.scpt
    
  • Open the Full Screen.app's Info.plist (e.g. vim '/Applications/Full Screen.app/Contents/Info.plist') and add the following to the dict:

        <key>NSUIElement</key>
        <true/>
    
  • Add Full Screen.app as an exception in System Preferences > Security & Privacy > Privacy > Accessibility.

  • Launch Automator and create a new Service.

  • Change "Service receives" to "no input in any application".
  • Add a Library > Utilities > Launch Application action.
  • Configure the action to launch the previously created Full Screen application.
  • Save the service as Full Screen and close Automator.
  • On System Preferences > Keyboard > Shortcuts > Services, scroll down to the bottom of the list and the just created Full Screen service should be listed there. Associate an unique Command shortcut for it, like Shift+Command+\ or Command+F11 for example.

This creates a shortcut to cause an application to enter full screen while removing the menu bar, or to exit full screen bringing the menu bar back. It provides an alternative full screen shortcut!

For application-specific full screen launchers, check my other answer.

Caveats

There may be some disadvantages and/or misbehavior using this approach:

  • It works by setting ApplicationType=UIElement, which causes the application icon not be added/highlighted in the Dock and make the application inaccessible via Command+Tab. The Command+Tab issue was reported in comments, I didn't notice it since I mostly use the Mission Control overview to change between full screen applications.
  • It may not behave as expected for some specific applications, I've noticed issues with the Activity Monitor application (which is generally not used full screen anyway) and there's a report on Chrome, which I didn't try since I use Firefox and it works great.
8
  • 1
    This is more than sufficient for the bounty. Excellent work! For future users, please edit to describe any potential limitations when you find them. Off the top of my head, it seems that chrome doesn't like this very much, and also, the apps disappear from the cmd+tab when using this shortcut.
    – cloneman
    Feb 1, 2018 at 19:08
  • 1
    @cloneman Nice, thanks. I've added a Caveats section.
    – oblitum
    Feb 1, 2018 at 20:11
  • always get error: this script contains uncompiled changes and cannot be run. (-2700)
    – Xin Meng
    May 22, 2018 at 6:46
  • 1
    This solution doesn't work for me, and I'm on macOS Sierra 10.12.6. The error window says: Can't get window 1 of <<class prcs>> "Full Screen" of application "System Events". Invalid index. And then is also says: System Events got an error: Can't get window 1 of process "Full Screen": Invalid index. (-1719)
    – rm.rf.etc
    Nov 22, 2018 at 2:06
  • @rm.rf.etc I'm still using it on Sierra, working fine.
    – oblitum
    Nov 22, 2018 at 7:03
9

The menu bar can NOT be hidden on command whenever you like to due to limitations in Mac OS X. Apple can do this in their own programs but they have NOT made it possible for other developers in Mac OS X. One of the reasons being that Apple Menu sits on the Menu bar and is helpful if the application becomes unresponsive or if the user needs to log off /shutdown the machine.

There is an application called Menu Eclipse which lets you change the Menu Bar behaviors(except for hide it).

7
  • 2
    "Menu eclipse" doesn't hide the menu bar.
    – Déjà vu
    Dec 11, 2014 at 8:15
  • 1
    the menu bar could be triggerable by a keystroke or by a longer pause - this would still allow for the user to break out of a broken app while also not interrupting their tab based work flow
    – Toni Leigh
    Oct 22, 2015 at 6:47
  • 1
    This can't be 100% true, since there are a lot of full screen games which don't allow you to access the menu bar. Although they are presumably using non-standard functions for full screen. Aug 31, 2016 at 16:59
  • @Wowfunhappy I would assume that is the result of running applications in the game mode.
    – Zeus
    Aug 31, 2016 at 18:39
  • Okay okay, and what about Command + Option + Shift + Esc? When app becomes unresponsive, shutting down the machine does nothing until the application responses. So menu bar should not be a must when fullscreen. Apr 18, 2018 at 14:15
8

The closest solution I've found is to do as mentioned earlier, disabling "Displays have separate spaces" in Mission Control. This only makes sense in a multi-monitor environment, as the menubar still shows on the primary monitor.

If you make the app "go fullscreen" (click green button), it fills the whole screen, but all other screens go black, and the menubar gets moved to the app's screen. So the solution there is to manually expand the app's edges as far or high as you want. Once upon a time, VMWare had some kind of full-screen workaround that didn't use Apple's full screen mechanism.

Unless/until Apple sees this as a problem that needs fixing, you're going to be hard pressed finding a non-hacky solution. It is so integral to how the operating system works (like the home-button on the iPhone/iPad/iPod).

7

My solution in Python:

import autopy.mouse as mouse
from time import sleep

while True:
    x, y = mouse.location()
    if y < 5:
        mouse.move(x, 5)
    sleep(0.1)
4
  • better than nothing
    – HumayunM
    Oct 14, 2020 at 13:49
  • For me this was the best solution, although I had to change the timing from 0.1 to 0.01 to get it to really stop it. I already have a command aliased to open an ssh tunnel for RDP, so I just included running this script in that command. Aug 22, 2022 at 17:59
  • This sounds good enough for me, but I'm having a hard time getting autopy to work in my environment, and not liking that it requires me to sync to a 3 year old version of rustc. Is there an alternative library I could use?
    – The111
    Dec 19, 2022 at 20:34
  • Answering my own comment/Q above: macmouse seems to be what I was looking for.
    – The111
    Dec 19, 2022 at 20:46
3

One possible solution is not to get rid of the menu completely, but actually keep the menu always on (it's not that big), and just get rid of the Dock instead, by doing the following trick.

Go to terminal and type:

defaults write com.apple.dock tilesize -int 1
killall Dock

This will make your Dock small. The press ⌘ ⌥ D to hide dock.

Idea stolen from here.

1
  • 2
    Downvoting this answer below zero is really mean. It could help people with the similar problem, but now they will ignore it, assuming that this solution doesn't work at all. My goal was to optimize for the screen space while not having the irritation with the tabs in the browser and code editors. None of the other answers above worked for me, but entirely getting rid of the Dock made me happy.
    – Alex
    Jun 29, 2019 at 6:48
1

I use Firefox and solved it by editing the browser chrome (userChrome.css).

I just reversed the vertical order of the main browser elements (tabs, toolbar, main content). On the screenshow below, notice my tabs are at the bottom.

This layout looks strange at first but I don't care - I just want to avoid the constant problem I have with unintentionally revealing the macOS menu bar while in fullscreen mode.

enter image description here

Here's my userChrome.css (I kept it simple). You can find instructions on how to edit your Firefox UI here.

body {
  display: flex !important;
  flex-direction: column-reverse !important;
}

#browser {
  flex: 1 1 auto !important;
}

#navigator-toolbox {
  display: flex !important;
  flex-direction: column-reverse !important;
}
1

I know this is a little old, but I was a little unsatisfied with most of the answers, so I thought I'd leave what I did for anyone who goes looking.

Similar to the python solution, I used a script in hammerspoon. Hammerspoon is an app that you can give scripts to, and then it will run them in the background. It will handle launching on startup, it has a menu item so you can quit it if you want, its more like a background app/extension. So I personally find it a little more friendly than a python script.

Unlike the python script, my hammerspoon script uses the eventTap. That way it gets notified of mouse move events, and can respond to them instead of running a timer to check to see where the mouse is. That way if you're not moving your mouse it doesn't keep running

mouseEventTap = hs.eventtap.new({hs.eventtap.event.types.mouseMoved}, function(event)
    --todo: you could filter with hs.application.frontmostApplication() if you want to only block the menu for certain apps. I don't
    local rel = hs.mouse.getRelativePosition()
    if(rel.y < 5) then
        local frame = hs.mouse.getCurrentScreen():fullFrame()
        local abs = event:location()
        abs.y = frame.y + 5
        local newEvent = event:copy():location(abs)
        newEvent:post()
        return true
    end
end)
mouseEventTap:start()

You can also have additional functions in your script. For example, I made a binding of Ctrl+Alt+Cmd+Space to enable/disable the event tap. That way if I do want to get to the menu bar, I can.

hs.hotkey.bind({"ctrl", "cmd", "alt"}, "space", function()
    if(mouseEventTap:isEnabled()) then
        mouseEventTap:stop()
    else
        mouseEventTap:start()
    end
end)

you could alternatively do something like, if the mouse moved within the top 8 pixels of the screen for more than 3 seconds, allow it to move past the 5 pixel barrier at the top of the screen. Or any number of similar methods to temporarily get through and show the menu bar

-4

Try to use hotkeys for switch tabs in browser/ide so you'll never move your mouse into the top to menubar appear

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .