diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-10-11 11:02:32 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-10-12 09:58:03 +0300 |
| commit | a038c5aaabd1cf4224268518f7c8840ae7b30078 (patch) | |
| tree | 1f7d599abe2489af8e66ad47f04004e1d6c72f5a | |
| parent | c9c985c9271345ba051332c1d6ef62c583dfb1cb (diff) | |
| download | niri-a038c5aaabd1cf4224268518f7c8840ae7b30078.tar.gz niri-a038c5aaabd1cf4224268518f7c8840ae7b30078.tar.bz2 niri-a038c5aaabd1cf4224268518f7c8840ae7b30078.zip | |
layout/workspace: Add add_tile_to_column()
| -rw-r--r-- | src/layout/workspace.rs | 139 |
1 files changed, 79 insertions, 60 deletions
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 034aaf0a..55d18a06 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -993,6 +993,54 @@ impl<W: LayoutElement> Workspace<W> { self.add_column(col_idx, column, activate, anim_config); } + pub fn add_tile_to_column( + &mut self, + col_idx: usize, + tile_idx: Option<usize>, + tile: Tile<W>, + activate: bool, + ) { + self.enter_output_for_window(tile.window()); + + let prev_next_x = self.column_x(col_idx + 1); + + let target_column = &mut self.columns[col_idx]; + let tile_idx = tile_idx.unwrap_or(target_column.tiles.len()); + let was_fullscreen = target_column.tiles[target_column.active_tile_idx].is_fullscreen(); + + target_column.add_tile_at(tile_idx, tile, true); + self.data[col_idx].update(target_column); + + // If the target column is the active column and its window was requested to, but hasn't + // gone into fullscreen yet, then clear the stored view offset, since we just asked it to + // stop going into fullscreen. + if col_idx == self.active_column_idx && !was_fullscreen { + self.view_offset_before_fullscreen = None; + } + + if activate { + target_column.active_tile_idx = tile_idx; + if self.active_column_idx != col_idx { + self.activate_column(col_idx); + } + } else if tile_idx <= target_column.active_tile_idx { + target_column.active_tile_idx += 1; + } + + // Adding a wider window into a column increases its width now (even if the window will + // shrink later). Move the columns to account for this. + let offset = self.column_x(col_idx + 1) - prev_next_x; + if self.active_column_idx <= col_idx { + for col in &mut self.columns[col_idx + 1..] { + col.animate_move_from(-offset); + } + } else { + for col in &mut self.columns[..=col_idx] { + col.animate_move_from(offset); + } + } + } + pub fn add_window_right_of( &mut self, right_of: &W::Id, @@ -1779,29 +1827,14 @@ impl<W: LayoutElement> Workspace<W> { Transaction::new(), Some(self.options.animations.window_movement.0), ); - self.enter_output_for_window(tile.window()); - - let next_col_idx = source_col_idx; - let prev_next_x = self.column_x(next_col_idx); + self.add_tile_to_column(target_column_idx, None, tile, true); let target_column = &mut self.columns[target_column_idx]; offset.x -= target_column.render_offset().x; - - target_column.add_tile(tile, true); - self.data[target_column_idx].update(target_column); - target_column.focus_last(); - offset += prev_off - target_column.tile_offset(target_column.tiles.len() - 1); let new_tile = target_column.tiles.last_mut().unwrap(); new_tile.animate_move_from(offset); - - // Consuming a window into a column could've increased its width if the new window had a - // larger min width. Move the next columns to account for this. - let offset_next = prev_next_x - self.column_x(next_col_idx); - for col in &mut self.columns[next_col_idx..] { - col.animate_move_from(offset_next); - } } else { // Move out of column. let width = source_column.width; @@ -1865,26 +1898,13 @@ impl<W: LayoutElement> Workspace<W> { Transaction::new(), Some(self.options.animations.window_movement.0), ); - self.enter_output_for_window(tile.window()); - - let prev_next_x = self.column_x(target_column_idx + 1); + self.add_tile_to_column(target_column_idx, None, tile, true); let target_column = &mut self.columns[target_column_idx]; - target_column.add_tile(tile, true); - self.data[target_column_idx].update(target_column); - target_column.focus_last(); - offset += prev_off - target_column.tile_offset(target_column.tiles.len() - 1); let new_tile = target_column.tiles.last_mut().unwrap(); new_tile.animate_move_from(offset); - - // Consuming a window into a column could've increased its width if the new window had a - // larger min width. Move the next columns to account for this. - let offset_next = prev_next_x - self.column_x(target_column_idx + 1); - for col in &mut self.columns[target_column_idx + 1..] { - col.animate_move_from(offset_next); - } } else { // Move out of column. let width = source_column.width; @@ -1921,42 +1941,24 @@ impl<W: LayoutElement> Workspace<W> { return; } + let target_column_idx = self.active_column_idx; let source_column_idx = self.active_column_idx + 1; let offset = self.column_x(source_column_idx) + self.columns[source_column_idx].render_offset().x - - self.column_x(self.active_column_idx); + - self.column_x(target_column_idx); let mut offset = Point::from((offset, 0.)); let prev_off = self.columns[source_column_idx].tile_offset(0); let tile = self.remove_tile_by_idx(source_column_idx, 0, Transaction::new(), None); - self.enter_output_for_window(tile.window()); - - let prev_next_x = self.column_x(self.active_column_idx + 1); - - let target_column = &mut self.columns[self.active_column_idx]; - let was_fullscreen = target_column.tiles[target_column.active_tile_idx].is_fullscreen(); - - target_column.add_tile(tile, true); - self.data[self.active_column_idx].update(target_column); + self.add_tile_to_column(target_column_idx, None, tile, false); + let target_column = &mut self.columns[target_column_idx]; offset += prev_off - target_column.tile_offset(target_column.tiles.len() - 1); - - if !was_fullscreen { - self.view_offset_before_fullscreen = None; - } - offset.x -= target_column.render_offset().x; let new_tile = target_column.tiles.last_mut().unwrap(); new_tile.animate_move_from(offset); - - // Consuming a window into a column could've increased its width if the new window had a - // larger min width. Move the next columns to account for this. - let offset_next = prev_next_x - self.column_x(self.active_column_idx + 1); - for col in &mut self.columns[self.active_column_idx + 1..] { - col.animate_move_from(offset_next); - } } pub fn expel_from_column(&mut self) { @@ -2912,7 +2914,7 @@ impl<W: LayoutElement> Column<W> { let is_pending_fullscreen = tile.window().is_pending_fullscreen(); - rv.add_tile(tile, animate_resize); + rv.add_tile_at(0, tile, animate_resize); if is_pending_fullscreen { rv.set_fullscreen(true); @@ -3056,11 +3058,27 @@ impl<W: LayoutElement> Column<W> { self.active_tile_idx = idx; } - fn add_tile(&mut self, tile: Tile<W>, animate: bool) { + fn add_tile_at(&mut self, idx: usize, tile: Tile<W>, animate: bool) { + // Inserting a tile pushes down all tiles below it, but also in always-centering mode it + // will affect the X position of all tiles in the column. + let mut prev_offsets = Vec::with_capacity(self.tiles.len() + 1); + prev_offsets.extend(self.tile_offsets().take(self.tiles.len())); + self.is_fullscreen = false; - self.data.push(TileData::new(&tile, WindowHeight::auto_1())); - self.tiles.push(tile); + self.data + .insert(idx, TileData::new(&tile, WindowHeight::auto_1())); + self.tiles.insert(idx, tile); self.update_tile_sizes(animate); + + // Animate tiles according to the offset changes. + prev_offsets.insert(idx, Point::default()); + for (i, ((tile, offset), prev)) in zip(self.tiles_mut(), prev_offsets).enumerate() { + if i == idx { + continue; + } + + tile.animate_move_from(prev - offset); + } } fn update_window(&mut self, window: &W::Id) { @@ -3081,6 +3099,11 @@ impl<W: LayoutElement> Column<W> { self.data[tile_idx].update(tile); // Move windows below in tandem with resizing. + // + // FIXME: in always-centering mode, window resizing will affect the offsets of all other + // windows in the column, so they should all be animated. How should this interact with + // animated vs. non-animated resizes? For example, an animated +20 resize followed by two + // non-animated -10 resizes. if tile.resize_animation().is_some() && offset != 0. { for tile in &mut self.tiles[tile_idx + 1..] { tile.animate_move_y_from_with_config( @@ -3341,10 +3364,6 @@ impl<W: LayoutElement> Column<W> { self.active_tile_idx = min(self.active_tile_idx + 1, self.tiles.len() - 1); } - fn focus_last(&mut self) { - self.active_tile_idx = self.tiles.len() - 1; - } - fn move_up(&mut self) { let new_idx = self.active_tile_idx.saturating_sub(1); if self.active_tile_idx == new_idx { |
