mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-17 00:34:01 -04:00
layout: let an overview-only bar share the row of a bar that hides in the overview
fixes #3527
This commit is contained in:
@@ -41,13 +41,25 @@ function islandMetrics(config, defaults) {
|
||||
const reserve = Math.max(24, Math.min(128, value("islandReserveThickness")));
|
||||
const compact = Math.max(24, Math.min(72, value("islandCompactThickness")));
|
||||
const gap = Math.max(0, Math.min(48, value("islandOuterGap")));
|
||||
return { reserve, compact, gap, thickness: Math.max(reserve, gap + compact) };
|
||||
return {
|
||||
reserve,
|
||||
compact,
|
||||
gap,
|
||||
thickness: Math.max(reserve, gap + compact)
|
||||
};
|
||||
}
|
||||
|
||||
function islandThickness(config, defaults) {
|
||||
return islandMetrics(config, defaults).thickness;
|
||||
}
|
||||
|
||||
function overviewStandInHost(input, selected) {
|
||||
const config = input.config;
|
||||
if (config.island === true || config.visible !== false || !config.openOnOverview)
|
||||
return null;
|
||||
return selected.find(other => other.config.island !== true && !other.config.openOnOverview) ?? null;
|
||||
}
|
||||
|
||||
function resolveScreen(inputs, screen, options) {
|
||||
const assigned = inputs.filter(input => coversScreen(input.config, screen, options.screens, options.displayNameMode));
|
||||
const enabled = assigned.filter(input => input.config.enabled);
|
||||
@@ -64,30 +76,47 @@ function resolveScreen(inputs, screen, options) {
|
||||
const hosted = active.filter(input => !input.config.useOverlayLayer);
|
||||
let offset = 0;
|
||||
let reservation = 0;
|
||||
for (const input of selected) {
|
||||
const rowOffsets = new Map();
|
||||
const place = (input, rowOffset) => {
|
||||
const config = input.config;
|
||||
const kind = config.island === true ? "island" : frameHosted && !config.useOverlayLayer ? "frame" : "bar";
|
||||
const spacing = frameStyled || config.attachToScreenEdge ? 0 : config.spacing ?? 4;
|
||||
const thickness = kind === "island" ? input.islandThickness : frameStyled ? Math.round(Math.round(options.frameBarSize * (screen.scale || 1)) / (screen.scale || 1)) : input.barThickness + spacing + (config.bottomGap ?? 0);
|
||||
const paintedThickness = thickness + (kind !== "island" && !frameStyled ? input.wingSize ?? 0 : 0);
|
||||
const reserves = kind === "island" ? !(input.islandFloating ?? config.islandFloating)
|
||||
: config.visible !== false && (!config.autoHide || frameStyled);
|
||||
const contribution = reserves ? Math.max(0, offset + thickness - reservation) : 0;
|
||||
const reserves = kind === "island" ? !(input.islandFloating ?? config.islandFloating) : config.visible !== false && (!config.autoHide || frameStyled);
|
||||
const contribution = reserves ? Math.max(0, rowOffset + thickness - reservation) : 0;
|
||||
instances.push({
|
||||
key: JSON.stringify([screen.name, config.id]), screenName: screen.name,
|
||||
barId: config.id, configOrder: inputs.indexOf(input), edge, kind,
|
||||
row: selected.indexOf(input), rowThickness: paintedThickness, rowOffset: offset,
|
||||
key: JSON.stringify([screen.name, config.id]),
|
||||
screenName: screen.name,
|
||||
barId: config.id,
|
||||
configOrder: inputs.indexOf(input),
|
||||
edge,
|
||||
kind,
|
||||
row: selected.indexOf(input),
|
||||
rowThickness: paintedThickness,
|
||||
rowOffset,
|
||||
reservation: contribution
|
||||
});
|
||||
offset += paintedThickness;
|
||||
reservation += contribution;
|
||||
rowOffsets.set(input, rowOffset);
|
||||
return paintedThickness;
|
||||
};
|
||||
const standIns = frameStyled ? [] : selected.filter(input => overviewStandInHost(input, selected));
|
||||
for (const input of selected) {
|
||||
if (standIns.includes(input))
|
||||
continue;
|
||||
offset += place(input, offset);
|
||||
}
|
||||
for (const input of standIns)
|
||||
place(input, rowOffsets.get(overviewStandInHost(input, selected)));
|
||||
const island = selected.find(input => input.config.island === true);
|
||||
bands[edge] = {
|
||||
island: island?.config ?? null,
|
||||
islandThickness: selected.filter(input => input.config.island === true).reduce((sum, input) => sum + input.islandThickness, 0),
|
||||
bars: active.map(input => input.config), hostedBars: hosted.map(input => input.config),
|
||||
occupancy: offset, reservation: Math.max(frameStyled ? options.frameThickness : 0, reservation),
|
||||
bars: active.map(input => input.config),
|
||||
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)))
|
||||
};
|
||||
@@ -108,7 +137,12 @@ function resolveScreen(inputs, screen, options) {
|
||||
instance.exclusiveZone = manualPlacement || instance.kind === "frame" ? -1 : instance.reservation || -1;
|
||||
instance.exclusionSize = manualPlacement && !frameStyled && instance.row === 0 ? band.reservation : 0;
|
||||
instance.paintedBounds = rowBounds(screen, instance.edge, instance.rowOffset, instance.rowThickness, bands);
|
||||
instance.margins = { top: 0, bottom: 0, left: 0, right: 0 };
|
||||
instance.margins = {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
};
|
||||
if (!manualPlacement)
|
||||
continue;
|
||||
instance.margins[instance.edge] = instance.rowOffset;
|
||||
@@ -122,7 +156,17 @@ function resolveScreen(inputs, screen, options) {
|
||||
bands[edge].frameExclusionEnabled = true;
|
||||
}
|
||||
instances.sort((a, b) => a.configOrder - b.configOrder);
|
||||
return { screen, assigned, bars, islands, instances, edges: bands, frameConfigured, frameStyled, manualPlacement };
|
||||
return {
|
||||
screen,
|
||||
assigned,
|
||||
bars,
|
||||
islands,
|
||||
instances,
|
||||
edges: bands,
|
||||
frameConfigured,
|
||||
frameStyled,
|
||||
manualPlacement
|
||||
};
|
||||
}
|
||||
|
||||
function adjacentBar(layout, edge, config) {
|
||||
@@ -133,7 +177,12 @@ function adjacentBar(layout, edge, config) {
|
||||
}
|
||||
|
||||
function adjacentInfo(layout, config, defaults) {
|
||||
const result = { topBar: 0, bottomBar: 0, leftBar: 0, rightBar: 0 };
|
||||
const result = {
|
||||
topBar: 0,
|
||||
bottomBar: 0,
|
||||
leftBar: 0,
|
||||
rightBar: 0
|
||||
};
|
||||
if (!layout || !config || config.autoHide)
|
||||
return result;
|
||||
for (const edge of edges) {
|
||||
@@ -154,11 +203,19 @@ function adjacentInfo(layout, config, defaults) {
|
||||
}
|
||||
|
||||
function barBounds(layout, thickness, position, config, defaults, connected, wingSize) {
|
||||
const empty = { x: 0, y: 0, width: 0, height: 0, wingSize: 0 };
|
||||
const empty = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
wingSize: 0
|
||||
};
|
||||
if (!layout || !edgeName(position))
|
||||
return empty;
|
||||
const instance = layout.instances.find(instance => instance.barId === config?.id);
|
||||
return Object.assign(rowBounds(layout.screen, edgeName(position), instance?.rowOffset ?? 0, thickness + wingSize, layout.edges), { wingSize });
|
||||
return Object.assign(rowBounds(layout.screen, edgeName(position), instance?.rowOffset ?? 0, thickness + wingSize, layout.edges), {
|
||||
wingSize
|
||||
});
|
||||
}
|
||||
|
||||
function rowBounds(screen, edge, offset, thickness, bands) {
|
||||
@@ -168,7 +225,8 @@ function rowBounds(screen, edge, offset, thickness, bands) {
|
||||
return {
|
||||
x: horizontal ? 0 : edge === "right" ? screen.width - width - offset : offset,
|
||||
y: horizontal ? edge === "bottom" ? screen.height - height - offset : offset : bands.top.occupancy,
|
||||
width, height
|
||||
width,
|
||||
height
|
||||
};
|
||||
}
|
||||
|
||||
@@ -184,7 +242,10 @@ function surfaceOrigin(layout, width, height, anchors, margins) {
|
||||
x += Math.min(Math.max(0, screen.width - width - left - right), layout.edges?.left?.reservation ?? 0);
|
||||
if (anchors.top && anchors.bottom)
|
||||
y += Math.min(Math.max(0, screen.height - height - top - bottom), layout.edges?.top?.reservation ?? 0);
|
||||
return { x, y };
|
||||
return {
|
||||
x,
|
||||
y
|
||||
};
|
||||
}
|
||||
|
||||
function popupTrigger(pos, screen, thickness, width, spacing, position, config, defaults, connected) {
|
||||
@@ -194,13 +255,29 @@ function popupTrigger(pos, screen, thickness, width, spacing, position, config,
|
||||
const offset = thickness + (connected ? 0 : spacing) + gap;
|
||||
switch (position) {
|
||||
case 2:
|
||||
return { x: offset, y: pos.y, width };
|
||||
return {
|
||||
x: offset,
|
||||
y: pos.y,
|
||||
width
|
||||
};
|
||||
case 3:
|
||||
return { x: (screen?.width || 0) - offset, y: pos.y, width };
|
||||
return {
|
||||
x: (screen?.width || 0) - offset,
|
||||
y: pos.y,
|
||||
width
|
||||
};
|
||||
case 1:
|
||||
return { x: pos.x, y: (screen?.height || 0) - offset - bottomGap, width };
|
||||
return {
|
||||
x: pos.x,
|
||||
y: (screen?.height || 0) - offset - bottomGap,
|
||||
width
|
||||
};
|
||||
default:
|
||||
return { x: pos.x, y: offset + bottomGap, width };
|
||||
return {
|
||||
x: pos.x,
|
||||
y: offset + bottomGap,
|
||||
width
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,3 +145,19 @@ test("surface origins include native cross-edge exclusions without adding manual
|
||||
assert.equal(frameIsland.instances[0].rowOffset, 12);
|
||||
assert.equal(frameIsland.edges.top.reservation, 54);
|
||||
});
|
||||
|
||||
test("an overview-only bar shares the row of a same-edge bar that retracts for the overview", () => {
|
||||
const main = bar("main");
|
||||
const standIn = bar("standin", 0, { visible: false, openOnOverview: true });
|
||||
const always = bar("always", 0, { openOnOverview: true });
|
||||
const offsets = layout => Object.fromEntries(layout.instances.map(instance => [instance.barId, instance.rowOffset]));
|
||||
const shared = resolve([main, standIn]);
|
||||
assert.deepEqual(offsets(shared), { main: 0, standin: 0 });
|
||||
assert.equal(shared.instances.find(instance => instance.barId === "standin").margins.top, 0);
|
||||
assert.equal(shared.edges.top.occupancy, 44);
|
||||
assert.equal(shared.edges.top.reservation, 44);
|
||||
assert.deepEqual(offsets(resolve([standIn, main])), { standin: 0, main: 0 });
|
||||
assert.deepEqual(offsets(resolve([main, always, standIn])), { main: 0, always: 44, standin: 0 });
|
||||
assert.deepEqual(offsets(resolve([always, standIn])), { always: 0, standin: 44 });
|
||||
assert.deepEqual(offsets(resolve([main, standIn], { effectiveFrameEnabled: true })), { main: 0, standin: 48 });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user