Skip to content

fix(linux): enumerate screens and windows in separate calls under X11 - #1065

Merged
EtienneLescot merged 2 commits into
mainfrom
ci/462-source-enumeration-hang
Oct 8, 2026
Merged

EtienneLescot merged 2 commits into
mainfrom
ci/462-source-enumeration-hang

Conversation

@EtienneLescot

@EtienneLescot EtienneLescot commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Summary

Cause found. On X11, a single desktopCapturer.getSources call that asks for screen and window together makes the X11 screen capturer's thumbnail grab fail now and then (Failed to initialize pixel buffer). What the caller sees depends on Electron:

Fix.

  • The get-sources handler asks for one type per call, one call after the other, on Linux X11 only. This covers openscreen sources, openscreen record and the GUI pickers.
  • Wayland keeps the single call. There Electron serves both types from one PipeWire capturer, so splitting would open the portal twice.
  • Windows and macOS keep the single call.
  • nix-build.yml now counts an attempt that exits 0 with displays: [] as a failure. The verdict requires all 5 attempts, as the old comment asked once the cause was known.

Related issue

Refs #462

Testing

Reproduced under Xvfb in WSL with a minimal Electron app, using the flake's xvfb-run and its Electron 43.4.1 plus a stored Electron 41.0.2. Eight runs per cell:

request Electron 41 Electron 43
screen,window in one call 4/8 hang 3/8 lose the screen
screen then window 0/8 0/8
window then screen 0/8 0/8
screen alone (18 calls each) 0 0
  • Each failure came with exactly one Failed to initialize pixel buffer line, and runs without a failure had none.
  • After a hung combined call, a screen-only call in the same process still answered in about 12 ms.

The packaged app, A/B. I ran nix build .#openscreen in WSL with a local npmDepsHash patch, then openscreen sources 10 times under xvfb-run -a, the way the smoke step does:

build runs with a display
main 2/10 (the other 8 returned displays: [])
this branch 10/10

The record probe now finds the screen. It still fails after that, with Recording did not start within 30s. That is a separate capture problem under Xvfb, and the probe stays informational.

Unit tests and checks.

  • electron/ipc/desktopSourceTypes.test.ts checks the platform and Wayland gating, one type per call, that calls never overlap, the pass-through cases and error propagation.
  • tsc passes for the app and test configs. Biome is clean.

Not proven.

  • The mechanism below Electron. Two X11 capturers running at once in one process is a likely cause, but I did not trace it.
  • That the fix holds on a GitHub runner. That needs a nix-build.yml run.
  • Whether the combined call also fails on a real X11 desktop with a window manager.
  • The main-process callers that still combine both types (select-source, source restore) are unchanged. They use 0×0 thumbnails and are not on the CLI path.

Before CI can say anything, nix-build.yml on main must get past the build again. It currently fails on an npmDepsHash mismatch in nix/package.nix, which this PR does not touch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved screen and window source detection on Linux X11 by enumerating each source type separately, helping prevent source enumeration from hanging.
    • Updated source enumeration checks to require successful results across all expected attempts.

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 39548ac8-cb11-4ed1-9079-115ca93f8172
📥 Commits

Reviewing files that changed from the base of the PR and between 39c0210 and 9f6256c.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0ed06923-dbd0-4348-9655-e279d9335170
📥 Commits

Reviewing files that changed from the base of the PR and between db8a31c and 39c0210.

📒 Files selected for processing (5)
  • .github/workflows/nix-build.yml
  • electron/ipc/desktopSourceTypes.test.ts
  • electron/ipc/desktopSourceTypes.ts
  • electron/ipc/handlers.ts
  • src/cli/CliSourcesRunner.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

The IPC handler now enumerates source types separately on Linux unless the session indicates Wayland. The Nix smoke test now requires each of five enumeration attempts to return a display and requires export to succeed.

Changes

Desktop source enumeration

Layer / File(s) Summary
Platform decision and per-type enumeration
electron/ipc/desktopSourceTypes.ts, electron/ipc/desktopSourceTypes.test.ts
The helper selects separate enumeration on Linux outside Wayland. When enabled for multiple types, it calls getSources sequentially for each type and combines results in request order. Tests cover platform conditions, passthrough cases, ordering, and rejected calls.
IPC handler integration
electron/ipc/handlers.ts, src/cli/CliSourcesRunner.tsx
The get-sources handler uses the helper and retains its existing deadline. CLI comments describe the X11/Electron 41 case and distinguish the renderer and handler timeouts.
Enumeration smoke-test gate
.github/workflows/nix-build.yml
The smoke test treats an empty display result as a failed attempt. The final gate requires export and all five enumeration attempts to succeed.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant GetSourcesHandler
  participant getSourcesByType
  participant desktopCapturer
  GetSourcesHandler->>getSourcesByType: Pass options, getSources callback, and platform decision
  loop Each requested source type when separate enumeration is enabled
    getSourcesByType->>desktopCapturer: Call getSources with one source type
    desktopCapturer-->>getSourcesByType: Return sources for that type
  end
  getSourcesByType-->>GetSourcesHandler: Return combined sources
Loading

Suggested reviewers: my-denia

Merge Risk: ⚪ Minimal · up to 39c02

This change makes screen enumeration on Linux X11 more reliable and tightens the CI smoke test. No concrete merge-blocking issue was found. The author notes validation on a real X11 desktop and a GitHub runner is still pending.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 4 files. (1 skipped: 1… 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 clearly and concisely describes the main change: separate screen and window enumeration on Linux X11.
Description check ✅ Passed The description is detailed and on-topic. It includes the summary, related issue, reproduction data, testing results, limitations, and CI context. The template's Type of change, Release impact, Deskto…
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 4 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

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

Asking desktopCapturer.getSources for both types in one call intermittently fails the X11 screen capturer's thumbnail grab: Electron 41 never settles the call, Electron 43 settles after 3s without the screen. Measured under Xvfb: 7 failures in 16 combined runs, none in 32 runs with one type per call. Wayland keeps the single call, where splitting would raise the portal twice. Refs #462.
With enumeration split by type, the sources smoke test no longer has a known flake. Exit 0 with displays: [] now counts as a failure, and the verdict requires all attempts. Refs #462.
@EtienneLescot
EtienneLescot force-pushed the ci/462-source-enumeration-hang branch from 39c0210 to 9f6256c Compare October 8, 2026 11:15
@EtienneLescot
EtienneLescot merged commit 9bc6e1d into main Oct 8, 2026
23 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.

1 participant