Give the title bar strip back its drag, and the rule its full height

The window's content runs the full height underneath the title bar, so
the shell covers the bar - and a webview covering the bar swallows the
gesture that moves the window. The strip standing in for it now says it
is a drag region.

That strip also moves inside each column instead of spanning both, so the
rule between the nav and the app runs the whole height of the window
rather than starting below the bar.
This commit is contained in:
2026-09-02 09:44:51 +02:00
parent aa19da48de
commit 0ae5746a30
3 changed files with 47 additions and 34 deletions
+34 -32
View File
@@ -195,13 +195,13 @@ export default function App() {
if (!config) return null;
return (
/* The inset is the nav's own colour, so the title bar above it and the
sidebar below read as one surface. */
<div
className="flex h-screen flex-col bg-white dark:bg-slate-900"
style={{ paddingTop: chrome }}
>
<div className="flex min-h-0 flex-1">
/* The window's content runs the full height, underneath the title bar. Each
column carries its own strip for that rather than one across the top, so
the rule between the nav and the app runs the whole height of the window
instead of starting below the bar. The strips are drag regions: they
cover the title bar, and without saying so they would swallow the gesture
that moves the window. */
<div className="flex h-screen bg-white dark:bg-slate-900">
<Nav
config={config}
activeId={activeId}
@@ -214,35 +214,37 @@ export default function App() {
onForward={() => activeId && api.historyGo(activeId, 1)}
onReload={() => activeId && api.historyGo(activeId, 0)}
unread={unread}
chrome={chrome}
/>
{/* The hole an app's native webview is positioned into. It stays empty
on purpose — anything drawn here would be painted over. */}
<div
ref={stageRef}
className="relative min-w-0 flex-1 overflow-hidden bg-slate-100 dark:bg-slate-950"
>
{backdrop && (
<img
src={backdrop}
alt=""
aria-hidden
/* Scaled up so the blur has no soft edge to give itself away. */
className="absolute inset-0 h-full w-full scale-110 object-cover blur-[16px]"
/>
)}
{config.apps.length === 0 && (
<div className="flex h-full flex-col items-center justify-center gap-3 px-6 text-center">
<p className="text-[13px] text-slate-500 dark:text-slate-400">
No apps yet. Add the tools you work in and they appear in the nav.
</p>
<button onClick={() => setSettingsOpen(true)} className={BTN_PRIMARY}>
Add your first app
</button>
</div>
)}
</div>
<div className="flex min-w-0 flex-1 flex-col">
<div data-tauri-drag-region className="shrink-0" style={{ height: chrome }} />
<div
ref={stageRef}
className="relative min-h-0 flex-1 overflow-hidden bg-slate-100 dark:bg-slate-950"
>
{backdrop && (
<img
src={backdrop}
alt=""
aria-hidden
/* Scaled up so the blur has no soft edge to give itself away. */
className="absolute inset-0 h-full w-full scale-110 object-cover blur-[16px]"
/>
)}
{config.apps.length === 0 && (
<div className="flex h-full flex-col items-center justify-center gap-3 px-6 text-center">
<p className="text-[13px] text-slate-500 dark:text-slate-400">
No apps yet. Add the tools you work in and they appear in the nav.
</p>
<button onClick={() => setSettingsOpen(true)} className={BTN_PRIMARY}>
Add your first app
</button>
</div>
)}
</div>
</div>
{offer && (
+5 -1
View File
@@ -15,6 +15,8 @@ interface Props {
onBack: () => void;
onForward: () => void;
onReload: () => void;
/** Height of the title bar the window's content runs underneath. */
chrome: number;
}
/**
@@ -29,7 +31,7 @@ export const navWidth = (collapsed: boolean) => (collapsed ? RAIL : PANEL);
export default function Nav({
config, activeId, collapsed, unread,
onSelect, onToggleCollapse, onOpenSettings, onToggleGroup,
onBack, onForward, onReload,
onBack, onForward, onReload, chrome,
}: Props) {
const groups = [...config.groups].sort((a, b) => a.order - b.order);
const inGroup = (id: string | null) =>
@@ -124,6 +126,7 @@ export default function Nav({
return (
<aside className={`${shell} items-center`} style={{ width: RAIL }}>
<div data-tauri-drag-region className="w-full shrink-0" style={{ height: chrome }} />
{/* Only the expander survives the rail's header. Back and forward are
a two-finger swipe and reload is ⌘R, so a toolbar here would be
clutter standing in for something nobody asked for. */}
@@ -178,6 +181,7 @@ export default function Nav({
return (
<aside className={shell} style={{ width: PANEL }}>
<div data-tauri-drag-region className="shrink-0" style={{ height: chrome }} />
<header className="flex items-center gap-0.5 border-b border-slate-200 px-1.5 py-2.5 dark:border-slate-800">
{controls}
<button