Menu

Display Server and Desktop Environment Detection

Relevant source files

Purpose and Scope

This document describes the display server and desktop environment detection subsystem, which identifies the graphical environment, window manager (WM), desktop environment (DE), and connected displays with their properties. This subsystem is invoked by the Display module (see 3.5) and provides platform-abstracted access to display information across Linux, Windows, macOS, and BSD systems.

The detection layer gathers:

  • Display Server Protocol: Wayland, X11, TTY, SurfaceFlinger (Android), or proprietary protocols
  • Window Manager (WM): Process name and user-friendly name (e.g., "KWin", "Mutter")
  • Desktop Environment (DE): Process name and user-friendly name (e.g., "KDE Plasma", "GNOME")
  • Display Properties: Resolution, refresh rate, rotation, HDR status, physical dimensions, manufacturer info

For terminal and shell detection, see Terminal and Shell Detection. For the Display module that consumes this data, see page 3.5 context above.


Architecture Overview

Detection Flow

Sources: src/detection/displayserver/displayserver.c55-69 src/detection/displayserver/linux/displayserver_linux.c46-97

The detection process follows a singleton pattern where ffConnectDisplayServer() initializes a static FFDisplayServerResult on first call and returns it on subsequent calls. The platform-specific ffConnectDisplayServerImpl() populates this structure using appropriate APIs.


Core Data Structures

FFDisplayServerResult

Sources: src/detection/displayserver/displayserver.h49-104

FieldDescription
wmProcessNameActual process name (e.g., "kwin", "mutter")
wmPrettyNameUser-friendly name (e.g., "KWin", "Mutter")
wmProtocolNameProtocol identifier (e.g., "Wayland", "X11", "TTY")
deProcessNameDE process name (e.g., "plasmashell", "gnome-shell")
dePrettyNameUser-friendly DE name (e.g., "KDE Plasma", "GNOME")
displaysFFlist of FFDisplayResult structures

FFDisplayResult Properties

PropertyDescription
width, heightConfigured resolution in pixels
scaledWidth, scaledHeightHiDPI scaled resolution
preferredWidth, preferredHeightNative/preferred resolution from EDID
refreshRate, preferredRefreshRateIn Hz, calculated from mode timings
physicalWidth, physicalHeightPhysical dimensions in millimeters
rotationDisplay rotation in degrees (0, 90, 180, 270)
bitDepthBits per color channel
hdrStatusHDR capability and enablement status
drrStatusDynamic refresh rate (VRR) status
manufactureYear, manufactureWeekFrom EDID data
serialDisplay serial number from EDID
platformApiDetection method used (e.g., "xlib-randr-mode", "GDI")

Sources: src/detection/displayserver/displayserver.h70-94


Linux Implementation

Detection Chain with Fallbacks

Sources: src/detection/displayserver/linux/displayserver_linux.c46-97

The Linux implementation tries multiple backends in priority order:

  1. Wayland (highest priority): Uses libwayland-client.so to connect to Wayland compositor
  2. XCB RandR: Uses libxcb-randr.so for X11 via XCB protocol
  3. Xlib RandR: Uses libXrandr.so for X11 via Xlib
  4. DRM: Direct Rendering Manager, display-server-independent method
  5. FreeBSD kenv: Fallback on FreeBSD using kernel environment variables

Each method is tried only if the previous one failed (determined by displays.length == 0). The dsForceDrm configuration flag can skip protocol-specific methods and go directly to DRM.

Wayland Detection

Wayland detection dynamically loads libwayland-client.so and uses the Wayland protocol to:

  • Query compositor information via wl_compositor interface
  • Enumerate outputs via wl_output interface
  • Retrieve output properties (resolution, refresh rate, physical size, name)
  • Detect the WM process name from compositor identification

Sources: Referenced in src/detection/displayserver/linux/displayserver_linux.c52

X11 Detection via XCB

Sources: src/detection/displayserver/linux/xcb.c358-428

The XCB RandR implementation:

  1. Connects to X server via xcb_connect()
  2. Iterates screens via xcb_setup_roots_iterator()
  3. For each screen, queries monitors via xcb_randr_get_monitors()
  4. For each monitor, iterates outputs and retrieves:
    • EDID data for display name and physical properties
    • CRTC information for current configuration (resolution, rotation)
    • Mode information for refresh rate calculation
  5. Detects WM via EWMH _NET_SUPPORTING_WM_CHECK property
  6. Reads X server vendor string

Key Functions:

X11 Detection via Xlib

The Xlib implementation follows a similar pattern but uses libXrandr.so functions:

  • XRRGetMonitors() - Enumerate monitors
  • XRRGetOutputInfo() - Get output properties
  • XRRGetCrtcInfo() - Get CRTC configuration
  • XRRGetOutputProperty() - Retrieve EDID data

Sources: src/detection/displayserver/linux/xlib.c299-346

The Xlib implementation includes additional features:


WM/DE Detection Strategy

Detection Sources Priority

Sources: src/detection/displayserver/linux/wmde.c434-501

Environment Variable Parsing

The parseEnv() function checks environment variables in priority order:

PriorityVariableExample Value
1XDG_CURRENT_DESKTOP"KDE", "GNOME", "XFCE"
2XDG_SESSION_DESKTOP"plasma", "gnome"
3CURRENT_DESKTOPDesktop identifier
4SESSION_DESKTOPDesktop identifier
5DESKTOP_SESSIONDesktop session name
6KDE_FULL_SESSIONIf set → "KDE"
7GNOME_DESKTOP_SESSION_IDIf set → "GNOME"
8MATE_DESKTOP_SESSION_IDIf set → "Mate"
9TDE_FULL_SESSIONIf set → "Trinity"
10HYPRLAND_CMDIf set → "Hyprland"
11SWAYSOCKIf set → "Sway"
12WAYLAND_DISPLAY + /mnt/wslg/If both → "WSLg"

Sources: src/detection/displayserver/linux/wmde.c26-76

Process Enumeration

When environment variables don't provide complete information, the system enumerates processes owned by the current user:

Linux: Iterates /proc/[pid]/cmdline files src/detection/displayserver/linux/wmde.c354-405

/proc/ ├── 1234/ │ ├── loginuid (check if matches current user) │ └── cmdline (extract process name) └── 5678/ ├── loginuid └── cmdline 

FreeBSD: Uses sysctl(CTL_KERN, KERN_PROC, KERN_PROC_UID) src/detection/displayserver/linux/wmde.c271-298

OpenBSD: Uses kvm_getprocs(KERN_PROC_UID) src/detection/displayserver/linux/wmde.c299-317

NetBSD: Uses sysctl(KERN_PROC2, KERN_PROC_UID) src/detection/displayserver/linux/wmde.c406-428

Solaris: Iterates /proc/[pid]/psinfo src/detection/displayserver/linux/wmde.c318-353

Known WM/DE Mapping

The system maintains hardcoded mappings for known window managers and desktop environments:

Desktop Environments src/detection/displayserver/linux/wmde.c164-264:

Process Name PatternPretty NameProcess Name Set
"KDE", "plasma", "plasmashell""KDE Plasma""plasmashell"
"GNOME", "gnome-shell""GNOME""gnome-shell"
"Cinnamon""Cinnamon""cinnamon"
"XFCE", "xfce4-session""Xfce4""xfce4-session"
"MATE", "mate-session""Mate""mate-session"
"LXQt", "lxqt-session""LXQt""lxqt-session"
"Budgie", "budgie-desktop""Budgie""budgie-desktop"

Window Managers src/detection/displayserver/linux/wmde.c78-140:

Process Name PatternPretty Name
"kwin", "kwin_*""KWin"
"gnome-shell", "Mutter""Mutter"
"cinnamon", "Muffin""Muffin"
"sway""Sway"
"hyprland""Hyprland"
"openbox""Openbox"
"xfwm4""Xfwm4"
"bspwm""bspwm"
"dwm""dwm"

Special Cases:


Windows Implementation

Display Enumeration

Sources: src/detection/displayserver/displayserver_windows.c238-255 src/detection/displayserver/displayserver_windows.c30-236

Windows implementation workflow:

  1. WM Detection: Checks if DWM (Desktop Window Manager) is enabled via DwmIsCompositionEnabled() src/detection/displayserver/displayserver_windows.c240-245
  2. Monitor Enumeration: Uses EnumDisplayMonitors() to collect monitor handles src/detection/displayserver/displayserver_windows.c32-33
  3. Display Configuration: Calls QueryDisplayConfig() to get active display paths and modes src/detection/displayserver/displayserver_windows.c40-46
  4. Per-Display Properties:

Display Type Detection: Determines built-in vs external displays based on outputTechnology field src/detection/displayserver/displayserver_windows.c175-179


macOS Implementation

CoreGraphics-Based Detection

Sources: src/detection/displayserver/displayserver_apple.c188-200 src/detection/displayserver/displayserver_apple.c21-186

macOS implementation details:

  1. WM Detection: Creates server port to verify WindowServer is running src/detection/displayserver/displayserver_apple.c191-197
  2. Display Enumeration: Uses CGGetOnlineDisplayList() to get all active displays src/detection/displayserver/displayserver_apple.c23-26
  3. Per-Display Properties:

Platform-Specific APIs: macOS 10.15+ uses private CoreDisplay APIs, older versions use deprecated IOKit APIs src/detection/displayserver/displayserver_apple.c55-62


EDID Parsing

All platforms utilize EDID (Extended Display Identification Data) parsing to extract accurate display information when available.

EDID Functions (referenced in utility helpers):

FunctionPurpose
ffEdidGetName()Extract manufacturer and model name
ffEdidGetPhysicalSize()Get width and height in millimeters
ffEdidGetSerialAndManufactureDate()Extract serial number, year, and week
ffEdidGetHdrCompatible()Check HDR capability from EDID extensions

EDID data sources per platform:


Module Integration

Display Module Usage

Sources: src/modules/display/display.c20-224 src/detection/displayserver/displayserver.c55-69

The Display module consumes detection results:

  1. Retrieval: Calls ffConnectDisplayServer() to get singleton result src/modules/display/display.c22
  2. Error Handling: Checks if displays.length == 0 src/modules/display/display.c24-28
  3. Sorting: Optionally sorts displays by name (ascending/descending) src/modules/display/display.c30-33
  4. Output Formatting:

Display Result Helper

The ffdsAppendDisplay() function creates and initializes display entries:

Sources: src/detection/displayserver/displayserver.c3-51

This helper:


Protocol Constants

The system defines string constants for known protocols and WM/DE names:

Protocol Names

ConstantValueUsage
FF_WM_PROTOCOL_TTY"TTY"Terminal-only session
FF_WM_PROTOCOL_X11"X11"X Window System
FF_WM_PROTOCOL_WAYLAND"Wayland"Wayland compositor
FF_WM_PROTOCOL_SURFACEFLINGER"SurfaceFlinger"Android display server

Sources: src/detection/displayserver/displayserver.h44-47

Pretty Names

Desktop environments and window managers have standardized pretty names for consistent output:

DE Pretty Names: FF_DE_PRETTY_PLASMA ("KDE Plasma"), FF_DE_PRETTY_GNOME ("GNOME"), etc. src/detection/displayserver/displayserver.h6-17

WM Pretty Names: FF_WM_PRETTY_KWIN ("KWin"), FF_WM_PRETTY_MUTTER ("Mutter"), etc. src/detection/displayserver/displayserver.h19-42

These constants ensure consistent naming across different detection methods and platforms.