Skip to content

Use native OS shadow for main ask bar (tight window, no CSS pad) #342

Description

@quiet-node

Summary

Use native macOS compositor shadow (NSPanel / set_has_shadow(true)) for the main ask bar and chat overlay, so the native window can hug the pill instead of carrying a large transparent CSS padding margin for drop-shadow room.

Today the overlay keeps native shadow off and paints elevation with CSS (shadow-bar / shadow-chat) inside a transparent pad (pt-2 / pb-6 / motion py-2CONTAINER_VERTICAL_PADDING = 48). That pad blocks clicks on content under/near the bar even when the user is clearly aiming past the visible chrome.

Goal

Today (ask bar) Target
Shadow CSS shadow-bar / shadow-chat Native OS shadow outside window bounds
Window Content + transparent pad Tight to visible chrome (onboarding-style)
Clicks near bar Pad steals hits Click-through immediately outside the pill

Same technique already used successfully for:

  • Onboarding (set_has_shadow(true), window fit to card)
  • Compact meeting ambient strip (set_overlay_native_shadow + content-sized frame)

Why we avoided it before

init_panel disables native shadow because macOS paints different shadows for key vs non-key panels, which can flicker when the user clicks another app while the overlay stays visible. CSS shadow was chosen for focus-independent elevation.

Local trial (2026-07, feat/meeting-notes-ui)

A temporary EXPERIMENT_NATIVE_ASKBAR_SHADOW flag was dogfooded:

  1. Native shadow on for main overlay
  2. CSS drop-shadow removed from layout chrome
  3. Transparent pad set to 0 (tight window)

Observed:

  • Window sat tight on the ask-bar pill
  • Clicks a few pixels outside the pill hit Safari/links underneath (pad no longer in the way)
  • Hard focus-away to another app did not produce an obvious key/non-key shadow jump on the tested Mac/OS

Experiment was reverted after the trial; this issue tracks doing it properly for ship.

Proposed approach

  1. Default overlay to native shadow (or enable for ask-bar + chat surfaces), via existing set_overlay_native_shadow (or always-on after init_panel policy change).
  2. Remove CSS elevation on the main layout wrapper (shadow-bar / shadow-chat) when native shadow is on; keep border/glass only.
  3. Drop CONTAINER_VERTICAL_PADDING (and root pt-2/pb-6 / motion py-2 pad) for that path so RO/setSize hug content.
  4. Keep ambient meeting path consistent (already tight + native shadow).
  5. QA matrix: key/non-key after clicking Safari/Notes; chat expand; minimize/restore; multi-monitor; older macOS if available.
  6. If key/non-key flicker returns on some OS versions: document or gate (flag / per-OS), do not reintroduce a large click-blocking pad without measuring hit-target cost.

Acceptance criteria

  • Ask bar window hugs visible chrome (no large transparent pad around the pill)
  • Clicks immediately outside the pill reach underlying apps
  • Elevation still looks premium (native shadow)
  • No unacceptable shadow jump when overlay loses/gains key
  • Chat expand / meeting ambient / onboarding handoff still correct
  • No double-shadow (CSS + native)

Related code

  • src-tauri/src/lib.rsinit_panel (set_has_shadow(false) rationale); onboarding enables native shadow; set_overlay_native_shadow
  • src/App.tsxCONTAINER_VERTICAL_PADDING, layout shadow-bar/shadow-chat, ResizeObserver frame sizing
  • Compact meeting ambient: content-tight frame + native shadow (reference implementation)

Non-goals

  • Changing Settings window shadow model (filled chrome, different constraints)
  • Reintroducing a large invisible hit pad solely for CSS blur room

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions