fix(overlay): Linux X11/XWayland stacking, stale pause state, multi-copy selector (#101)

This commit is contained in:
2026-05-31 20:59:18 -07:00
committed by GitHub
parent b46b8dfa41
commit e1ea464bc9
103 changed files with 6314 additions and 353 deletions
+34
View File
@@ -0,0 +1,34 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { shouldForceX11ElectronBackend } from './electron-backend';
function withPlatform(platform: NodeJS.Platform, run: () => void): void {
const original = Object.getOwnPropertyDescriptor(process, 'platform');
Object.defineProperty(process, 'platform', { configurable: true, value: platform });
try {
run();
} finally {
if (original) Object.defineProperty(process, 'platform', original);
}
}
test('shouldForceX11ElectronBackend forces X11 on Linux except Hyprland/Sway', () => {
withPlatform('linux', () => {
assert.equal(shouldForceX11ElectronBackend({ XDG_CURRENT_DESKTOP: 'KDE' }), true);
assert.equal(shouldForceX11ElectronBackend({ WAYLAND_DISPLAY: 'wayland-0' }), true);
// Even an explicit Wayland hint is overridden to x11 on unsupported compositors.
assert.equal(shouldForceX11ElectronBackend({ ELECTRON_OZONE_PLATFORM_HINT: 'wayland' }), true);
// Hyprland/Sway keep native Wayland (guard reports explicit wayland hints elsewhere).
assert.equal(shouldForceX11ElectronBackend({ HYPRLAND_INSTANCE_SIGNATURE: 'hypr' }), false);
assert.equal(shouldForceX11ElectronBackend({ SWAYSOCK: '/tmp/sway.sock' }), false);
});
});
test('shouldForceX11ElectronBackend is false off Linux', () => {
withPlatform('darwin', () => {
assert.equal(shouldForceX11ElectronBackend({ XDG_CURRENT_DESKTOP: 'KDE' }), false);
});
withPlatform('win32', () => {
assert.equal(shouldForceX11ElectronBackend({}), false);
});
});
+21 -10
View File
@@ -1,27 +1,38 @@
import { CliArgs, shouldStartApp } from '../../cli/args';
import { createLogger } from '../../logger';
import { isSupportedWaylandCompositor } from '../../shared/mpv-x11-backend';
const logger = createLogger('core:electron-backend');
function getElectronOzonePlatformHint(): string | null {
const hint = process.env.ELECTRON_OZONE_PLATFORM_HINT?.trim().toLowerCase();
function getElectronOzonePlatformHint(env: NodeJS.ProcessEnv = process.env): string | null {
const hint = env.ELECTRON_OZONE_PLATFORM_HINT?.trim().toLowerCase();
if (hint) return hint;
const ozone = process.env.OZONE_PLATFORM?.trim().toLowerCase();
const ozone = env.OZONE_PLATFORM?.trim().toLowerCase();
if (ozone) return ozone;
return null;
}
function shouldPreferWaylandBackend(): boolean {
return Boolean(process.env.HYPRLAND_INSTANCE_SIGNATURE || process.env.SWAYSOCK);
/**
* Should the Electron app be pinned to the X11/XWayland ozone backend? True on Linux
* unless we're on a natively-supported Wayland compositor (Hyprland/Sway) or the user
* explicitly opted into the (unsupported) Wayland backend — which is reported by
* {@link enforceUnsupportedWaylandMode} instead.
*
* The overlay relies on `setAlwaysOnTop`/`moveTop` to stay above mpv; those are no-ops
* under a native Wayland surface, so XWayland is required for parity with Win/macOS. An
* explicit `ELECTRON_OZONE_PLATFORM_HINT=wayland` is still overridden to x11 here (the
* 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;
return !isSupportedWaylandCompositor(env);
}
export function forceX11Backend(args: CliArgs): void {
if (process.platform !== 'linux') return;
if (!shouldStartApp(args)) return;
if (shouldPreferWaylandBackend()) return;
const hint = getElectronOzonePlatformHint();
if (hint === 'x11') return;
if (!shouldForceX11ElectronBackend()) return;
if (getElectronOzonePlatformHint() === 'x11') return;
process.env.ELECTRON_OZONE_PLATFORM_HINT = 'x11';
process.env.OZONE_PLATFORM = 'x11';
+5 -1
View File
@@ -1,5 +1,9 @@
export { generateDefaultConfigFile } from './config-gen';
export { enforceUnsupportedWaylandMode, forceX11Backend } from './electron-backend';
export {
enforceUnsupportedWaylandMode,
forceX11Backend,
shouldForceX11ElectronBackend,
} from './electron-backend';
export { resolveKeybindings } from './keybindings';
export { resolveConfiguredShortcuts } from './shortcut-config';
export { showDesktopNotification } from './notification';