diff --git a/apps/readest-app/src/app/auth/page.tsx b/apps/readest-app/src/app/auth/page.tsx index 82f83255..b74f41fd 100644 --- a/apps/readest-app/src/app/auth/page.tsx +++ b/apps/readest-app/src/app/auth/page.tsx @@ -67,7 +67,7 @@ export default function AuthPage() { const router = useRouter(); const { login } = useAuth(); const { envConfig, appService } = useEnv(); - const { isDarkMode, safeAreaInsets } = useThemeStore(); + const { isDarkMode, safeAreaInsets, isRoundedWindow } = useThemeStore(); const { isTrafficLightVisible } = useTrafficLightStore(); const { settings, setSettings, saveSettings } = useSettingsStore(); const [port, setPort] = useState(null); @@ -346,8 +346,7 @@ export default function AuthPage() { className={clsx( 'bg-base-100 inset-0 flex select-none flex-col items-center overflow-hidden', appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh', - appService?.isLinuxApp && 'window-border', - appService?.hasRoundedWindow && 'rounded-window', + appService?.hasRoundedWindow && isRoundedWindow && 'window-border rounded-window', )} >
diff --git a/apps/readest-app/src/app/reader/components/Reader.tsx b/apps/readest-app/src/app/reader/components/Reader.tsx index 65dfb80a..ce45ed1b 100644 --- a/apps/readest-app/src/app/reader/components/Reader.tsx +++ b/apps/readest-app/src/app/reader/components/Reader.tsx @@ -57,7 +57,8 @@ const Reader: React.FC<{ ids?: string }> = ({ ids }) => { const { settings, setSettings } = useSettingsStore(); const { isSideBarVisible, getIsSideBarVisible, setSideBarVisible } = useSidebarStore(); const { isNotebookVisible, getIsNotebookVisible, setNotebookVisible } = useNotebookStore(); - const { isDarkMode, systemUIAlwaysHidden, showSystemUI, dismissSystemUI } = useThemeStore(); + const { isDarkMode, systemUIAlwaysHidden, isRoundedWindow } = useThemeStore(); + const { showSystemUI, dismissSystemUI } = useThemeStore(); const { acquireBackKeyInterception, releaseBackKeyInterception } = useDeviceControlStore(); const [libraryLoaded, setLibraryLoaded] = useState(false); const isInitiating = useRef(false); @@ -142,8 +143,7 @@ const Reader: React.FC<{ ids?: string }> = ({ ids }) => { className={clsx( `reader-page bg-base-100 text-base-content select-none overflow-hidden`, appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh', - appService?.isLinuxApp && 'window-border', - appService?.hasRoundedWindow && 'rounded-window', + appService?.hasRoundedWindow && isRoundedWindow && 'window-border rounded-window', )} >
}> diff --git a/apps/readest-app/src/app/user/page.tsx b/apps/readest-app/src/app/user/page.tsx index c6d6f524..a6f7f53d 100644 --- a/apps/readest-app/src/app/user/page.tsx +++ b/apps/readest-app/src/app/user/page.tsx @@ -59,7 +59,7 @@ const ProfilePage = () => { const { envConfig, appService } = useEnv(); const { token, user, logout } = useAuth(); const { settings, setSettings, saveSettings } = useSettingsStore(); - const { safeAreaInsets } = useThemeStore(); + const { safeAreaInsets, isRoundedWindow } = useThemeStore(); const [loading, setLoading] = useState(false); const [availablePlans, setAvailablePlans] = useState([]); @@ -342,8 +342,7 @@ const ProfilePage = () => { className={clsx( 'bg-base-100 inset-0 select-none overflow-hidden', appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh', - appService?.isLinuxApp && 'window-border', - appService?.hasRoundedWindow && 'rounded-window', + appService?.hasRoundedWindow && isRoundedWindow && 'window-border rounded-window', )} >
void; setStatusBarHeight: (height: number) => void; showSystemUI: () => void; @@ -68,6 +70,7 @@ export const useThemeStore = create((set, get) => { statusBarHeight: 24, systemUIAlwaysHidden: false, safeAreaInsets: { top: 0, right: 0, bottom: 0, left: 0 }, + isRoundedWindow: true, showSystemUI: () => set({ systemUIVisible: true }), dismissSystemUI: () => set({ systemUIVisible: false }), setStatusBarHeight: (height: number) => set({ statusBarHeight: height }), @@ -136,7 +139,7 @@ export const initSystemThemeListener = (appService: AppService) => { if (typeof window === 'undefined' || !appService) return; const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); - const update = async () => { + const updateColorTheme = async () => { let systemIsDarkMode; if (appService.isIOSApp) { const res = await getSystemColorScheme(); @@ -147,7 +150,16 @@ export const initSystemThemeListener = (appService: AppService) => { useThemeStore.getState().handleSystemThemeChange(systemIsDarkMode); }; - mediaQuery?.addEventListener('change', update); - document.addEventListener('visibilitychange', update); - update(); + const updateWindowTheme = async () => { + if (!appService.hasWindow || !appService.isLinuxApp) return; + const currentWindow = getCurrentWindow(); + const isFullscreen = await currentWindow.isFullscreen(); + const isMaximized = await currentWindow.isMaximized(); + useThemeStore.setState({ isRoundedWindow: !isMaximized && !isFullscreen }); + }; + + mediaQuery?.addEventListener('change', updateColorTheme); + document.addEventListener('visibilitychange', updateColorTheme); + window.addEventListener('resize', updateWindowTheme); + updateColorTheme(); }; diff --git a/apps/readest-app/src/utils/window.ts b/apps/readest-app/src/utils/window.ts index 0c6bfc20..34e2d7f9 100644 --- a/apps/readest-app/src/utils/window.ts +++ b/apps/readest-app/src/utils/window.ts @@ -1,6 +1,7 @@ import { getCurrentWindow } from '@tauri-apps/api/window'; import { emitTo, TauriEvent } from '@tauri-apps/api/event'; import { exit } from '@tauri-apps/plugin-process'; +import { type as osType } from '@tauri-apps/plugin-os'; import { eventDispatcher } from './event'; export const tauriGetWindowLogicalPosition = async () => { @@ -14,6 +15,20 @@ export const tauriHandleMinimize = async () => { getCurrentWindow().minimize(); }; +// workaround to reset transparent background when toggling fullscreen/maximize +const linuxWindowRestoreTransparentBg = async () => { + const currentSize = await getCurrentWindow().innerSize(); + currentSize.width -= 1; + currentSize.height -= 1; + await getCurrentWindow().setSize(currentSize); + setTimeout(async () => { + const currentSize = await getCurrentWindow().innerSize(); + currentSize.width += 1; + currentSize.height += 1; + await getCurrentWindow().setSize(currentSize); + }, 100); +}; + export const tauriHandleToggleMaximize = async () => { const currentWindow = getCurrentWindow(); const isFullscreen = await currentWindow.isFullscreen(); @@ -21,7 +36,10 @@ export const tauriHandleToggleMaximize = async () => { await currentWindow.setFullscreen(false); await currentWindow.unmaximize(); } else { - getCurrentWindow().toggleMaximize(); + await currentWindow.toggleMaximize(); + } + if ((await osType()) === 'linux') { + linuxWindowRestoreTransparentBg(); } }; @@ -51,6 +69,9 @@ export const tauriHandleToggleFullScreen = async () => { } else { await currentWindow.setFullscreen(!isFullscreen); } + if ((await osType()) === 'linux') { + linuxWindowRestoreTransparentBg(); + } }; export const tauriHandleSetAlwaysOnTop = async (isAlwaysOnTop: boolean) => {