srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/input
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-09-28 20:46:00 +0200
committersrdusr <[email protected]>2025-09-28 20:46:00 +0200
commit58a368df5f7a5d579335d1cb68213baacba5bc63 (patch)
tree6d3e765b3307c94b17bbaabbc646f324fe11fef2 /crates/wayland/src/input
parent9a9aa8fe9d4f4f9b15860b45244e695942c90afd (diff)
downloadsrdwm-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/input')
-rw-r--r--crates/wayland/src/input/pointer.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/crates/wayland/src/input/pointer.rs b/crates/wayland/src/input/pointer.rs
index 602f613..44b0bd7 100644
--- a/crates/wayland/src/input/pointer.rs
+++ b/crates/wayland/src/input/pointer.rs
@@ -663,7 +663,20 @@ pub(crate) fn handle_pointer_button(state: &mut CompState, pos: Point<f64, Logic
state.select_desktop_icon(Some(&id));
state.open_desktop_icon(&id);
} else {
- state.select_desktop_icon(Some(&id));
+ // Don't collapse an existing multi-selection
+ // just because the drag grabbed one of its own
+ // members - `start_desktop_icon_drag` itself
+ // carries every currently-selected icon along
+ // when the one grabbed is already selected
+ // (see its own doc comment), the same "drag one
+ // of several selected files, they all move"
+ // convention every real desktop uses. Grabbing
+ // an icon *outside* the current selection still
+ // replaces it, same as before.
+ let already_selected = state.desktop_icons.as_ref().is_some_and(|icons| icons.icons.iter().any(|i| i.id == id && i.selected));
+ if !already_selected {
+ state.select_desktop_icon(Some(&id));
+ }
state.start_desktop_icon_drag(&id, origin, (pos.x as i32, pos.y as i32));
}
}