fix: electron window frame and `backgroundMaterial`

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-08-19 14:52:56 +08:00
parent 430ee81228
commit e18ec754a0
7 changed files with 93 additions and 51 deletions

View File

@ -31,35 +31,59 @@ export function createWindow(
} & BrowserWindowConstructorOptions,
) {
const { extraPath, height, width, ...configs } = options
// Create the browser window.
const window = new BrowserWindow({
const baseWindowConfig: Electron.BrowserWindowConstructorOptions = {
width,
height,
show: false,
resizable: configs?.resizable ?? true,
autoHideMenuBar: true,
...(platform !== "darwin" ? { icon: getIconPath() } : {}),
webPreferences: {
preload: path.join(__dirname, "../preload/index.mjs"),
sandbox: false,
webviewTag: true,
},
}
// @windows
backgroundMaterial: "mica",
titleBarStyle: platform === "win32" ? "hidden" : "hiddenInset",
trafficLightPosition: {
x: 18,
y: 18,
},
switch (platform) {
case "darwin": {
Object.assign(baseWindowConfig, {
titleBarStyle: "hiddenInset",
trafficLightPosition: {
x: 18,
y: 18,
},
vibrancy: "sidebar",
visualEffectState: "active",
transparent: true,
} as Electron.BrowserWindowConstructorOptions)
break
}
transparent: true,
backgroundColor: "#00000000", // transparent hexadecimal or anything with transparency,
vibrancy: "sidebar",
visualEffectState: "active",
case "win32": {
Object.assign(baseWindowConfig, {
icon: getIconPath(),
backgroundMaterial: "mica",
titleBarStyle: "hidden",
// titleBarOverlay: {
// height: 30,
// },
} as Electron.BrowserWindowConstructorOptions)
break
}
default: {
baseWindowConfig.icon = getIconPath()
}
}
// Create the browser window.
const window = new BrowserWindow({
...baseWindowConfig,
...configs,
})
window.webContents.openDevTools()
function refreshBound(timeout = 0) {
setTimeout(() => {
const mainWindow = getMainWindow()

View File

@ -1,25 +1,44 @@
import { useUISettingKey } from "@renderer/atoms/settings/ui"
import { cn } from "@renderer/lib/utils"
export const Vibrancy: Component<
type Props = Component<
React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
> = ({ className, children, ...rest }) => {
>
const MacOSVibrancy: Props = ({ className, children, ...rest }) => (
<div className={cn("bg-native/50 dark:bg-native/10", className)} {...rest}>
{children}
</div>
)
const Noop: Props = ({ children, className, ...rest }) => (
<div className={cn("bg-native", className)} {...rest}>
{children}
</div>
)
const Win32Material: Props = ({ className, children, ...rest }) => (
<div className={cn("bg-transparent", className)} {...rest}>
{children}
</div>
)
export const WindowUnderBlur: Props = (props) => {
const opaqueSidebar = useUISettingKey("opaqueSidebar")
const canVibrancy =
window.electron &&
window.electron.process.platform === "darwin" &&
!opaqueSidebar
if (opaqueSidebar) {
return <Noop {...props} />
}
return (
<div
className={cn(
canVibrancy ? "bg-native/50 dark:bg-native/10" : "bg-native",
className,
)}
{...rest}
>
{children}
</div>
)
if (!window.electron) {
return <Noop {...props} />
}
switch (window.electron.process.platform) {
case "darwin": {
return <MacOSVibrancy {...props} />
}
case "win32": {
return <Win32Material {...props} />
}
default: {
return <Noop {...props} />
}
}
}

View File

@ -1,2 +1,2 @@
export const ElECTRON_CUSTOM_TITLEBAR_HEIGHT = 30
export const ELECTRON_WINDOWS_RADIUS = 12
// export const ELECTRON_WINDOWS_RADIUS = 12

View File

@ -6,7 +6,9 @@ import ReactDOM from "react-dom/client"
import { RouterProvider } from "react-router-dom"
import { setAppIsReady } from "./atoms/app"
import { ElECTRON_CUSTOM_TITLEBAR_HEIGHT, ELECTRON_WINDOWS_RADIUS } from "./constants"
import {
ElECTRON_CUSTOM_TITLEBAR_HEIGHT,
} from "./constants"
import { initializeApp } from "./initialize"
import { getOS } from "./lib/utils"
import { router } from "./router"
@ -18,11 +20,7 @@ await initializeApp().finally(() => {
const $container = document.querySelector("#root") as HTMLElement
if (window.electron && getOS() === "Windows") {
$container.style.borderRadius = `${ELECTRON_WINDOWS_RADIUS}px`
$container.style.overflow = "hidden"
$container.style.background = "var(--fo-background)"
document.body.style.cssText += `--fo-window-padding-top: ${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px; --fo-window-radius: ${ELECTRON_WINDOWS_RADIUS}px;`
document.body.style.cssText += `--fo-window-padding-top: ${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px;`
}
ReactDOM.createRoot($container).render(
<React.StrictMode>

View File

@ -1,4 +1,4 @@
import { ElECTRON_CUSTOM_TITLEBAR_HEIGHT, ELECTRON_WINDOWS_RADIUS } from "@renderer/constants"
import { ElECTRON_CUSTOM_TITLEBAR_HEIGHT } from "@renderer/constants"
import { tipcClient } from "@renderer/lib/client"
import { useQuery } from "@tanstack/react-query"
@ -12,10 +12,7 @@ export const Titlebar = () => {
<div
className="drag-region flex w-full items-center justify-end overflow-hidden"
style={{
height:
`${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px`,
borderTopLeftRadius: `${ELECTRON_WINDOWS_RADIUS}px`,
borderTopRightRadius: `${ELECTRON_WINDOWS_RADIUS}px`,
height: `${ElECTRON_CUSTOM_TITLEBAR_HEIGHT}px`,
}}
>
<button
@ -36,7 +33,11 @@ export const Titlebar = () => {
refetch()
}}
>
{isMaximized ? <i className="i-mingcute-restore-line" /> : <i className="i-mingcute-square-line" />}
{isMaximized ? (
<i className="i-mingcute-restore-line" />
) : (
<i className="i-mingcute-square-line" />
)}
</button>
<button

View File

@ -30,7 +30,7 @@ import { useCallback, useLayoutEffect, useRef } from "react"
import { isHotkeyPressed, useHotkeys } from "react-hotkeys-hook"
import { Link } from "react-router-dom"
import { Vibrancy } from "../../components/ui/background"
import { WindowUnderBlur } from "../../components/ui/background"
import { FeedList } from "./list"
const lethargy = new Lethargy()
@ -178,7 +178,7 @@ export function FeedColumn({ children }: PropsWithChildren) {
})
return (
<Vibrancy
<WindowUnderBlur
className="relative flex h-full flex-col space-y-3 rounded-l-[12px] pt-2.5"
onClick={useCallback(() => navigateBackHome(), [navigateBackHome])}
>
@ -271,7 +271,7 @@ export function FeedColumn({ children }: PropsWithChildren) {
</div>
{children}
</Vibrancy>
</WindowUnderBlur>
)
}

View File

@ -1,5 +1,5 @@
import { Logo } from "@renderer/components/icons/logo"
import { Vibrancy } from "@renderer/components/ui/background"
import { WindowUnderBlur } from "@renderer/components/ui/background"
import { isElectronBuild } from "@renderer/constants"
import { preventDefault } from "@renderer/lib/dom"
import { settings } from "@renderer/modules/settings/constants"
@ -13,7 +13,7 @@ function Layout() {
return (
<div className="flex h-screen flex-col" onContextMenu={preventDefault}>
<div className="flex flex-1">
<Vibrancy className="flex h-full w-44 flex-col border-r px-2.5 py-3 pt-3.5">
<WindowUnderBlur className="flex h-full w-44 flex-col border-r px-2.5 py-3 pt-3.5">
<div className="grow pt-8">
{settings.map((t) => (
<Link
@ -34,7 +34,7 @@ function Layout() {
<Logo className="size-6" />
<span className="ml-2 font-semibold">{APP_NAME}</span>
</div>
</Vibrancy>
</WindowUnderBlur>
<div className="h-screen flex-1 overflow-y-auto bg-theme-background p-8 pt-0">
<Outlet />
</div>