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:
For terminal and shell detection, see Terminal and Shell Detection. For the Display module that consumes this data, see page 3.5 context above.
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.
Sources: src/detection/displayserver/displayserver.h49-104
| Field | Description |
|---|---|
wmProcessName | Actual process name (e.g., "kwin", "mutter") |
wmPrettyName | User-friendly name (e.g., "KWin", "Mutter") |
wmProtocolName | Protocol identifier (e.g., "Wayland", "X11", "TTY") |
deProcessName | DE process name (e.g., "plasmashell", "gnome-shell") |
dePrettyName | User-friendly DE name (e.g., "KDE Plasma", "GNOME") |
displays | FFlist of FFDisplayResult structures |
| Property | Description |
|---|---|
width, height | Configured resolution in pixels |
scaledWidth, scaledHeight | HiDPI scaled resolution |
preferredWidth, preferredHeight | Native/preferred resolution from EDID |
refreshRate, preferredRefreshRate | In Hz, calculated from mode timings |
physicalWidth, physicalHeight | Physical dimensions in millimeters |
rotation | Display rotation in degrees (0, 90, 180, 270) |
bitDepth | Bits per color channel |
hdrStatus | HDR capability and enablement status |
drrStatus | Dynamic refresh rate (VRR) status |
manufactureYear, manufactureWeek | From EDID data |
serial | Display serial number from EDID |
platformApi | Detection method used (e.g., "xlib-randr-mode", "GDI") |
Sources: src/detection/displayserver/displayserver.h70-94
Sources: src/detection/displayserver/linux/displayserver_linux.c46-97
The Linux implementation tries multiple backends in priority order:
libwayland-client.so to connect to Wayland compositorlibxcb-randr.so for X11 via XCB protocollibXrandr.so for X11 via XlibEach 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 dynamically loads libwayland-client.so and uses the Wayland protocol to:
wl_compositor interfacewl_output interfaceSources: Referenced in src/detection/displayserver/linux/displayserver_linux.c52
Sources: src/detection/displayserver/linux/xcb.c358-428
The XCB RandR implementation:
xcb_connect()xcb_setup_roots_iterator()xcb_randr_get_monitors()_NET_SUPPORTING_WM_CHECK propertyKey Functions:
xcbRandrHandleMonitor() - Processes each monitor src/detection/displayserver/linux/xcb.c245-295xcbRandrHandleOutput() - Processes each output src/detection/displayserver/linux/xcb.c143-243xcbDetectWMfromEWMH() - Queries WM name src/detection/displayserver/linux/xcb.c77-94The Xlib implementation follows a similar pattern but uses libXrandr.so functions:
XRRGetMonitors() - Enumerate monitorsXRRGetOutputInfo() - Get output propertiesXRRGetCrtcInfo() - Get CRTC configurationXRRGetOutputProperty() - Retrieve EDID dataSources: src/detection/displayserver/linux/xlib.c299-346
The Xlib implementation includes additional features:
Xft.dpi from RESOURCE_MANAGER property for HiDPI scaling src/detection/displayserver/linux/xlib.c250-257Sources: src/detection/displayserver/linux/wmde.c434-501
The parseEnv() function checks environment variables in priority order:
| Priority | Variable | Example Value |
|---|---|---|
| 1 | XDG_CURRENT_DESKTOP | "KDE", "GNOME", "XFCE" |
| 2 | XDG_SESSION_DESKTOP | "plasma", "gnome" |
| 3 | CURRENT_DESKTOP | Desktop identifier |
| 4 | SESSION_DESKTOP | Desktop identifier |
| 5 | DESKTOP_SESSION | Desktop session name |
| 6 | KDE_FULL_SESSION | If set → "KDE" |
| 7 | GNOME_DESKTOP_SESSION_ID | If set → "GNOME" |
| 8 | MATE_DESKTOP_SESSION_ID | If set → "Mate" |
| 9 | TDE_FULL_SESSION | If set → "Trinity" |
| 10 | HYPRLAND_CMD | If set → "Hyprland" |
| 11 | SWAYSOCK | If set → "Sway" |
| 12 | WAYLAND_DISPLAY + /mnt/wslg/ | If both → "WSLg" |
Sources: src/detection/displayserver/linux/wmde.c26-76
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
The system maintains hardcoded mappings for known window managers and desktop environments:
Desktop Environments src/detection/displayserver/linux/wmde.c164-264:
| Process Name Pattern | Pretty Name | Process 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 Pattern | Pretty 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:
$KDEWM environment variable for WM override src/detection/displayserver/linux/wmde.c177$GNOME_SHELL_SESSION_MODE for "classic" mode src/detection/displayserver/linux/wmde.c188lxqt/session.conf config file src/detection/displayserver/linux/wmde.c230Sources: src/detection/displayserver/displayserver_windows.c238-255 src/detection/displayserver/displayserver_windows.c30-236
Windows implementation workflow:
DwmIsCompositionEnabled() src/detection/displayserver/displayserver_windows.c240-245EnumDisplayMonitors() to collect monitor handles src/detection/displayserver/displayserver_windows.c32-33QueryDisplayConfig() to get active display paths and modes src/detection/displayserver/displayserver_windows.c40-46DisplayConfigGetDeviceInfo() src/detection/displayserver/displayserver_windows.c52-62HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\...\Device Parameters\EDID src/detection/displayserver/displayserver_windows.c91-124DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2 src/detection/displayserver/displayserver_windows.c189-206Display Type Detection: Determines built-in vs external displays based on outputTechnology field src/detection/displayserver/displayserver_windows.c175-179
Sources: src/detection/displayserver/displayserver_apple.c188-200 src/detection/displayserver/displayserver_apple.c21-186
macOS implementation details:
CGGetOnlineDisplayList() to get all active displays src/detection/displayserver/displayserver_apple.c23-26CGDisplayCopyDisplayMode() for current resolution src/detection/displayserver/displayserver_apple.c32CGDisplayModeGetRefreshRate() with fallback to CVDisplayLink for variable refresh displays src/detection/displayserver/displayserver_apple.c36-51kDisplayProductName dictionary src/detection/displayserver/displayserver_apple.c71-73kDisplayHorizontalImageSize/kDisplayVerticalImageSize src/detection/displayserver/displayserver_apple.c76-89CGDisplayScreenSize() for primary display dimensions src/detection/displayserver/displayserver_apple.c112-117CoreDisplay_Display_SupportsHDRMode() APIs on macOS 10.15+ src/detection/displayserver/displayserver_apple.c158-168Platform-Specific APIs: macOS 10.15+ uses private CoreDisplay APIs, older versions use deprecated IOKit APIs src/detection/displayserver/displayserver_apple.c55-62
All platforms utilize EDID (Extended Display Identification Data) parsing to extract accurate display information when available.
EDID Functions (referenced in utility helpers):
| Function | Purpose |
|---|---|
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:
XRRGetOutputProperty(output, "EDID") src/detection/displayserver/linux/xlib.c177-193HKEY_LOCAL_MACHINE\...\Device Parameters\EDID src/detection/displayserver/displayserver_windows.c106-112IODisplayEDIDKey from display info dictionary src/detection/displayserver/displayserver_apple.c76-83Sources: src/modules/display/display.c20-224 src/detection/displayserver/displayserver.c55-69
The Display module consumes detection results:
ffConnectDisplayServer() to get singleton result src/modules/display/display.c22displays.length == 0 src/modules/display/display.c24-28The ffdsAppendDisplay() function creates and initializes display entries:
Sources: src/detection/displayserver/displayserver.c3-51
This helper:
FFDisplayResult in the list src/detection/displayserver/displayserver.c25The system defines string constants for known protocols and WM/DE names:
| Constant | Value | Usage |
|---|---|---|
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
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.
Refresh this wiki
This wiki was recently refreshed. Please wait 1 day to refresh again.