Skip to content

Conversation

@oscartbeaumont
Copy link
Contributor

@oscartbeaumont oscartbeaumont commented Aug 4, 2025

TODO:

  • Merge Main and NewMain into one window with different URL based on feature flag
    • Open settings -> close it -> why doesn't the Cap main window reopen?
    • Tray icon "New recording" breaks after clicking settings.
    • "Start recording" isn't closing the main window
  • Convert the feature flag into one that shows up in the UI
  • The window seems to spawn the incorrect size and then clicking it seems to fix it.
  • Overlay is a different color on Windows?
  • Windows support for selecting windows
  • open_target_select_overlays inside needs a windows alternative
  • Cap window should sit on top of recording overlay on Windows
    • Any interaction with overlay needs to refocus main Cap window
    • Escape broken when the focus is on the cap main window not the overlay
    • Properly feature flag the Windows-specific z-index code
  • Why does area select have a vertical line on Windows
  • Escape-key to close the preview
  • Tauri window spawning in the incorrect size Seems to be working for me now when I switch back and forth with main but might come back with more testing?
  • When clicking settings, etc in the main window, we should close the overlay
  • Close the overlay when the recording starts or is quit, etc (This can be generalised to close overlay when the cap main window is closed)
  • macOS crashing on recording start
  • Overlay appears at start of recording
  • Extra metadata in selection UI
    • Show monitor name, fps and framerate
    • Show application logo for windows
    • On windows the text is the wrong color?
  • Cleanup Tokio task for cursor tracking
  • Does Tauri now steal with Escape key from other applications?
  • Adjust recording area button to switch from window to area easily
  • Fix toggles in experimental panel being broken
  • The contrast on the overlay can be pretty bad
  • The coordinate scaling logic would make Brendan cry
  • Overlay text is wrong color on Windows until HMR event???
  • Windows application icon working

Summary by CodeRabbit

  • New Features

    • Target selection overlay across displays (screen/window/area) with live highlights and Esc to close.
    • New recording flow UI: device selection, permissions, system-audio toggle, target mode switching, changelog badge and update prompt.
  • Improvements

    • Main window can route to the new experience when enabled; improved window/focus behavior on macOS and multi-display handling.
    • Added monitor/window detection and new UI icons; refined button hover behavior and query prefetching.
  • Bug Fixes

    • Avoids crashing when a previously selected camera is unavailable.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 4, 2025

Warning

Rate limit exceeded

@Brendonovich has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e905650 and 2f4229f.

📒 Files selected for processing (5)
  • apps/desktop/src-tauri/src/hotkeys.rs (2 hunks)
  • apps/desktop/src-tauri/src/lib.rs (10 hunks)
  • apps/desktop/src-tauri/src/target_select_overlay.rs (1 hunks)
  • apps/desktop/src-tauri/src/tray.rs (2 hunks)
  • crates/displays/src/platform/win.rs (2 hunks)

Walkthrough

Adds a cross-platform target-select overlay system: new Tauri commands/events/types, per-display overlay windows with cursor tracking and Escape handling, display/window APIs in a new displays crate, a SolidJS overlay and new recording flow UI, settings and binding updates, plus dependency and minor UI tweaks.

Changes

Cohort / File(s) Summary of changes
Overlay subsystem (Tauri Rust)
apps/desktop/src-tauri/src/lib.rs, apps/desktop/src-tauri/src/target_select_overlay.rs, apps/desktop/src-tauri/src/windows.rs, apps/desktop/src-tauri/src/hotkeys.rs, apps/desktop/src-tauri/Cargo.toml
Adds target-select overlay module, new CapWindowId/ShowCapWindow variant, WindowFocusManager, cursor-tracking tasks, global Escape registration/event (OnEscapePress), open/close overlay commands, lifecycle wiring, and cap-displays crate dependency.
Settings schema (Rust + UI)
apps/desktop/src-tauri/src/general_settings.rs, apps/desktop/src/routes/(window-chrome)/settings/general.tsx, apps/desktop/src/routes/(window-chrome)/settings/experimental.tsx
Removes deprecated openEditorAfterRecording; adds enableNewRecordingFlow with conditional default; refactors enableNativeCameraPreview serialization/default; updates frontend defaults/UI layout (DEV toggle commented).
Overlay UI and new recording flow (SolidJS)
apps/desktop/src/routes/target-select-overlay.tsx, apps/desktop/src/routes/(window-chrome)/new-main.tsx, apps/desktop/src/routes/(window-chrome)/(main).tsx
Adds interactive target-select overlay component (screen/window/area modes, drag/resize), new recording flow page with device/permission handling, and focus-based navigation to new-main; removes stray console.log.
Tauri bindings, queries, App
apps/desktop/src/utils/tauri.ts, apps/desktop/src/utils/queries.ts, apps/desktop/src/App.tsx
Exposes open/close overlay commands and targetUnderCursor/OnEscapePress events and geometry types; exports listVideoDevices; refactors persisted store handling; changes license query key; enables experimental_prefetchInRender.
Displays crate (core APIs)
crates/displays/src/lib.rs, crates/displays/src/bounds.rs, crates/displays/src/platform/mod.rs, crates/displays/src/platform/macos.rs, crates/displays/src/platform/win.rs, crates/displays/Cargo.toml, crates/displays/src/main.rs
New bounds/geometry types, Display/Window abstractions, DisplayId/WindowId wrappers with Serde/Specta, platform-specific macOS/Windows implementations for enumeration, cursor containment, topmost window, names/icons/refresh rates; expanded deps and diagnostic main.
Frontend assets & UI tweaks
apps/desktop/package.json, packages/ui-solid/src/auto-imports.d.ts, packages/ui-solid/src/Button.tsx
Adds @solid-primitives/mouse; declares new global icon imports; adjusts primary Button hover class to apply only when enabled.
Misc / Robustness
apps/desktop/src-tauri/src/tray.rs, crates/media/src/feeds/camera.rs
Consolidates imports and explicitly discards awaited result in tray spawn; replaces an unwrap with error propagation when selected camera is missing.
Tauri TypeScript bindings (client)
apps/desktop/src/utils/tauri.ts
Adds DisplayId, WindowId, LogicalBounds/Position/Size, PhysicalSize types; updates ShowCapWindow and GeneralSettingsStore shapes to match Rust surface.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Frontend (overlay / new-main)
  participant Tauri as Tauri Runtime
  participant Disp as cap-displays
  participant Win as Window Manager
  participant GS as Global Shortcut

  UI->>Tauri: open_target_select_overlays()
  Tauri->>Disp: enumerate displays
  loop per display
    Tauri->>Win: create TargetSelectOverlay window (display_id)
    Tauri->>Tauri: spawn cursor-tracking task -> emit TargetUnderCursor
    Tauri->>GS: register Escape shortcut (once)
  end
  UI-->>Tauri: close_target_select_overlays() or OnEscapePress
  Tauri->>Win: close overlay windows
  Tauri->>GS: unregister Escape when no overlays remain
Loading
sequenceDiagram
  participant OS as OS Keyboard
  participant GS as Global Shortcut
  participant Tauri as Tauri Runtime
  participant UI as Frontend Overlay

  OS-->>GS: Escape pressed
  GS->>Tauri: deliver Escape event
  Tauri->>UI: emit OnEscapePress
  UI->>Tauri: request close_target_select_overlays()
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90 minutes

Possibly related PRs

Suggested labels

codex

Poem

I hop across displays at night, 🐇
I trace the cursor, soft and light.
Escape to close the overlay’s song,
I bind focus fast and tidy wrong.
New flows and bounds, a tidy trail —
I leave a carrot-shaped exclamation mark for sale. 🎋

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch new-recording-flow

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@oscartbeaumont oscartbeaumont linked an issue Aug 4, 2025 that may be closed by this pull request
@Brendonovich
Copy link
Contributor

Merging with the experimental feature toggled, until recording mode selection is resolved + new design is settled on.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
apps/desktop/src-tauri/src/general_settings.rs (1)

83-87: Fix incorrect serde predicate and formalize deprecations

  • The skip_serializing_if = "no" predicate never skips serialization because no always returns false. If the intent is to skip when the value is false, the predicate must check the value.
  • The deprecation notes are comments. Use Rust’s #[deprecated] attribute so the compiler warns on use.

Apply this diff:

-    // #[deprecated = "can be removed when native camera preview is ready"]
+    #[deprecated(note = "can be removed when native camera preview is ready")]
     #[serde(
         default = "default_enable_native_camera_preview",
-        skip_serializing_if = "no"
+        skip_serializing_if = "is_false"
     )]
     pub enable_native_camera_preview: bool,
@@
-    // #[deprecated = "can be removed when new recording flow is the default"]
+    #[deprecated(note = "can be removed when new recording flow is the default")]
     #[serde(
         default = "default_enable_new_recording_flow",
-        skip_serializing_if = "no"
+        skip_serializing_if = "is_false"
     )]
     pub enable_new_recording_flow: bool,
@@
-fn no(_: &bool) -> bool {
-    false
-}
+fn is_false(value: &bool) -> bool {
+    !*value
+}

Also applies to: 91-96, 111-114

apps/desktop/src-tauri/src/windows.rs (1)

243-247: Replace magic window-level numbers with named constants

Use named constants to document intent and avoid “50”/“45” magic numbers. This was flagged previously.

Apply these diffs in-place:

-                        crate::platform::set_window_level(window.as_ref().window(), 50);
+                        crate::platform::set_window_level(window.as_ref().window(), NEW_RECORDING_FLOW_WINDOW_LEVEL);
-                    crate::platform::set_window_level(window.as_ref().window(), 45);
+                    crate::platform::set_window_level(window.as_ref().window(), TARGET_SELECT_OVERLAY_WINDOW_LEVEL);

Add the constants near the top of this file:

#[cfg(target_os = "macos")]
const NEW_RECORDING_FLOW_WINDOW_LEVEL: i32 = 50;

#[cfg(target_os = "macos")]
const TARGET_SELECT_OVERLAY_WINDOW_LEVEL: i32 = 45;

Also applies to: 283-285

🧹 Nitpick comments (4)
packages/ui-solid/src/auto-imports.d.ts (2)

62-63: Nit: Inconsistent quoting style (double vs single).

The rest of the file uses single quotes, while these two lines use double quotes. If you prefer consistency (even in generated files), align them to single quotes or update the generator config.

Apply this diff if you choose to normalize:

-  const IconIcBaselineMonitor: typeof import("~icons/ic/baseline-monitor.jsx")["default"]
-  const IconIcRoundSearch: typeof import("~icons/ic/round-search.jsx")["default"]
+  const IconIcBaselineMonitor: typeof import('~icons/ic/baseline-monitor.jsx')['default']
+  const IconIcRoundSearch: typeof import('~icons/ic/round-search.jsx')['default']

Note: since this file is generated, prefer fixing at the plugin/config level if possible.


86-90: Ergonomics: Extremely long/duplicated component names; consider aliasing.

Declarations like IconMaterialSymbolsLightScreenshotFrame2MaterialSymbolsScreenshotFrame2Rounded are verbose and contain duplicated segments. To keep JSX more readable, consider aliasing via a local module (or adjusting the icon resolver naming strategy) and importing those aliases where used.

Example alias module outside the generated file (e.g., packages/ui-solid/src/icons.ts):

export { default as IconScreenshotFrameRounded } from '~icons/material-symbols/screenshot-frame2-rounded.jsx'
export { default as IconScreenshotFrameLight } from '~icons/material-symbols-light/screenshot-frame2.jsx'
export { default as IconClose } from '~icons/lucide/x.jsx'
export { default as IconMonitor } from '~icons/mdi/monitor.jsx'

Then use <IconScreenshotFrameRounded />, etc., instead of relying on the long auto-imported globals. This keeps the generated d.ts intact while improving call sites.

apps/desktop/src-tauri/src/general_settings.rs (1)

101-106: Replace TODO with explicit intent or tracked issue

The TODO suggests platform-conditional defaulting. Consider referencing an issue ID or adding a short rationale to avoid confusion later.

apps/desktop/src-tauri/src/windows.rs (1)

226-232: Nit: avoid redundant reference when fetching settings

Pass app directly; &app introduces an extra borrow.

-                    let new_recording_flow = GeneralSettingsStore::get(&app)
+                    let new_recording_flow = GeneralSettingsStore::get(app)
                         .ok()
                         .flatten()
                         .map(|s| s.enable_new_recording_flow)
                         .unwrap_or_default();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1afa479 and 290f6f5.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • apps/desktop/package.json (1 hunks)
  • apps/desktop/src-tauri/Cargo.toml (1 hunks)
  • apps/desktop/src-tauri/src/general_settings.rs (2 hunks)
  • apps/desktop/src-tauri/src/hotkeys.rs (3 hunks)
  • apps/desktop/src-tauri/src/lib.rs (10 hunks)
  • apps/desktop/src-tauri/src/windows.rs (10 hunks)
  • apps/desktop/src/routes/(window-chrome)/(main).tsx (2 hunks)
  • apps/desktop/src/routes/(window-chrome)/settings/experimental.tsx (3 hunks)
  • apps/desktop/src/routes/(window-chrome)/settings/general.tsx (1 hunks)
  • apps/desktop/src/utils/tauri.ts (11 hunks)
  • crates/displays/src/platform/win.rs (2 hunks)
  • crates/media/src/feeds/camera.rs (1 hunks)
  • packages/ui-solid/src/auto-imports.d.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • apps/desktop/package.json
  • apps/desktop/src-tauri/Cargo.toml
  • crates/media/src/feeds/camera.rs
  • apps/desktop/src/routes/(window-chrome)/(main).tsx
  • apps/desktop/src-tauri/src/hotkeys.rs
  • apps/desktop/src/routes/(window-chrome)/settings/general.tsx
  • crates/displays/src/platform/win.rs
  • apps/desktop/src/utils/tauri.ts
  • apps/desktop/src/routes/(window-chrome)/settings/experimental.tsx
  • apps/desktop/src-tauri/src/lib.rs
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/desktop/src-tauri/src/windows.rs (5)
apps/desktop/src-tauri/src/target_select_overlay.rs (1)
  • cap_displays (51-54)
crates/displays/src/lib.rs (5)
  • s (65-65)
  • s (86-86)
  • s (147-147)
  • s (168-168)
  • from_id (27-29)
apps/desktop/src-tauri/src/lib.rs (4)
  • None (2428-2428)
  • app (1190-1191)
  • app (2183-2183)
  • app (2211-2211)
apps/desktop/src-tauri/src/general_settings.rs (1)
  • get (172-183)
apps/desktop/src-tauri/src/platform/macos/mod.rs (1)
  • set_window_level (15-24)
apps/desktop/src-tauri/src/general_settings.rs (1)
apps/desktop/src/utils/tauri.ts (1)
  • PostDeletionBehaviour (394-394)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Clippy
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
🔇 Additional comments (14)
packages/ui-solid/src/auto-imports.d.ts (1)

60-60: LGTM: New global icon declaration is correct.

The added IconFa6SolidDisplay declaration matches the established pattern and path resolution.

apps/desktop/src-tauri/src/general_settings.rs (2)

107-110: LGTM: sensible default for experimental flow

Defaulting enable_new_recording_flow to cfg!(debug_assertions) aligns with “experimental on dev, off on prod.”


150-153: LGTM: defaults wired through helper fns

Using default_enable_* helpers in Default is clean and consistent with serde defaults.

apps/desktop/src-tauri/src/windows.rs (11)

4-10: LGTM: additional imports required for new overlay flow

New imports are consistent with added functionality.


31-31: LGTM: derive additions on CapWindowId

Deriving Clone, Deserialize, and Type is appropriate for routing and TS bridging.


40-40: LGTM: add TargetSelectOverlay variant

The new CapWindowId::TargetSelectOverlay { display_id } cleanly represents per-display overlays.


76-81: LGTM: FromStr branch for target-select-overlay

Parsing display_id via DisplayId::from_str is straightforward; errors are handled.


98-100: LGTM: Display impl for target-select-overlay

String format matches the FromStr branch, maintaining round-trip symmetry.


156-158: LGTM: exclude overlays from macOS traffic lights

Correct to return None for overlays to avoid drawing traffic controls.


184-190: LGTM: ShowCapWindow variant for TargetSelectOverlay

This keeps the show-path aligned with the new CapWindowId variant.


194-205: LGTM: avoid duplicate editor windows

Borrowing self to access project_path and tracking IDs prevents duplicates.


233-242: Confirm always-on-top + all-workspaces policy for Main

Setting the Main window .always_on_top(true) and .visible_on_all_workspaces(true) unconditionally may degrade UX (e.g., pinning across virtual desktops) and differs from the macOS-specific window-level handling used elsewhere.

  • If the goal is Windows-only z-order behavior, consider gating:
    • .always_on_top(cfg!(target_os = "windows"))
    • or tie it to the feature flag.
  • If intended globally, ignore this.

Proposed adjustment:

-                        .always_on_top(true)
-                        .visible_on_all_workspaces(true)
+                        .always_on_top(cfg!(target_os = "windows"))
+                        .visible_on_all_workspaces(cfg!(target_os = "windows"))

253-289: LGTM: per-display overlay window config

Sizing/positioning to display bounds, per-display URL param, focus management spawn, and taskbar skipping look correct. macOS window-level handling is consistent with the rest of the codebase.


624-626: LGTM: id mapping for TargetSelectOverlay

Correctly maps ShowCapWindow to CapWindowId with cloned display_id.

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.

New recording picker

3 participants