feat(titlebar): selectable window button styles + minimize toggle (#1083)

* feat(titlebar): selectable window button styles + minimize toggle

Custom title bar (Linux) gains a window-button style picker, mirroring
the seekbar style picker pattern. Six form-named styles: dots, dotsGlyph,
flat, pill, outline, glyph. All buttons now carry minimize/maximize/close
glyphs for clear, colour-blind-friendly iconography; dots reveal glyphs on
hover, dotsGlyph always shows them.

- New authStore state windowButtonStyle (default dots) + showMinimizeButton,
  with rehydrate validation falling back to dots on unknown values.
- WindowButtonPreview reuses the real .titlebar-btn classes for WYSIWYG tiles.
- Picker + minimize toggle render under the Custom title bar setting, gated
  on the toggle being on.
- Monochrome styles use --text-primary glyphs and stronger borders for
  contrast on dark themes.
- Dev-build grey marker scoped to the real title bar so previews show true
  colours.
- i18n keys in all 9 locales; setter and rehydrate tests.

* docs(changelog): window button styles (#1083)
This commit is contained in:
Psychotoxical
2026-06-13 23:52:56 +02:00
committed by GitHub
parent be3f1dc299
commit 028eb65f7d
21 changed files with 386 additions and 47 deletions
+13
View File
@@ -19,6 +19,7 @@ import type {
LyricsSourceConfig,
QueueDisplayMode,
SeekbarStyle,
WindowButtonStyle,
} from './authStoreTypes';
import { migrateLegacyLastfm, sanitizeAccounts } from '../music-network';
@@ -93,6 +94,17 @@ export function computeAuthStoreRehydration(state: AuthState): Partial<AuthState
? {}
: { seekbarStyle: 'truewave' as SeekbarStyle };
// Unknown / missing / tampered window-button style falls back to the
// default 'dots' so the title bar never renders an unstyled data-attr.
const VALID_WINDOW_BUTTON_STYLES = new Set<string>([
'dots', 'dotsGlyph', 'flat', 'pill', 'outline', 'glyph',
]);
const windowButtonStyleMigrated = VALID_WINDOW_BUTTON_STYLES.has(
(state as { windowButtonStyle?: unknown }).windowButtonStyle as string,
)
? {}
: { windowButtonStyle: 'dots' as WindowButtonStyle };
// Garbage / null / undefined / missing key from a legacy or tampered persist
// payload maps back to 'total' so the duration chip never receives an
// unknown mode (would render an empty label).
@@ -236,6 +248,7 @@ export function computeAuthStoreRehydration(state: AuthState): Partial<AuthState
...youLyPlusMigrated,
...wheelSmoothOneTime,
...seekbarStyleMigrated,
...windowButtonStyleMigrated,
...queueDurationDisplayModeMigrated,
...queueDisplayModeMigrated,
...linuxWaylandTextRenderProfileMigrated,