diff --git a/README.md b/README.md index 5ac4062a..3b1755c8 100644 --- a/README.md +++ b/README.md @@ -468,6 +468,7 @@ Full function reference with examples can be found at | | uefi | X | X | X | X | | OS started via UEFI | | | hypervisor | | | | X | | hyper-v enabled? (win only) | | | remoteSession | | | | X | | runs in remote session (win only) | +| | displayServer | X | X | X | X | X | display server e.g. wayland, x11, quartz, dwm, surfaceflinger or '' (headless) | | si.uuid(cb) | {...} | X | X | X | X | X | object of several UUIDs | | | os | X | X | X | X | | os specific UUID | | | hardware | X | X | X | X | | hardware specific UUID | diff --git a/docs/os.html b/docs/os.html index eec6157f..572ad6bc 100644 --- a/docs/os.html +++ b/docs/os.html @@ -236,6 +236,16 @@

Operating System, Shell, Versions, Users

runs in remote session (win only) + + + displayServer + X + X + X + X + X + display server: wayland, x11, quartz, dwm, tty + @@ -257,7 +267,8 @@
Example
serial: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', build: '19D76', servicepack: '', - uefi: true + uefi: true, + displayServer: 'quartz' } diff --git a/docs/v4/os.html b/docs/v4/os.html index add0487c..3d96222b 100644 --- a/docs/v4/os.html +++ b/docs/v4/os.html @@ -216,6 +216,16 @@

Operating System, Shell, Versions, Users

OS uses UEFI on startup + + + displayServer + X + X + X + X + X + display server: wayland, x11, quartz, dwm, tty + @@ -237,7 +247,8 @@
Example
serial: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', build: '19D76', servicepack: '', - uefi: true + uefi: true, + displayServer: 'quartz' } diff --git a/lib/index.d.ts b/lib/index.d.ts index e38786f4..f481f41e 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -379,6 +379,7 @@ export namespace Systeminformation { uefi: boolean | null; hypervizor?: boolean; remoteSession?: boolean; + displayServer: string; } interface UuidData { diff --git a/lib/osinfo.js b/lib/osinfo.js index f8ae96cb..d3ada2f6 100644 --- a/lib/osinfo.js +++ b/lib/osinfo.js @@ -217,6 +217,81 @@ function getFQDN() { return fqdn; } +// -------------------------- +// Display Server Detection + +function getDisplayServer() { + let result = ''; + + // Linux and BSD systems can use X11, Wayland, or run headless (tty) + // Android uses SurfaceFlinger + if (_linux || _freebsd || _openbsd || _netbsd || _sunos) { + // Check for Android's SurfaceFlinger first + if (_platform === 'android') { + try { + // Check if surfaceflinger process is running + const stdout = execSync('pgrep -f surfaceflinger 2>/dev/null || ps -A 2>/dev/null | grep surfaceflinger', { encoding: 'utf8' }); + if (stdout && stdout.trim()) { + result = 'surfaceflinger'; + } + } catch { + // If check fails, still might be Android but headless or termux environment + result = ''; + } + } else { + // Primary method: XDG_SESSION_TYPE is the most reliable + const sessionType = process.env.XDG_SESSION_TYPE || ''; + if (sessionType) { + result = sessionType.toLowerCase(); + } else { + // Fallback: check for display environment variables + if (process.env.WAYLAND_DISPLAY) { + result = 'wayland'; + } else if (process.env.DISPLAY) { + result = 'x11'; + } else { + // No GUI - TTY/console session or headless + result = ''; + } + } + } + } + + // macOS uses Quartz Compositor when GUI is active + if (_darwin) { + try { + // Try to verify WindowServer is running + const stdout = execSync('pgrep WindowServer 2>/dev/null', { encoding: 'utf8' }); + // If output exists, WindowServer is running + if (stdout && stdout.trim()) { + result = 'quartz'; + } + } catch { + // If pgrep fails or WindowServer not found, assume headless + result = ''; + } + } + + // Windows uses DWM (Desktop Window Manager) when GUI is active + // Note: WSL2/WSLg is detected as Linux, not Windows + if (_windows) { + try { + // Check if dwm.exe process exists using simpler tasklist approach + const stdout = execSync('tasklist /NH /FI "IMAGENAME eq dwm.exe"', util.execOptsWin); + const output = stdout.toString().toLowerCase(); + // If dwm.exe in output, GUI is running + if (output && output.indexOf('dwm.exe') !== -1) { + result = 'dwm'; + } + } catch { + // If tasklist fails or dwm.exe not found, assume headless + result = ''; + } + } + + return result; +} + // -------------------------- // OS Information @@ -237,7 +312,8 @@ function osInfo(callback) { serial: '', build: '', servicepack: '', - uefi: false + uefi: false, + displayServer: '' }; if (_linux) { @@ -273,6 +349,7 @@ function osInfo(callback) { result.codename = codename; result.codepage = util.getCodepage(); result.build = (release.BUILD_ID || '').replace(/"/g, '').trim(); + result.displayServer = getDisplayServer(); isUefiLinux().then((uefi) => { result.uefi = uefi; uuid().then((data) => { @@ -302,6 +379,7 @@ function osInfo(callback) { result.codename = ''; result.codepage = util.getCodepage(); result.uefi = uefi || null; + result.displayServer = getDisplayServer(); if (callback) { callback(result); } @@ -337,6 +415,7 @@ function osInfo(callback) { result.codename = result.release.startsWith('26.') ? 'Tahoe' : result.codename; result.uefi = true; result.codepage = util.getCodepage(); + result.displayServer = getDisplayServer(); if (callback) { callback(result); } @@ -349,6 +428,7 @@ function osInfo(callback) { const lines = stdout.toString().split('\n'); result.distro = lines[0]; result.logofile = getLogoFile(result.distro); + result.displayServer = getDisplayServer(); if (callback) { callback(result); } @@ -383,6 +463,7 @@ function osInfo(callback) { result.codename = getWindowsRelease(buildNum); } result.remoteSession = term.toString().toLowerCase().indexOf('true') >= 0; + result.displayServer = getDisplayServer(); isUefiWindows().then((uefi) => { result.uefi = uefi; if (callback) {