aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/mod.rs28
-rw-r--r--src/layout/mod.rs35
-rw-r--r--src/layout/workspace.rs11
3 files changed, 74 insertions, 0 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 6e116d9e..c510a958 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -1318,6 +1318,34 @@ impl State {
self.niri.queue_redraw_all();
}
}
+ Action::MoveWindowToFloating => {
+ self.niri.layout.set_window_floating(None, true);
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ Action::MoveWindowToFloatingById(id) => {
+ let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id);
+ let window = window.map(|(_, m)| m.window.clone());
+ if let Some(window) = window {
+ self.niri.layout.set_window_floating(Some(&window), true);
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ }
+ Action::MoveWindowToTiling => {
+ self.niri.layout.set_window_floating(None, false);
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ Action::MoveWindowToTilingById(id) => {
+ let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id);
+ let window = window.map(|(_, m)| m.window.clone());
+ if let Some(window) = window {
+ self.niri.layout.set_window_floating(Some(&window), false);
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ }
Action::SwitchFocusBetweenFloatingAndTiling => {
self.niri.layout.switch_focus_floating_tiling();
// FIXME: granular
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index acdf1301..53c9ce6b 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -2703,6 +2703,32 @@ impl<W: LayoutElement> Layout<W> {
workspace.toggle_window_floating(window);
}
+ pub fn set_window_floating(&mut self, window: Option<&W::Id>, floating: bool) {
+ if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
+ if window.is_none() || window == Some(move_.tile.window().id()) {
+ if move_.is_floating != floating {
+ self.toggle_window_floating(window);
+ }
+ return;
+ }
+ }
+
+ let workspace = if let Some(window) = window {
+ Some(
+ self.workspaces_mut()
+ .find(|ws| ws.has_window(window))
+ .unwrap(),
+ )
+ } else {
+ self.active_workspace_mut()
+ };
+
+ let Some(workspace) = workspace else {
+ return;
+ };
+ workspace.set_window_floating(window, floating);
+ }
+
pub fn switch_focus_floating_tiling(&mut self) {
let Some(workspace) = self.active_workspace_mut() else {
return;
@@ -4362,6 +4388,11 @@ mod tests {
#[proptest(strategy = "proptest::option::of(1..=5usize)")]
id: Option<usize>,
},
+ SetWindowFloating {
+ #[proptest(strategy = "proptest::option::of(1..=5usize)")]
+ id: Option<usize>,
+ floating: bool,
+ },
SwitchFocusFloatingTiling,
SetParent {
#[proptest(strategy = "1..=5usize")]
@@ -4874,6 +4905,10 @@ mod tests {
let id = id.filter(|id| layout.has_window(id));
layout.toggle_window_floating(id.as_ref());
}
+ Op::SetWindowFloating { id, floating } => {
+ let id = id.filter(|id| layout.has_window(id));
+ layout.set_window_floating(id.as_ref(), floating);
+ }
Op::SwitchFocusFloatingTiling => {
layout.switch_focus_floating_tiling();
}
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index cd1a6261..099b449c 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -1146,6 +1146,17 @@ impl<W: LayoutElement> Workspace<W> {
tile.animate_move_from(render_pos - new_render_pos);
}
+ pub fn set_window_floating(&mut self, id: Option<&W::Id>, floating: bool) {
+ if id.map_or(self.floating_is_active.get(), |id| {
+ self.floating.has_window(id)
+ }) == floating
+ {
+ return;
+ }
+
+ self.toggle_window_floating(id);
+ }
+
pub fn switch_focus_floating_tiling(&mut self) {
if self.floating.is_empty() {
// If floating is empty, keep focus on scrolling.