Skip to content

feat: video capture frontend — consent, notifications, activity stream & settings#292

Merged
shanselman merged 9 commits intoopenclaw:masterfrom
christineyan4:christiney/video-capture
May 7, 2026
Merged

feat: video capture frontend — consent, notifications, activity stream & settings#292
shanselman merged 9 commits intoopenclaw:masterfrom
christineyan4:christiney/video-capture

Conversation

@christineyan4
Copy link
Copy Markdown
Contributor

Summary

Adds the complete frontend experience for the video capture capabilities (screen.record and camera.clip). The backend recording commands already existed but had no UI feedback, consent flow, or user-facing controls.

Demo

📹 Video walkthrough

What's included

1. Recording state tracking (NodeService.cs)

  • RecordingType enum (Screen, Camera), RecordingStateEventArgs class
  • RecordingStateChanged event with IsScreenRecording/IsCameraRecording properties
  • Wrappers around OnScreenRecord and OnCameraClip that emit state start/complete/error

2. Toast notifications

  • System toasts for recording start, complete, and error (both screen & camera)
  • 10 new resource strings across all 5 locales

3. Activity stream integration (App.xaml.cs, ActivityPage.xaml)

  • Recording events appear in the activity feed with emoji indicators (🔴 recording, ✅ complete)
  • Fixed WinUI color emoji clipping issue with separate TextBlock in StackPanel layout
  • Added Icon property to ActivityStreamItem

4. Recording consent dialog (RecordingConsentDialog.cs)

  • Standalone WindowEx with Mica backdrop and custom titlebar
  • Separate consent per capability (screen vs camera)
  • TaskCompletionSource pattern for async result
  • SetForegroundWindow + HWND_TOPMOST for reliable z-order
  • Deny = block this request only (re-prompts next time)
  • Allow = persist consent, skip dialog for future requests

5. Privacy settings UI (SettingsPage.xaml)

  • New "Privacy" expander with screen/camera recording toggles
  • Live-updates via SettingsManager.Saved event when consent changes externally
  • "✓ Saved" indicator when auto-updated by consent dialog

6. Localization

  • All new strings localized across en-us, fr-fr, zh-cn, zh-tw, nl-nl
  • Passes LocalizationValidationTests (all locales have matching keys)

Testing

  • All 1220 shared tests + 389 tray tests pass
  • Manual verification: consent flow (allow/deny), toast notifications, activity stream, settings toggle sync, permission persistence across restarts, z-order behavior

Copy link
Copy Markdown
Contributor

@shanselman shanselman left a comment

Choose a reason for hiding this comment

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

Thanks for adding the recording UX surfaces. I think the consent model needs changes before this can merge.

Two blockers stood out:

  1. Concurrent recording requests can show multiple consent dialogs and race unsynchronized SettingsManager.Save calls, so consent state can be lost or applied unpredictably.
  2. The sticky consent flags can be granted from Settings and then future recording requests proceed without a fresh prompt. For camera/screen recording, that needs a clearer privacy model: settings text should make the behavior explicit, future recordings should have reliable user-visible indication, and consent updates should be serialized/atomic.

@christineyan4 christineyan4 force-pushed the christiney/video-capture branch from 25d0072 to 40b674a Compare May 7, 2026 17:54
@christineyan4
Copy link
Copy Markdown
Contributor Author

Thanks for feedback! Pushed changes addressing these blockers--fixed the consent dialog race condition and added a lock on SettingsManager.Save() to serialize concurrent writes. Also updated the Settings text to make the sticky consent behavior more explicit.

Also added a 3-2-1 countdown overlay before recording, to give users a clear visual cue that recording is about to start, whether thru camera or on screen.

@shanselman
Copy link
Copy Markdown
Contributor

Thanks so much for the quick follow-up, Christine — this is really close. 🙏

Bot-assisted note from Scott's triage pass: I can see you addressed the big issues we called out around consent dialog coalescing and serializing SettingsManager.Save(). That moved the PR a lot closer.

I think there are just a few small things left before we can comfortably clear the requested-changes review:

  1. CI needs one more passbuild-extension (arm64) is failing and build-extension (x64) was cancelled. This may be transient, but we need those green or a clear explanation.
  2. Consent lock cleanup — the current _consentLock flow manually releases the semaphore in multiple paths and uses CurrentCount in the catch block. Could you refactor that so we don't rely on CurrentCount/best-effort release? The intent looks right; I just want to avoid an over-release/race edge case.
  3. Sticky consent copy — since clicking Allow persists future recording consent until changed in Settings, could the dialog copy say that explicitly? Something like “Allow future screen/camera recordings until disabled in Settings” would make the privacy model clearer.
  4. Settings page dirty state — external consent saves can still update the recording toggles while the Settings page has unsaved edits. A small dirty-state guard, or only applying external consent updates when the page is clean, would make this safer.
  5. Focused tests if practical — even one test around consent coalescing or settings-save behavior would help lock this down.

Again, thank you — the feature direction is good, and the latest commits show exactly the kind of quick iteration we were hoping for. This feels like a small cleanup pass away rather than a major rework.

Christine Yan and others added 8 commits May 7, 2026 16:23
Add IsScreenRecording/IsCameraRecording properties and RecordingStateChanged
event to NodeService. Wrap OnScreenRecord and OnCameraClip handlers to set
state and raise events before/after async recording calls.

This enables downstream UI components (tray icon, toasts, activity log) to
react to recording lifecycle changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Show toasts on recording start, completion, and failure for both screen
recording and camera clips. Extract reusable ShowToast helper and add
localized strings for all 5 locales (en-us, fr-fr, zh-cn, zh-tw, nl-nl).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add recording start/complete events with emoji indicators (🔴/✅) to the
activity stream. Render emoji in a separate TextBlock element to prevent
color emoji clipping by the card's CornerRadius clip mask.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Show a standalone WindowEx consent dialog the first time an agent
requests screen or camera recording. Consent is tracked separately
per recording type (ScreenRecordingConsentGiven, CameraRecordingConsentGiven)
so users can allow screen recording without granting camera access.
The dialog uses extend-into-titlebar styling, Mica backdrop, and
SetForegroundWindow to ensure visibility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add Privacy section to Settings with screen/camera recording toggles
- Settings toggles auto-refresh when consent changes externally
- Fix consent dialog z-order with HWND_TOPMOST technique
- Fix button width (MinWidth instead of fixed Width)
- Add SettingsManager.Saved event for cross-component reactivity
- Allow button uses AccentButtonStyle for consistency
- Remove misleading 'only asked once' from privacy text

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add SemaphoreSlim guard in EnsureRecordingConsentAsync so concurrent
  recording requests coalesce onto a single consent dialog per type
- Add lock around SettingsManager.Save() to prevent concurrent file writes
- Update privacy toggle text in all 5 locales to clarify that enabling
  skips future consent prompts (e.g. 'Allow screen recording without prompting')

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Show a translucent topmost countdown window (3 → 2 → 1) before screen
and camera recordings begin, similar to Windows Snipping Tool. Gives users
clear visual indication that recording is about to start.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanselman shanselman force-pushed the christiney/video-capture branch from 40b674a to 3780405 Compare May 7, 2026 20:32
- Add dirty-state guard to SettingsPage: external consent saves no
  longer overwrite unsaved user edits on the Settings page
- Update consent dialog description in all 5 locales to explicitly
  state that the choice persists until changed in Settings
- Add 4 focused tests for settings save thread safety, Saved event,
  consent persistence, and consent revocation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanselman shanselman merged commit adcccc9 into openclaw:master May 7, 2026
7 checks passed
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