diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index a1619994..d9a0dc2e 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -986,6 +986,10 @@ impl ScrollingSpace { self.data.insert(idx, ColumnData::new(&column)); self.columns.insert(idx, column); + if !was_empty && idx <= self.active_column_idx { + self.active_column_idx += 1; + } + if activate { // If this is the first window on an empty workspace, remove the effect of whatever // view_offset was left over and skip the animation. @@ -1002,8 +1006,6 @@ impl ScrollingSpace { anim_config.unwrap_or(self.options.animations.horizontal_view_movement.0); self.activate_column_with_anim_config(idx, anim_config); self.activate_prev_column_on_removal = prev_offset; - } else if !was_empty && idx <= self.active_column_idx { - self.active_column_idx += 1; } // Animate movement of other columns. diff --git a/src/layout/tests.rs b/src/layout/tests.rs index 96491800..e0be1730 100644 --- a/src/layout/tests.rs +++ b/src/layout/tests.rs @@ -3674,6 +3674,34 @@ fn tabs_with_different_border() { check_ops_with_options(options, ops); } +#[test] +fn expel_pending_left_from_fullscreen_tabbed_column() { + let ops = [ + Op::AddOutput(1), + Op::AddWindow { + params: TestWindowParams::new(1), + }, + Op::FullscreenWindow(1), + Op::Communicate(1), + // 1 is now fullscreen, view_offset_to_restore is set. + Op::ToggleColumnTabbedDisplay, + Op::AddWindow { + params: TestWindowParams::new(2), + }, + Op::ConsumeOrExpelWindowLeft { id: Some(2) }, + // 2 is consumed into a fullscreen column, fullscreen is requested but not applied. + // + // Now, get it back out while keeping it focused. + // + // Importantly, we expel it *left*, which results in adding a new column with the exact + // same active_column_idx. + Op::FocusWindow(2), + Op::ConsumeOrExpelWindowLeft { id: None }, + ]; + + check_ops(ops); +} + fn parent_id_causes_loop(layout: &Layout, id: usize, mut parent_id: usize) -> bool { if parent_id == id { return true;