aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/mod.rs14
-rw-r--r--src/layout/floating.rs6
-rw-r--r--src/layout/mod.rs21
-rw-r--r--src/layout/scrolling.rs22
-rw-r--r--src/layout/workspace.rs12
5 files changed, 71 insertions, 4 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index d45d0e8a..98bbbb8e 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -1127,6 +1127,20 @@ impl State {
// FIXME: granular
self.niri.queue_redraw_all();
}
+ Action::CenterWindow => {
+ self.niri.layout.center_window(None);
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ Action::CenterWindowById(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.center_window(Some(&window));
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ }
Action::MaximizeColumn => {
self.niri.layout.toggle_full_width();
}
diff --git a/src/layout/floating.rs b/src/layout/floating.rs
index 6192d119..5302e158 100644
--- a/src/layout/floating.rs
+++ b/src/layout/floating.rs
@@ -902,11 +902,11 @@ impl<W: LayoutElement> FloatingSpace<W> {
self.move_to(idx, new_pos, animate);
}
- pub fn center_window(&mut self) {
- let Some(active_id) = &self.active_window_id else {
+ pub fn center_window(&mut self, id: Option<&W::Id>) {
+ let Some(id) = id.or(self.active_window_id.as_ref()).cloned() else {
return;
};
- let idx = self.idx_of(active_id).unwrap();
+ let idx = self.idx_of(&id).unwrap();
let new_pos = center_preferring_top_left_in_area(self.working_area, self.data[idx].size);
self.move_to(idx, new_pos, true);
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 433cae43..571411fc 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1993,6 +1993,19 @@ impl<W: LayoutElement> Layout<W> {
monitor.center_column();
}
+ pub fn center_window(&mut self, id: Option<&W::Id>) {
+ let workspace = if let Some(id) = id {
+ Some(self.workspaces_mut().find(|ws| ws.has_window(id)).unwrap())
+ } else {
+ self.active_workspace_mut()
+ };
+
+ let Some(workspace) = workspace else {
+ return;
+ };
+ workspace.center_window(id);
+ }
+
pub fn focus(&self) -> Option<&W> {
self.focus_with_output().map(|(win, _out)| win)
}
@@ -4390,6 +4403,10 @@ mod tests {
ConsumeWindowIntoColumn,
ExpelWindowFromColumn,
CenterColumn,
+ CenterWindow {
+ #[proptest(strategy = "proptest::option::of(1..=5usize)")]
+ id: Option<usize>,
+ },
FocusWorkspaceDown,
FocusWorkspaceUp,
FocusWorkspace(#[proptest(strategy = "0..=4usize")] usize),
@@ -4901,6 +4918,10 @@ mod tests {
Op::ConsumeWindowIntoColumn => layout.consume_into_column(),
Op::ExpelWindowFromColumn => layout.expel_from_column(),
Op::CenterColumn => layout.center_column(),
+ Op::CenterWindow { id } => {
+ let id = id.filter(|id| layout.has_window(id));
+ layout.center_window(id.as_ref());
+ }
Op::FocusWorkspaceDown => layout.switch_workspace_down(),
Op::FocusWorkspaceUp => layout.switch_workspace_up(),
Op::FocusWorkspace(idx) => layout.switch_workspace(idx),
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs
index a378c461..6fa6fbfc 100644
--- a/src/layout/scrolling.rs
+++ b/src/layout/scrolling.rs
@@ -1747,6 +1747,28 @@ impl<W: LayoutElement> ScrollingSpace<W> {
cancel_resize_for_column(&mut self.interactive_resize, col);
}
+ pub fn center_window(&mut self, window: Option<&W::Id>) {
+ if self.columns.is_empty() {
+ return;
+ }
+
+ let col_idx = if let Some(window) = window {
+ self.columns
+ .iter()
+ .position(|col| col.contains(window))
+ .unwrap()
+ } else {
+ self.active_column_idx
+ };
+
+ // We can reasonably center only the active column.
+ if col_idx != self.active_column_idx {
+ return;
+ }
+
+ self.center_column();
+ }
+
pub fn view_pos(&self) -> f64 {
self.column_x(self.active_column_idx) + self.view_offset.current()
}
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index 991e7e42..0e67f3b3 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -971,12 +971,22 @@ impl<W: LayoutElement> Workspace<W> {
pub fn center_column(&mut self) {
if self.floating_is_active.get() {
- self.floating.center_window();
+ self.floating.center_window(None);
} else {
self.scrolling.center_column();
}
}
+ pub fn center_window(&mut self, id: Option<&W::Id>) {
+ if id.map_or(self.floating_is_active.get(), |id| {
+ self.floating.has_window(id)
+ }) {
+ self.floating.center_window(id);
+ } else {
+ self.scrolling.center_window(id);
+ }
+ }
+
pub fn toggle_width(&mut self) {
if self.floating_is_active.get() {
self.floating.toggle_window_width(None);