fix(desktop): restore sidebar titlebar dragging

The sidebar title area also needs to participate in Electron's CSS app-region chrome. Mark only the sidebar title/header region as draggable and keep the full sidebar body out of the drag region so session rows, search controls, and project actions remain normal interactions.

Constraint: Electron window dragging is driven by CSS app-region regions after the migration
Rejected: Keep the sidebar-wide startDragging mouse handler | Electron does not use that as the active drag path and it misses the left title gap
Confidence: high
Scope-risk: narrow
Directive: Keep sidebar body interactions outside the drag region unless a real titlebar affordance is added there
Tested: cd desktop && bun run test src/components/layout/Sidebar.test.tsx --run
Tested: bun run check:desktop
This commit is contained in:
程序员阿江(Relakkes) 2026-06-03 16:37:28 +08:00
parent aed3e7d038
commit eaa940ab90
2 changed files with 6 additions and 16 deletions

View File

@ -255,6 +255,7 @@ describe('Sidebar', () => {
])
expect(useTabStore.getState().activeTabId).toBe('session-new-1')
expect(screen.getByRole('complementary')).not.toHaveAttribute('data-desktop-drag-region')
expect(screen.getByTestId('sidebar-title-region')).toHaveAttribute('data-desktop-drag-region')
})
it('groups sessions by project and expands overflow rows', () => {

View File

@ -15,7 +15,6 @@ import { publicAssetPath } from '../../lib/publicAsset'
const desktopHost = getDesktopHost()
const isDesktopRuntime = desktopHost.isDesktop
const canUseNativeDialogs = desktopHost.capabilities.dialogs
const canStartWindowDragging = desktopHost.capabilities.windowControls
const isWindows = typeof navigator !== 'undefined' && /Win/.test(navigator.platform)
const SESSION_LIST_AUTO_REFRESH_MS = 30_000
const SESSION_LIST_FOCUS_REFRESH_MIN_MS = 5_000
@ -575,19 +574,6 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
setRenameValue('')
}, [renamingId, renameValue, renameSession])
const startDraggingRef = useRef<(() => Promise<void>) | null>(null)
useEffect(() => {
if (!canStartWindowDragging) return
startDraggingRef.current = () => getDesktopHost().window.startDragging()
}, [])
const handleSidebarDrag = useCallback((e: React.MouseEvent) => {
if (e.button !== 0) return
if ((e.target as HTMLElement).closest('button, input, textarea, select, a, [role="button"]')) return
startDraggingRef.current?.()
}, [])
useEffect(() => {
if (!isBatchMode) return
@ -611,12 +597,15 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
return (
<aside
onMouseDown={handleSidebarDrag}
className="sidebar-panel relative h-full flex flex-col bg-[var(--color-surface-sidebar)] border-r border-[var(--color-border)] select-none"
data-state={expanded ? 'open' : 'closed'}
aria-label="Sidebar"
>
<div className={`px-3 pb-2 ${isDesktopRuntime && !isWindows ? 'pt-[44px]' : 'pt-3'}`}>
<div
data-testid="sidebar-title-region"
data-desktop-drag-region
className={`px-3 pb-2 ${isDesktopRuntime && !isWindows ? 'pt-[44px]' : 'pt-3'}`}
>
<div className={`flex ${expanded ? 'items-center justify-between gap-3' : 'flex-col items-center gap-2'}`}>
<div className={`flex min-w-0 items-center ${expanded ? 'gap-2.5' : 'justify-center'}`}>
<img src={publicAssetPath('app-icon.png')} alt="" className="h-8 w-8 flex-shrink-0" />