Skip to content

drm: address codex review (per-crtc probe, hidden cursor, --package deb)#7

Open
fxd0h wants to merge 4 commits into
feature/drm-capture-cleanfrom
feature/drm-codex-fixes
Open

drm: address codex review (per-crtc probe, hidden cursor, --package deb)#7
fxd0h wants to merge 4 commits into
feature/drm-capture-cleanfrom
feature/drm-codex-fixes

Conversation

@fxd0h

@fxd0h fxd0h commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Codex flagged 3 P2s on the drm feature (multi-monitor probe, cursor visibility, and the --package deb path). This addresses all three. Opening here first so coderabbit takes a pass before it goes to rustdesk#15420.

  • the probe was gating the whole session on crtc 0: a per-crtc grab failure there (unsupported format, or a crtc asleep) sank every display to PipeWire even when other crtcs work. now a non-setup, non-transient probe failure returns a new ProbeResult::Available so Display::all() enumerates and drops just the bad connector; only setup errnos (EACCES/EPERM/ENOENT) still disable DRM globally.
  • update_cursor skipped its block when the plane reported the cursor hidden (visible == 0), leaving the last shape stuck on the client. it now publishes a distinct empty cursor (HIDDEN_CURSOR_ID) so the get_cursor() id changes and the client hides the pointer.
  • build_deb_from_folder (the --package path) shipped the helper but never set the drm package name nor the setcap/group postinst. extracted append_drm_helper_postinst() and used it in both deb paths.

verified on a real 3-monitor DRM host: injecting ENOTSUP at the probe keeps all 3 displays on DRM, injecting EACCES falls back; forcing visible==0 flips the cursor id to the hidden sentinel. added a unit test for the errno classification and the bad-crtc set.

fxd0h added 2 commits July 9, 2026 12:24
adds an opt-in `drm` feature that captures below the compositor through the
privileged libdrmtap helper, for unattended remote access on Wayland: no
xdg-desktop-portal consent dialog, and it works at the login screen.

off by default. when the feature is off the build is unchanged. everything
is gated behind feature = "drm" or lives only in the separate
rustdesk-unattended-wayland deb, whose package name is the informed consent.

- scrap: DRM/KMS capture backend on libdrmtap-sys, homogeneous per-session
  backend selection, availability decided by a real grab probe with per-crtc
  fallback to pipewire/portal
- helper: shipped only in the drm deb, installed 0750 root:rustdesk-capture
  with cap_sys_admin via setcap (postinst appended by build.py)
- ci: builds a separate rustdesk-unattended-wayland deb on x86_64
- cursor: downscale the hardware cursor to the served display logical scale
- DRM_CAPTURE_SECURITY.md: threat model and hardening notes
- capture_available(): a per-crtc grab failure on the probed crtc 0 (unsupported
  format, or ENODEV asleep) no longer sinks the whole session to PipeWire; the
  helper is known to run, so return available and let Display::all() enumerate
  and drop just the bad connector (new ProbeResult::Available)
- update_cursor(): publish a distinct empty cursor when the plane reports the
  cursor hidden (visible == 0), so get_cursor()'s id changes and the client hides
  the pointer instead of keeping the last shape
- build.py build_deb_from_folder(): a --package bundle carrying the helper now
  gets the rustdesk-unattended-wayland name and the same group/setcap postinst as
  build_flutter_deb (extracted into append_drm_helper_postinst)
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved DRM capture availability detection when individual displays or connectors cannot be accessed.
    • Fixed cursor updates so hidden cursors no longer remain visible during DRM capture.
    • Improved handling of DRM-enabled Debian packages, including required permissions and capability setup.
    • DRM helper packages now receive the appropriate package naming and installation configuration.

Walkthrough

DRM Debian packaging now shares post-install setup for the capture helper. Staged bundles select dedicated package metadata. DRM dependencies use pinned Git revisions, probing distinguishes helper failures from per-CRTC failures, hidden cursors emit a sentinel shape, and probe tests cover errno and topology state handling.

Changes

DRM support

Layer / File(s) Summary
DRM helper postinst setup
build.py
Extracts helper group, ownership, permission, and capability setup into a reusable function and applies it to Flutter and staged Debian builds.
Staged DRM package integration
build.py
Staged bundles use the unattended Wayland package name when the helper is present, add libcap2-bin, copy Debian metadata, apply shared post-install setup, and rename the output package.
DRM dependency and availability probing
Cargo.toml, libs/scrap/Cargo.toml, libs/scrap/src/common/drm.rs
Pins libdrmtap-sys to a Git revision, classifies per-CRTC grab failures as available DRM, caches that result, and tests setup-errno and topology-based bad-CRTC handling.
Hidden DRM cursor signaling
libs/scrap/src/common/drm.rs
Publishes a distinct sentinel cursor when the DRM cursor plane reports that the cursor is hidden.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BuildScript
  participant DebianPackage
  participant DrmTapHelper
  BuildScript->>DebianPackage: select package name and libcap2-bin dependency
  BuildScript->>DebianPackage: append configure postinst
  DebianPackage->>DrmTapHelper: configure group, permissions, and setcap
Loading

Poem

I’m a rabbit with a DRM hat,
Hopping through postinsts neat and flat.
Hidden cursors fade from view,
Probes learn which CRTCs are true.
Packages bloom with caps anew!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly references the DRM probe, hidden cursor, and Debian package changes made in the PR.
Description check ✅ Passed The description matches the three DRM fixes and Debian build-path updates described in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
  • Commit unit tests in branch feature/drm-codex-fixes

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

@fxd0h

fxd0h commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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 `@build.py`:
- Around line 459-467: Update the final .deb rename in the staged DRM build path
to use the local package_name, matching build_flutter_deb(), so
rustdesk-unattended-wayland bundles are emitted with the correct
package-specific filename while stock bundles retain the rustdesk name.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d5b4879e-fb0b-44c2-b467-3a1a9a2b2ba6

📥 Commits

Reviewing files that changed from the base of the PR and between e54377c and f6205c7.

📒 Files selected for processing (2)
  • build.py
  • libs/scrap/src/common/drm.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (11)
  • GitHub Check: CodeRabbit / Review
  • GitHub Check: run-ci / build rustdesk linux x86_64-unknown-linux-gnu
  • GitHub Check: run-ci / build rustdesk android apk armv7-linux-androideabi
  • GitHub Check: run-ci / build rustdesk android apk aarch64-linux-android
  • GitHub Check: run-ci / x86_64-pc-windows-msvc
  • GitHub Check: run-ci / x86_64-apple-darwin
  • GitHub Check: run-ci / aarch64-apple-darwin
  • GitHub Check: run-ci / build rustdesk android apk x86_64-linux-android
  • GitHub Check: run-ci / aarch64-pc-windows-msvc
  • GitHub Check: run-ci / i686-pc-windows-msvc (windows-2022)
  • GitHub Check: x86_64-unknown-linux-gnu (ubuntu-24.04)
🔇 Additional comments (7)
build.py (1)

334-354: 🩺 Stability & Availability

No issue here. res/DEBIAN/postinst already has a shebang, is executable, and does not exit 0 before the appended DRM setup, so the helper postinst block will still run as intended.

libs/scrap/src/common/drm.rs (6)

49-55: LGTM!


90-96: LGTM!


125-135: LGTM!


258-266: LGTM!


676-692: LGTM!


765-808: LGTM!

Comment thread build.py
build_deb_from_folder set the control Package to rustdesk-unattended-wayland
for a staged drm bundle but still renamed the output to rustdesk-<version>.deb,
a filename/metadata mismatch that could also collide with a stock bundle. Match
build_flutter_deb and rename by package_name.
@fxd0h

fxd0h commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Point the drm feature's libdrmtap-sys at the rustdesk-org/libdrmtap fork
(pinned by rev to the 0.4.5 / HDR-guard commit df530502) instead of the
crates.io crate, so the privileged drmtap-helper is compiled from source
RustDesk owns and reviews, in RustDesk CI. Same code as the =0.4.5 pin.
@fxd0h

fxd0h commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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 `@Cargo.toml`:
- Around line 181-184: Centralize the duplicated libdrmtap-sys git revision by
defining it once under the workspace dependencies in Cargo.toml, then update the
libs/scrap dependency declaration to reference the workspace entry instead of
repeating the git URL and rev; preserve its optional behavior and ensure no
duplicate pin remains.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f5538b8-2e1e-41a5-a99f-14e08712517f

📥 Commits

Reviewing files that changed from the base of the PR and between 529b6c0 and 40a3c33.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • Cargo.toml
  • libs/scrap/Cargo.toml
📜 Review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: CodeRabbit / Review
  • GitHub Check: run-ci / generate-bridge / generate_bridge (x86_64-unknown-linux-gnu, ubuntu-22.04, 3.22.3, bridge-artifact)
  • GitHub Check: run-ci / generate-bridge / generate_bridge (x86_64-unknown-linux-gnu, ubuntu-22.04, 3.44.0, bridge-artifact-flutter-3.44)
  • GitHub Check: run-ci / i686-pc-windows-msvc (windows-2022)
  • GitHub Check: x86_64-unknown-linux-gnu (ubuntu-24.04)
🔇 Additional comments (2)
libs/scrap/Cargo.toml (1)

58-60: The rev here (df530502...) matches the root Cargo.toml, so Cargo will unify to a single source. The drift/centralization concern is already raised on the root manifest.

Cargo.toml (1)

184-184: 🗄️ Data Integrity & Integration

No issue: the pinned commit exists and the crate is present in the repository.

			> Likely an incorrect or invalid review comment.

Comment thread Cargo.toml
@fxd0h fxd0h force-pushed the feature/drm-capture-clean branch from e54377c to a3399ca Compare July 10, 2026 05:45
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