From 48e30d9585f4a42e63adfc886fe7df6ea365981d Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Wed, 28 Oct 2026 23:43:16 -0700 Subject: [PATCH] fix(scrolling): resizing a column by its left edge moves that edge A column was made wider, or narrower, from its left edge whichever edge was resized: dragging the left edge of the last window of a strip to the left made it wider to the right, which is where its right edge went, and its left edge stayed where it was. In the recording of the drag, it was the same window, 1651 wide before and 1982 wide after, still at the same left edge, to the right of where the user had put it. The strip is panned by what the column was made wider by, so that the left edge is where it was moved to and the right edge stays, and the columns to the left of the column follow it. The right edge is the one that moves for any other direction, as it was. --- komorebi-layouts/src/scrolling.rs | 82 ++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/komorebi-layouts/src/scrolling.rs b/komorebi-layouts/src/scrolling.rs index 192aa101..45fb1ae0 100644 --- a/komorebi-layouts/src/scrolling.rs +++ b/komorebi-layouts/src/scrolling.rs @@ -213,8 +213,17 @@ pub fn resize( return; }; - let width = ((width + change).round() as i32).max(MINIMUM_COLUMN_WIDTH); - space.set_width(id, ColumnWidth::Fixed(width)); + let resized = ((width + change).round() as i32).max(MINIMUM_COLUMN_WIDTH); + space.set_width(id, ColumnWidth::Fixed(resized)); + + // a column grows to the right, from its left edge, unless it is its left edge that is + // moved: that one is to be where it is moved to, and its right edge where it was + if matches!(direction, OperationDirection::Left) + && space.active_id() == Some(id) + && let Some(width_now) = space.column_width(id) + { + space.pan_by(width - width_now); + } } /// How many containers that were taken out of a workspace are waited for at another one. @@ -406,4 +415,73 @@ mod tests { Some(f64::from(MINIMUM_COLUMN_WIDTH)) ); } + + #[test] + fn the_left_edge_of_a_column_that_is_resized_by_it_moves_and_the_right_edge_stays() { + let work_area = Rect { + left: 0, + top: 0, + right: 1200, + bottom: 800, + }; + let ids = vec!["a".to_string(), "b".to_string()]; + let mut space = None; + + sync( + &mut space, + scrolling_options(options(3, None)), + viewport_of(&work_area), + &ids, + ids.get(1), + ); + + let space = space.as_mut().unwrap(); + let edges = |space: &ScrollingSpace| { + place(space, &work_area, 0) + .iter() + .map(|placement| { + ( + placement.rect.left, + placement.rect.left + placement.rect.right, + ) + }) + .collect::>() + }; + + let before = edges(space); + + // by half of the delta, which is 100 here, out + resize( + space, + &ids[1], + OperationDirection::Left, + Sizing::Increase, + 200, + ); + let grown = edges(space); + assert_eq!(grown[1].0, before[1].0 - 100); + assert_eq!(grown[1].1, before[1].1); + + // and in, which gives it back + resize( + space, + &ids[1], + OperationDirection::Left, + Sizing::Decrease, + 200, + ); + assert_eq!(edges(space), before); + + // the right edge of the last column is the one that grows when it is the right edge + resize( + space, + &ids[1], + OperationDirection::Right, + Sizing::Increase, + 200, + ); + let grown = edges(space); + assert_eq!(grown[1].0, before[1].0); + assert_eq!(grown[1].1, before[1].1 + 100); + } }