diff options
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | src/input.rs | 5 | ||||
| -rw-r--r-- | src/layout.rs | 45 |
3 files changed, 51 insertions, 0 deletions
@@ -65,6 +65,7 @@ The general system is: if a hotkey switches somewhere, then adding <kbd>Ctrl</kb | <kbd>Mod</kbd><kbd>Ctrl</kbd><kbd>I</kbd> | Move the focused window to the workspace above | | <kbd>Mod</kbd><kbd>,</kbd> | Consume the window to the right into the focused column | | <kbd>Mod</kbd><kbd>.</kbd> | Expel the focused window into its own column | +| <kbd>Mod</kbd><kbd>R</kbd> | Toggle between preset window widths | | <kbd>Mod</kbd><kbd>Shift</kbd><kbd>E</kbd> | Exit niri | [PaperWM]: https://github.com/paperwm/PaperWM diff --git a/src/input.rs b/src/input.rs index 2f442c34..7ea2e457 100644 --- a/src/input.rs +++ b/src/input.rs @@ -32,6 +32,7 @@ enum Action { SwitchWorkspaceUp, MoveToWorkspaceDown, MoveToWorkspaceUp, + ToggleWidth, } pub enum CompositorMod { @@ -88,6 +89,7 @@ fn action(comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState) - KEY_i => Action::SwitchWorkspaceUp, KEY_comma => Action::ConsumeIntoColumn, KEY_period => Action::ExpelFromColumn, + KEY_r => Action::ToggleWidth, _ => Action::None, } } @@ -225,6 +227,9 @@ impl Niri { // FIXME: granular self.queue_redraw_all(); } + Action::ToggleWidth => { + self.monitor_set.toggle_width(); + } } } } diff --git a/src/layout.rs b/src/layout.rs index 618f6fe0..6e4d9306 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -50,6 +50,11 @@ use smithay::wayland::shell::xdg::XdgToplevelSurfaceData; use crate::animation::Animation; const PADDING: i32 = 16; +const WIDTH_PROPORTIONS: [ColumnWidth; 3] = [ + ColumnWidth::Proportion(1. / 3.), + ColumnWidth::Proportion(0.5), + ColumnWidth::Proportion(2. / 3.), +]; #[derive(Debug, Clone, PartialEq, Eq)] pub struct OutputId(String); @@ -135,6 +140,11 @@ pub struct Workspace<W: LayoutElement> { enum ColumnWidth { /// Proportion of the current view width. Proportion(f64), + /// One of the proportion presets. + /// + /// This is separate from Proportion in order to be able to reliably cycle between preset + /// proportions. + PresetProportion(usize), /// Fixed width in logical pixels. Fixed(i32), } @@ -199,6 +209,7 @@ impl ColumnWidth { fn resolve(self, view_width: i32) -> i32 { match self { ColumnWidth::Proportion(proportion) => (view_width as f64 * proportion).floor() as i32, + ColumnWidth::PresetProportion(idx) => WIDTH_PROPORTIONS[idx].resolve(view_width), ColumnWidth::Fixed(width) => width, } } @@ -741,6 +752,13 @@ impl<W: LayoutElement> MonitorSet<W> { } } } + + pub fn toggle_width(&mut self) { + let Some(monitor) = self.active_monitor() else { + return; + }; + monitor.toggle_width(); + } } impl MonitorSet<Window> { @@ -954,6 +972,10 @@ impl<W: LayoutElement> Monitor<W> { ws.advance_animations(current_time); } } + + fn toggle_width(&mut self) { + self.active_workspace().toggle_width(); + } } impl Monitor<Window> { @@ -1362,6 +1384,14 @@ impl<W: LayoutElement> Workspace<W> { None } + + fn toggle_width(&mut self) { + if self.columns.is_empty() { + return; + } + + self.columns[self.active_column_idx].toggle_width(self.view_size); + } } impl Workspace<Window> { @@ -1510,6 +1540,21 @@ impl<W: LayoutElement> Column<W> { assert!(!self.windows.is_empty(), "columns can't be empty"); assert!(self.active_window_idx < self.windows.len()); } + + fn toggle_width(&mut self, view_size: Size<i32, Logical>) { + let idx = match self.width { + ColumnWidth::PresetProportion(idx) => (idx + 1) % WIDTH_PROPORTIONS.len(), + _ => { + let current = self.size().w; + WIDTH_PROPORTIONS + .into_iter() + .position(|prop| prop.resolve(view_size.w - PADDING) - PADDING > current) + .unwrap_or(0) + } + }; + let width = ColumnWidth::PresetProportion(idx); + self.set_width(view_size, width); + } } pub fn output_size(output: &Output) -> Size<i32, Logical> { |
