diff options
| author | srdusr <[email protected]> | 2025-09-28 20:46:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-09-28 20:46:00 +0200 |
| commit | 58a368df5f7a5d579335d1cb68213baacba5bc63 (patch) | |
| tree | 6d3e765b3307c94b17bbaabbc646f324fe11fef2 /crates/wayland/src/state/mod.rs | |
| parent | 9a9aa8fe9d4f4f9b15860b45244e695942c90afd (diff) | |
| download | srdwm-58a368df5f7a5d579335d1cb68213baacba5bc63.tar.gz srdwm-58a368df5f7a5d579335d1cb68213baacba5bc63.zip | |
Fix multi-selected desktop icons only ever dragging one at a time
Reported live: "try move desktop items all at once somewhere else"
didn't work. Two compounding bugs, both real: CompState::
desktop_icon_drag only ever tracked one icon id, and the click handler
that starts a drag unconditionally collapsed any existing multi-
selection down to just the grabbed icon before the drag even began.
desktop_icon_drag is now Option<DesktopIconDrag> (crates/wayland/src/
desktop_icons.rs, new type): a grab offset, the grabbed icon's own live
position, and a members list - every currently-selected icon (the
grabbed one included), each a fixed offset from the grabbed icon's own
top-left at drag start, so the group moves as one rigid unit.
input/pointer.rs's click handler now only resets to single-selection
when the grabbed icon isn't already part of the current selection --
grabbing one inside an existing multi-selection keeps the whole group
selected and dragging, matching Windows/GNOME/macOS/KDE convention.
end_desktop_icon_drag snaps every dragged icon to its own nearest free
grid cell independently, tracking newly-claimed cells across the group
so two icons landing near each other never claim the same one.
Full workspace build/test/clippy clean, built and installed. Not unit-
testable (this module has no CompState test fixture for its own
selection/drag logic, an already-documented, accepted gap) - needs a
live drag to confirm.
Diffstat (limited to 'crates/wayland/src/state/mod.rs')
| -rw-r--r-- | crates/wayland/src/state/mod.rs | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs index 3519297..629b58c 100644 --- a/crates/wayland/src/state/mod.rs +++ b/crates/wayland/src/state/mod.rs @@ -353,17 +353,11 @@ pub(crate) struct CompState { /// same cached-until-dirty convention as every other decoration /// buffer in this codebase. pub(crate) desktop_icon_buffers: HashMap<String, MemoryRenderBuffer>, - /// An in-progress icon drag: the icon's own id, the pointer's grab - /// offset from that icon's cell origin at the moment the drag started - /// (so the icon tracks the pointer smoothly rather than snapping its - /// top-left corner straight to the cursor), and the icon's own live - /// top-left position this frame - updated on every pointer-motion - /// event by `update_desktop_icon_drag`, read straight back by - /// `desktop_icon_render_list` with no separate "current pointer - /// position" field needed anywhere on `CompState`. `None` whenever no - /// drag is active. - #[allow(clippy::type_complexity)] - pub(crate) desktop_icon_drag: Option<(String, (i32, i32), (i32, i32))>, + /// An in-progress icon drag - see `desktop_icons::DesktopIconDrag`'s + /// own doc comment for the full shape (it may carry more than one + /// icon, when the drag started on an already-multi-selected icon). + /// `None` whenever no drag is active. + pub(crate) desktop_icon_drag: Option<crate::desktop_icons::DesktopIconDrag>, /// An active rubber-band/marquee selection drag on bare desktop -- /// `(start, current)`, both global-space pointer positions. The one /// "click and drag" desktop interaction this compositor never had at |