-
Notifications
You must be signed in to change notification settings - Fork 0
Multi Display Orchestration
Webpage Signage Runner is architected from the ground up for multi-monitor setups, video walls, digital menu boards, and heterogeneous display arrays.
Electron provides physical screen information via electron.screen.getAllDisplays(). In multi-monitor systems, screens are arranged along a virtual desktop canvas that spans across negative and positive X and Y coordinate spaces.
Virtual Desktop Coordinate Space
┌────────────────────────────┬────────────────────────────┐
│ Display 1 (Primary) │ Display 2 (Secondary) │
│ Bounds: { x: 0, y: 0, │ Bounds: { x: 1920, y: 0, │
│ w: 1920, h: 1080}│ w: 3840, h: 2160}│
│ Zoom: 1.0 (100%) │ Zoom: 1.5 (150% 4K scale) │
│ URL: https://youtube.com │ URL: https://grafana.int/ │
└────────────────────────────┴────────────────────────────┘
The internal WindowManager module executes the following lifecycle for each detected screen:
-
Calculates Exact Screen Bounds: Retrieves the physical rectangle (
{ x, y, width, height }) without relying on the OS taskbar work area. -
Creates Borderless, Frameless Window:
frame: falsekiosk: truealwaysOnTop: trueskipTaskbar: trueenableLargerThanScreen: true
-
Explicit Coordinate Pinning: Calls
window.setBounds(display.bounds)before rendering, ensuring the window cannot drift onto adjacent monitors or snap back to the primary display. -
DPI & Scale Factor Handling: Detects
display.scaleFactorand automatically applies configuredzoomFactorviawebContents.setZoomFactor().
Digital signage hardware in field deployments frequently encounters HDMI/DisplayPort handshakes, cables being disconnected, or displays powered down by building timers.
Webpage Signage Runner attaches listeners to OS display events:
-
screen.on('display-added'): When a new monitor is connected, the app detects its bounds, checksconfig.jsonfor a matching display ID or applies thedefaultUrl, and spawns a new kiosk window seamlessly without disrupting existing displays. -
screen.on('display-removed'): When a monitor is disconnected, the associated window and watchdog timers are cleanly disposed of to free RAM. -
screen.on('display-metrics-changed'): If resolution or rotation changes (e.g. pivoting a screen from landscape to portrait), the window bounds are recalculated and adjusted live.
When setting up 4, 8, or 16 screens on a video wall matrix, physical cables rarely match the logical numbering assigned by the operating system.
Webpage Signage Runner includes a built-in Visual Screen Identifier:
- Trigger via Wizard: Click the "Identify Screens" button in the setup wizard.
-
Trigger via REST API: Send a POST request to
http://<ip>:9191/api/identify. -
Behavior:
- Opens a transparent, high-contrast overlay window on every connected display.
- Renders a prominent badge displaying:
- Display Index (e.g. Display #1, Display #2)
- Hardware ID
- Resolution (e.g.
3840 x 2160 @ 60Hz) - Scale factor & Primary status
- Automatically fades out and closes after 5 seconds.
In unattended public kiosks, visible mouse cursors degrade visual presentation.
Webpage Signage Runner suppresses cursors at the renderer level:
- Injects a universal CSS rule:
* { cursor: none !important; }
- Can be toggled globally via
hideCursorGlobalinconfig.jsonor individually per display (hideCursor: true/false).
Webpage Signage Runner leverages Chromium's GPU acceleration:
- WebGL 2.0 and hardware-accelerated canvas rendering are enabled by default.
- Video decoding (H.264, VP9, AV1) uses OS GPU hardware decoding for smooth 4K/60fps playback on YouTube, HTML5 video streams, and interactive 3D dashboards.
Webpage Signage Runner Wiki • Created & Maintained with ❤️ by Maximiliano Contartesi • LinkedIn • GitHub Repository • MIT License
By Maximiliano Contartesi