
{"id":12982,"date":"2026-07-28T07:18:47","date_gmt":"2026-07-28T07:18:47","guid":{"rendered":"https:\/\/developer.rdkcentral.com\/documentation\/?page_id=12982"},"modified":"2026-07-28T07:20:40","modified_gmt":"2026-07-28T07:20:40","slug":"rdk-window-manager","status":"publish","type":"page","link":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/","title":{"rendered":"RDK Window Manager"},"content":{"rendered":"\n<p>RDK Window Manager (rdkwindowmanager) is responsible for creating Wayland displays, compositing application surfaces, managing window properties, and handling input routing and focus on RDK video and entertainment devices. It depends on Westeros for Wayland compositor creation and Essos for display context management, and exposes its control surface as a Thunder plugin that clients reach through the Firebolt API layer.<\/p>\n\n\n\n<p>RDK Window Manager is the display and input management layer within the RDK Core Middleware stack. It initialises a Westeros-backed Wayland compositor, allocates per-application display surfaces, composites those surfaces onto the screen using OpenGL ES 2.0, and routes key and pointer input from Linux input devices to the correct application. Window properties \u2014 position, size, opacity, z-order, visibility, and crop \u2014 are managed at runtime. An inactivity-detection mechanism monitors the elapsed time since the last key event and notifies subscribers when the device becomes idle.<\/p>\n\n\n\n<p>The component ships three Wayland protocol extensions (<code>firebolt_shell<\/code>,&nbsp;<code>firebolt_surface<\/code>,&nbsp;<code>firebolt_wm<\/code>) that give Wayland clients direct access to surface creation and property control without requiring a Thunder round-trip. When enabled at build time, a VNC server provides remote frame-buffer access over a TCP connection.<\/p>\n\n\n\n<p>From a device perspective the component acts as the single Wayland display server for all applications \u2014 native, HTML, and Lightning \u2014 and arbitrates which application receives keyboard focus at any given moment. It is consumed by the Thunder plugin that bridges higher-level Firebolt API calls down to the compositor.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">flowchart LR\n\n%% Styles\nclassDef Apps stroke:#00B9F1,fill:#E6F7FD,stroke-width:2px;\nclassDef RDKMW stroke:#75D701,fill:#F1FFE6,stroke-width:2px;\nclassDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px;\n\n    subgraph Apps[\"Apps &amp; Runtimes\"]\n        NativeApp[\"Native App\"]\n        HTMLApp[\"HTML \/ WPE App\"]\n        LightningApp[\"Lightning App\"]\n    end\n\n    subgraph RDKMW[\"RDK Core Middleware\"]\n        Thunder[\"WPEFramework (Thunder)\"]\n        RDKWM[\"RDK Window Manager\\n(librdkwindowmanager.so)\"]\n        Westeros[\"Westeros Compositor\"]\n        Essos[\"Essos Display Context\"]\n    end\n\n    subgraph VL[\"Vendor Layer\"]\n        EGL[\"EGL \/ OpenGL ES 2.0\"]\n        LinuxInput[\"Linux Input Devices\"]\n    end\n\n    Apps -->|Wayland \/ Firebolt WM Protocol| RDKWM\n    Thunder -->|JSON-RPC \/ Thunder API| RDKWM\n    RDKWM --> Westeros\n    RDKWM --> Essos\n    RDKWM -->|HAL APIs| VL<\/pre><\/div>\n\n\n\n<p><strong>Key Features &amp; Responsibilities:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Wayland Display Creation<\/strong>: Creates and manages per-application embedded Westeros compositor instances, assigns display names, and tracks client connection and disconnection lifecycle.<\/li>\n\n\n\n<li><strong>Surface Composition<\/strong>: Composites multiple application surfaces onto the display each frame using OpenGL ES 2.0, respecting z-order, opacity, position, size, and crop parameters for each surface.<\/li>\n\n\n\n<li><strong>Input Routing and Focus Management<\/strong>: Receives key and pointer events from Essos, maps Linux\/Wayland key codes to RDK virtual key codes, and dispatches events to the focused application or to registered key intercept and listener handlers.<\/li>\n\n\n\n<li><strong>Key Intercept and Listener Registration<\/strong>: Allows applications to register intercepts for specific key codes \u2014 with optional focus-only and propagation modes \u2014 and listeners that can activate or suppress key propagation.<\/li>\n\n\n\n<li><strong>Inactivity Reporting<\/strong>: Tracks elapsed time since the last key event and fires an inactivity notification to registered listeners once the configurable threshold is exceeded.<\/li>\n\n\n\n<li><strong>Firebolt Wayland Extensions<\/strong>: Provides\u00a0<code>firebolt_shell<\/code>,\u00a0<code>firebolt_surface<\/code>, and\u00a0<code>firebolt_wm<\/code>\u00a0Westeros protocol plugins that give Wayland clients fine-grained surface management without a Thunder round-trip.<\/li>\n\n\n\n<li><strong>VNC Remote Access<\/strong>: Optionally starts a TCP-based VNC server that captures the current frame buffer and serves it to remote clients (enabled at build time via\u00a0<code>RDK_WINDOW_MANAGER_VNC_SERVER<\/code>).<\/li>\n\n\n\n<li><strong>Input Device Classification<\/strong>: Reads a JSON configuration file to classify attached Linux input devices by vendor, product, and device type, allowing key metadata to carry device-type information to applications.<\/li>\n\n\n\n<li><strong>Memory Threshold Configuration (not currently enforced)<\/strong>: Parses RAM\/swap threshold environment variables (<code>RDK_WINDOW_MANAGER_LOW_MEMORY_THRESHOLD<\/code>,\u00a0<code>RDK_WINDOW_MANAGER_CRITICALLY_LOW_MEMORY_THRESHOLD<\/code>,\u00a0<code>RDK_WINDOW_MANAGER_SWAP_MEMORY_INCREASE_THRESHOLD<\/code>), but does not currently emit notifications because memory monitoring is not started in the main loop.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RDKWindowManager-Design\">Design<\/h2>\n\n\n\n<p>RDK Window Manager is built as a shared library (<code>librdkwindowmanager.so<\/code>) that typically runs inside a Thunder plugin; the repository also provides a standalone&nbsp;<code>rdkwindowmanager<\/code>&nbsp;executable that links the same code for direct execution\/testing. Its architecture separates concerns across five focused layers: initialisation and lifecycle (<code>RdkWindowManager<\/code>&nbsp;namespace), Essos context and input ingestion (<code>EssosInstance<\/code>), compositor creation and per-client surface management (<code>RdkCompositor<\/code>&nbsp;\/&nbsp;<code>RdkCompositorNested<\/code>), the orchestration and routing logic that operates across all active compositors (<code>CompositorController<\/code>), and the Wayland extension plugins (<code>firebolt_shell<\/code>,&nbsp;<code>firebolt_surface<\/code>,&nbsp;<code>firebolt_wm<\/code>). Each layer communicates through well-defined C++ interfaces, and the component exposes its full north-bound API via this shared library.<\/p>\n\n\n\n<p>Northbound interaction is through the Thunder JSON-RPC interface exposed by the companion Thunder plugin. That plugin forwards calls directly to&nbsp;<code>CompositorController<\/code>&nbsp;static methods. The Wayland extension layer provides an orthogonal northbound path: Wayland clients load the extension protocols and communicate directly with the window manager process over the existing Wayland socket, bypassing Thunder entirely for performance-sensitive surface property updates.<\/p>\n\n\n\n<p>Southbound, the component binds to Essos for display context initialisation and key\/pointer event delivery, and to Westeros for embedded compositor creation (<code>WstCompositorCreate<\/code>,&nbsp;<code>WstCompositorStart<\/code>, and associated callbacks). OpenGL ES 2.0 is used directly for off-screen frame buffer rendering and final composition. Linux input devices are enumerated and classified through a JSON configuration file parsed by&nbsp;<code>RdkWindowManagerJson<\/code>, and raw Wayland key codes are translated to RDK virtual key codes by&nbsp;<code>linuxkeys<\/code>.<\/p>\n\n\n\n<p>The Thunder plugin calls into the window manager in-process via the shared library interface (<code>librdkwindowmanager.so<\/code>). Communication between the window manager and Wayland client applications is through the standard Wayland socket protocol, extended by the three Firebolt Westeros protocol plugins.<\/p>\n\n\n\n<p>Runtime state \u2014 including window property changes, focus assignments, and key intercept registrations \u2014 is held in process memory for the duration of the session.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">graph TD\n    subgraph RDKWindowManagerProcess[\"rdkwindowmanager process\"]\n\n        subgraph Lifecycle[\"Lifecycle\"]\n            Init[\"initialize()\"]\n            RunLoop[\"run() \/ draw() \/ update()\"]\n        end\n\n        subgraph EssosLayer[\"Essos Integration\"]\n            EssCtx[\"EssosInstance\"]\n            KeyEvt[\"Key \/ Pointer Callbacks\"]\n        end\n\n        subgraph CtrlLayer[\"Compositor Controller\"]\n            CompCtrl[\"CompositorController (static)\"]\n            KeyIntercept[\"Key Intercept Table\"]\n            KeyListener[\"Key Listener Table\"]\n            InactivityTimer[\"Inactivity Timer\"]\n            VNCServer[\"VNC Server (optional)\"]\n        end\n\n        subgraph CompositorLayer[\"Per-App Compositors\"]\n            RdkComp[\"RdkCompositor (base)\"]\n            NestedComp[\"RdkCompositorNested\"]\n            FrameBuf[\"FrameBuffer \/ FrameBufferRenderer\"]\n            CursorMgr[\"Cursor\"]\n        end\n\n        subgraph ExtensionLayer[\"Wayland Extensions\"]\n            FBShell[\"firebolt_shell plugin\"]\n            FBSurface[\"firebolt_surface plugin\"]\n            FBWM[\"firebolt_wm plugin\"]\n        end\n\n        subgraph InputLayer[\"Input Handling\"]\n            LinuxInput[\"linuxinput (device config)\"]\n            LinuxKeys[\"linuxkeys (key mapping)\"]\n        end\n\n    end\n\n    Init --> EssCtx\n    Init --> CompCtrl\n    RunLoop --> CompCtrl\n    EssCtx --> KeyEvt\n    KeyEvt --> CompCtrl\n    CompCtrl --> KeyIntercept\n    CompCtrl --> KeyListener\n    CompCtrl --> InactivityTimer\n    CompCtrl --> NestedComp\n    NestedComp --> RdkComp\n    RdkComp --> FrameBuf\n    NestedComp --> FBShell\n    NestedComp --> FBSurface\n    NestedComp --> FBWM\n    CompCtrl --> CursorMgr\n    CompCtrl --> VNCServer\n    LinuxInput --> EssCtx\n    LinuxKeys --> CompCtrl<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-ThreadingModel\">Threading Model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Threading Architecture<\/strong>: Multi-threaded.<\/li>\n\n\n\n<li><strong>Main Thread<\/strong>: Runs the\u00a0<code>RdkWindowManager::run()<\/code>\u00a0loop, calling\u00a0<code>EssosInstance::update()<\/code>,\u00a0<code>CompositorController::update()<\/code>, and\u00a0<code>CompositorController::draw()<\/code>\u00a0at the configured frame rate (default 40 fps, overridable via\u00a0<code>RDK_WINDOW_MANAGER_FRAMERATE<\/code>). All Westeros callbacks and key-event processing also execute on this thread.<\/li>\n\n\n\n<li><strong>Worker Threads<\/strong>:<\/li>\n\n\n\n<li><em>Application launch thread<\/em>: Each\u00a0<code>RdkCompositor<\/code>\u00a0can spawn a background thread via\u00a0<code>launchApplicationInBackground()<\/code>\u00a0to start the associated application process without blocking the main loop.<\/li>\n\n\n\n<li><em>VNC GMainLoop thread<\/em>\u00a0(when\u00a0<code>RDK_WINDOW_MANAGER_VNC_SERVER<\/code>\u00a0is enabled):\u00a0<code>VncServer<\/code>\u00a0runs a GLib main loop on a dedicated thread to serve VNC TCP connections.<\/li>\n\n\n\n<li><strong>Synchronization<\/strong>: A\u00a0<code>std::mutex<\/code>\u00a0(<code>gFireboltExtensionListenerMapMutex<\/code>) guards the Firebolt extension event listener map.\u00a0<code>RdkCompositor<\/code>\u00a0uses\u00a0<code>mInputLock<\/code>\u00a0and\u00a0<code>mStateChangeLock<\/code>\u00a0mutexes to protect its input-listener and state-change-listener maps.\u00a0<code>FireboltWindowManager<\/code>\u00a0and\u00a0<code>FireboltShell<\/code>\u00a0each hold a\u00a0<code>mContextLock<\/code>\u00a0mutex protecting their per-compositor client maps.<\/li>\n\n\n\n<li><strong>Async \/ Event Dispatch<\/strong>: Essos delivers key and pointer callbacks synchronously on the main thread. Application lifecycle events (connect, disconnect, terminate) are dispatched from Westeros\u00a0<code>WstClient_*<\/code>\u00a0status callbacks, also on the main thread, and forwarded to registered\u00a0<code>RdkWindowManagerEventListener<\/code>\u00a0implementations.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-PlatformandIntegrationRequirements\">Platform and Integration Requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Build Dependencies<\/strong>:\u00a0<code>westeros<\/code>,\u00a0<code>wayland<\/code>,\u00a0<code>essos<\/code>,\u00a0<code>virtual\/egl<\/code>,\u00a0<code>rapidjson<\/code>,\u00a0<code>jpeg<\/code>,\u00a0<code>libpng<\/code>. For the\u00a0<code>rdkwmtest<\/code>\u00a0test executable: additionally\u00a0<code>curl<\/code>. When\u00a0<code>RDK_WINDOW_MANAGER_VNC_SERVER=ON<\/code>: additionally\u00a0<code>libsoup-2.4<\/code>,\u00a0<code>boost<\/code>,\u00a0<code>libsyswrapper<\/code>. When\u00a0<code>BUILD_ENABLE_ERM<\/code>: additionally\u00a0<code>essos-resmgr<\/code>.<\/li>\n\n\n\n<li><strong>Wayland Protocol Extensions<\/strong>:\u00a0<code>firebolt_shell<\/code>,\u00a0<code>firebolt_surface<\/code>, and\u00a0<code>firebolt_wm<\/code>\u00a0protocol XML files are compiled into server-side Westeros plugins (<code>libwstplugin_rdkwmfirebolt*.so<\/code>) and client-side shared libraries (<code>librdkwmext*.so<\/code>). Extensions are loaded from the compiled-in path defined by\u00a0<code>RDK_WINDOW_MANAGER_WESTEROS_PLUGIN_DIRECTORY<\/code>\u00a0(set via CMake\u00a0<code>RDK_WINDOW_MANAGER_WESTEROS_PLUGIN_FOLDER<\/code>; default\u00a0<code>\/usr\/lib\/plugins\/westeros\/<\/code>).<\/li>\n\n\n\n<li><strong>Configuration Files<\/strong>: Input device type configuration file path supplied through\u00a0<code>RDK_WINDOW_MANAGER_INPUT_DEVICES_CONFIG<\/code>. Splash screen suppression: presence of\u00a0<code>\/tmp\/.rdkwindowmanagersplash<\/code>\u00a0controls splash rendering.<\/li>\n\n\n\n<li><strong>Startup Order<\/strong>: The\u00a0<code>rdkwindowmanager<\/code>\u00a0executable must be started before any Wayland client applications attempt to connect.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-ComponentStateFlow\">Component State Flow<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"RDKWindowManager-InitializationtoActiveState\">Initialization to Active State<\/h4>\n\n\n\n<p>The component progresses from system start through Essos and Westeros initialisation before entering its render and event loop.<\/p>\n\n\n\n<p>The component transitions through the following states during its lifecycle:&nbsp;<strong>Initializing<\/strong>&nbsp;(configure logging, read key mappings, read input device config, apply environment-variable overrides) \u2192&nbsp;<strong>DisplaySetup<\/strong>&nbsp;(initialise Essos context at target resolution) \u2192&nbsp;<strong>CompositorReady<\/strong>&nbsp;(<code>CompositorController::initialize()<\/code>&nbsp;called, OpenGL blend state configured) \u2192&nbsp;<strong>Active<\/strong>&nbsp;(frame-rate render loop running, key and pointer events dispatched) \u2192&nbsp;<strong>Shutdown<\/strong>&nbsp;(loop exits, resources released).<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Main as main()\n    participant WM as RdkWindowManager\n    participant Essos as EssosInstance\n    participant CC as CompositorController\n\n    Main->>WM: initialize()\n    WM->>WM: mapNativeKeyCodes() \/ mapVirtualKeyCodes()\n    WM->>WM: readInputDevicesConfiguration()\n    WM->>WM: Apply env-var overrides (framerate, memory thresholds, key delays)\n    WM->>Essos: instance()->initialize(false, width, height)\n    Essos-->>WM: Essos context ready\n    WM->>WM: glEnable(GL_BLEND)\n    WM->>CC: initialize()\n    CC-->>WM: CompositorController ready\n    WM-->>Main: initialize() returns\n\n    Main->>WM: run()\n    loop Frame loop (40 fps default)\n        WM->>Essos: update()\n        WM->>CC: update()\n        WM->>CC: draw()\n    end\n\n    WM-->>Main: run() returns (on shutdown)<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"RDKWindowManager-RuntimeStateChanges\">Runtime State Changes<\/h4>\n\n\n\n<p>Application connection and disconnection events arrive through Westeros&nbsp;<code>WstClient_*<\/code>&nbsp;callbacks and are forwarded to registered&nbsp;<code>RdkWindowManagerEventListener<\/code>&nbsp;instances. Focus changes are driven by explicit&nbsp;<code>CompositorController::setFocus()<\/code>&nbsp;calls from the Thunder plugin. Inactivity detection runs inside&nbsp;<code>CompositorController::update()<\/code>: when&nbsp;<code>gEnableInactivityReporting<\/code>&nbsp;is true and the time since the last key event exceeds&nbsp;<code>gInactivityIntervalInSeconds<\/code>,&nbsp;<code>onUserInactive<\/code>&nbsp;is fired on the registered listener.<\/p>\n\n\n\n<p><strong>State Change Triggers:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A new Wayland client connecting fires\u00a0<code>onApplicationConnected<\/code>; disconnection fires\u00a0<code>onApplicationDisconnected<\/code>.<\/li>\n\n\n\n<li>Receipt of the first rendered frame from a client fires\u00a0<code>onReady<\/code>.<\/li>\n\n\n\n<li>Time elapsed without key input exceeding\u00a0<code>gInactivityIntervalInSeconds<\/code>\u00a0fires\u00a0<code>onUserInactive<\/code>.<\/li>\n\n\n\n<li>Visibility changes (set via\u00a0<code>CompositorController::setVisibility()<\/code>) fire\u00a0<code>onApplicationVisible<\/code>\u00a0or\u00a0<code>onApplicationHidden<\/code>.<\/li>\n\n\n\n<li>Focus assignment via\u00a0<code>CompositorController::setFocus()<\/code>\u00a0fires\u00a0<code>onApplicationFocus<\/code>\u00a0on the newly focused client and\u00a0<code>onApplicationBlur<\/code>\u00a0on the previously focused one.<\/li>\n<\/ul>\n\n\n\n<p><strong>Context Switching Scenarios:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When\u00a0<code>ignoreKeyInputs(true)<\/code>\u00a0is active, all key events are dropped before reaching the intercept or listener evaluation logic.<\/li>\n\n\n\n<li>Key intercept entries marked\u00a0<code>focusOnly=true<\/code>\u00a0suppress delivery to non-focused applications.<\/li>\n\n\n\n<li>Topmost compositor entries (stored in\u00a0<code>gTopmostCompositorList<\/code>) are evaluated independently from the standard compositor list, allowing system overlays to receive input regardless of normal focus order.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-CallFlows\">Call Flows<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"RDKWindowManager-InitializationCallFlow\">Initialization Call Flow<\/h4>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Main as main()\n    participant WM as RdkWindowManager::initialize()\n    participant Essos as EssosInstance\n    participant Keys as linuxkeys \/ linuxinput\n    participant CC as CompositorController\n\n    Main->>WM: initialize()\n    WM->>Keys: mapNativeKeyCodes()\n    WM->>Keys: mapVirtualKeyCodes()\n    WM->>Keys: readInputDevicesConfiguration()\n    WM->>WM: Read env vars (log level, framerate, memory thresholds, key delays)\n    WM->>Essos: configureKeyInput(initialDelay, repeatInterval)\n    WM->>Essos: initialize(false, width, height)\n    Essos-->>WM: EssContext created and started\n    WM->>WM: glEnable \/ glBlendFunc\n    WM->>CC: initialize()\n    CC-->>WM: Done\n    WM-->>Main: returns<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"RDKWindowManager-RequestProcessingCallFlow\">Request Processing Call Flow<\/h4>\n\n\n\n<p>The following illustrates&nbsp;<code>CreateDisplay<\/code>&nbsp;\u2014 the most common setup call \u2014 flowing from the Thunder plugin down through&nbsp;<code>CompositorController<\/code>&nbsp;to the Westeros-backed nested compositor. The component validates the provided parameters before forwarding the request, and propagates the Westeros API result back to the caller as a boolean response.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Client as Thunder Plugin\n    participant CC as CompositorController\n    participant Nested as RdkCompositorNested\n    participant Wst as WstCompositor (Westeros)\n\n    Client->>CC: createDisplay(client, displayName, width, height, ...)\n    CC->>Nested: new RdkCompositorNested\n    Nested->>Wst: WstCompositorCreate()\n    Nested->>Wst: WstCompositorSetIsEmbedded(true)\n    Nested->>Wst: WstCompositorSetOutputSize(width, height)\n    Nested->>Wst: WstCompositorSetDisplayName(displayName)\n    Nested->>Nested: loadExtensions() \/ loadfireboltExtensions()\n    Nested->>Wst: WstCompositorStart()\n    Wst-->>Nested: compositor started\n    Nested-->>CC: createDisplay returns true\n    CC-->>Client: true<\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RDKWindowManager-InternalModules\">Internal Modules<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Module \/ Class<\/strong><\/td><td><strong>Description<\/strong><\/td><td><strong>Key Files<\/strong><\/td><\/tr><tr><td><code>RdkWindowManager<\/code>&nbsp;namespace<\/td><td>Top-level lifecycle:&nbsp;<code>initialize()<\/code>&nbsp;applies environment-variable configuration, sets up Essos, configures OpenGL blend state, and calls&nbsp;<code>CompositorController::initialize()<\/code>.&nbsp;<code>run()<\/code>&nbsp;drives the frame loop.<\/td><td><code>src\/rdkwindowmanager.cpp<\/code>,&nbsp;<code>include\/rdkwindowmanager.h<\/code><\/td><\/tr><tr><td><code>EssosInstance<\/code><\/td><td>Wraps the Essos display context (<code>EssContext*<\/code>). Owns key and pointer event callbacks from Essos and forwards them to&nbsp;<code>CompositorController<\/code>. Manages resolution, key-repeat configuration, and AV blocking (when ERM is enabled).<\/td><td><code>src\/essosinstance.cpp<\/code>,&nbsp;<code>include\/essosinstance.h<\/code><\/td><\/tr><tr><td><code>CompositorController<\/code><\/td><td>Static class providing the full public API: display creation, focus, z-order, bounds, opacity, visibility, key intercepts, key listeners, inactivity reporting, cursor control, screenshot, VNC server lifecycle, and Firebolt surface management. Maintains the ordered compositor lists (<code>gCompositorList<\/code>,&nbsp;<code>gTopmostCompositorList<\/code>) and the key intercept map.<\/td><td><code>src\/compositorcontroller.cpp<\/code>,&nbsp;<code>include\/compositorcontroller.h<\/code><\/td><\/tr><tr><td><code>RdkCompositor<\/code><\/td><td>Abstract base class for a per-application Westeros compositor instance. Manages the&nbsp;<code>WstCompositor<\/code>&nbsp;context, draw\/update cycle, input forwarding, surface properties (position, size, opacity, z-order, visibility, crop), Firebolt surface list, and application process lifecycle.<\/td><td><code>src\/rdkcompositor.cpp<\/code>,&nbsp;<code>include\/rdkcompositor.h<\/code><\/td><\/tr><tr><td><code>RdkCompositorNested<\/code><\/td><td>Concrete subclass of&nbsp;<code>RdkCompositor<\/code>&nbsp;that creates a nested (embedded) Westeros display. Loads Westeros protocol extension plugins and starts the compositor.<\/td><td><code>src\/rdkcompositornested.cpp<\/code>,&nbsp;<code>include\/rdkcompositornested.h<\/code><\/td><\/tr><tr><td><code>FrameBuffer<\/code>&nbsp;\/&nbsp;<code>FrameBufferRenderer<\/code><\/td><td>Off-screen render target (OpenGL FBO + texture) and the GLSL shader program that blits a frame buffer onto the screen with alpha blending, matrix transform, and crop support.<\/td><td><code>src\/framebuffer.cpp<\/code>,&nbsp;<code>src\/framebufferrenderer.cpp<\/code>,&nbsp;<code>include\/framebuffer.h<\/code>,&nbsp;<code>include\/framebufferrenderer.h<\/code><\/td><\/tr><tr><td><code>Cursor<\/code><\/td><td>Manages loading, positioning, showing\/hiding, and drawing a cursor image on screen. Supports configurable inactivity-based auto-hide.<\/td><td><code>src\/cursor.cpp<\/code>,&nbsp;<code>include\/cursor.h<\/code><\/td><\/tr><tr><td><code>linuxkeys<\/code><\/td><td>Provides&nbsp;<code>mapNativeKeyCodes()<\/code>,&nbsp;<code>mapVirtualKeyCodes()<\/code>, and&nbsp;<code>keyCodeFromWayland()<\/code>&nbsp;to translate raw Wayland\/Linux key codes and modifier flags to RDK virtual key codes.<\/td><td><code>src\/linuxkeys.cpp<\/code>,&nbsp;<code>include\/linuxkeys.h<\/code><\/td><\/tr><tr><td><code>linuxinput<\/code><\/td><td>Reads the JSON input device configuration file (path from&nbsp;<code>RDK_WINDOW_MANAGER_INPUT_DEVICES_CONFIG<\/code>) and populates the device-type and device-mode tables used by the key-metadata path.<\/td><td><code>src\/linuxinput.cpp<\/code>,&nbsp;<code>include\/linuxinput.h<\/code><\/td><\/tr><tr><td><code>RdkWindowManagerJson<\/code><\/td><td>Thin wrapper around RapidJSON for reading JSON configuration files from disk.<\/td><td><code>src\/rdkwindowmanagerjson.cpp<\/code>,&nbsp;<code>include\/rdkwindowmanagerjson.h<\/code><\/td><\/tr><tr><td><code>Image<\/code><\/td><td>Loads JPEG, PNG, and BMP images from disk or raw data using libjpeg and libpng, creates an OpenGL texture, and renders it with a GLSL shader. Used for watermarks and the splash screen.<\/td><td><code>src\/rdkwindowmanagerimage.cpp<\/code>,&nbsp;<code>include\/rdkwindowmanagerimage.h<\/code><\/td><\/tr><tr><td><code>Logger<\/code><\/td><td>Lightweight, level-filtered logger (<code>Debug<\/code>,&nbsp;<code>Information<\/code>,&nbsp;<code>Warn<\/code>,&nbsp;<code>Error<\/code>,&nbsp;<code>Fatal<\/code>). Log level is runtime-configurable via&nbsp;<code>RDK_WINDOW_MANAGER_LOG_LEVEL<\/code>. When built with&nbsp;<code>RDK_WINDOW_MANAGER_LOGGER<\/code>, output goes to&nbsp;<code>\/opt\/logs\/rdkwindowmanager.log<\/code>.<\/td><td><code>src\/logger.cpp<\/code>,&nbsp;<code>include\/logger.h<\/code><\/td><\/tr><tr><td><code>firebolt_shell<\/code>&nbsp;extension<\/td><td>Westeros plugin implementing the&nbsp;<code>firebolt_shell<\/code>&nbsp;Wayland protocol. Handles&nbsp;<code>get_firebolt_surface<\/code>&nbsp;requests from Wayland clients, forwarding surface-ID and type information to&nbsp;<code>CompositorController<\/code>.<\/td><td><code>extensions\/firebolt_shell\/src\/firebolt_shell.cpp<\/code>,&nbsp;<code>extensions\/firebolt_shell\/include\/firebolt_shell.h<\/code><\/td><\/tr><tr><td><code>firebolt_surface<\/code>&nbsp;extension<\/td><td>Westeros plugin implementing the&nbsp;<code>firebolt_surface<\/code>&nbsp;protocol: destroy, set_name, set_visible, set_bounds, set_crop, set_zorder, set_opacity.<\/td><td><code>extensions\/firebolt_surface\/src\/<\/code>,&nbsp;<code>extensions\/firebolt_surface\/include\/<\/code><\/td><\/tr><tr><td><code>firebolt_wm<\/code>&nbsp;extension<\/td><td>Westeros plugin implementing the&nbsp;<code>firebolt_wm<\/code>&nbsp;protocol for full surface management (create, create_with_bounds, create_with_properties, destroy, set_properties, set_client_bounds, set_client_display_bounds, set_client_focus, get_properties, get_focused_client, get_clients, set_owner, get_owner) and associated events.<\/td><td><code>extensions\/firebolt_wm\/src\/firebolt_wm.cpp<\/code>,&nbsp;<code>extensions\/firebolt_wm\/include\/firebolt_wm.h<\/code><\/td><\/tr><tr><td><code>VncServer<\/code>&nbsp;(optional)<\/td><td>TCP VNC server built on libsoup. Captures the compositor frame buffer into a&nbsp;<code>VncFrameBuffer<\/code>&nbsp;and serves it to connecting&nbsp;<code>VncClient<\/code>&nbsp;instances. Enabled only when&nbsp;<code>RDK_WINDOW_MANAGER_VNC_SERVER=ON<\/code>.<\/td><td><code>src\/VncServer\/<\/code>,&nbsp;<code>include\/VncServer\/<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RDKWindowManager-ComponentInteractions\">Component Interactions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-InteractionMatrix\">Interaction Matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Target Component \/ Layer<\/strong><\/td><td><strong>Interaction Purpose<\/strong><\/td><td><strong>Key APIs \/ Topics<\/strong><\/td><\/tr><tr><td><strong>Westeros Compositor<\/strong><\/td><td>Create, configure, and start per-application embedded Wayland compositors; receive client-status and invalidate callbacks<\/td><td><code>WstCompositorCreate()<\/code>,&nbsp;<code>WstCompositorStart()<\/code>,&nbsp;<code>WstCompositorSetIsEmbedded()<\/code>,&nbsp;<code>WstCompositorSetOutputSize()<\/code>,&nbsp;<code>WstCompositorSetDisplayName()<\/code>,&nbsp;<code>WstCompositorSetInvalidateCallback()<\/code>,&nbsp;<code>WstCompositorSetClientStatusCallback()<\/code>,&nbsp;<code>WstCompositorSetDispatchCallback()<\/code>,&nbsp;<code>WstCompositorDestroy()<\/code><\/td><\/tr><tr><td><strong>Essos<\/strong><\/td><td>Obtain display context, receive key and pointer events, manage resolution, control key repeats, block AV by app<\/td><td><code>EssContextCreate()<\/code>,&nbsp;<code>EssContextSetKeyListener()<\/code>,&nbsp;<code>EssContextSetPointerListener()<\/code>,&nbsp;<code>EssContextGetDisplaySize()<\/code>,&nbsp;<code>EssContextUpdateDisplay()<\/code>,&nbsp;<code>EssContextRunEventLoopOnce()<\/code><\/td><\/tr><tr><td><strong>Essos Resource Manager (ERM)<\/strong><\/td><td>Resource management and AV block\/unblock per application (optional, enabled by&nbsp;<code>BUILD_ENABLE_ERM<\/code>)<\/td><td><code>essos-resmgr<\/code>&nbsp;API,&nbsp;<code>EssRMgr<\/code>&nbsp;context<\/td><\/tr><tr><td><strong>Thunder Plugin<\/strong><\/td><td>Receive JSON-RPC control calls and forward to&nbsp;<code>CompositorController<\/code>; publish events back to Thunder clients<\/td><td><code>librdkwindowmanager.so<\/code>&nbsp;\u2014&nbsp;<code>CompositorController<\/code>&nbsp;static methods<\/td><\/tr><tr><td><strong>Wayland Client Applications<\/strong><\/td><td>Deliver key\/pointer events; notify of display size changes; receive connect\/disconnect lifecycle events<\/td><td>Wayland socket protocol;&nbsp;<code>firebolt_wm<\/code>,&nbsp;<code>firebolt_shell<\/code>,&nbsp;<code>firebolt_surface<\/code>&nbsp;protocol extensions<\/td><\/tr><tr><td><strong>OpenGL ES 2.0 \/ EGL<\/strong><\/td><td>Off-screen frame buffer rendering, texture blit, alpha blending<\/td><td><code>glEnable<\/code>,&nbsp;<code>glBlendFunc<\/code>,&nbsp;<code>glUseProgram<\/code>,&nbsp;<code>glDrawArrays<\/code>,&nbsp;<code>glUniform*<\/code>, FBO management<\/td><\/tr><tr><td><strong>libjpeg \/ libpng<\/strong><\/td><td>Decode image assets (watermarks, splash screen, cursor)<\/td><td><code>loadJpeg()<\/code>,&nbsp;<code>loadPng()<\/code>&nbsp;in&nbsp;<code>rdkwindowmanagerimage.cpp<\/code><\/td><\/tr><tr><td><strong>RapidJSON<\/strong><\/td><td>Parse input-device configuration JSON<\/td><td><code>RdkWindowManagerJson::readJsonFile()<\/code><\/td><\/tr><tr><td><strong>libsoup \/ GLib<\/strong>&nbsp;(optional)<\/td><td>TCP server for VNC remote access<\/td><td><code>VncSoupTcpServer<\/code>, GLib&nbsp;<code>GMainLoop<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-EventsPublished\">Events Published<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Event Name<\/strong><\/td><td><strong>Topic<\/strong><\/td><td><strong>Trigger Condition<\/strong><\/td><td><strong>Subscriber<\/strong><\/td><\/tr><tr><td><code>onApplicationConnected<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_CONNECTED<\/code><\/td><td>Westeros client connects to a display<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onApplicationDisconnected<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_DISCONNECTED<\/code><\/td><td>Westeros client disconnects from a display<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onApplicationTerminated<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_TERMINATED<\/code><\/td><td>Application process exits<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onReady<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_FIRST_FRAME<\/code><\/td><td>First frame rendered for a client<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onUserInactive<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_USER_INACTIVE<\/code><\/td><td>No key event for&nbsp;<code>gInactivityIntervalInSeconds<\/code>&nbsp;while inactivity reporting is enabled<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onApplicationVisible<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_VISIBLE<\/code><\/td><td>Visibility set to true for a client<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onApplicationHidden<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_HIDDEN<\/code><\/td><td>Visibility set to false for a client<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code><\/td><\/tr><tr><td><code>onApplicationFocus<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_FOCUS<\/code><\/td><td>Focus assigned to a client<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code>&nbsp;\/&nbsp;<code>firebolt_wm<\/code>&nbsp;(<code>focused_client<\/code>&nbsp;event)<\/td><\/tr><tr><td><code>onApplicationBlur<\/code><\/td><td><code>RDK_WINDOW_MANAGER_EVENT_APPLICATION_BLUR<\/code><\/td><td>Focus removed from a client<\/td><td>Thunder plugin \/&nbsp;<code>RdkWindowManagerEventListener<\/code>&nbsp;\/&nbsp;<code>firebolt_wm<\/code><\/td><\/tr><tr><td><code>client_connected<\/code><\/td><td><code>RDK_WINDOW_MANAGER_FIREBOLT_EXTENSION_EVENT_CLIENT_CONNECTED<\/code><\/td><td>Wayland client connects (Firebolt WM extension path)<\/td><td><code>firebolt_wm<\/code>&nbsp;Wayland clients<\/td><\/tr><tr><td><code>client_disconnected<\/code><\/td><td><code>RDK_WINDOW_MANAGER_FIREBOLT_EXTENSION_EVENT_CLIENT_DISCONNECTED<\/code><\/td><td>Wayland client disconnects (Firebolt WM extension path)<\/td><td><code>firebolt_wm<\/code>&nbsp;Wayland clients<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-IPCFlowPatterns\">IPC Flow Patterns<\/h3>\n\n\n\n<p><strong>Primary Request \/ Response Flow (Thunder JSON-RPC to CompositorController):<\/strong><\/p>\n\n\n\n<p>The Thunder plugin receives a JSON-RPC request, validates parameters, and calls the corresponding&nbsp;<code>CompositorController<\/code>&nbsp;static method directly through the shared library interface. The method return value or output parameter is converted back to a JSON-RPC response.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Client as Client Application\n    participant Thunder as WPEFramework (Thunder)\n    participant Plugin as RDK WM Thunder Plugin\n    participant CC as CompositorController\n\n    Client->>Thunder: JSON-RPC request (e.g., setFocus)\n    Thunder->>Plugin: Dispatch to plugin handler\n    Plugin->>CC: CompositorController::setFocus(client)\n    CC-->>Plugin: true \/ false\n    Plugin-->>Thunder: JSON-RPC response\n    Thunder-->>Client: JSON-RPC response<\/pre><\/div>\n\n\n\n<p><strong>Key Event Flow (Essos to CompositorController to Application):<\/strong><\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant HW as Linux Input Device\n    participant Essos as EssosInstance\n    participant CC as CompositorController\n    participant App as Focused Wayland App\n\n    HW->>Essos: Key event (Essos callback)\n    Essos->>Essos: Translate modifiers, process metadata\n    Essos->>CC: onKeyPress(keyCode, flags, metadata)\n    CC->>CC: Check ignoreKeyInputs flag\n    CC->>CC: Evaluate key intercepts\n    CC->>CC: Evaluate key listeners\n    CC->>App: compositor->onKeyPress(keyCode, flags, metadata)\n    App-->>CC: (processed)<\/pre><\/div>\n\n\n\n<p><strong>Event Notification Flow (Westeros client lifecycle to Thunder plugin):<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Wst as Westeros\n    participant Comp as RdkCompositor\n    participant CC as CompositorController\n    participant Plugin as Thunder Plugin\n\n    Wst->>Comp: clientStatus(WstClient_connected, pid, ...)\n    Comp->>CC: onEvent(compositor, \"onApplicationConnected\")\n    CC->>Plugin: listener->onApplicationConnected(client)\n    Plugin->>Plugin: Fire JSON-RPC OnConnected event<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RDKWindowManager-ImplementationDetails\">Implementation Details<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-MajorHALAPIsIntegration\">Major HAL APIs Integration<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>HAL \/ API<\/strong><\/td><td><strong>Purpose<\/strong><\/td><td><strong>Implementation File<\/strong><\/td><\/tr><tr><td><code>WstCompositorCreate()<\/code><\/td><td>Allocate a new Westeros compositor context<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetIsEmbedded()<\/code><\/td><td>Configure compositor as an embedded (nested) display<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetOutputSize()<\/code><\/td><td>Set the output resolution of the compositor<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetDisplayName()<\/code><\/td><td>Assign a Wayland display name to the compositor<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetInvalidateCallback()<\/code><\/td><td>Register invalidate (repaint request) callback<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetClientStatusCallback()<\/code><\/td><td>Register client connect\/disconnect\/terminate callback<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorSetDispatchCallback()<\/code><\/td><td>Register display-size-change dispatch callback<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorStart()<\/code><\/td><td>Start the Westeros compositor and its Wayland socket<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorDestroy()<\/code><\/td><td>Release a Westeros compositor context<\/td><td><code>src\/rdkcompositor.cpp<\/code><\/td><\/tr><tr><td><code>WstCompositorGetDisplayName()<\/code><\/td><td>Retrieve the auto-assigned Wayland display name<\/td><td><code>src\/rdkcompositornested.cpp<\/code><\/td><\/tr><tr><td>Essos context APIs<\/td><td>Initialise display context, register key\/pointer listeners, update event loop<\/td><td><code>src\/essosinstance.cpp<\/code><\/td><\/tr><tr><td>GLES2 draw calls (<code>glEnable<\/code>,&nbsp;<code>glBlendFunc<\/code>,&nbsp;<code>glUseProgram<\/code>,&nbsp;<code>glDrawArrays<\/code>)<\/td><td>Configure alpha blending; render compositor surfaces and images to screen<\/td><td><code>src\/rdkwindowmanager.cpp<\/code>,&nbsp;<code>src\/framebufferrenderer.cpp<\/code>,&nbsp;<code>src\/rdkwindowmanagerimage.cpp<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-KeyImplementationLogic\">Key Implementation Logic<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>State \/ Lifecycle Management<\/strong>: Application state per compositor (<code>Unknown<\/code>,\u00a0<code>Running<\/code>,\u00a0<code>Suspended<\/code>,\u00a0<code>Stopped<\/code>) is tracked in\u00a0<code>RdkCompositor::mApplicationState<\/code>. Transitions are driven by\u00a0<code>WstClient_*<\/code>\u00a0status codes received in\u00a0<code>RdkCompositor::onClientStatus()<\/code>. The global flag\u00a0<code>gRdkWindowManagerIsRunning<\/code>\u00a0controls the main frame loop.<\/li>\n\n\n\n<li>Core lifecycle:\u00a0<code>src\/rdkwindowmanager.cpp<\/code><\/li>\n\n\n\n<li>Per-compositor state:\u00a0<code>src\/rdkcompositor.cpp<\/code><\/li>\n\n\n\n<li><strong>Event Processing<\/strong>: Essos key callbacks (<code>processKeyEvent<\/code>\u00a0in\u00a0<code>essosinstance.cpp<\/code>) translate raw Wayland key codes using\u00a0<code>keyCodeFromWayland()<\/code>, pack modifier flags, and call\u00a0<code>CompositorController::onKeyPress<\/code>\u00a0\/\u00a0<code>onKeyRelease<\/code>.\u00a0<code>CompositorController<\/code>\u00a0first checks\u00a0<code>gIgnoreKeyInputEnabled<\/code>, then evaluates the key-intercept map (<code>gKeyInterceptInfoMap<\/code>), and finally dispatches to the focused compositor or evaluates the key-listener table for each matching compositor. Key-repeat generation is handled in\u00a0<code>CompositorController::update()<\/code>\u00a0using\u00a0<code>gKeyRepeatConfig<\/code>.<\/li>\n\n\n\n<li><strong>Error Handling Strategy<\/strong>: Westeros API failures are logged at\u00a0<code>Information<\/code>\u00a0level and propagate as\u00a0<code>bool<\/code>\u00a0return values from\u00a0<code>createDisplay()<\/code>. A failure at any Westeros setup step sets a local\u00a0<code>error<\/code>\u00a0flag that causes\u00a0<code>createDisplay<\/code>\u00a0to return\u00a0<code>false<\/code>, which the caller (Thunder plugin) maps to a JSON-RPC error response.<\/li>\n\n\n\n<li><strong>Logging &amp; Diagnostics<\/strong>: Log output uses the\u00a0<code>RdkWindowManager::Logger<\/code>\u00a0class. Log levels:\u00a0<code>Debug<\/code>,\u00a0<code>Information<\/code>,\u00a0<code>Warn<\/code>,\u00a0<code>Error<\/code>,\u00a0<code>Fatal<\/code>. Runtime log level is set via the\u00a0<code>RDK_WINDOW_MANAGER_LOG_LEVEL<\/code>\u00a0environment variable. When built with\u00a0<code>RDK_WINDOW_MANAGER_LOGGER<\/code>, log output is written to\u00a0<code>\/opt\/logs\/rdkwindowmanager.log<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"RDKWindowManager-Configuration\">Configuration<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-KeyConfigurationFiles\">Key Configuration Files<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Configuration File<\/strong><\/td><td><strong>Purpose<\/strong><\/td><td><strong>Override Mechanism<\/strong><\/td><\/tr><tr><td>Path from&nbsp;<code>RDK_WINDOW_MANAGER_INPUT_DEVICES_CONFIG<\/code><\/td><td>JSON file mapping input device vendor\/product IDs to device type and mode, used to annotate key-press metadata<\/td><td>Environment variable at process start<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-KeyConfigurationParameters\">Key Configuration Parameters<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Parameter<\/strong><\/td><td><strong>Type<\/strong><\/td><td><strong>Default<\/strong><\/td><td><strong>Description<\/strong><\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_FRAMERATE<\/code><\/td><td>int<\/td><td><code>40<\/code><\/td><td>Target render frames per second for the main compositor loop.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_LOW_MEMORY_THRESHOLD<\/code><\/td><td>double (MB)<\/td><td><code>200<\/code><\/td><td>Parsed at startup; intended RAM threshold for low-memory warnings (memory monitoring is not currently started).<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_CRITICALLY_LOW_MEMORY_THRESHOLD<\/code><\/td><td>double (MB)<\/td><td><code>100<\/code><\/td><td>Parsed at startup; intended RAM threshold for critically-low-memory warnings (memory monitoring is not currently started).<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_SWAP_MEMORY_INCREASE_THRESHOLD<\/code><\/td><td>double (MB)<\/td><td><code>50<\/code><\/td><td>Parsed at startup; intended swap-growth threshold (MB per interval) (memory monitoring is not currently started).<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_KEY_INITIAL_DELAY<\/code><\/td><td>int (ms)<\/td><td><code>500<\/code><\/td><td>Delay before key-repeat begins, forwarded to Essos.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_KEY_REPEAT_INTERVAL<\/code><\/td><td>int (ms)<\/td><td><code>100<\/code><\/td><td>Interval between repeated key events while a key is held.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_LOG_LEVEL<\/code><\/td><td>string<\/td><td><code>Info<\/code><\/td><td>Runtime log level (<code>Debug<\/code>,&nbsp;<code>Info<\/code>,&nbsp;<code>Warn<\/code>,&nbsp;<code>Error<\/code>,&nbsp;<code>Fatal<\/code>).<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_SET_GRAPHICS_720<\/code><\/td><td>string (<code>\"1\"<\/code>)<\/td><td>unset<\/td><td>Force graphics resolution to 1280\u00d7720 instead of 1920\u00d71080. Requires&nbsp;<code>RDK_WINDOW_MANAGER_BUILD_FORCE_1080=ON<\/code>.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_INPUT_DEVICES_CONFIG<\/code><\/td><td>string (path)<\/td><td>unset<\/td><td>Path to the JSON input-device classification configuration file.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_WESTEROS_PLUGIN_FOLDER<\/code><\/td><td>string (path)<\/td><td>unset<\/td><td>CMake cache variable that sets the compiled-in Westeros extension plugin directory (defaults to&nbsp;<code>\/usr\/lib\/plugins\/westeros\/<\/code>).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-RuntimeConfiguration\">Runtime Configuration<\/h3>\n\n\n\n<p>The render frame rate and memory thresholds are configured through environment variables read at process startup. Key-intercept and key-listener registrations, focus assignments, visibility, opacity, z-order, and bounds are adjustable at runtime through the&nbsp;<code>CompositorController<\/code>&nbsp;API, surfaced via the Thunder plugin JSON-RPC interface.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"RDKWindowManager-Build-TimeConfigurationFlags\">Build-Time Configuration Flags<\/h3>\n\n\n\n<p>The following flags are defined in&nbsp;<code>CMakeLists.txt<\/code>&nbsp;and control compiled-in feature availability:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Flag<\/strong><\/td><td><strong>Default<\/strong><\/td><td><strong>Effect<\/strong><\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_VNC_SERVER<\/code><\/td><td><code>OFF<\/code>&nbsp;(prod),&nbsp;<code>ON<\/code>&nbsp;(non-prod via bb file)<\/td><td>Builds the VNC server (libsoup\/GLib\/Boost required).<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_EXTENSIONS<\/code><\/td><td><code>ON<\/code><\/td><td>Enables compilation of&nbsp;<code>firebolt_shell<\/code>,&nbsp;<code>firebolt_surface<\/code>, and&nbsp;<code>firebolt_wm<\/code>&nbsp;Wayland extension plugins.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_FORCE_1080<\/code><\/td><td><code>ON<\/code><\/td><td>Enables 1080p\/720p forced-resolution logic at startup.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_KEY_METADATA<\/code><\/td><td><code>OFF<\/code><\/td><td>Enables key-press metadata (device-type, device-mode info) propagation to applications.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_HIDDEN_SUPPORT<\/code><\/td><td><code>OFF<\/code><\/td><td>Enables hidden-surface support.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_KEYBUBBING_TOP_MODE<\/code><\/td><td><code>ON<\/code><\/td><td>Enables key-bubbling-to-topmost-compositor mode.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_ENABLE_KEYREPEATS<\/code><\/td><td><code>OFF<\/code><\/td><td>Enables built-in key-repeat delivery.<\/td><\/tr><tr><td><code>RDK_WINDOW_MANAGER_BUILD_EXTERNAL_APPLICATION_SURFACE_COMPOSITION<\/code><\/td><td><code>ON<\/code><\/td><td>Enables external application surface composition path.<\/td><\/tr><tr><td><code>BUILD_ENABLE_ERM<\/code><\/td><td>unset<\/td><td>Enables Essos Resource Manager integration for AV blocking.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><a href=\"https:\/\/wiki.rdkcentral.com\/spaces\/DOC\/pages\/502404658\/RDK+Window+Manager\"><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>RDK Window Manager (rdkwindowmanager) is responsible for creating Wayland displays, compositing application surfaces, managing window [&hellip;]<\/p>\n","protected":false},"author":659,"featured_media":0,"parent":9844,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-12982","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RDK Window Manager - RDK Documentation Portal | Documentation<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RDK Window Manager - RDK Documentation Portal | Documentation\" \/>\n<meta property=\"og:description\" content=\"RDK Window Manager (rdkwindowmanager) is responsible for creating Wayland displays, compositing application surfaces, managing window [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/\" \/>\n<meta property=\"og:site_name\" content=\"RDK Documentation Portal | Documentation\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-28T07:20:40+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/\",\"url\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/\",\"name\":\"RDK Window Manager - RDK Documentation Portal | Documentation\",\"isPartOf\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/#website\"},\"datePublished\":\"2026-07-28T07:18:47+00:00\",\"dateModified\":\"2026-07-28T07:20:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Documentation\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"RDK Video\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Components\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/\"},{\"@type\":\"ListItem\",\"position\":5,\"name\":\"RDK Window Manager\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/#website\",\"url\":\"https:\/\/developer.rdkcentral.com\/documentation\/\",\"name\":\"RDK Documentation Portal | Documentation\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/developer.rdkcentral.com\/documentation\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RDK Window Manager - RDK Documentation Portal | Documentation","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/","og_locale":"en_US","og_type":"article","og_title":"RDK Window Manager - RDK Documentation Portal | Documentation","og_description":"RDK Window Manager (rdkwindowmanager) is responsible for creating Wayland displays, compositing application surfaces, managing window [&hellip;]","og_url":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/","og_site_name":"RDK Documentation Portal | Documentation","article_modified_time":"2026-07-28T07:20:40+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/","url":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/","name":"RDK Window Manager - RDK Documentation Portal | Documentation","isPartOf":{"@id":"https:\/\/developer.rdkcentral.com\/documentation\/#website"},"datePublished":"2026-07-28T07:18:47+00:00","dateModified":"2026-07-28T07:20:40+00:00","breadcrumb":{"@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/rdk-window-manager\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/developer.rdkcentral.com\/documentation\/"},{"@type":"ListItem","position":2,"name":"Documentation","item":"https:\/\/developer.rdkcentral.com\/documentation\/"},{"@type":"ListItem","position":3,"name":"RDK Video","item":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/"},{"@type":"ListItem","position":4,"name":"Components","item":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_video_documentation\/components\/"},{"@type":"ListItem","position":5,"name":"RDK Window Manager"}]},{"@type":"WebSite","@id":"https:\/\/developer.rdkcentral.com\/documentation\/#website","url":"https:\/\/developer.rdkcentral.com\/documentation\/","name":"RDK Documentation Portal | Documentation","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/developer.rdkcentral.com\/documentation\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/12982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/users\/659"}],"replies":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/comments?post=12982"}],"version-history":[{"count":1,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/12982\/revisions"}],"predecessor-version":[{"id":12983,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/12982\/revisions\/12983"}],"up":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/9844"}],"wp:attachment":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/media?parent=12982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}