A fix for the issue reported in
https://github.com/pop-os/cosmic-comp/pull/2450.
Using `block_on` in some places for zbus calls is fine (that's what
zbus's blocking API does; it has its own executor for background tasks),
but this is problematic with `async_once_cell`. If we also use that in
the calloop async executor.
I think ideally we should avoid blocking the main thread on any async
tasks, but for now we can just block in initialization here.
Using `with_surface_tree_downward()` is wrong because it will traverse
other branches of the surface tree than the one containing `surface`,
and add their offsets.
It's simple enough to instead walk up the surface tree.
Deduplicate this before making it more complicated.
Also allows early returns to avoid deep nesting. And avoid duplicating
calculations here for multiple sessions (though normally there won't be
multiple capture sessions of same toplevel with cursor metadata,
probably).
We should avoid creating more than one session connection or more than
one system connection. We should also ideally avoid blocking the main
thread.
For now this still uses blocking in a couple places, but wrapping async
code (which is how `zbus::blocking` is implemented anyway).
This moves the `NameOwners` creation out of `A11yKeyboardMonitorState`,
so it can be shared with other things. We will likely want that for
https://github.com/pop-os/cosmic-comp/pull/465 to define a secured
protocol to pass an fd to the portal, and potentially any other
sensitive DBus protocols implemented by the compositor.
new_constraint: check if the surface has pointer focus, keyboard focus, and if the pointer is within toplevel geometry or constraint region. If these conditions are met, then enable the constraint.
remove_constraint: apply last cursor position hint that saved in seat.
cursor_position_hint: save the cursor position hints provided by the client to the seat.
Adds a cursor_hide_timeout config key (Option<u32> seconds) to
CosmicCompConfig. When set, the cursor is hidden after the configured
period of pointer inactivity and revealed again by any pointer event.
Touch input does not count as activity (no visible cursor to surface).
Implementation:
- Per-seat hidden flag, calloop timer token, and last-armed Instant on
CursorStateInner.
- notify_cursor_activity called from each pointer-related input branch
(motion, button, axis, tablet) resets the flag and reschedules the
timer; rapid successive calls are coalesced behind a 100ms throttle
so high-frequency mice don't churn the calloop timer source.
- On timer fire, the hidden flag is set, draw_cursor short-circuits to
an empty element list, and a render is scheduled. Active pointer
grabs (drags, resizes) suppress the hide.
- Config reload arms or cancels the timer immediately; None as the
configured value collapses the cancel path into the same function.
Closes#2231.
Drafted with Claude (Anthropic); reviewed and tested by the committer.