fix: detect screen picker type reliably inside sandboxes (#3308) - #3386
Conversation
detectPickerType() read XDG_SESSION_TYPE / XDG_CURRENT_DESKTOP to choose between the XDG-portal picker and the internal cached-thumbnail picker. Flatpak and Snap strip those env vars from the sandbox, so on a Wayland host the function fell through to 'internal', whose provider sets requiresCacheWarming = true. That warms the desktopCapturer cache at WEBVIEW_READY via desktopCapturer.getSources(); on Wayland (we force --enable-features=WebRTCPipeWireCapturer on all Linux) getSources() routes through the XDG portal and pops the screen-share picker dialog on every launch. Flip the Linux default to 'portal' and only recover 'internal' when we can positively confirm a silent-capable environment: a Wayland session is detected via XDG_SESSION_TYPE or a real WAYLAND_DISPLAY socket on disk (mirroring the ozone-platform decision in app.ts), pure X11 is detected via XDG_SESSION_TYPE=x11, and ROCKETCHAT_INTERNAL_SCREEN_PICKER=1 forces the internal picker. Ambiguous/stripped env now defaults to portal, so no picker dialog fires at launch. Add createScreenPicker.spec.ts covering sandbox, Wayland (env + socket), X11, escape hatch, and macOS/Windows.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout. (3)
🧰 Additional context used📓 Path-based instructions (5)**/*.ts📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{tsx,ts}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.spec.ts📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{spec.ts,main.spec.ts}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🔇 Additional comments (3)
WalkthroughThe screen picker's Wayland detection logic is rewritten to verify Wayland sessions by checking for the existence of a Wayland socket file via ChangesScreen picker Wayland detection fix
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
… rule (#3402) * docs: post-mortems for #3308 screen-picker triggers + capture-testing rule Two-phase investigation of the launch-time screen-share picker on Linux Wayland (#3308, fixed by #3386 and #3400). Adds the phase-2 post-mortem covering the startup-enumeration trigger, the Electron 40 vs 42 manifestation split, and the verification protocol; commits the phase-1 sandbox-detection post-mortem that previously lived untracked. CLAUDE.md gains the extracted testing rule: Chromium capture/portal behavior requires hardware GL to validate — software-rendered VMs mask it; assert on dbus ScreenCast requests, not dialog visibility. * docs: refresh GitNexus section in CLAUDE.md Tool-generated section update: current index stats, short tool names (impact/query/context/rename), detect_changes compare syntax, and the run.cjs analyze entrypoint.
Problem
Fixes #3308 — the screen-share picker dialog ("Rocket.Chat wants to share your screen. Choose what you'd like to share.") opens automatically on every app launch on Linux, before any user action. Reported on Flatpak/Flathub, reproducible on 4.14.0, 4.14.1 and 4.15.0.
Root cause
detectPickerType()chooses between the XDG-portal picker and the internal cached-thumbnail picker by readingXDG_SESSION_TYPE/XDG_CURRENT_DESKTOP. Flatpak and Snap strip those variables from the sandbox environment, so on a Wayland host the function fell through to'internal'.The
InternalPickerProvidersetsrequiresCacheWarming = true, which warms the desktopCapturer cache atWEBVIEW_READYviadesktopCapturer.getSources(). Because we force--enable-features=WebRTCPipeWireCaptureron all Linux,getSources()on Wayland routes through the XDG portal and pops the picker dialog — at every launch, with no user involvement.This is a picker detection gap, not a webapp probe: the Rocket.Chat web client does not call
getDisplayMedia()at load (verified against the webapp call graph — the onlygetDisplayMediais the user-gesture-gated VoIP path).Fix
Flip the Linux default to
'portal'and only recover'internal'when a silent-capable environment can be positively confirmed:ROCKETCHAT_INTERNAL_SCREEN_PICKER=1→internal(escape hatch for legacy X11-without-portal setups).portal. Detection no longer trustsXDG_SESSION_TYPEalone: it also accepts a realWAYLAND_DISPLAYsocket on disk (fs.statSync().isSocket()), mirroring the ozone-platform decision insrc/app/main/app.ts. Sandbox-safe.XDG_SESSION_TYPE=x11→internal(pure X11 enumerates silently; the internal picker with cached thumbnails is preferable there).portal— the core fix. Worst case the picker appears on user demand (correct) instead of at launch.Non-Linux (macOS / Windows) is unchanged →
internal.Complements the existing
requiresCacheWarmingguard inserverViewScreenSharing.ts: withportalcorrectly detected, the launch-timegetSources()prewarm never runs.Testing
createScreenPicker.spec.ts— 7 cases: sandbox (no env) → portal, Wayland env → portal, Flatpak-Wayland socket → portal, X11 → internal, escape hatch → internal, macOS → internal, Windows → internal.npx tsc --noEmitclean ·eslintclean ·jest(createScreenPicker + serverViewScreenSharing) 10/10 pass.Impact
GitNexus impact analysis: LOW risk. Only direct caller is
createScreenPicker; return type unchanged, both consumers (videoCallWindow/ipc.tsmain,video-call-window.tsrenderer) already switch on'portal' | 'internal'.Note
The Flathub package (
chat.rocket.RocketChat) is community-maintained and separate from this repo's official builds; this fix flows to the AppImage/deb/rpm/snap/flatpak artifacts produced here and downstream once released.Summary by CodeRabbit
New Features
Bug Fixes