aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-11-13 19:08:29 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-11-13 19:08:29 +0400
commit1ce3c1392dd10a47a003f59fbbed7c3170094336 (patch)
tree9e7dd2e8f4dc52c70f5146b680f361c0d03d7944
parente397f773bd56405da2829fb1aeb6e6747837da90 (diff)
downloadniri-1ce3c1392dd10a47a003f59fbbed7c3170094336.tar.gz
niri-1ce3c1392dd10a47a003f59fbbed7c3170094336.tar.bz2
niri-1ce3c1392dd10a47a003f59fbbed7c3170094336.zip
Add an action to center column within view bound to Ctrl-C
-rw-r--r--README.md1
-rw-r--r--resources/default-config.kdl1
-rw-r--r--src/config.rs1
-rw-r--r--src/input.rs5
-rw-r--r--src/layout.rs54
5 files changed, 62 insertions, 0 deletions
diff --git a/README.md b/README.md
index 89a6320f..5e17ca5e 100644
--- a/README.md
+++ b/README.md
@@ -120,6 +120,7 @@ The general system is: if a hotkey switches somewhere, then adding <kbd>Ctrl</kb
| <kbd>Mod</kbd><kbd>.</kbd> | Expel the focused window into its own column |
| <kbd>Mod</kbd><kbd>R</kbd> | Toggle between preset column widths |
| <kbd>Mod</kbd><kbd>F</kbd> | Maximize column |
+| <kbd>Mod</kbd><kbd>C</kbd> | Center column within view |
| <kbd>Mod</kbd><kbd>-</kbd> | Decrease column width by 10% |
| <kbd>Mod</kbd><kbd>=</kbd> | Increase column width by 10% |
| <kbd>Mod</kbd><kbd>Shift</kbd><kbd>-</kbd> | Decrease window height by 10% |
diff --git a/resources/default-config.kdl b/resources/default-config.kdl
index 02cbac63..002df225 100644
--- a/resources/default-config.kdl
+++ b/resources/default-config.kdl
@@ -219,6 +219,7 @@ binds {
Mod+R { switch-preset-column-width; }
Mod+F { maximize-column; }
Mod+Shift+F { fullscreen-window; }
+ Mod+C { center-column; }
// Finer width adjustments.
// This command can also:
diff --git a/src/config.rs b/src/config.rs
index b7510d8d..a76bf348 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -279,6 +279,7 @@ pub enum Action {
MoveWindowUp,
ConsumeWindowIntoColumn,
ExpelWindowFromColumn,
+ CenterColumn,
FocusWorkspaceDown,
FocusWorkspaceUp,
FocusWorkspace(#[knuffel(argument)] u8),
diff --git a/src/input.rs b/src/input.rs
index 83f186fd..347ef6c5 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -282,6 +282,11 @@ impl State {
Action::SwitchPresetColumnWidth => {
self.niri.layout.toggle_width();
}
+ Action::CenterColumn => {
+ self.niri.layout.center_column();
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
Action::MaximizeColumn => {
self.niri.layout.toggle_full_width();
}
diff --git a/src/layout.rs b/src/layout.rs
index f123c9f9..fd7bf1cf 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -1049,6 +1049,13 @@ impl<W: LayoutElement> Layout<W> {
monitor.expel_from_column();
}
+ pub fn center_column(&mut self) {
+ let Some(monitor) = self.active_monitor() else {
+ return;
+ };
+ monitor.center_column();
+ }
+
pub fn focus(&self) -> Option<&W> {
let MonitorSet::Normal {
monitors,
@@ -1710,6 +1717,10 @@ impl<W: LayoutElement> Monitor<W> {
self.active_workspace().expel_from_column();
}
+ pub fn center_column(&mut self) {
+ self.active_workspace().center_column();
+ }
+
pub fn focus(&self) -> Option<&W> {
let workspace = &self.workspaces[self.active_workspace_idx];
if !workspace.has_windows() {
@@ -2419,6 +2430,45 @@ impl<W: LayoutElement> Workspace<W> {
self.add_window(window, true, width, is_full_width);
}
+ fn center_column(&mut self) {
+ if self.columns.is_empty() {
+ return;
+ }
+
+ let col = &self.columns[self.active_column_idx];
+ if col.is_fullscreen {
+ return;
+ }
+
+ let width = col.width();
+
+ // If the column is wider than the working area, then on commit it will be shifted to left
+ // edge alignment by the usual positioning code, so there's no use in doing anything here.
+ if self.working_area.size.w <= width {
+ return;
+ }
+
+ let new_view_offset = -(self.working_area.size.w - width) / 2 - self.working_area.loc.x;
+
+ // If we're already animating towards that, don't restart it.
+ if let Some(anim) = &self.view_offset_anim {
+ if anim.to().round() as i32 == new_view_offset {
+ return;
+ }
+ }
+
+ // If our view offset is already this, we don't need to do anything.
+ if self.view_offset == new_view_offset {
+ return;
+ }
+
+ self.view_offset_anim = Some(Animation::new(
+ self.view_offset as f64,
+ new_view_offset as f64,
+ Duration::from_millis(250),
+ ));
+ }
+
fn view_pos(&self) -> i32 {
self.column_x(self.active_column_idx) + self.view_offset
}
@@ -3278,6 +3328,7 @@ mod tests {
MoveWindowUp,
ConsumeWindowIntoColumn,
ExpelWindowFromColumn,
+ CenterColumn,
FocusWorkspaceDown,
FocusWorkspaceUp,
FocusWorkspace(#[proptest(strategy = "1..=5u8")] u8),
@@ -3384,6 +3435,7 @@ mod tests {
Op::MoveWindowUp => layout.move_up(),
Op::ConsumeWindowIntoColumn => layout.consume_into_column(),
Op::ExpelWindowFromColumn => layout.expel_from_column(),
+ Op::CenterColumn => layout.center_column(),
Op::FocusWorkspaceDown => layout.switch_workspace_down(),
Op::FocusWorkspaceUp => layout.switch_workspace_up(),
Op::FocusWorkspace(idx) => layout.switch_workspace(idx),
@@ -3488,6 +3540,7 @@ mod tests {
Op::MoveColumnRight,
Op::ConsumeWindowIntoColumn,
Op::ExpelWindowFromColumn,
+ Op::CenterColumn,
Op::FocusWorkspaceDown,
Op::FocusWorkspaceUp,
Op::FocusWorkspace(1),
@@ -3603,6 +3656,7 @@ mod tests {
Op::MoveColumnRight,
Op::ConsumeWindowIntoColumn,
Op::ExpelWindowFromColumn,
+ Op::CenterColumn,
Op::FocusWorkspaceDown,
Op::FocusWorkspaceUp,
Op::FocusWorkspace(1),