mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-10-15 08:20:28 +00:00
A cursor id was the platform's handle for the shape: HCURSOR on Windows, the XFixes serial on X11. Apps mint a new handle for a shape they have shown before (Chrome, Electron, Qt custom cursors), and an X11 animated cursor gets one per frame, so one arrow arrived under thousands of ids over a session. The controlled side cached and sent it again under each, and the controller decoded, rendered and kept it again under each, and grew by gigabytes over weeks of connection. The controlled side now names a shape by an xxh3 hash of its size, hotspot and pixels, taken once when a handle is first seen, before the pixels are compressed. The per-connection send already sends a shape once and afterwards only its id, so a shape now crosses once however many handles it has. The id is opaque in the protocol, so controllers of any version accept it. The DRM backend already named shapes by content with FNV-1a; it uses the same hash now. A peer before 1.5.0 still names shapes by handle, and the fix has to work against every deployed peer. For those peers the controller hashes each CursorData's compressed colors with its geometry: one peer compresses the same pixels to the same bytes, so a shape seen before is recognised without being decompressed. The UI gets that shape once, under one id, and every later handle for it is passed on as a cursor_id of that id. The map from the peer's ids is kept for the connection, unbounded, since the peer sends a shape once and may select any id it named again; an entry is two integers. From 1.5.0 the controller passes the peer's ids through unchanged, on the old path. The web core in flutter/web does the same in its own tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
81 lines
3.0 KiB
TOML
81 lines
3.0 KiB
TOML
[package]
|
|
name = "scrap"
|
|
description = "Screen capture made easy."
|
|
version = "0.5.0"
|
|
repository = "https://github.com/quadrupleslap/scrap"
|
|
documentation = "https://docs.rs/scrap"
|
|
keywords = ["screen", "capture", "record"]
|
|
license = "MIT"
|
|
authors = ["Ram <quadrupleslap@gmail.com>"]
|
|
edition = "2018"
|
|
|
|
[features]
|
|
wayland = ["gstreamer", "gstreamer-app", "gstreamer-video", "dbus", "tracing", "zbus"]
|
|
# `drm` is a pure runtime-dlopen backend: rustdesk loads `libdrmtap.so.0` at runtime (`drmtap_dl.rs`)
|
|
# and NEVER link-time links it, so the graceful PipeWire fallback when the .so or EGL is absent is
|
|
# preserved and the drm build pulls in no libdrm/seccomp/cap/EGL link-time deps. The .so is pinned by
|
|
# `DRMTAP_SHA` in build.py, which fetches that exact commit (libdrmtap v0.5.6). We deliberately do
|
|
# NOT depend on the `libdrmtap-sys` crate: its build.rs statically compiles the whole libdrmtap C tree
|
|
# and a CAP_SYS_ADMIN helper and emits `-ldrm -lseccomp -lcap`, which would defeat the dlopen model.
|
|
# Depends on `wayland`: the three drm modules live inside the `#[cfg(feature = "wayland")]` arm of
|
|
# common/mod.rs, so `scrap/drm` on its own would compile nothing. The root crate happens to always
|
|
# enable `scrap/wayland`, which is what hid this.
|
|
drm = ["wayland", "base/wayland_probe", "dep:xxhash-rust"]
|
|
mediacodec = ["ndk"]
|
|
linux-pkg-config = ["dep:pkg-config"]
|
|
hwcodec = ["dep:hwcodec"]
|
|
vram = ["hwcodec/vram"]
|
|
|
|
[dependencies]
|
|
cfg-if = "1.0"
|
|
num_cpus = "1.15"
|
|
lazy_static = "1.4"
|
|
hbb_common = { path = "../hbb_common" }
|
|
base = { path = "../base" }
|
|
webm = { git = "https://github.com/rustdesk-org/rust-webm" }
|
|
serde = {version="1.0", features=["derive"]}
|
|
|
|
[dependencies.winapi]
|
|
version = "0.3"
|
|
default-features = true
|
|
features = ["dxgi", "dxgi1_2", "dxgi1_5", "dxgi1_6", "d3d11", "winuser", "winerror", "errhandlingapi", "libloaderapi"]
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
block = "0.1"
|
|
|
|
[target.'cfg(target_os = "android")'.dependencies]
|
|
android_logger = "0.13"
|
|
jni = "0.21"
|
|
lazy_static = "1.4"
|
|
log = "0.4"
|
|
serde_json = "1.0"
|
|
ndk = { version = "0.7", features = ["media"], optional = true}
|
|
ndk-context = "0.1"
|
|
|
|
[target.'cfg(not(target_os = "android"))'.dev-dependencies]
|
|
repng = "0.2"
|
|
docopt = "1.1"
|
|
quest = "0.3"
|
|
|
|
[build-dependencies]
|
|
target_build_utils = "0.3"
|
|
bindgen = "0.72.1"
|
|
pkg-config = { version = "0.3.27", optional = true }
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
dbus = { version = "0.9", optional = true }
|
|
tracing = { version = "0.1", optional = true }
|
|
gstreamer = { version = "0.16", optional = true }
|
|
gstreamer-app = { version = "0.16", features = ["v1_10"], optional = true }
|
|
gstreamer-video = { version = "0.16", optional = true }
|
|
zbus = { version = "3.15", optional = true }
|
|
xxhash-rust = { version = "0.8", features = ["xxh3"], optional = true }
|
|
|
|
[dependencies.hwcodec]
|
|
git = "https://github.com/rustdesk-org/hwcodec"
|
|
optional = true
|
|
|
|
[target.'cfg(any(target_os = "windows", target_os = "linux"))'.dependencies]
|
|
nokhwa = { git = "https://github.com/rustdesk-org/nokhwa.git", branch = "fix_from_raw_parts", features = ["input-native"] }
|
|
|