fix(overlay): handle X11 display scaling across monitors (#193)

This commit is contained in:
2026-08-11 22:24:01 -07:00
committed by GitHub
parent ee25536d90
commit 57ddd19953
14 changed files with 272 additions and 37 deletions
+68 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { shouldForceX11ElectronBackend } from './electron-backend';
import { resolveX11ElectronRelaunchArgs, shouldForceX11ElectronBackend } from './electron-backend';
function withPlatform(platform: NodeJS.Platform, run: () => void): void {
const original = Object.getOwnPropertyDescriptor(process, 'platform');
@@ -32,3 +32,70 @@ test('shouldForceX11ElectronBackend is false off Linux', () => {
assert.equal(shouldForceX11ElectronBackend({}), false);
});
});
test('resolveX11ElectronRelaunchArgs adds the raw X11 Ozone argument on unsupported Linux', () => {
assert.deepEqual(
resolveX11ElectronRelaunchArgs(
['--start'],
{
DISPLAY: ':1',
WAYLAND_DISPLAY: 'wayland-0',
XDG_CURRENT_DESKTOP: 'KDE',
},
'linux',
),
['--start', '--ozone-platform=x11'],
);
});
test('resolveX11ElectronRelaunchArgs avoids loops and preserves native Wayland backends', () => {
const kdeWayland = {
DISPLAY: ':1',
WAYLAND_DISPLAY: 'wayland-0',
XDG_CURRENT_DESKTOP: 'KDE',
};
assert.equal(
resolveX11ElectronRelaunchArgs(['--start', '--ozone-platform=x11'], kdeWayland, 'linux'),
null,
);
assert.equal(
resolveX11ElectronRelaunchArgs(
['--start'],
{ ...kdeWayland, HYPRLAND_INSTANCE_SIGNATURE: 'hypr' },
'linux',
),
null,
);
assert.equal(resolveX11ElectronRelaunchArgs(['--start'], kdeWayland, 'darwin'), null);
assert.equal(
resolveX11ElectronRelaunchArgs(
[],
{
...kdeWayland,
SUBMINER_APP_ARGC: '1',
SUBMINER_APP_ARG_0: '--start',
},
'linux',
)?.at(-1),
'--ozone-platform=x11',
);
assert.equal(
resolveX11ElectronRelaunchArgs([], { ...kdeWayland, SUBMINER_X11_BOOTSTRAPPED: '1' }, 'linux'),
null,
);
});
test('resolveX11ElectronRelaunchArgs replaces an explicit unsupported Wayland argument', () => {
assert.deepEqual(
resolveX11ElectronRelaunchArgs(
['--start', '--ozone-platform', 'wayland'],
{
DISPLAY: ':1',
WAYLAND_DISPLAY: 'wayland-0',
XDG_CURRENT_DESKTOP: 'KDE',
},
'linux',
),
['--start', '--ozone-platform=x11'],
);
});
+36 -2
View File
@@ -4,6 +4,9 @@ import { isSupportedWaylandCompositor } from '../../shared/mpv-x11-backend';
const logger = createLogger('core:electron-backend');
export const X11_ELECTRON_BOOTSTRAP_ENV = 'SUBMINER_X11_BOOTSTRAPPED';
const X11_ELECTRON_OZONE_ARG = '--ozone-platform=x11';
function getElectronOzonePlatformHint(env: NodeJS.ProcessEnv = process.env): string | null {
const hint = env.ELECTRON_OZONE_PLATFORM_HINT?.trim().toLowerCase();
if (hint) return hint;
@@ -24,11 +27,42 @@ function getElectronOzonePlatformHint(env: NodeJS.ProcessEnv = process.env): str
* Electron Wayland backend is unsupported); the Hyprland/Sway case is left untouched so
* {@link enforceUnsupportedWaylandMode} can report it.
*/
export function shouldForceX11ElectronBackend(env: NodeJS.ProcessEnv = process.env): boolean {
if (process.platform !== 'linux') return false;
export function shouldForceX11ElectronBackend(
env: NodeJS.ProcessEnv = process.env,
platform: NodeJS.Platform = process.platform,
): boolean {
if (platform !== 'linux') return false;
return !isSupportedWaylandCompositor(env);
}
export function resolveX11ElectronRelaunchArgs(
args: string[],
env: NodeJS.ProcessEnv = process.env,
platform: NodeJS.Platform = process.platform,
): string[] | null {
if (!shouldForceX11ElectronBackend(env, platform)) return null;
if (env[X11_ELECTRON_BOOTSTRAP_ENV] === '1') return null;
const retainedArgs: string[] = [];
let alreadyForced = false;
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === '--ozone-platform') {
const value = args[index + 1];
alreadyForced = value?.trim().toLowerCase() === 'x11';
if (value && !value.startsWith('--')) index += 1;
continue;
}
if (arg?.startsWith('--ozone-platform=')) {
alreadyForced = arg.slice('--ozone-platform='.length).trim().toLowerCase() === 'x11';
continue;
}
if (arg) retainedArgs.push(arg);
}
return alreadyForced ? null : [...retainedArgs, X11_ELECTRON_OZONE_ARG];
}
export function forceX11Backend(args: CliArgs): void {
if (!shouldStartApp(args)) return;
if (!shouldForceX11ElectronBackend()) return;