frame: collapse a hidden bar's band to the gutter

fixes #3630
This commit is contained in:
bbedward
2026-09-30 20:57:39 -04:00
parent d84037066e
commit c4ea1a1dbd
3 changed files with 45 additions and 7 deletions
+31 -6
View File
@@ -93,16 +93,40 @@ function resolveScreen(inputs, screen, options) {
// A free island keeps its satellites in a bar window on its configured edge; that band never reserves or shadows.
const satellites = !dot && (input.islandSatellites ?? input.config.islandSatellitesEnabled ?? true);
instances.push({
key: JSON.stringify([screen.name, input.config.id]), screenName: screen.name,
barId: input.config.id, configOrder: inputs.indexOf(input), edge: "", kind: "island", free: true, dot, hostsIsland: true,
key: JSON.stringify([screen.name, input.config.id]),
screenName: screen.name,
barId: input.config.id,
configOrder: inputs.indexOf(input),
edge: "",
kind: "island",
free: true,
dot,
hostsIsland: true,
satelliteEdge: satellites ? edgeName(input.config.position ?? 0) || "top" : "",
row: 0, rowThickness: 0, rowOffset: 0, reservation: 0, exclusiveZone: -1, exclusionSize: 0,
paintedBounds: { x: 0, y: 0, width: 0, height: 0 }, margins: { top: 0, bottom: 0, left: 0, right: 0 }
row: 0,
rowThickness: 0,
rowOffset: 0,
reservation: 0,
exclusiveZone: -1,
exclusionSize: 0,
paintedBounds: {
x: 0,
y: 0,
width: 0,
height: 0
},
margins: {
top: 0,
bottom: 0,
left: 0,
right: 0
}
});
}
for (const edge of edges) {
const selected = enabled.filter(input => !isFree(input) && (edgeName(input.config.position ?? 0) || "top") === edge);
const active = selected.filter(input => !isIsland(input.config));
const shown = active.filter(input => input.config.visible !== false);
const hosted = active.filter(input => !input.config.useOverlayLayer);
let offset = 0;
let reservation = 0;
@@ -148,8 +172,9 @@ function resolveScreen(inputs, screen, options) {
hostedBars: hosted.map(input => input.config),
occupancy: offset,
reservation: Math.max(frameStyled ? options.frameThickness : 0, reservation),
frameReservation: active.length ? Math.max(options.frameThickness, offset) : options.frameThickness,
frameExclusionEnabled: frameStyled && (!active.length || (frameHosted && !active.some(input => input.config.useOverlayLayer)))
frameReservation: shown.length ? Math.max(options.frameThickness, offset) : options.frameThickness,
overviewFrameReservation: active.length ? Math.max(options.frameThickness, offset) : options.frameThickness,
frameExclusionEnabled: frameStyled && (!shown.length || (frameHosted && !shown.some(input => input.config.useOverlayLayer)))
};
}
const manualPlacement = edges.some(edge => instances.filter(instance => instance.edge === edge).length > 1);
+4 -1
View File
@@ -97,7 +97,10 @@ Singleton {
}
function frameReservation(screen, side) {
return edge(screen, side)?.frameReservation ?? 0;
const band = edge(screen, side);
if (SettingsData.frameShowOnOverview && CompositorService.overviewActiveOnScreen(screen))
return band?.overviewFrameReservation ?? 0;
return band?.frameReservation ?? 0;
}
function frameContentInset(screen, barId, side) {
+10
View File
@@ -120,6 +120,16 @@ test("frame overlays reserve once and every row retains its position", () => {
assert.equal(resolve(configs, { effectiveFrameEnabled: true, effectiveConnected: true, framePreferences: [] }).instances[0].kind, "bar");
});
test("a hidden bar collapses its frame band to a reserved gutter outside the overview", () => {
for (const effectiveConnected of [false, true]) {
const options = { effectiveFrameEnabled: true, effectiveConnected };
const shown = resolve([bar("main")], options).edges.top;
const hidden = resolve([bar("main", 0, { visible: false })], options).edges.top;
assert.deepEqual([shown.frameReservation, shown.overviewFrameReservation], [48, 48]);
assert.deepEqual([hidden.frameReservation, hidden.frameExclusionEnabled, hidden.overviewFrameReservation], [12, true, 48]);
}
});
test("popup triggers preserve each edge and connected gap policy", () => {
const config = { bottomGap: 8, popupGapsAuto: false, popupGapsManual: 6 };
const expected = [{ x: 20, y: 58, width: 24 }, { x: 20, y: 1022, width: 24 }, { x: 50, y: 30, width: 24 }, { x: 1870, y: 30, width: 24 }];