godotengine/godot
Display server
Purpose
DisplayServer is the engine's window-and-input abstraction. It owns the OS windows, processes the OS event stream into InputEvents, manages the cursor, clipboard, IME, and screen enumeration, and creates the rendering context the GPU drivers attach to. The interface lives at the engine level (servers/display_server.h); each platform supplies a concrete DisplayServer<Platform> that implements it.
Layout
servers/display_server.{cpp,h} Public abstract interface
servers/display_server_headless.h Headless implementation (no window, no input)
platform/linuxbsd/
├── x11/display_server_x11.{cpp,h} X11 implementation
└── wayland/display_server_wayland.{cpp,h} Wayland implementation
platform/windows/display_server_windows.{cpp,h} Win32 implementation
platform/macos/display_server_macos.mm AppKit / Metal implementation
platform/android/display_server_android.{cpp,h} Android implementation (UI thread + JNI)
platform/ios/display_server_ios.{mm,h} UIKit implementation
platform/visionos/display_server_visionos.mm visionOS implementation
platform/web/display_server_web.{cpp,h} Browser DOM + WebGL/WebGPU canvasPublic API surface
DisplayServer exposes (selectively):
- Window management —
window_create,window_set_size,window_set_position,window_set_mode(FULLSCREEN / EXCLUSIVE_FULLSCREEN / MINIMIZED / MAXIMIZED / WINDOWED),window_set_flag(BORDERLESS, RESIZE_DISABLED, ON_TOP, …),window_set_title,window_request_attention,window_set_transient,window_can_draw. - Multiple windows — Godot fully supports multiple OS windows. The root
Windowof the scene tree is one; popups and additionalWindownodes get their own native window viaDisplayServer::window_create. - Cursor —
cursor_set_shape,cursor_set_custom_image,mouse_set_mode,cursor_get_position,warp_mouse. - Clipboard —
clipboard_set,clipboard_get,clipboard_has_image, plusclipboard_set_primaryon Linux. - IME —
window_set_ime_active,window_set_ime_position, IME composition events. - Screens —
get_screen_count,screen_get_size,screen_get_dpi,screen_get_refresh_rate,screen_get_usable_rect,screen_get_orientation. - Native dialogs —
dialog_show,dialog_input_text,file_dialog_show,file_dialog_with_options_show(where the platform supports them). - Drag and drop — incoming OS drag events are routed to the root window via
Window::set_drop_files_callback. - Status icons — tray icons via
create_status_indicatoron supported platforms. - Tablet pen —
tablet_get_driver_count,tablet_set_current_driverfor stylus input on Windows. - Native menus — macOS-only
global_menu_*API for the global app menu.
How input flows
sequenceDiagram
participant OS
participant DS as DisplayServer<Platform>
participant Input as Input (singleton)
participant Viewport
participant Node
OS->>DS: native event (mouse, key, touch, …)
DS->>DS: translate to InputEvent*
DS->>Input: parse_input_event
DS->>Viewport: route to active Viewport via Window
Viewport->>Node: _input → _gui_input → _shortcut_input → _unhandled_key_input → _unhandled_input
Note over Viewport,Node: Viewport handles GUI focus / hover / drag<br/>before delegating to scene scriptsInput (core/input/input.cpp) keeps the parallel "current state" snapshot (held keys, joypad axes, action strengths) so scripts can poll without subscribing to events.
Window::push_input is the entry point on the scene side. The viewport then dispatches per-node based on focus, mouse hover, and Control input modes.
Rendering context creation
The display server is responsible for:
- Creating the OS window.
- Creating a graphics context appropriate to the chosen rendering driver:
- Vulkan — via VK-WSI extensions; Linux uses VK_KHR_xcb_surface or VK_KHR_wayland_surface, Windows uses VK_KHR_win32_surface, macOS uses MoltenVK + VK_EXT_metal_surface.
- D3D12 — Windows-only; the swapchain is a
IDXGISwapChainattached to the HWND. - Metal — macOS/iOS/visionOS; a
CAMetalLayeris attached to theNSView/UIView/CALayer. - OpenGL ES 3 — context creation via EGL/GLX/WGL/CGL;
drivers/egl/,drivers/gl_context/.
- Handing the swapchain/render-target back to the rendering driver so frames can be presented.
For headless mode (--headless or --display-driver headless), the server is DisplayServerHeadless, which has no window and no input — useful for CI, command-line tools (importing assets, baking), and dedicated game servers.
Multiple windows + sub-viewports
A scene tree's root is a Window whose id is MAIN_WINDOW_ID. Additional Window nodes added to the tree create native OS windows. Sub-viewports (SubViewport nodes) do not get their own OS window; they render to a texture that the parent uses as a regular sampler.
This same machinery powers:
- Editor dialogs and floating panels.
- Detached editor docks (the editor lets users tear off any dock into its own OS window).
- Multi-monitor games with independent windows per screen.
Key abstractions
| Abstraction | File | Role |
|---|---|---|
DisplayServer |
servers/display_server.h |
Pure virtual interface |
DisplayServer::Context |
servers/display_server.h |
Rendering context type passed to drivers |
Input |
core/input/input.h |
Aggregates current input state |
InputEvent* |
core/input/input_event.h |
Polymorphic event types |
Window |
scene/main/window.cpp |
The scene-tree wrapper that owns a window ID |
Viewport |
scene/main/viewport.cpp |
Receives push_input and routes to nodes |
Integration points
- The platform layer creates the
DisplayServerearly inMain::setup2, beforeRenderingServer. - The rendering server queries
DisplayServer::screen_get_size,screen_get_max_scale, and the display server's render context to set up per-window swapchains. Inputreads the activeInputMapfromProjectSettingsand applies it to incoming events to populate "actions" (is_action_pressed("ui_accept")).- The editor's "remote debug viewport" feature uses
DisplayServercapabilities to forward IME and cursor state between editor and running game.
Entry points for modification
- Adding a new window flag → extend
DisplayServer::WindowFlags, implement on each platform's display server, expose viaWindow::set_flag. - Per-platform input quirks → modify the platform's
display_server_*.cpp(e.g., touch routing on Android, IME on Windows, clipboard primary on X11). - Adding a new IME mode or input event → declare
InputEvent*subclass, route fromdisplay_server_*and updateViewport::push_inputif special handling is needed. - New screen attribute (e.g., HDR capabilities) → add a query method, implement per platform (Windows + macOS lead the way; Linux lags depending on Wayland support).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.