Skip to content

Commit

Permalink
layout: Return Tile + info upon removal
Browse files Browse the repository at this point in the history
  • Loading branch information
YaLTeR committed Oct 14, 2024
1 parent 06ec9ee commit be7fbd4
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 82 deletions.
36 changes: 23 additions & 13 deletions src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
use smithay::output::{self, Output};
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::{Logical, Point, Scale, Serial, Size, Transform};
use tile::Tile;
use workspace::WorkspaceId;

pub use self::monitor::MonitorRenderElement;
Expand Down Expand Up @@ -281,6 +282,15 @@ impl Default for Options {
}
}

/// Tile that was just removed from the layout.
pub struct RemovedTile<W: LayoutElement> {
tile: Tile<W>,
/// Width of the column the tile was in.
width: ColumnWidth,
/// Whether the column the tile was in was full-width.
is_full_width: bool,
}

impl Options {
fn from_config(config: &Config) -> Self {
let layout = &config.layout;
Expand Down Expand Up @@ -743,13 +753,17 @@ impl<W: LayoutElement> Layout<W> {
);
}

pub fn remove_window(&mut self, window: &W::Id, transaction: Transaction) -> Option<W> {
pub fn remove_window(
&mut self,
window: &W::Id,
transaction: Transaction,
) -> Option<RemovedTile<W>> {
match &mut self.monitor_set {
MonitorSet::Normal { monitors, .. } => {
for mon in monitors {
for (idx, ws) in mon.workspaces.iter_mut().enumerate() {
if ws.has_window(window) {
let win = ws.remove_window(window, transaction);
let removed = ws.remove_tile(window, transaction);

// Clean up empty workspaces that are not active and not last.
if !ws.has_windows()
Expand All @@ -765,22 +779,22 @@ impl<W: LayoutElement> Layout<W> {
}
}

return Some(win);
return Some(removed);
}
}
}
}
MonitorSet::NoOutputs { workspaces, .. } => {
for (idx, ws) in workspaces.iter_mut().enumerate() {
if ws.has_window(window) {
let win = ws.remove_window(window, transaction);
let removed = ws.remove_tile(window, transaction);

// Clean up empty workspaces.
if !ws.has_windows() && ws.name.is_none() {
workspaces.remove(idx);
}

return Some(win);
return Some(removed);
}
}
}
Expand Down Expand Up @@ -2111,24 +2125,20 @@ impl<W: LayoutElement> Layout<W> {
let mon = &mut monitors[mon_idx];
let ws = &mut mon.workspaces[ws_idx];
let column = &ws.columns[col_idx];
let width = column.width;
let is_full_width = column.is_full_width;
let activate = mon_idx == *active_monitor_idx
&& ws_idx == mon.active_workspace_idx
&& col_idx == ws.active_column_idx
&& tile_idx == column.active_tile_idx;

let window = ws
.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None)
.into_window();
let removed = ws.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None);

self.add_window_by_idx(
new_idx,
workspace_idx,
window,
removed.tile.into_window(),
activate,
width,
is_full_width,
removed.width,
removed.is_full_width,
);

let MonitorSet::Normal { monitors, .. } = &mut self.monitor_set else {
Expand Down
62 changes: 34 additions & 28 deletions src/layout/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,18 +458,20 @@ impl<W: LayoutElement> Monitor<W> {
}

let column = &workspace.columns[workspace.active_column_idx];
let width = column.width;
let is_full_width = column.is_full_width;
let window = workspace
.remove_tile_by_idx(
workspace.active_column_idx,
column.active_tile_idx,
Transaction::new(),
None,
)
.into_window();
let removed = workspace.remove_tile_by_idx(
workspace.active_column_idx,
column.active_tile_idx,
Transaction::new(),
None,
);

self.add_window(new_idx, window, true, width, is_full_width);
self.add_window(
new_idx,
removed.tile.into_window(),
true,
removed.width,
removed.is_full_width,
);
}

pub fn move_to_workspace_down(&mut self) {
Expand All @@ -486,18 +488,20 @@ impl<W: LayoutElement> Monitor<W> {
}

let column = &workspace.columns[workspace.active_column_idx];
let width = column.width;
let is_full_width = column.is_full_width;
let window = workspace
.remove_tile_by_idx(
workspace.active_column_idx,
column.active_tile_idx,
Transaction::new(),
None,
)
.into_window();
let removed = workspace.remove_tile_by_idx(
workspace.active_column_idx,
column.active_tile_idx,
Transaction::new(),
None,
);

self.add_window(new_idx, window, true, width, is_full_width);
self.add_window(
new_idx,
removed.tile.into_window(),
true,
removed.width,
removed.is_full_width,
);
}

pub fn move_to_workspace(&mut self, window: Option<&W::Id>, idx: usize) {
Expand Down Expand Up @@ -534,17 +538,19 @@ impl<W: LayoutElement> Monitor<W> {

let workspace = &mut self.workspaces[source_workspace_idx];
let column = &workspace.columns[col_idx];
let width = column.width;
let is_full_width = column.is_full_width;
let activate = source_workspace_idx == self.active_workspace_idx
&& col_idx == workspace.active_column_idx
&& tile_idx == column.active_tile_idx;

let window = workspace
.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None)
.into_window();
let removed = workspace.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None);

self.add_window(new_idx, window, activate, width, is_full_width);
self.add_window(
new_idx,
removed.tile.into_window(),
activate,
removed.width,
removed.is_full_width,
);

if self.workspace_switch.is_none() {
self.clean_up_workspaces();
Expand Down
77 changes: 36 additions & 41 deletions src/layout/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform};

use super::closing_window::{ClosingWindow, ClosingWindowRenderElement};
use super::tile::{Tile, TileRenderElement};
use super::{ConfigureIntent, InteractiveResizeData, LayoutElement, Options};
use super::{ConfigureIntent, InteractiveResizeData, LayoutElement, Options, RemovedTile};
use crate::animation::Animation;
use crate::input::swipe_tracker::SwipeTracker;
use crate::niri_render_elements;
Expand Down Expand Up @@ -1124,10 +1124,10 @@ impl<W: LayoutElement> Workspace<W> {
pub fn remove_tile_by_idx(
&mut self,
column_idx: usize,
window_idx: usize,
tile_idx: usize,
transaction: Transaction,
anim_config: Option<niri_config::Animation>,
) -> Tile<W> {
) -> RemovedTile<W> {
let offset = self.column_x(column_idx + 1) - self.column_x(column_idx);

let column = &mut self.columns[column_idx];
Expand All @@ -1136,13 +1136,13 @@ impl<W: LayoutElement> Workspace<W> {
// Animate movement of other tiles.
// FIXME: tiles can move by X too, in a centered or resizing layout with one window smaller
// than the others.
let offset_y = column.tile_offset(window_idx + 1).y - column.tile_offset(window_idx).y;
for tile in &mut column.tiles[window_idx + 1..] {
let offset_y = column.tile_offset(tile_idx + 1).y - column.tile_offset(tile_idx).y;
for tile in &mut column.tiles[tile_idx + 1..] {
tile.animate_move_y_from(offset_y);
}

let tile = column.tiles.remove(window_idx);
column.data.remove(window_idx);
let tile = column.tiles.remove(tile_idx);
column.data.remove(tile_idx);

// If one window is left, reset its weight to 1.
if column.data.len() == 1 {
Expand All @@ -1162,6 +1162,12 @@ impl<W: LayoutElement> Workspace<W> {
}
}

let tile = RemovedTile {
tile,
width: column.width,
is_full_width: column.is_full_width,
};

let became_empty = column.tiles.is_empty();
let offset = if became_empty {
offset
Expand Down Expand Up @@ -1322,17 +1328,16 @@ impl<W: LayoutElement> Workspace<W> {
column
}

pub fn remove_window(&mut self, window: &W::Id, transaction: Transaction) -> W {
pub fn remove_tile(&mut self, window: &W::Id, transaction: Transaction) -> RemovedTile<W> {
let column_idx = self
.columns
.iter()
.position(|col| col.contains(window))
.unwrap();
let column = &self.columns[column_idx];

let window_idx = column.position(window).unwrap();
self.remove_tile_by_idx(column_idx, window_idx, transaction, None)
.into_window()
let tile_idx = column.position(window).unwrap();
self.remove_tile_by_idx(column_idx, tile_idx, transaction, None)
}

pub fn update_window(&mut self, window: &W::Id, serial: Option<Serial>) {
Expand Down Expand Up @@ -1852,7 +1857,7 @@ impl<W: LayoutElement> Workspace<W> {
}

offset.x += self.columns[source_col_idx].render_offset().x;
let tile = self.remove_tile_by_idx(
let RemovedTile { tile, .. } = self.remove_tile_by_idx(
source_col_idx,
0,
Transaction::new(),
Expand All @@ -1868,23 +1873,20 @@ impl<W: LayoutElement> Workspace<W> {
new_tile.animate_move_from(offset);
} else {
// Move out of column.
let width = source_column.width;
let is_full_width = source_column.is_full_width;

let mut offset = Point::from((source_column.render_offset().x, 0.));

let tile =
let removed =
self.remove_tile_by_idx(source_col_idx, source_tile_idx, Transaction::new(), None);

// We're inserting into the source column position.
let target_column_idx = source_col_idx;

self.add_tile(
Some(target_column_idx),
tile,
removed.tile,
source_tile_was_active,
width,
is_full_width,
removed.width,
removed.is_full_width,
Some(self.options.animations.window_movement.0),
);

Expand Down Expand Up @@ -1951,7 +1953,7 @@ impl<W: LayoutElement> Workspace<W> {
self.activate_prev_column_on_removal = None;
}

let tile = self.remove_tile_by_idx(
let RemovedTile { tile, .. } = self.remove_tile_by_idx(
source_col_idx,
0,
Transaction::new(),
Expand All @@ -1966,22 +1968,19 @@ impl<W: LayoutElement> Workspace<W> {
new_tile.animate_move_from(offset);
} else {
// Move out of column.
let width = source_column.width;
let is_full_width = source_column.is_full_width;

let prev_width = self.data[source_col_idx].width;

let tile =
let removed =
self.remove_tile_by_idx(source_col_idx, source_tile_idx, Transaction::new(), None);

let target_column_idx = source_col_idx + 1;

self.add_tile(
Some(target_column_idx),
tile,
removed.tile,
source_tile_was_active,
width,
is_full_width,
removed.width,
removed.is_full_width,
Some(self.options.animations.window_movement.0),
);

Expand Down Expand Up @@ -2017,8 +2016,8 @@ impl<W: LayoutElement> Workspace<W> {
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.add_tile_to_column(target_column_idx, None, tile, false);
let removed = self.remove_tile_by_idx(source_column_idx, 0, Transaction::new(), None);
self.add_tile_to_column(target_column_idx, None, removed.tile, false);

let target_column = &mut self.columns[target_column_idx];
offset += prev_off - target_column.tile_offset(target_column.tiles.len() - 1);
Expand All @@ -2045,9 +2044,7 @@ impl<W: LayoutElement> Workspace<W> {
let mut offset = Point::from((source_column.render_offset().x, 0.));
let prev_off = source_column.tile_offset(source_column.active_tile_idx);

let width = source_column.width;
let is_full_width = source_column.is_full_width;
let tile = self.remove_tile_by_idx(
let removed = self.remove_tile_by_idx(
source_col_idx,
source_column.active_tile_idx,
Transaction::new(),
Expand All @@ -2056,10 +2053,10 @@ impl<W: LayoutElement> Workspace<W> {

self.add_tile(
Some(target_col_idx),
tile,
removed.tile,
true,
width,
is_full_width,
removed.width,
removed.is_full_width,
Some(self.options.animations.window_movement.0),
);

Expand Down Expand Up @@ -2412,19 +2409,17 @@ impl<W: LayoutElement> Workspace<W> {
if is_fullscreen && col.tiles.len() > 1 {
// This wasn't the only window in its column; extract it into a separate column.
let activate = self.active_column_idx == col_idx && col.active_tile_idx == tile_idx;
let width = col.width;
let is_full_width = col.is_full_width;

let tile = self.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None);
let removed = self.remove_tile_by_idx(col_idx, tile_idx, Transaction::new(), None);
// Create a column manually to disable the resize animation.
let column = Column::new_with_tile(
tile,
removed.tile,
self.view_size,
self.working_area,
self.scale.fractional_scale(),
self.options.clone(),
width,
is_full_width,
removed.width,
removed.is_full_width,
false,
);
self.add_column(Some(col_idx + 1), column, activate, None);
Expand Down

0 comments on commit be7fbd4

Please sign in to comment.