fix: align Hyprland overlay windows to mpv and stop pinning them

- Force-apply exact Hyprland move/resize/setprop dispatches when bounds are provided
- Stop pinning overlay windows; toggle pin off when Hyprland reports pinned=true
- Compensate stats overlay outer placement for Electron/Wayland content insets
- Make stats overlay window and page opaque so mpv cannot show through transparent insets
- Constrain stats app to h-screen with internal scroll so content covers mpv from y=0
- Lock overlay/stats window titles against page-title-updated events
- Add regression coverage for placement dispatches, inset compensation, and CSS overlay mode
This commit is contained in:
2026-05-03 23:56:52 -07:00
parent 8342fa0c0e
commit 4d5bf3de41
15 changed files with 398 additions and 85 deletions
@@ -53,32 +53,67 @@ test('findHyprlandWindowForPlacement matches current process by title', () => {
assert.equal(client?.address, '0xmatch');
});
test('buildHyprlandPlacementDispatches floats and pins tiled overlay windows', () => {
test('buildHyprlandPlacementDispatches floats tiled overlay windows without pinning them', () => {
assert.deepEqual(
buildHyprlandPlacementDispatches({
address: '0xabc',
floating: false,
pinned: false,
}),
[['dispatch', 'setfloating', 'address:0xabc']],
);
});
test('buildHyprlandPlacementDispatches force-aligns floating overlay windows to target bounds', () => {
assert.deepEqual(
buildHyprlandPlacementDispatches(
{
address: '0xabc',
floating: true,
pinned: false,
},
{
x: 0,
y: 0,
width: 1920,
height: 1080,
},
),
[
['dispatch', 'setfloating', 'address:0xabc'],
['dispatch', 'pin', 'address:0xabc'],
['dispatch', 'movewindowpixel', 'exact 0 0,address:0xabc'],
['dispatch', 'resizewindowpixel', 'exact 1920 1080,address:0xabc'],
['dispatch', 'setprop', 'address:0xabc rounding 0'],
['dispatch', 'setprop', 'address:0xabc border_size 0'],
['dispatch', 'setprop', 'address:0xabc no_shadow 1'],
['dispatch', 'setprop', 'address:0xabc no_blur 1'],
['dispatch', 'setprop', 'address:0xabc decorate 0'],
],
);
});
test('buildHyprlandPlacementDispatches skips already floating and pinned windows', () => {
test('buildHyprlandPlacementDispatches does not pin already floating overlay windows', () => {
assert.deepEqual(
buildHyprlandPlacementDispatches({
address: '0xabc',
floating: true,
pinned: false,
}),
[],
);
});
test('buildHyprlandPlacementDispatches unpins previously pinned overlay windows', () => {
assert.deepEqual(
buildHyprlandPlacementDispatches({
address: '0xabc',
floating: true,
pinned: true,
}),
[],
[['dispatch', 'pin', 'address:0xabc']],
);
});
test('ensureHyprlandWindowFloatingByTitle dispatches placement for matching tiled window', () => {
test('ensureHyprlandWindowFloatingByTitle dispatches float-only placement for matching tiled window', () => {
const calls: unknown[][] = [];
const placed = ensureHyprlandWindowFloatingByTitle({
title: 'SubMiner Stats',
@@ -111,7 +146,55 @@ test('ensureHyprlandWindowFloatingByTitle dispatches placement for matching tile
[
['-j', 'clients'],
['dispatch', 'setfloating', 'address:0xmatch'],
['dispatch', 'pin', 'address:0xmatch'],
],
);
});
test('ensureHyprlandWindowFloatingByTitle dispatches exact Hyprland geometry when bounds are provided', () => {
const calls: unknown[][] = [];
const placed = ensureHyprlandWindowFloatingByTitle({
title: 'SubMiner Stats',
platform: 'linux',
env: {
HYPRLAND_INSTANCE_SIGNATURE: 'abc',
},
pid: 456,
bounds: {
x: 0,
y: 0,
width: 1920,
height: 1080,
},
execFileSync: ((command: string, args: string[], options: unknown) => {
calls.push([command, args, options]);
if (args.join(' ') === '-j clients') {
return JSON.stringify([
{
address: '0xmatch',
pid: 456,
title: 'SubMiner Stats',
mapped: true,
floating: true,
pinned: false,
},
]);
}
return '';
}) as never,
});
assert.equal(placed, true);
assert.deepEqual(
calls.map(([, args]) => args),
[
['-j', 'clients'],
['dispatch', 'movewindowpixel', 'exact 0 0,address:0xmatch'],
['dispatch', 'resizewindowpixel', 'exact 1920 1080,address:0xmatch'],
['dispatch', 'setprop', 'address:0xmatch rounding 0'],
['dispatch', 'setprop', 'address:0xmatch border_size 0'],
['dispatch', 'setprop', 'address:0xmatch no_shadow 1'],
['dispatch', 'setprop', 'address:0xmatch no_blur 1'],
['dispatch', 'setprop', 'address:0xmatch decorate 0'],
],
);
});