Skip to content

Wayland: cursor is never tracked; SPA_META_Cursor size is declared as an exact int #32

Description

@jiisanda

Environment

  • Ubuntu 26.04 LTS, GNOME Shell 50.1, Wayland
  • xdg-desktop-portal-gnome 50.0, ScreenCast portal v5 (AvailableCursorModes = 7)
  • Tauri 2.11.5, tao 0.35.3
  • Intel Iris Xe (TigerLake-LP) + NVIDIA RTX 3050 Mobile

Symptom

On Wayland, no recording ever gets a cursor track:

  • cursor.json contains "samples": []
  • The editor's Cursor panel shows "No cursor track for this recording. Record with cursor capture enabled."
  • Every pointer style / size / motion-blur / click-bounce control is inert
  • Follow-cursor zoom holds centre instead of following

The portal reports that Metadata cursor mode was negotiated successfully, so nothing in the logs indicates a failure.

Root cause

build_cursor_meta_pod() in src-tauri/src/recorder/backend/portal_backend.rs declares
SPA_PARAM_META_size as an exact integer:

let meta_size = (size_of::<spa_meta_cursor>()
    + size_of::<spa_meta_bitmap>()
    + 64 * 64 * 4) as i32;          // 16432

SPA negotiates meta sizes by intersection. That size embeds a cursor bitmap
dimension
which each side chooses independently, we hardcode 64×64, the
compositor picks its own maximum cursor size. Two different exact values
intersect to nothing, so the meta is dropped from the buffer while the session
itself still reports Metadata mode as negotiated.

Evidence

Logging the metas actually attached to each buffer:

INFO  portal cursor mode cursor_mode=Metadata cursor_via_metadata=true
INFO  portal stream selected source_type=Some(Monitor) size=Some((1920, 1080))
WARN  buffer metas present (type, size) present=[(7, 8), (1, 32)] want_type=5 want_size=28
INFO  portal negotiated Metadata but buffers carry no SPA_META_Cursor

SPA_META_Header (type 1) negotiates fine because its size is
sizeof(spa_meta_header), a struct size, identical on both sides, so it always
agrees. SPA_META_Cursor (type 5) is absent. That asymmetry isolates the cause
to how the size is expressed, not to whether the request reaches the compositor.

Fix

Declare the size as a range, which is what OBS does for this same meta SPA_META_Header should stay an exact int, its size genuinely is fixed.

Verification

INFO  portal cursor metadata flowing

cursor.json for a 10.9 s take: 482 samples, t spanning 0.18 to 10.86 s,
normalised x/y. The full cursor style panel and follow-cursor zoom become live.

Scope

Confined to portal_backend.rs, already behind the portal-capture feature.
No effect on macOS or Windows.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions