Skip to content

Add native context menus and macOS title-bar affordances#178

Merged
ecto merged 2 commits intomainfrom
claude/native-macos-ui-2yZU7
May 10, 2026
Merged

Add native context menus and macOS title-bar affordances#178
ecto merged 2 commits intomainfrom
claude/native-macos-ui-2yZU7

Conversation

@ecto
Copy link
Copy Markdown
Owner

@ecto ecto commented May 10, 2026

Summary

This PR adds native OS context menus (via Tauri) and macOS-specific title-bar features (proxy icon, document edited indicator, path popover). It also introduces macOS vibrancy styling and AppKit-aligned motion curves to make the desktop app feel native on macOS.

Key Changes

Native Context Menus

  • New Rust command (crates/vcad-desktop/src/commands/context_menu.rs): Builds and pops native OS menus (NSMenu on macOS, GTK/Win32 on Linux/Windows) from a flat JSON spec sent by the webview
  • Menu state management: Added ContextMenuState to keep menu objects alive while the OS popup is onscreen (required by Tauri's fire-and-forget popup API)
  • JS bridge (packages/app/src/lib/native-context-menu.ts): Exposes popupNativeContextMenu() helper that returns a Promise resolving to the chosen item id, with a 30s watchdog timeout
  • ContextMenu component refactor: Detects native menu availability and branches to native popup on right-click; falls back to Radix-rendered HTML menu in browser or if native popup fails
  • Menu action dispatch: Unified dispatchById() handler maps menu item ids to store actions (duplicate, delete, boolean ops, PCB design, etc.)

macOS Title-Bar Features

  • Proxy icon (packages/app/src/components/DocTitle.tsx): Renders a small "v" glyph in the title bar (Finder-style document indicator); draggable to export a virtual .vcad file reference
  • ⌘-click path popover: Breadcrumb panel showing vcad > Cloud/Local > filename.vcad that slides down from the proxy icon on Cmd+click
  • Document edited indicator: New set_document_edited command paints the dot inside the close traffic light when the document is dirty (and not read-only)
  • Represented filename: New set_represented_filename command surfaces the proxy icon and unlocks Window menu's "Recent Documents"

macOS Vibrancy & Styling

  • Sidebar material (crates/vcad-desktop/src/platform.rs): Changed from UnderWindowBackground to Sidebar for stronger, more lively blur that matches Finder/Mail/Music
  • CSS variables (packages/app/src/index.css): New body.tauri-mac block with translucent surface/card colors and softer borders that layer over the vibrancy material
  • AppKit motion springs: Added .appkit-spring utility class using cubic-bezier(0.32, 0.72, 0, 1) to match macOS deceleration curves
  • Keyboard-only focus rings: Stripped mouse-focus outlines on Tauri-mac (keeping :focus-visible for Tab navigation) to match native app behavior
  • Overlay scrollbars: WebKit scrollbars now overlay content and only appear on hover, matching native macOS behavior
  • System font tuning: Enabled Inter's straighter "a" and tighter alternates with slight negative tracking for better pairing with AppKit chrome

Refactoring & Cleanup

  • PCB design logic extracted: Moved bounding-box computation for "Design PCB to fit" into a standalone dispatchDesignPcbForSelection() helper so both native and Radix paths share the same logic
  • useCallback hooks: Wrapped event handlers (handleDelete, handleDuplicate, handleBoolean) to stabilize closures and avoid unnecessary re-renders
  • Capabilities detection: New useNativeShellClass() hook stamps body.tauri-mac / body.tauri-windows / body.tauri-linux classes for scoped styling

Integration

  • Main.rs wiring: Registered show_context_menu command and ContextMenuState manager; hooked on_menu_event to emit context-menu-select events back to the webview
  • App.tsx: Calls useNativeShellClass() to apply platform-specific styling

https://claude.ai/code/session_01QB85d1CDSGASSkTWkdCdLM

…menus

Layers four passes on top of the Tauri shell so the desktop build feels
carved out of macOS instead of "web app in a window":

- Per-region vibrancy: switch base material to NSVisualEffectMaterial::Sidebar
  and drop chrome backgrounds to translucent over it via a `body.tauri-mac`
  scope, so the AppKit blur actually shows through.
- Title bar: proxy icon + ⌘-click path popover in DocTitle; live
  `[NSWindow setDocumentEdited:]` from the dirty flag so the standard dot
  appears inside the close traffic light. Adds `set_represented_filename`
  command for future use.
- Native context menus: the shared ContextMenu component now pops a real
  NSMenu (built via Tauri's MenuBuilder) on Tauri, falling back to Radix
  in the browser. Submenus, accelerators, and disabled state all flow
  through a typed JSON spec.
- Motion + type polish: AppKit spring curves (`appkit-spring` utility),
  keyboard-only focus rings, overlay-style scrollbars, Inter feature
  flags + tighter tracking — all scoped to `body.tauri-mac` so the
  browser build is unchanged.

Cargo.lock will pick up the cocoa+objc entries on first build; not
included here because cross-resolution on Linux destabilizes the
existing graph.

https://claude.ai/code/session_01QB85d1CDSGASSkTWkdCdLM
@vercel
Copy link
Copy Markdown

vercel Bot commented May 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mecheval Ready Ready Preview, Comment May 10, 2026 0:25am
vcad Ready Ready Preview, Comment May 10, 2026 0:25am
vcad-docs Ready Ready Preview, Comment May 10, 2026 0:25am
vcad-mcp Ready Ready Preview, Comment May 10, 2026 0:25am

Request Review

Reformat platform.rs and commands/context_menu.rs to satisfy the
Rust (stable) format-check job — no behavior changes.

https://claude.ai/code/session_01QB85d1CDSGASSkTWkdCdLM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants