Skip to content

Commit 3ce34e6

Browse files
author
outsourc-e
committed
fix: app-wide Electron title bar offset via --titlebar-h CSS variable
Sets --titlebar-h on document.documentElement (40px in Electron, 0px otherwise). All fixed-position elements now use top-[var(--titlebar-h)] instead of top-0 so nothing overlaps the title bar. Updated: workspace-shell, chat-panel, agent-view-panel, agent-stream-panel, toast, update-notifier, openclaw-update-notifier, mobile-prompt-trigger, provider-wizard, sidebar-backdrop.
1 parent 18d4f31 commit 3ce34e6

9 files changed

Lines changed: 25 additions & 10 deletions

File tree

src/components/agent-view/agent-stream-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export function AgentStreamPanel({ sessionKey, agentName, agentColor, onClose }:
193193
return (
194194
<>
195195
<button type="button" aria-label="Close live stream panel" className="fixed inset-0 z-40 bg-black/30" onClick={onClose} />
196-
<aside className="fixed inset-x-0 bottom-0 z-50 h-[70vh] rounded-t-2xl border-t border-neutral-200 bg-white shadow-2xl dark:border-neutral-800 dark:bg-neutral-900 md:inset-y-0 md:right-0 md:left-auto md:h-auto md:w-[400px] md:rounded-none md:border-t-0 md:border-l">
196+
<aside className="fixed inset-x-0 bottom-0 z-50 h-[70vh] rounded-t-2xl border-t border-neutral-200 bg-white shadow-2xl dark:border-neutral-800 dark:bg-neutral-900 md:right-0 md:bottom-0 md:left-auto md:top-[var(--titlebar-h,0px)] md:h-auto md:w-[400px] md:rounded-none md:border-t-0 md:border-l">
197197
<div className="flex h-full min-h-0 flex-col">
198198
<div className="sticky top-0 z-10 border-b border-neutral-200 bg-white/95 backdrop-blur dark:border-neutral-800 dark:bg-neutral-900/95">
199199
<div className="mx-auto mt-2 h-1 w-10 rounded-full bg-neutral-300 dark:bg-neutral-700 md:hidden" />

src/components/agent-view/agent-view-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ export function AgentViewPanel() {
809809
animate={{ x: panelVisible ? 0 : panelWidth }}
810810
transition={{ duration: 0.22, ease: 'easeInOut' }}
811811
className={cn(
812-
'fixed inset-y-0 right-0 z-40 w-72 border-l border-primary-300/70 bg-primary-100/92 backdrop-blur-xl',
812+
'fixed right-0 bottom-0 top-[var(--titlebar-h,0px)] z-40 w-72 border-l border-primary-300/70 bg-primary-100/92 backdrop-blur-xl',
813813
panelVisible ? 'pointer-events-auto' : 'pointer-events-none',
814814
)}
815815
>

src/components/chat-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export function ChatPanel() {
142142
animate={{ x: 0, opacity: 1 }}
143143
exit={{ x: '100%', opacity: 0 }}
144144
transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}
145-
className="fixed inset-y-0 right-0 h-[100dvh] max-h-[100dvh] w-[420px] max-w-[100vw] border-l border-primary-200 bg-surface overflow-hidden flex flex-col z-20 shadow-xl"
145+
className="fixed right-0 bottom-0 top-[var(--titlebar-h,0px)] h-[calc(100dvh-var(--titlebar-h,0px))] max-h-[calc(100dvh-var(--titlebar-h,0px))] w-[420px] max-w-[100vw] border-l border-primary-200 bg-surface overflow-hidden flex flex-col z-20 shadow-xl"
146146
>
147147
{/* Panel header */}
148148
<div className="flex items-center justify-between h-10 px-3 border-b border-primary-200 shrink-0">

src/components/mobile-prompt/MobilePromptTrigger.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function MobilePromptTrigger() {
8888
animate={{ opacity: 1, y: 0, scale: 1 }}
8989
exit={{ opacity: 0, y: -50, scale: 0.95 }}
9090
transition={{ duration: 0.35, ease: [0.23, 1, 0.32, 1] }}
91-
className="fixed top-4 left-1/2 z-[9999] w-[90vw] max-w-md -translate-x-1/2 overflow-hidden rounded-2xl border border-primary-800/60 bg-primary-950 text-white shadow-2xl shadow-black/40"
91+
className="fixed left-1/2 z-[9999] w-[90vw] max-w-md -translate-x-1/2 overflow-hidden rounded-2xl border border-primary-800/60 bg-primary-950 text-white shadow-2xl shadow-black/40 top-[calc(var(--titlebar-h,0px)+1rem)]"
9292
>
9393
<div className="px-4 py-3">
9494
<div className="flex items-center gap-3">

src/components/openclaw-update-notifier.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export function OpenClawUpdateNotifier() {
166166
exit={{ opacity: 0, y: -50, scale: 0.95 }}
167167
transition={{ duration: 0.35, ease: [0.23, 1, 0.32, 1] }}
168168
className={cn(
169-
'fixed top-4 left-1/2 -translate-x-1/2 z-[9998]',
169+
'fixed left-1/2 -translate-x-1/2 z-[9998] top-[calc(var(--titlebar-h,0px)+1rem)]',
170170
'flex flex-col rounded-2xl overflow-hidden',
171171
'bg-primary-950 text-white',
172172
'shadow-2xl shadow-black/40',

src/components/ui/toast.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export function Toaster() {
7474
if (!toasts.length) return null
7575

7676
return createPortal(
77-
<div className="pointer-events-none fixed top-4 left-2 right-2 z-[9999] flex flex-col gap-2 sm:left-auto sm:right-4 sm:w-auto">
77+
<div className="pointer-events-none fixed left-2 right-2 z-[9999] flex flex-col gap-2 top-[calc(var(--titlebar-h,0px)+1rem)] sm:left-auto sm:right-4 sm:w-auto">
7878
{toasts.map((t) => (
7979
<div
8080
key={t.id}

src/components/update-notifier.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export function UpdateNotifier() {
201201
exit={{ opacity: 0, y: -50, scale: 0.95 }}
202202
transition={{ duration: 0.35, ease: [0.23, 1, 0.32, 1] }}
203203
className={cn(
204-
'fixed top-4 left-1/2 -translate-x-1/2 z-[9999]',
204+
'fixed left-1/2 -translate-x-1/2 z-[9999] top-[calc(var(--titlebar-h,0px)+1rem)]',
205205
'flex flex-col rounded-2xl overflow-hidden',
206206
'bg-primary-950 text-white',
207207
'shadow-2xl shadow-black/40',

src/components/workspace-shell.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import type { SessionMeta } from '@/screens/chat/types'
3636

3737
type SessionsListResponse = Array<SessionMeta>
3838
export const DESKTOP_SIDEBAR_BACKDROP_CLASS =
39-
'fixed inset-y-0 left-0 w-[300px] z-10 bg-black/10 backdrop-blur-[1px]'
39+
'fixed left-0 bottom-0 top-[var(--titlebar-h,0px)] w-[300px] z-10 bg-black/10 backdrop-blur-[1px]'
4040

4141
async function fetchSessions(): Promise<SessionsListResponse> {
4242
const res = await fetch('/api/sessions')
@@ -188,6 +188,15 @@ export function WorkspaceShell() {
188188
return () => media.removeEventListener('change', update)
189189
}, [])
190190

191+
useEffect(() => {
192+
if (typeof document === 'undefined') return
193+
const titlebarHeight = isElectron ? '40px' : '0px'
194+
document.documentElement.style.setProperty('--titlebar-h', titlebarHeight)
195+
return () => {
196+
document.documentElement.style.removeProperty('--titlebar-h')
197+
}
198+
}, [isElectron])
199+
191200
// Keep mobile sidebar state closed after resize and route changes.
192201
useEffect(() => {
193202
if (!isMobile) return
@@ -300,11 +309,17 @@ export function WorkspaceShell() {
300309
return <LoginScreen />
301310
}
302311

312+
const shellStyle: React.CSSProperties & Record<'--titlebar-h', string> = {
313+
height: 'var(--vvh, 100dvh)',
314+
paddingTop: isElectron ? 40 : 0,
315+
'--titlebar-h': isElectron ? '40px' : '0px',
316+
}
317+
303318
return (
304319
<>
305320
<div
306321
className="relative overflow-hidden theme-bg theme-text"
307-
style={{ height: 'var(--vvh, 100dvh)', paddingTop: isElectron ? 40 : 0 }}
322+
style={shellStyle}
308323
>
309324
{/* Electron: native-style title bar (absolute over the padding) */}
310325
{isElectron && (

src/screens/settings/components/provider-wizard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ export function ProviderWizard({ open, onOpenChange, editProvider }: ProviderWiz
326326

327327
return (
328328
<DialogRoot open={open} onOpenChange={handleDialogOpenChange}>
329-
<DialogContent className="left-auto right-0 top-0 h-[100dvh] w-screen translate-x-0 translate-y-0 overflow-hidden rounded-none border-primary-200 bg-primary-50/95 backdrop-blur-sm duration-300 ease-out sm:w-[min(860px,100vw)] sm:rounded-l-2xl data-[state=open]:scale-100 data-[state=closed]:scale-100 data-[state=open]:translate-x-0 data-[state=closed]:translate-x-full">
329+
<DialogContent className="left-auto right-0 top-[var(--titlebar-h,0px)] h-[calc(100dvh-var(--titlebar-h,0px))] w-screen translate-x-0 translate-y-0 overflow-hidden rounded-none border-primary-200 bg-primary-50/95 backdrop-blur-sm duration-300 ease-out sm:w-[min(860px,100vw)] sm:rounded-l-2xl data-[state=open]:scale-100 data-[state=closed]:scale-100 data-[state=open]:translate-x-0 data-[state=closed]:translate-x-full">
330330
<div className="flex h-full min-h-0 flex-col">
331331
<div className="border-b border-primary-200 p-4 sm:p-5">
332332
<div className="flex items-start justify-between gap-4">

0 commit comments

Comments
 (0)