Open-Source Wikis

/

Godot

/

Systems

/

Display server

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 canvas

Public API surface

DisplayServer exposes (selectively):

  • Window managementwindow_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 Window of the scene tree is one; popups and additional Window nodes get their own native window via DisplayServer::window_create.
  • Cursorcursor_set_shape, cursor_set_custom_image, mouse_set_mode, cursor_get_position, warp_mouse.
  • Clipboardclipboard_set, clipboard_get, clipboard_has_image, plus clipboard_set_primary on Linux.
  • IMEwindow_set_ime_active, window_set_ime_position, IME composition events.
  • Screensget_screen_count, screen_get_size, screen_get_dpi, screen_get_refresh_rate, screen_get_usable_rect, screen_get_orientation.
  • Native dialogsdialog_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_indicator on supported platforms.
  • Tablet pentablet_get_driver_count, tablet_set_current_driver for 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 scripts

Input (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:

  1. Creating the OS window.
  2. 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 IDXGISwapChain attached to the HWND.
    • Metal — macOS/iOS/visionOS; a CAMetalLayer is attached to the NSView/UIView/CALayer.
    • OpenGL ES 3 — context creation via EGL/GLX/WGL/CGL; drivers/egl/, drivers/gl_context/.
  3. 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 DisplayServer early in Main::setup2, before RenderingServer.
  • 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.
  • Input reads the active InputMap from ProjectSettings and applies it to incoming events to populate "actions" (is_action_pressed("ui_accept")).
  • The editor's "remote debug viewport" feature uses DisplayServer capabilities 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 via Window::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 from display_server_* and update Viewport::push_input if 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.

Display server – Godot wiki | Factory