srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/desktop_icons.rs
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/desktop_icons.rs
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/desktop_icons.rs')
-rw-r--r--crates/wayland/src/desktop_icons.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/crates/wayland/src/desktop_icons.rs b/crates/wayland/src/desktop_icons.rs
index 7cfcbd1..c3b573a 100644
--- a/crates/wayland/src/desktop_icons.rs
+++ b/crates/wayland/src/desktop_icons.rs
@@ -57,6 +57,30 @@ impl DesktopIcon {
}
}
+/// An in-progress icon drag that may carry more than one icon along
+/// together. `primary` is whichever icon the pointer actually grabbed;
+/// `members` is every icon moving with it (always includes `primary`, at
+/// offset `(0, 0)`), each recorded as a fixed offset from `primary`'s own
+/// top-left at the moment the drag started - the whole group moves as
+/// one rigid unit regardless of where each member's own cell happens to
+/// be, the same way dragging one file in a multi-selection in Windows/
+/// GNOME/macOS/KDE carries every other selected file along with it.
+/// Reported live as missing: "try move desktop items all at once
+/// somewhere else" didn't work at all before this - `members` used to
+/// not exist, a drag only ever carried the one icon it grabbed no matter
+/// how many were selected.
+pub(crate) struct DesktopIconDrag {
+ /// Pointer's grab offset from `primary`'s own top-left at drag start,
+ /// so the icon tracks the pointer smoothly rather than snapping its
+ /// top-left corner straight to the cursor.
+ pub(crate) grab_offset: (i32, i32),
+ /// `primary`'s own live top-left this frame.
+ pub(crate) primary_pos: (i32, i32),
+ /// `(icon id, fixed offset from primary's own top-left at drag
+ /// start)` - primary included at offset `(0, 0)`.
+ pub(crate) members: Vec<(String, (i32, i32))>,
+}
+
pub(crate) struct DesktopIcons {
/// Top-left of the grid's own `(0, 0)` cell, in global space, one per
/// participating monitor - each monitor's own usable-area origin plus