fix: enable macOS window dragging and rename app to Claude Code Haha

Add core🪟allow-start-dragging permission and acceptFirstMouse
config to fix window dragging on macOS with overlay title bar. Also add
JS-based startDragging() fallback in AppShell and Sidebar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
程序员阿江(Relakkes) 2026-04-08 21:11:26 +08:00
parent 158f2de13e
commit 00a9cba066
4 changed files with 45 additions and 9 deletions

View File

@ -5,6 +5,7 @@
"windows": ["main"],
"permissions": [
"core:default",
"core:window:allow-start-dragging",
"shell:allow-open",
{
"identifier": "shell:allow-execute",

View File

@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json",
"productName": "Claude Code",
"productName": "Claude Code Haha",
"version": "0.1.0",
"identifier": "com.claude-code.desktop",
"build": {
@ -12,7 +12,7 @@
"app": {
"windows": [
{
"title": "Claude Code",
"title": "Claude Code Haha",
"width": 1280,
"height": 800,
"minWidth": 900,
@ -20,7 +20,8 @@
"decorations": true,
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"transparent": false
"transparent": false,
"acceptFirstMouse": true
}
],
"security": {

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useEffect, useState, useCallback, useRef } from 'react'
import { Sidebar } from './Sidebar'
import { ContentRouter } from './ContentRouter'
import { ToastContainer } from '../shared/Toast'
@ -12,6 +12,7 @@ export function AppShell() {
const fetchSettings = useSettingsStore((s) => s.fetchAll)
const [ready, setReady] = useState(false)
const [startupError, setStartupError] = useState<string | null>(null)
const startDraggingRef = useRef<(() => Promise<void>) | null>(null)
useEffect(() => {
let cancelled = false
@ -38,6 +39,22 @@ export function AppShell() {
}
}, [fetchSettings])
// Pre-cache Tauri window drag function
useEffect(() => {
if (!isTauri) return
import(/* @vite-ignore */ '@tauri-apps/api/window')
.then(({ getCurrentWindow }) => {
const win = getCurrentWindow()
startDraggingRef.current = () => win.startDragging()
})
.catch(() => {})
}, [])
const handleDragMouseDown = useCallback((e: React.MouseEvent) => {
if ((e.target as HTMLElement).closest('button, input, textarea, select, a, [role="button"]')) return
startDraggingRef.current?.()
}, [])
useKeyboardShortcuts()
if (startupError) {
@ -65,12 +82,12 @@ export function AppShell() {
return (
<div className="h-screen flex overflow-hidden relative">
{/* Drag region for macOS Overlay title bar — only relevant in Tauri */}
{/* Drag region for macOS Overlay title bar — full width strip at the top */}
{isTauri && (
<div
data-tauri-drag-region
className="absolute top-0 right-0 h-[38px] z-10"
style={{ left: 'var(--sidebar-width)' }}
onMouseDown={handleDragMouseDown}
className="absolute top-0 left-0 right-0 h-[38px] z-[9999]"
/>
)}
<Sidebar />

View File

@ -1,4 +1,4 @@
import { useEffect, useState, useCallback, useMemo } from 'react'
import { useEffect, useState, useCallback, useMemo, useRef } from 'react'
import { useSessionStore } from '../../stores/sessionStore'
import { useUIStore } from '../../stores/uiStore'
import { useTranslation } from '../../i18n'
@ -80,6 +80,23 @@ export function Sidebar() {
setRenameValue('')
}, [renamingId, renameValue, renameSession])
const startDraggingRef = useRef<(() => Promise<void>) | null>(null)
useEffect(() => {
if (!isTauri) return
import(/* @vite-ignore */ '@tauri-apps/api/window')
.then(({ getCurrentWindow }) => {
const win = getCurrentWindow()
startDraggingRef.current = () => win.startDragging()
})
.catch(() => {})
}, [])
const handleSidebarDrag = useCallback((e: React.MouseEvent) => {
if ((e.target as HTMLElement).closest('button, input, textarea, select, a, [role="button"]')) return
startDraggingRef.current?.()
}, [])
const t = useTranslation()
const TIME_GROUP_LABELS: Record<TimeGroup, string> = {
@ -91,7 +108,7 @@ export function Sidebar() {
}
return (
<aside data-tauri-drag-region className="w-[var(--sidebar-width)] h-full flex flex-col bg-[var(--color-surface-sidebar)] border-r border-[var(--color-border)] select-none">
<aside data-tauri-drag-region onMouseDown={handleSidebarDrag} className="w-[var(--sidebar-width)] h-full flex flex-col bg-[var(--color-surface-sidebar)] border-r border-[var(--color-border)] select-none">
{/* Brand logo — extra top padding in desktop to clear macOS traffic lights */}
<div className={`px-3 pb-1.5 flex items-center justify-between ${isTauri ? 'pt-[44px]' : 'pt-3'}`}>
<div className="flex items-center gap-2.5">