mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 04:04:16 +02:00
launcher-menu grid: drive Steam's scroll edge shadows from the real scroll position
Besides the ScrollFade mask, the scroll region has ::before/::after shadows toggled by stale can-scroll classes; with everything visible the bottom shadow still covered the last row. Checker covers the shadow CSS.
This commit is contained in:
1 parent
01645ffcf6
commit
9ddb450057
2 files changed
+24
-5
No files matched your search
@@ -35,6 +35,11 @@
|
||||
// recomputed (same thresholds) on scroll, resize and mutation and
|
||||
// put in data-sfui-fade (none/top/bottom/both), which selects the
|
||||
// same gradients as Steam's stylesheet (var(--scroll-fade-size)).
|
||||
// - shadow: the other stock indicator: the scroller's ::before/::after
|
||||
// shadows (box-shadow in the background colour at the top and
|
||||
// bottom edge), shown by Steam's can-scroll-up/-down classes, which
|
||||
// go stale the same way. The same state goes in data-sfui-shadow
|
||||
// on the scroller and sets the pseudo-elements' opacity.
|
||||
// Steam's gamepad navigation derives a panel's layout from its computed
|
||||
// style (display: grid), so up/down/left/right move between tiles.
|
||||
// With the pinned-desktop patch, its pinned row (.sfui-pinned-desktop,
|
||||
@@ -46,7 +51,7 @@
|
||||
// which removes markers, stylesheets, observers and the timer.
|
||||
((find, sigs, opts) => {
|
||||
const NAME = 'launcher-menu-grid';
|
||||
const VERSION = 4;
|
||||
const VERSION = 5;
|
||||
const COLS = opts.columns;
|
||||
const ROWS = opts.maxRows ?? null;
|
||||
if (!(Number.isInteger(COLS) && COLS >= 1) || !(ROWS === null || (Number.isInteger(ROWS) && ROWS >= 1)))
|
||||
@@ -55,6 +60,7 @@
|
||||
const SECTION_KEY = 'programs';
|
||||
const ATTR = 'data-sfui-grid';
|
||||
const FADE = 'data-sfui-fade';
|
||||
const SHADOW = 'data-sfui-shadow';
|
||||
const MAXH = '--sfui-grid-max-height';
|
||||
const STYLE_ID = 'sfui-launcher-grid-style';
|
||||
const PIN = 'sfui-pinned-desktop'; // pinned-desktop patch's block
|
||||
@@ -78,6 +84,10 @@
|
||||
[${FADE}=top] { mask-image: ${gradient('transparent 0%, black var(--scroll-fade-size), black 100%')}; }
|
||||
[${FADE}=bottom] { mask-image: ${gradient('black 0%, black calc(100% - var(--scroll-fade-size)), transparent 100%')}; }
|
||||
[${FADE}=both] { mask-image: ${gradient('transparent 0%, black var(--scroll-fade-size), black calc(100% - var(--scroll-fade-size)), transparent 100%')}; }
|
||||
[${SHADOW}=none]::before, [${SHADOW}=none]::after,
|
||||
[${SHADOW}=top]::after, [${SHADOW}=bottom]::before { opacity: 0 !important; }
|
||||
[${SHADOW}=top]::before, [${SHADOW}=bottom]::after,
|
||||
[${SHADOW}=both]::before, [${SHADOW}=both]::after { opacity: 1 !important; }
|
||||
${TILE} {
|
||||
margin: 0 !important;
|
||||
padding: 8px 4px 6px !important;
|
||||
@@ -179,14 +189,16 @@ ${PINNED} > [role=button] * { flex-grow: 0 !important; text-align: center !impor
|
||||
for (let w = label.parentElement; w && w !== item; w = w.parentElement) mark(w, 'wrap');
|
||||
};
|
||||
|
||||
// Fade state from the actual scroll position (Steam's thresholds).
|
||||
// Scroll indicator state from the actual scroll position (Steam's
|
||||
// thresholds), for both the mask fade and the edge shadows.
|
||||
const fade = (sc) => {
|
||||
const r = regions.get(sc);
|
||||
if (!r?.fade) return;
|
||||
if (!r) return;
|
||||
const top = sc.scrollTop > 1;
|
||||
const bottom = sc.scrollHeight - sc.scrollTop > sc.clientHeight + 1;
|
||||
const v = top && bottom ? 'both' : top ? 'top' : bottom ? 'bottom' : 'none';
|
||||
if (r.fade.getAttribute(FADE) !== v) r.fade.setAttribute(FADE, v);
|
||||
if (sc.getAttribute(SHADOW) !== v) sc.setAttribute(SHADOW, v);
|
||||
if (r.fade && r.fade.getAttribute(FADE) !== v) r.fade.setAttribute(FADE, v);
|
||||
};
|
||||
|
||||
// maxRows: scroller max-height from its border-box top to the bottom of row
|
||||
@@ -241,6 +253,7 @@ ${PINNED} > [role=button] * { flex-grow: 0 !important; text-align: center !impor
|
||||
ro?.unobserve(sc);
|
||||
ro?.unobserve(r.panel);
|
||||
sc.style.removeProperty(MAXH);
|
||||
sc.removeAttribute(SHADOW);
|
||||
r.fade?.removeAttribute(FADE);
|
||||
};
|
||||
|
||||
@@ -300,7 +313,7 @@ ${PINNED} > [role=button] * { flex-grow: 0 !important; text-align: center !impor
|
||||
for (const [d, o] of docs) {
|
||||
detach(d, o);
|
||||
try {
|
||||
for (const el of d.querySelectorAll(`[${ATTR}], [${FADE}]`)) { el.removeAttribute(ATTR); el.removeAttribute(FADE); }
|
||||
for (const el of d.querySelectorAll(`[${ATTR}], [${FADE}], [${SHADOW}]`)) { el.removeAttribute(ATTR); el.removeAttribute(FADE); el.removeAttribute(SHADOW); }
|
||||
d.getElementById(STYLE_ID)?.remove();
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,12 @@
|
||||
"mask-image:linear-gradient(to bottom, transparent 0%, black var(--scroll-fade-size), black calc(100% - var(--scroll-fade-size)), transparent 100%)",
|
||||
"--scroll-fade-size:"
|
||||
] }
|
||||
},
|
||||
"scrollShadowStyle": {
|
||||
"checkOnly": true,
|
||||
"stylesheet": { "includes": [
|
||||
"z-index:9001;height:0;box-shadow:0 0 40px 40px #0e141b;transition:opacity .15s ease-out;pointer-events:none"
|
||||
] }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user