Repository navigation
[pull] master from rustdesk:master - #278
Merged
Merged
Conversation
…#16345) * fix(drm): turn a captured frame only when the plane did not rotate it A compositor rotates an output either in hardware, setting the primary plane's `rotation` property, or in software, drawing the scanout already turned. `wl_output` cannot tell the two apart, and `frame_transform` guessed: 90/270 turned, 180 left alone, which is right for i915 + mutter (rotate-180 in hardware, scanout upright) and wrong wherever the compositor drew the scanout turned, where 180 comes out upside down. Measured before changing it. virtio-gpu (no rotation property, mutter 46): the scanout dump at 180 is the desktop upside down, at 90 and 270 the logical desktop turned inside the native mode framebuffer. i915 + mutter (GNOME 50) at 180: the plane reports rotate-180 and the dump is upright, identical to the unrotated one. amdgpu + KWin 6 at 180: the plane stays at rotate-0 and the dump is upside down. The producer reads `drmtap_plane_rotation()` (libdrmtap 0.5.8, optional symbol) right after each grab and stamps it on the frame, in the dma-buf descriptor and in the CPU frame header, both `serde(default)` so an older producer still parses. A plane that rotated scans out the logical desktop whatever the output transform says: the compositor programs it from the CRTC transform, which also folds in the connector's panel orientation that `wl_output` never carries, so the consumer leaves such a frame alone. A plane at rotate-0 scanned out what the compositor drew, and the frame is turned by the whole output transform. `None` (a library before 0.5.8, or nothing it could read) keeps the previous rule, so nothing changes until the library says otherwise. The session is still sized from the output transform: a plane that rotated 90 in hardware hands over the portrait scanout those dims already name. * build: pin libdrmtap 0.5.8 (rustdesk-org/libdrmtap 95d4d7454) The rotation fix reads drmtap_plane_rotation(), added in libdrmtap 0.5.8. The mirror carries that commit since 2026-09-25, so the pin moves there. * drm: pin the decoding of a frame from a producer older than the plane rotation The root service and the --server are upgraded separately, so a frame header or a dma-buf descriptor without `plane_rotation` must still decode, as None, which keeps the previous rule. The tests built both messages with the field set to None; this one decodes payloads that omit it, and one that carries it (greptile on #16345). Serde already reads a missing Option as None, so what the test pins is the wire name and the None on absence, for both messages. Mutation: renaming the field on the wire, in either message, turns it red. * drm: take the plane rotation right after the grab, not after the copies `drmtap_plane_rotation()` reads the rotation property of the plane the last grab came from at the moment it is called. The cpu path asked only after `DrmReader::grab()` had copied the frame into its buffer and the producer had copied it again into the message, so on a large frame the compositor had time to change the plane and the frame went out with the rotation of the next one; `frame_transform` turns that frame by it with nothing to absorb the skew (zhou, review of 26-sep). `DrmReader` now reads the rotation right after a successful `drmtap_grab_mapped` or `drmtap_grab_desc`, before any copy or release, and `plane_rotation()` returns that snapshot, so both paths stamp a frame with the rotation its own grab saw. Test: a_frame_keeps_the_rotation_its_plane_had_when_it_was_grabbed, in `plane_rotation_tests` (which CI already runs), drives the reader through a fake library whose frame release turns the plane: the rotation read at the grab survives on the cpu grab and on the dma-buf export. Mutations: no snapshot on the cpu grab, none on the export, and the cpu snapshot taken after the release, each turn it red.
The uinput virtual mouse RustDesk creates on Linux reported bustype BUS_USB. libinput's evdev_tag_external_mouse() tags any BUS_USB or BUS_BLUETOOTH pointer device as an external mouse, so desktop environments' "disable touchpad when an external mouse is present" setting suspends the user's real touchpad whenever RustDesk creates this device, even though nothing is physically plugged in. Changed the constant to BUS_VIRTUAL (0x06, verified against the current upstream kernel's include/uapi/linux/input.h), which correctly identifies this as the software-only device it is. Fixes #16318. Signed-off-by: Mohsin Manzoor Bhat <mohsinmanzoor1913@gmail.com>
…ock across the await (#16362) * drm: apply the uinput range on one thread instead of holding a lock across the await #16122 serialized the three paths that apply a uinput range in a DRM session (the layout poll, `update_uinput_resolution` and `check_init`) with a tokio Mutex held over the awaited `update_mouse_resolution`, which AGENTS.md rules out ("Do not hold locks across `.await`"; greptile on #16122). The serialization itself has to stay: the uinput service keeps the range of whichever request reached it last and each apply sends it over its own connection, so two overlapping applies can leave the device on one range while the other one is recorded. The check, the apply and what it records now run as one job on a dedicated thread (`run_uinput_apply`), one job at a time in the order asked, with the runtime of that thread for the IPC and its 3 s timeout. The async paths await the answer and the display service loop blocks on it; nothing holds a lock while it waits. The poll publishes its drift flag inside its job, as it did under the lock. A thread that failed to start or died is started again for a later job, so one failure does not stop every later apply (the poll used to build a runtime per attempt and retry). The drm-off build keeps the code it had. Tests (in `input_map_tests`, which CI runs): uinput_applies_run_one_at_a_time_in_the_order_asked, a_uinput_apply_job_can_bound_its_ipc_with_a_timeout, a_uinput_apply_thread_that_died_is_started_again. Mutations: every job on its own thread, the apply runtime without timers, the answer never sent, a dead thread not started again; each turns a test red. The call sites run IPC and are covered by reading. * drm: log a layout poll whose uinput apply job got no answer The layout poll dropped the result of its job with let _ =, so a poll whose job was dropped (the apply thread failed to start or went away) left no trace, while update_uinput_resolution and check_init log it (greptile and CodeRabbit on #16362). It logs now. The drift flag keeps what the last poll that ran published; a later poll starts the thread again and publishes it. * drm: throttle the uinput apply thread failure logs The layout poll hands the apply thread a job every 1.5s, so a thread that cannot start logged two errors per poll for as long as a session lasted. Keep one line per site every 10 minutes, with the count of the rest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: rustdesk <71636191+rustdesk@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )