Merge pull request 'fix(desktop): show the Lotus titlebar only when the native frame is really gone' (#490) from fix/linux-custom-chrome into lotus
CI / Secret scan (gitleaks) (push) Successful in 28s
CI / Build & Quality Checks (push) Successful in 5m55s
CI / Docker image build & smoke test (push) Skipped
CI / Trigger Desktop Build (push) Successful in 1m1s
CI / Playwright smoke (e2e) (push) Successful in 27m35s
CI / Secret scan (gitleaks) (push) Successful in 28s
CI / Build & Quality Checks (push) Successful in 5m55s
CI / Docker image build & smoke test (push) Skipped
CI / Trigger Desktop Build (push) Successful in 1m1s
CI / Playwright smoke (e2e) (push) Successful in 27m35s
This commit was merged in pull request #490.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { MouseEvent, ReactNode } from 'react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { Text } from 'folds';
|
||||
import { customWindowChromeAtom } from '../../state/customWindowChrome';
|
||||
import { customChromeShownAtom } from '../../state/customWindowChrome';
|
||||
import { invokeTauri, isTauri } from '../../hooks/useTauri';
|
||||
import * as css from './TitleBar.css';
|
||||
|
||||
@@ -75,7 +75,7 @@ function ControlButton({ label, glyph, onClick, close }: ControlButtonProps) {
|
||||
* real traffic lights — are stripped while custom chrome is on.
|
||||
*/
|
||||
export function TitleBar() {
|
||||
const enabled = useAtomValue(customWindowChromeAtom);
|
||||
const enabled = useAtomValue(customChromeShownAtom);
|
||||
|
||||
if (!isTauri() || !enabled) return null;
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ function DesktopChromeSetting() {
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Custom window chrome (beta)"
|
||||
description="Replace the system title bar with a Lotus-styled one. Desktop only — reloads to apply."
|
||||
description="Replace the system title bar with a Lotus-styled one. Desktop only — reloads to apply. On Linux (Wayland) it takes effect the next time Lotus Chat starts."
|
||||
after={<Switch variant="Primary" value={customChrome} onChange={handleToggle} />}
|
||||
/>
|
||||
</SequenceCard>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { customWindowChromeAtom } from '../state/customWindowChrome';
|
||||
import { invokeTauri, isTauri } from './useTauri';
|
||||
import { useAtomValue, useSetAtom } from 'jotai';
|
||||
import { customWindowChromeAtom, nativeChromeActiveAtom } from '../state/customWindowChrome';
|
||||
import { isTauri, tauriInvoke } from './useTauri';
|
||||
|
||||
/**
|
||||
* P5-47 — drive the native window frame from the `customWindowChromeAtom`.
|
||||
@@ -11,12 +11,29 @@ import { invokeTauri, isTauri } from './useTauri';
|
||||
* web `<TitleBar/>` can take over, `enabled = false` restores the native frame.
|
||||
* No-op in the browser (`isTauri()` guard), so it's safe to call unconditionally
|
||||
* from the app shell.
|
||||
*
|
||||
* The command answers whether the native frame is stripped *now* (on Linux /
|
||||
* Wayland the frame only changes at the next launch); that drives whether the
|
||||
* Lotus titlebar is shown. Older desktop builds answer nothing, so the setting
|
||||
* is used as before.
|
||||
*/
|
||||
export function useTauriWindowChrome(): void {
|
||||
const enabled = useAtomValue(customWindowChromeAtom);
|
||||
const setNativeActive = useSetAtom(nativeChromeActiveAtom);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTauri()) return;
|
||||
invokeTauri('set_custom_chrome', { enabled });
|
||||
}, [enabled]);
|
||||
const invoke = isTauri() ? tauriInvoke() : undefined;
|
||||
if (!invoke) return undefined;
|
||||
let cancelled = false;
|
||||
invoke('set_custom_chrome', { enabled })
|
||||
.then((active) => {
|
||||
if (!cancelled) setNativeActive(typeof active === 'boolean' ? active : enabled);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) setNativeActive(enabled);
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [enabled, setNativeActive]);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import { useSessionAppeared } from '../hooks/useSessionAppeared';
|
||||
import { useTauriWindowChrome } from '../hooks/useTauriWindowChrome';
|
||||
import { isTauri } from '../hooks/useTauri';
|
||||
import { TitleBar } from '../features/desktop/TitleBar';
|
||||
import { customWindowChromeAtom } from '../state/customWindowChrome';
|
||||
import { customChromeShownAtom } from '../state/customWindowChrome';
|
||||
import { SeasonalEffect } from '../components/seasonal/SeasonalEffect';
|
||||
import { applyCustomAccent, removeCustomAccent } from '../utils/accentColor';
|
||||
import { zIndices } from '../styles/zIndex';
|
||||
@@ -110,7 +110,7 @@ function TauriEffects() {
|
||||
// default, and always in the browser) this returns children unchanged, so there
|
||||
// is zero layout impact for everyone else.
|
||||
function DesktopChrome({ children }: { children: ReactNode }) {
|
||||
const customChrome = useAtomValue(customWindowChromeAtom);
|
||||
const customChrome = useAtomValue(customChromeShownAtom);
|
||||
useTauriWindowChrome();
|
||||
const useChrome = isTauri() && customChrome;
|
||||
// Keep the wrapper element structure STABLE across the toggle so flipping the
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { atom } from 'jotai';
|
||||
import {
|
||||
atomWithLocalStorage,
|
||||
getLocalStorageItem,
|
||||
@@ -20,3 +21,20 @@ export const customWindowChromeAtom = atomWithLocalStorage<boolean>(
|
||||
(key) => getLocalStorageItem<boolean>(key, false),
|
||||
(key, value) => setLocalStorageItem(key, value),
|
||||
);
|
||||
|
||||
/**
|
||||
* [cinny-desktop: Linux custom chrome] Whether the native frame is **actually**
|
||||
* stripped right now, as reported by the desktop's `set_custom_chrome`. It can
|
||||
* differ from the setting: on Linux / Wayland the frame only changes when the
|
||||
* app restarts. `null` until the desktop has answered (or on desktop builds
|
||||
* that don't report it).
|
||||
*/
|
||||
export const nativeChromeActiveAtom = atom<boolean | null>(null);
|
||||
|
||||
/**
|
||||
* Show the Lotus titlebar only when the native frame is really gone (never two
|
||||
* titlebars, never none): the desktop's report, else the setting.
|
||||
*/
|
||||
export const customChromeShownAtom = atom<boolean>(
|
||||
(get) => get(nativeChromeActiveAtom) ?? get(customWindowChromeAtom),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user