Skip to content

feat(launch): add capture-excluded notes window for recordings#43

Open
Itzadetunji wants to merge 10 commits into
getopenscreen:mainfrom
Itzadetunji:main
Open

feat(launch): add capture-excluded notes window for recordings#43
Itzadetunji wants to merge 10 commits into
getopenscreen:mainfrom
Itzadetunji:main

Conversation

@Itzadetunji

@Itzadetunji Itzadetunji commented Jun 28, 2026

Copy link
Copy Markdown

Notes window

Recording-time plain-text notes in a separate Electron window, opened from the HUD. The window uses content protection so it is excluded from most screen capture pipelines.


Pull request summary

Use the section below as the PR description (gh pr create --body-file docs/features/notes-window.md — remove everything above this heading first, or copy from Summary onward).

Summary

Adds a dedicated Notes window for taking plain-text notes while recording. Users open it from a new notepad button on the recording HUD. Notes live in a separate BrowserWindow (not the HUD overlay) with setContentProtection(true) so the window is excluded from most screen capture pipelines.

Implementation follows the existing multi-window pattern: main-process factory in electron/windows.ts, lifecycle wrapper in electron/main.ts, IPC via open-notes / electronAPI.openNotes(), and renderer routing with the ?showNotes=true query param to render NotesWindow. Re-opening notes focuses the existing window instead of creating duplicates. Note content is persisted locally via localStorage.

Related issue

Fixes #

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging
  • Not platform-specific

Screenshots / video

Testing

Manual

  1. npm run dev
  2. Open the HUD and click the Notes (notepad) button on the tray.
  3. Confirm a separate framed window opens titled OpenScreen - Notes with a full-height textarea.
  4. Type notes, close the window, reopen via the HUD button — content should persist (localStorage).
  5. Click Notes again while the window is already open — the same window should be focused (no second instance).
  6. Start a screen recording and confirm the notes window is not visible in the captured output (content protection behavior varies by OS/capture method — verify on target platform).

Commands

  • npm run lint
  • npx tsc --noEmit
  • npm run test
  • npm run i18n:check

Platforms tested

  • Windows
  • macOS
  • Linux

Architecture

OpenScreen uses one Vite/React entry (index.html) for every window. The notes window is a second BrowserWindow that loads the same app with ?showNotes=true. App.tsx renders <NotesWindow /> when that param is present.

HUD (LaunchWindow)
  └─ click Notes button
       └─ electronAPI.openNotes()
            └─ IPC open-notes (handlers.ts)
                 └─ createNotesWindowWrapper() (main.ts)
                      └─ createNotesWindow() (windows.ts)
                           └─ loadURL(?showNotes=true)
                                └─ App.tsx → NotesWindow.tsx
Layer File Role
Window factory electron/windows.ts createNotesWindow() — size, title, setContentProtection, load URL
Lifecycle electron/main.ts notesWindow ref, createNotesWindowWrapper(), closed handler
IPC electron/ipc/handlers.ts open-notes — focus existing or create
Preload electron/preload.ts openNotes()
Types electron/electron-env.d.ts openNotes return type
Routing src/App.tsx, src/main.tsx showNotes query param
UI src/components/launch/NotesWindow.tsx Textarea + localStorage
HUD entry src/components/launch/LaunchWindow.tsx Notepad button
i18n src/i18n/locales/en/launch.json tooltips.openNotes

Window options

The notes window is a standard framed, resizable window:

  • Size: 400×540 default; min 320×400; max 640×720
  • Always on top: yes (stays usable while recording)
  • Content protection: enabled (excluded from capture where the OS supports it)
  • Taskbar / Dock: visible (skipTaskbar: false)

Persistence

Notes are stored in renderer localStorage under the key "notes". This is global to the app install, not tied to a specific recording or project.

Known limitations (v1)

  • Plain textarea only — no rich text formatting
  • Single global note — not per-recording or per-project
  • tooltips.openNotes added to English locale only; other locales need updating before npm run i18n:check passes
  • Content protection effectiveness depends on OS and capture method — manual verification required on Windows and macOS
  • HUD button focuses an open notes window; it does not close it (close via window chrome)

Release note (changelog)

Notes window: Take plain-text notes in a separate always-on-top window from the recording HUD. The notes window uses content protection so it stays out of screen recordings.

Summary by CodeRabbit

  • New Features

    • Added a “Notes” window accessible from the launch screen via a new “Open Notes” control.
    • Notes auto-save to local storage as you type and are restored when reopening.
    • Added support for a notes-specific view using a showNotes=true URL parameter, plus new notes tooltips.
  • Bug Fixes

    • Improved Notes window lifecycle: it now focuses an existing window when available, creates it when needed, and notifies the main app on close.

Changed the query parameter from "windowType=notes" to "showNotes=true" in both the Electron window creation and the React app. This enhances clarity and consistency in how the notes window is displayed based on URL parameters.
Modified the Electron notes window to enhance its appearance and functionality by adjusting dimensions, background color, and removing unnecessary properties. Updated the React NotesWindow component to ensure it occupies the full screen height and width, improving user experience for note-taking.
Updated the dimensions of the Electron notes window for better usability and added max width and height constraints. Enhanced the React NotesWindow component to store and retrieve notes from local storage, improving the user experience by preserving notes across sessions.
Rearranged the order of window creation to ensure the countdown overlay is displayed correctly. Updated the title of the NotesWindow to "OpenScreen - Notes" for better branding and clarity.
Updated the NotesWindow component to utilize useLayoutEffect instead of useEffect for setting initial notes from local storage, improving performance and ensuring the notes are rendered correctly before the browser paints the UI.
Eliminated the allowScripts configuration for specific dependencies in package.json, streamlining the file and removing unnecessary entries.
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a notes window flow: Electron creates and manages a notes BrowserWindow, the renderer opens it through openNotes(), and the app renders a notes UI when showNotes=true.

Changes

Notes Window Feature

Layer / File(s) Summary
Electron window factory and IPC handler
electron/windows.ts, electron/main.ts, electron/ipc/handlers.ts, electron/preload.ts, electron/electron-env.d.ts
Creates the notes window factory, tracks its lifecycle in main process state, registers open-notes, exposes openNotes() in preload, and adds the corresponding renderer type.
Notes UI and launch entry points
src/components/launch/NotesWindow.tsx, src/App.tsx, src/main.tsx, src/components/launch/LaunchWindow.tsx, src/i18n/locales/en/launch.json
Adds the notes editor UI with localStorage persistence, routes App into notes mode from showNotes, enables transparent rendering for that mode, adds the launch HUD control, updates tooltip strings, and applies the renderer transparency condition.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped to the notes, so neat and bright,
A little window to jot thoughts at night.
Click, open, write — let ideas flow free,
Stored in my burrow for future me!
🌙📝

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a notes window for recordings with capture protection.
Description check ✅ Passed The PR description covers the required template sections and includes summary, testing, and platform details, though the issue number and screenshots are still placeholders.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@Itzadetunji

Copy link
Copy Markdown
Author

@EtienneLescot, I would love to get feedback on this PR so I know what to improve upon

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/windows.ts`:
- Around line 324-346: The Notes window is still using the default OS window
chrome because the BrowserWindow created in createNotesWindow() does not disable
the frame. Update the BrowserWindow options in createNotesWindow() to make it
frameless by setting the appropriate frame/title bar option so the window
renders without OS controls.

In `@src/App.tsx`:
- Around line 23-24: App currently mounts NotesWindow through two separate
conditions, so when windowType=notes and showNotes=true are both set it renders
twice and competes for the same notes localStorage state. Update App’s render
logic so NotesWindow is created through a single mutually exclusive path, using
the existing windowType/showNotes checks to choose only one branch and prevent
duplicate mounts; adjust the related NotesWindow render sites in App
accordingly.

In `@src/components/launch/LaunchWindow.tsx`:
- Around line 1048-1055: The new Notes icon-only button in LaunchWindow needs an
accessible name because the Tooltip content does not label the trigger. Update
the button that calls window.electronAPI.openNotes() to expose a clear label for
assistive tech, using the existing t("tooltips.openNotes") text as the button’s
accessible name while keeping the Tooltip for hover behavior.

In `@src/components/launch/NotesWindow.tsx`:
- Around line 17-20: The NotesWindow textarea is using hardcoded user-facing
placeholder text, so it bypasses the app’s localization flow. Update the
placeholder in NotesWindow to use the existing i18n/translation mechanism used
elsewhere in the launch UI, and ensure the new key is added to the locale
resources instead of leaving "Take notes here..." inline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a24189e-3595-4780-8f6b-fa7b7d89cd0e

📥 Commits

Reviewing files that changed from the base of the PR and between f6b81e7 and 3dad308.

📒 Files selected for processing (10)
  • electron/electron-env.d.ts
  • electron/ipc/handlers.ts
  • electron/main.ts
  • electron/preload.ts
  • electron/windows.ts
  • src/App.tsx
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/NotesWindow.tsx
  • src/i18n/locales/en/launch.json
  • src/main.tsx

Comment thread electron/windows.ts
Comment thread src/App.tsx
Comment thread src/components/launch/LaunchWindow.tsx
Comment thread src/components/launch/NotesWindow.tsx
Removed the conditional rendering of NotesWindow from the main App component and integrated it directly within the return statement when showNotes is true. Added aria-label for the open notes button in LaunchWindow for better accessibility. Updated the placeholder text in NotesWindow to utilize localized strings for improved user experience.
Removed the conditional block for rendering NotesWindow and integrated it directly within the return statement, improving code clarity. This change ensures that NotesWindow is displayed when showNotes is true, streamlining the component structure.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/App.tsx`:
- Around line 117-120: The notes render path in App.tsx is not exclusive, so
when showNotes is true the NotesWindow renders but content still falls through
to the default Openscreen panel. Update the render logic around TooltipProvider,
NotesWindow, and the content branch so the notes route short-circuits the
default panel and only one view is shown. Use the existing showNotes and
windowType checks to make the NotesWindow path mutually exclusive from the
fallback content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd684725-4cb6-4f12-b5d4-1eae404e9272

📥 Commits

Reviewing files that changed from the base of the PR and between d1ff93e and b280512.

📒 Files selected for processing (1)
  • src/App.tsx

Comment thread src/App.tsx
Comment on lines 117 to 120
return (
<TooltipProvider>
{showNotes && <NotesWindow />}
{content}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the notes render path exclusive.

Per the new route contract, the notes window is opened with ?showNotes=true. In that case windowType stays empty, so content still falls through to the default "Openscreen" panel and renders alongside NotesWindow at Line 120. That breaks the notes-only window.

Suggested fix
	return (
		<TooltipProvider>
-			{showNotes && <NotesWindow />}
-			{content}
+			{showNotes ? <NotesWindow /> : content}
			<Toaster theme="dark" />
		</TooltipProvider>
	);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<TooltipProvider>
{showNotes && <NotesWindow />}
{content}
return (
<TooltipProvider>
{showNotes ? <NotesWindow /> : content}
<Toaster theme="dark" />
</TooltipProvider>
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/App.tsx` around lines 117 - 120, The notes render path in App.tsx is not
exclusive, so when showNotes is true the NotesWindow renders but content still
falls through to the default Openscreen panel. Update the render logic around
TooltipProvider, NotesWindow, and the content branch so the notes route
short-circuits the default panel and only one view is shown. Use the existing
showNotes and windowType checks to make the NotesWindow path mutually exclusive
from the fallback content.

@EtienneLescot

Copy link
Copy Markdown
Collaborator

@Itzadetunji thank you for this PR, could you provide us with screenshots of the feature ?

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