diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-28 11:40:16 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-30 20:12:37 +0300 |
| commit | 6c52077d922dce3a9b57c6785647b6befb700ac9 (patch) | |
| tree | edc2edb081630600c95e9356be9e43d5a2eea240 /src/layout/workspace.rs | |
| parent | 73bf7b1730e6911adb09d8253035f4510d83dbe0 (diff) | |
| download | niri-6c52077d922dce3a9b57c6785647b6befb700ac9.tar.gz niri-6c52077d922dce3a9b57c6785647b6befb700ac9.tar.bz2 niri-6c52077d922dce3a9b57c6785647b6befb700ac9.zip | |
Add move-floating-window action
Diffstat (limited to 'src/layout/workspace.rs')
| -rw-r--r-- | src/layout/workspace.rs | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 06900afc..de190275 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use std::time::Duration; use niri_config::{OutputName, PresetSize, Workspace as WorkspaceConfig}; -use niri_ipc::SizeChange; +use niri_ipc::{PositionChange, SizeChange}; use smithay::backend::renderer::gles::GlesRenderer; use smithay::desktop::{layer_map_for_output, Window}; use smithay::output::Output; @@ -1185,6 +1185,55 @@ impl<W: LayoutElement> Workspace<W> { }; } + pub fn move_floating_window( + &mut self, + id: Option<&W::Id>, + x: PositionChange, + y: PositionChange, + ) { + if id.map_or(self.floating_is_active.get(), |id| { + self.floating.has_window(id) + }) { + self.floating.move_window(id, x, y); + } else { + // If the target tile isn't floating, set its stored floating position. + let tile = if let Some(id) = id { + self.scrolling + .tiles_mut() + .find(|tile| tile.window().id() == id) + .unwrap() + } else if let Some(tile) = self.scrolling.active_tile_mut() { + tile + } else { + return; + }; + + let working_area_loc = self.floating.working_area().loc; + // If there's no stored floating position, we can only set both components at once, not + // adjust. + let Some(pos) = tile.floating_pos.or_else(|| { + (matches!(x, PositionChange::SetFixed(_)) + && matches!(y, PositionChange::SetFixed(_))) + .then_some(Point::default()) + }) else { + return; + }; + + let mut pos = self.floating.scale_by_working_area(pos); + match x { + PositionChange::SetFixed(x) => pos.x = x + working_area_loc.x, + PositionChange::AdjustFixed(x) => pos.x += x, + } + match y { + PositionChange::SetFixed(y) => pos.y = y + working_area_loc.y, + PositionChange::AdjustFixed(y) => pos.y += y, + } + + let pos = self.floating.logical_to_size_frac(pos); + tile.floating_pos = Some(pos); + } + } + pub fn has_windows(&self) -> bool { self.windows().next().is_some() } |
