Jump to content

macOS: hot corners remain active during fullscreen, triggering Mission Control / screensaver mid-game


GufraMirtol
 Share

Recommended Posts

Summary

On macOS, 0 A.D. running in fullscreen does not suppress system hot corners. Moving the cursor into a screen corner during gameplay triggers the user's configured corner action (Mission Control, screensaver, lock screen, Launchpad, etc.), interrupting the game and sometimes causing it to lose focus or minimize. This is inconsistent with how most macOS fullscreen games behave and is reproducible on a clean install.

Environment

  • macOS [26.3.1 (a) (25D771280a)], Apple Silicon
  • 0 A.D. 0.28.0 (official build, installed to /Applications/0 A.D..app)
  • Any user profile with one or more hot corners configured in System Settings → Desktop & Dock → Hot Corners

Steps to reproduce

  1. Configure a hot corner (e.g., top-right → Mission Control) in System Settings.
  2. Launch 0 A.D. and enter a match in fullscreen mode.
  3. Move the cursor to that corner during gameplay.
  4. Observed: the system hot corner action fires, overlaying or pulling focus away from the game.
  5. Expected: hot corners are suppressed while the game holds fullscreen focus, matching behavior of Blizzard, Valve, and Feral Interactive macOS titles.

Root cause (analysis)

From inspection of the SDL2-based windowing path used on macOS, fullscreen is implemented via a borderless NSWindowsized to the display (SDL_WINDOW_FULLSCREEN_DESKTOP semantics). This leaves the WindowServer fully in control of the display, so hot corner event taps continue to fire normally. No presentation options are set to inhibit them, and the display is not captured via Quartz Display Services.

User-side workaround I'm currently using

While a proper fix lands, I've written a launcher script that temporarily zeroes out the four com.apple.dock wvous-*-corner keys before open -W launching the app, and restores the original values via a trap ... EXIT handler when the game quits. It's wrapped in a minimal .app bundle so it sits in the Dock like a normal launcher. Sharing it here in case it helps other macOS users in the meantime:

#!/bin/bash
# play-0ad.sh — disable hot corners for the duration of a 0 A.D. session.
APP="/Applications/0 A.D..app"

TL=$(defaults read com.apple.dock wvous-tl-corner 2>/dev/null || echo 0)
TR=$(defaults read com.apple.dock wvous-tr-corner 2>/dev/null || echo 0)
BL=$(defaults read com.apple.dock wvous-bl-corner 2>/dev/null || echo 0)
BR=$(defaults read com.apple.dock wvous-br-corner 2>/dev/null || echo 0)

restore() {
    defaults write com.apple.dock wvous-tl-corner -int "$TL"
    defaults write com.apple.dock wvous-tr-corner -int "$TR"
    defaults write com.apple.dock wvous-bl-corner -int "$BL"
    defaults write com.apple.dock wvous-br-corner -int "$BR"
    killall Dock
}
trap restore EXIT INT TERM

defaults write com.apple.dock wvous-tl-corner -int 0
defaults write com.apple.dock wvous-tr-corner -int 0
defaults write com.apple.dock wvous-bl-corner -int 0
defaults write com.apple.dock wvous-br-corner -int 0
killall Dock

open -W "$APP"

This works, but it's a global side effect (modifies user prefs and restarts the Dock) and obviously not something that belongs in end-user hands. It's a stopgap, not a solution.

Proposed long-term fixes (in order of increasing invasiveness)

Option 1 — NSApplication presentation options (recommended). On entering fullscreen, set:

[NSApp setPresentationOptions: 
NSApplicationPresentationHideDock | 
NSApplicationPresentationHideMenuBar |
NSApplicationPresentationDisableProcessSwitching | 
NSApplicationPresentationDisableHideApplication |
NSApplicationPresentationDisableAppleMenu];


Restore the previous options on exit / windowed switch. The DisableProcessSwitching + HideDock combination suppresses hot corner activation of Mission Control, App Exposé, and Launchpad in practice, without giving up normal compositing or GL context behavior. This is the standard approach for macOS fullscreen games and the lowest-risk change. Would live in a small Objective-C++ shim under source/lib/sysdep/os/osx/ and be called from the fullscreen enter/exit path.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...