feat(desktop): gate traffic-lights behind window-controls style setting
Add a Window controls Style setting ('classic' | 'traffic-lights',
default 'classic') next to the existing Position setting. All four
position×style combinations render correctly with side-driven order
(close,min,max left; min,max,close right).
- Restore deleted left-classic branch (h-8 w-8 rounded-md buttons)
- Add right-traffic-lights branch (cluster with ml-1 container)
- Branch on style instead of side in WindowsWindowControls
- Store field + setter with 'classic' default (no migration needed;
Zustand persist shallow-merges over initial state)
- Settings UI: SettingsTwoColumn with Position chips + Style dropdown
- Sanitize on client (persistence.ts) and server (settings-helpers.js)
- 10 locale dictionaries updated (add-only, no existing keys changed)
- Traffic-light button spacing 8px→10px edge-to-edge
- Delete dead DESKTOP_WINDOW_CONTROLS_WIDTH_PX constant
This commit is contained in:
@@ -300,37 +300,6 @@ export const hasDesktopInvoke = (): boolean => {
|
||||
return typeof getDesktopBridge()?.invoke === 'function';
|
||||
};
|
||||
|
||||
/**
|
||||
* Linux frameless Electron windows show a 1px CSS border on #root (see
|
||||
* index.css). This function flips the attribute on <html> so the rule
|
||||
* matches, and tracks `data-oc-window-maximized` so the border drops when
|
||||
* maximized (a 1px line inset from every screen edge would look off).
|
||||
* No-op outside Linux frameless Electron.
|
||||
*/
|
||||
export const initLinuxWindowBorder = (): void => {
|
||||
if (typeof window === 'undefined' || typeof document === 'undefined') return;
|
||||
if (!usesFramelessElectronChrome()) return;
|
||||
const platform = getElectronPlatform();
|
||||
if (platform !== 'linux') return;
|
||||
|
||||
const root = document.documentElement;
|
||||
root.setAttribute('data-oc-window-border', '');
|
||||
|
||||
const applyMaximized = (maximized: boolean) => {
|
||||
root.toggleAttribute('data-oc-window-maximized', maximized);
|
||||
};
|
||||
|
||||
void invokeDesktop<{ maximized?: boolean }>('desktop_get_current_window_state')
|
||||
.then((state) => applyMaximized(Boolean(state?.maximized)))
|
||||
.catch(() => {});
|
||||
|
||||
const onMaximizedChange = (event: Event) => {
|
||||
const detail = (event as CustomEvent<{ maximized?: boolean }>).detail;
|
||||
applyMaximized(Boolean(detail?.maximized));
|
||||
};
|
||||
window.addEventListener('openchamber:window-maximized-changed', onMaximizedChange);
|
||||
};
|
||||
|
||||
export const canUseElectronDesktopIPC = (): boolean => isElectronShell() && hasDesktopInvoke();
|
||||
|
||||
export const invokeDesktop = async <T = unknown>(command: string, args?: Record<string, unknown>): Promise<T | null> => {
|
||||
|
||||
Reference in New Issue
Block a user