Skip to content

Commit

Permalink
fix: window titlebar maximize state sync, fixed #1982 (#1989)
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei authored Dec 3, 2024
1 parent 810516a commit 7ad1e30
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 28 deletions.
22 changes: 2 additions & 20 deletions apps/main/src/tipc/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url"

import { getRendererHandlers } from "@egoist/tipc/main"
import { callWindowExpose } from "@follow/shared/bridge"
import { app, BrowserWindow, clipboard, dialog, screen, shell } from "electron"
import { app, BrowserWindow, clipboard, dialog, shell } from "electron"

import { registerMenuAndContextMenu } from "~/init"
import { clearAllData, getCacheSize } from "~/lib/cleaner"
Expand All @@ -15,7 +15,7 @@ import { registerAppTray } from "~/lib/tray"
import { logger, revealLogFile } from "~/logger"
import { cleanupOldRender, loadDynamicRenderEntry } from "~/updater/hot-updater"

import { isDev, isWindows11 } from "../env"
import { isDev } from "../env"
import { downloadFile } from "../lib/download"
import { i18n } from "../lib/i18n"
import { cleanBetterAuthSessionCookie, cleanUser } from "../lib/user"
Expand Down Expand Up @@ -144,25 +144,7 @@ export const appRoute = {
}
}
}),
getWindowIsMaximized: t.procedure.input<void>().action(async ({ context }) => {
const window: BrowserWindow | null = (context.sender as Sender).getOwnerBrowserWindow()

if (isWindows11 && window) {
const size = screen.getDisplayMatching(window.getBounds()).workAreaSize

const windowSize = window.getSize()
const windowPosition = window.getPosition()
const isMaximized =
windowSize[0] === size.width &&
windowSize[1] === size.height &&
windowPosition[0] === 0 &&
windowPosition[1] === 0

return !!isMaximized
}

return window?.isMaximized()
}),
quitAndInstall: t.procedure.action(async () => {
quitAndInstall()
}),
Expand Down
23 changes: 22 additions & 1 deletion apps/main/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { fileURLToPath } from "node:url"

import { is } from "@electron-toolkit/utils"
import { APP_PROTOCOL } from "@follow/shared"
import { callWindowExpose } from "@follow/shared/bridge"
import { callWindowExpose, WindowState } from "@follow/shared/bridge"
import type { BrowserWindowConstructorOptions } from "electron"
import { app, BrowserWindow, screen, shell } from "electron"
import type { Event } from "electron/main"
Expand Down Expand Up @@ -197,6 +197,27 @@ export function createWindow(
})
}

// async render and main state
window.on("maximize", async () => {
const caller = callWindowExpose(window)
await caller.setWindowState(WindowState.MAXIMIZED)
})

window.on("unmaximize", async () => {
const caller = callWindowExpose(window)
await caller.setWindowState(WindowState.NORMAL)
})

window.on("minimize", async () => {
const caller = callWindowExpose(window)
await caller.setWindowState(WindowState.MINIMIZED)
})

window.on("restore", async () => {
const caller = callWindowExpose(window)
await caller.setWindowState(WindowState.NORMAL)
})

return window
}
export const windowStateStoreKey = "windowState"
Expand Down
6 changes: 6 additions & 0 deletions apps/renderer/src/atoms/app.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { WindowState } from "@follow/shared/bridge"
import { atom } from "jotai"

import { createAtomHooks } from "~/lib/jotai"

export const [, , useAppIsReady, , appIsReady, setAppIsReady] = createAtomHooks(atom(false))

export const [, , useAppSearchOpen, , , setAppSearchOpen] = createAtomHooks(atom(false))

// For electron
export const [, , useWindowState, , windowState, setWindowState] = createAtomHooks(
atom<WindowState>(WindowState.NORMAL),
)
9 changes: 3 additions & 6 deletions apps/renderer/src/modules/app/Titlebar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { useQuery } from "@tanstack/react-query"
import { WindowState } from "@follow/shared/bridge"

import { useWindowState } from "~/atoms/app"
import { useUISettingKey } from "~/atoms/settings/ui"
import { ElECTRON_CUSTOM_TITLEBAR_HEIGHT } from "~/constants"
import { tipcClient } from "~/lib/client"

export const Titlebar = () => {
const { data: isMaximized, refetch } = useQuery({
queryFn: () => tipcClient?.getWindowIsMaximized(),
queryKey: ["windowIsMaximized"],
})
const isMaximized = useWindowState() === WindowState.MAXIMIZED

const feedColWidth = useUISettingKey("feedColWidth")

Expand All @@ -35,7 +33,6 @@ export const Titlebar = () => {
className="no-drag-region pointer-events-auto flex h-full w-[50px] items-center justify-center duration-200 hover:bg-theme-item-active"
onClick={async () => {
await tipcClient?.windowAction({ action: "maximum" })
refetch()
}}
>
{isMaximized ? (
Expand Down
11 changes: 11 additions & 0 deletions apps/renderer/src/providers/extension-expose-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEffect, useLayoutEffect } from "react"
import { useTranslation } from "react-i18next"
import { toast } from "sonner"

import { setWindowState } from "~/atoms/app"
import { getGeneralSettings } from "~/atoms/settings/general"
import { getUISettings, useToggleZenMode } from "~/atoms/settings/ui"
import { setUpdaterStatus } from "~/atoms/updater"
Expand Down Expand Up @@ -85,5 +86,15 @@ export const ExtensionExposeProvider = () => {
dialog,
})
}, [dialog])

useBindElectronBridge()
return null
}

const useBindElectronBridge = () => {
useEffect(() => {
registerGlobalContext({
setWindowState,
})
}, [])
}
38 changes: 38 additions & 0 deletions apps/renderer/src/providers/inject-styles-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MemoedDangerousHTMLStyle } from "@follow/components/common/MemoedDangerousHTMLStyle.jsx"
import { RootPortal } from "@follow/components/ui/portal/index.js"
import type { FC, PropsWithChildren } from "react"
import { createContext, useCallback, useContext, useState } from "react"

const Provider = createContext<(id: string, styles: string) => () => void>(() => () => {})
export const PortalInjectStylesProvider: FC<PropsWithChildren> = ({ children }) => {
const [styles, setStyles] = useState({} as Record<string, string>)

const injectStyles = useCallback((id: string, styles: string) => {
const dispose = () => {
setStyles((prev) => {
const { [id]: _, ...rest } = prev
return rest
})
}
if (styles[id]) return dispose
setStyles((prev) => ({ ...prev, [id]: styles }))

return dispose
}, [])
return (
<Provider.Provider value={injectStyles}>
<RootPortal to={document.head}>
{Object.entries(styles).map(([id, style]) => (
<MemoedDangerousHTMLStyle key={id} id={`inject-${id}`}>
{style}
</MemoedDangerousHTMLStyle>
))}
</RootPortal>
{children}
</Provider.Provider>
)
}

export const useInjectStyles = () => {
return useContext(Provider)
}
1 change: 1 addition & 0 deletions apps/renderer/src/providers/root-providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const RootProviders: FC<PropsWithChildren> = ({ children }) => (
<SettingSync />
<FollowCommandManager />
{import.meta.env.DEV && <Devtools />}

{children}

<Suspense>
Expand Down
2 changes: 1 addition & 1 deletion apps/server/client/providers/root-providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const RootProviders: FC<PropsWithChildren> = ({ children }) => (
<StableRouterProvider />
<ModalStackContainer>
<OpenInAppDetector />
{/* <MobileDetector /> */}

<UserProvider />
<Toaster />
{children}
Expand Down
9 changes: 9 additions & 0 deletions packages/shared/src/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ declare const dialog: {
cancelText?: string
}) => Promise<boolean>
}

export enum WindowState {
MINIMIZED = "minimized",
MAXIMIZED = "maximized",
NORMAL = "normal",
}
interface RenderGlobalContext {
/// Access Settings
showSetting: (path?: string) => void
Expand Down Expand Up @@ -46,6 +52,9 @@ interface RenderGlobalContext {
/// Utils
toast: typeof toast

/// Electron State
setWindowState: (state: WindowState) => void

readyToUpdate: () => void
dialog: typeof dialog
// URL
Expand Down

0 comments on commit 7ad1e30

Please sign in to comment.