A cross-platform GDExtension for capturing global media key presses (Play/Pause, Next, Previous, Stop) in Godot 4 projects.
- Cross-platform support: Linux, Windows, and macOS
- Global media key capture: Works even when your game is in the background
- Simple GDScript API: Easy to integrate into your Godot projects
- Native implementations: Uses platform-specific APIs for optimal performance
- Linux: D-Bus with MPRIS2 protocol + GNOME Settings Daemon signals
- Windows: WM_APPCOMMAND message handling
- macOS: CGEventTap for system-level event interception
- Copy the
addons/godot-media-keysdirectory to your project'saddons/folder - Enable the plugin in Project Settings → Plugins
- The plugin will automatically register the
MediaKeyssingleton and autoload
extends Node
func _ready():
# Get the MediaKeys singleton
var media_keys = Engine.get_singleton("MediaKeys")
# Connect to the media_key_pressed signal
media_keys.media_key_pressed.connect(_on_media_key_pressed)
func _on_media_key_pressed(key: int):
match key:
MediaKeys.MEDIA_KEY_PLAY_PAUSE:
print("Play/Pause pressed")
MediaKeys.MEDIA_KEY_NEXT:
print("Next pressed")
MediaKeys.MEDIA_KEY_PREVIOUS:
print("Previous pressed")
MediaKeys.MEDIA_KEY_STOP:
print("Stop pressed")MediaKeys.MEDIA_KEY_PLAY_PAUSE- Play/Pause media keyMediaKeys.MEDIA_KEY_NEXT- Next track media keyMediaKeys.MEDIA_KEY_PREVIOUS- Previous track media keyMediaKeys.MEDIA_KEY_STOP- Stop media key
media_key_pressed(key: int)- Emitted when a media key is pressed
- Requires D-Bus session bus
- Registers as an MPRIS2 media player (
org.mpris.MediaPlayer2.godot) - Supports both MPRIS2 method calls and GNOME Settings Daemon signals
- Works automatically with most desktop environments
- Uses a message-only window to receive WM_APPCOMMAND messages
- No special permissions required
- Works with standard keyboard media keys
- Requires Accessibility permissions on first run
- System will prompt: "App wants to access Accessibility features"
- Grant permission in: System Preferences → Security & Privacy → Privacy → Accessibility
- Uses CGEventTap to intercept media key events
- Works with Apple keyboard media keys and compatible third-party keyboards
- All platforms: Python 3.6+, SCons
- Linux: g++, libdbus-1-dev
- Windows: MinGW-w64 (for cross-compilation from Linux)
- macOS: Xcode command line tools
# Build for current platform
./build_local.sh linux # Linux
./build_local.sh windows # Windows (cross-compile)
./build_local.sh macos # macOS
# The compiled libraries will be placed in:
# addons/godot-media-keys/bin/Run the included unit tests using GUT (Godot Unit Testing):
./run_tests.shOr manually test using the example scene at example/test_scene.tscn.
- MediaKeys singleton: Inherits from
Objectand is registered viaEngine::register_singleton() - Worker thread: Each platform runs its own event-listening thread to avoid blocking the game
- Event queue: Thread-safe queue for passing events from worker thread to main thread
- MediaKeysAutoload: A Node-based autoload that polls events every frame and emits signals
This architecture ensures media key events are captured reliably without impacting game performance.
To enable debug logging during development:
- Edit
SConstruct - Uncomment:
env.Append(CPPDEFINES=['MEDIA_KEYS_DEBUG']) - Rebuild the project
Debug messages will appear in Godot's output console.
This project is licensed under the MIT License. See LICENSE for details.
Contributions are welcome! Please feel free to submit issues and pull requests.
This project was inspired by and uses reference implementations from:
- SPMediaKeyTap for macOS media key handling
Hi! I’m krazyjakee 🎮, creator and maintainer of the NodotProject - a suite of open‑source Godot tools (e.g. Nodot, Gedis, GedisQueue etc) that empower game developers to build faster and maintain cleaner code.
I’m looking for sponsors to help sustain and grow the project: more dev time, better docs, more features, and deeper community support. Your support means more stable, polished tools used by indie makers and studios alike.
Every contribution helps maintain and improve this project. And encourage me to make more projects like this!
This is optional support. The tool remains free and open-source regardless.
Created with ❤️ for Godot Developers
For contributions, please open PRs on GitHub
