Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions niri-config/src/binds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,19 @@ pub enum Action {
#[knuffel(skip)]
ResetWindowHeightById(u64),
SwitchPresetColumnWidth,
SwitchPresetColumnWidthBack,
SwitchPresetWindowWidth,
SwitchPresetWindowWidthBack,
#[knuffel(skip)]
SwitchPresetWindowWidthById(u64),
#[knuffel(skip)]
SwitchPresetWindowWidthBackById(u64),
SwitchPresetWindowHeight,
SwitchPresetWindowHeightBack,
#[knuffel(skip)]
SwitchPresetWindowHeightById(u64),
#[knuffel(skip)]
SwitchPresetWindowHeightBackById(u64),
MaximizeColumn,
SetColumnWidth(#[knuffel(argument, str)] SizeChange),
ExpandColumnToAvailableWidth,
Expand Down Expand Up @@ -525,16 +532,29 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::ResetWindowHeight { id: None } => Self::ResetWindowHeight,
niri_ipc::Action::ResetWindowHeight { id: Some(id) } => Self::ResetWindowHeightById(id),
niri_ipc::Action::SwitchPresetColumnWidth {} => Self::SwitchPresetColumnWidth,
niri_ipc::Action::SwitchPresetColumnWidthBack {} => Self::SwitchPresetColumnWidthBack,
niri_ipc::Action::SwitchPresetWindowWidth { id: None } => Self::SwitchPresetWindowWidth,
niri_ipc::Action::SwitchPresetWindowWidthBack { id: None } => {
Self::SwitchPresetWindowWidthBack
}
niri_ipc::Action::SwitchPresetWindowWidth { id: Some(id) } => {
Self::SwitchPresetWindowWidthById(id)
}
niri_ipc::Action::SwitchPresetWindowWidthBack { id: Some(id) } => {
Self::SwitchPresetWindowWidthBackById(id)
}
niri_ipc::Action::SwitchPresetWindowHeight { id: None } => {
Self::SwitchPresetWindowHeight
}
niri_ipc::Action::SwitchPresetWindowHeightBack { id: None } => {
Self::SwitchPresetWindowHeightBack
}
niri_ipc::Action::SwitchPresetWindowHeight { id: Some(id) } => {
Self::SwitchPresetWindowHeightById(id)
}
niri_ipc::Action::SwitchPresetWindowHeightBack { id: Some(id) } => {
Self::SwitchPresetWindowHeightBackById(id)
}
niri_ipc::Action::MaximizeColumn {} => Self::MaximizeColumn,
niri_ipc::Action::SetColumnWidth { change } => Self::SetColumnWidth(change),
niri_ipc::Action::ExpandColumnToAvailableWidth {} => Self::ExpandColumnToAvailableWidth,
Expand Down
18 changes: 18 additions & 0 deletions niri-ipc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ pub enum Action {
},
/// Switch between preset column widths.
SwitchPresetColumnWidth {},
/// Switch between preset column widths backwards.
SwitchPresetColumnWidthBack {},
/// Switch between preset window widths.
SwitchPresetWindowWidth {
/// Id of the window whose width to switch.
Expand All @@ -685,6 +687,14 @@ pub enum Action {
#[cfg_attr(feature = "clap", arg(long))]
id: Option<u64>,
},
/// Switch between preset window widths backwards.
SwitchPresetWindowWidthBack {
/// Id of the window whose width to switch.
///
/// If `None`, uses the focused window.
#[cfg_attr(feature = "clap", arg(long))]
id: Option<u64>,
},
/// Switch between preset window heights.
SwitchPresetWindowHeight {
/// Id of the window whose height to switch.
Expand All @@ -693,6 +703,14 @@ pub enum Action {
#[cfg_attr(feature = "clap", arg(long))]
id: Option<u64>,
},
/// Switch between preset window heights backwards.
SwitchPresetWindowHeightBack {
/// Id of the window whose height to switch.
///
/// If `None`, uses the focused window.
#[cfg_attr(feature = "clap", arg(long))]
id: Option<u64>,
},
/// Toggle the maximized state of the focused column.
MaximizeColumn {},
/// Change the width of the focused column.
Expand Down
2 changes: 2 additions & 0 deletions resources/default-config.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ binds {
Mod+Period { expel-window-from-column; }

Mod+R { switch-preset-column-width; }
// Cycling through the presets in reverse order is also possible.
// Mod+R { switch-preset-column-width-back; }
Mod+Shift+R { switch-preset-window-height; }
Mod+Ctrl+R { reset-window-height; }
Mod+F { maximize-column; }
Expand Down
33 changes: 28 additions & 5 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1442,26 +1442,49 @@ impl State {
self.niri.queue_redraw_all();
}
Action::SwitchPresetColumnWidth => {
self.niri.layout.toggle_width();
self.niri.layout.toggle_width(true);
}
Action::SwitchPresetColumnWidthBack => {
self.niri.layout.toggle_width(false);
}
Action::SwitchPresetWindowWidth => {
self.niri.layout.toggle_window_width(None);
self.niri.layout.toggle_window_width(None, true);
}
Action::SwitchPresetWindowWidthBack => {
self.niri.layout.toggle_window_width(None, false);
}
Action::SwitchPresetWindowWidthById(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.toggle_window_width(Some(&window));
self.niri.layout.toggle_window_width(Some(&window), true);
}
}
Action::SwitchPresetWindowWidthBackById(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.toggle_window_width(Some(&window), false);
}
}
Action::SwitchPresetWindowHeight => {
self.niri.layout.toggle_window_height(None);
self.niri.layout.toggle_window_height(None, true);
}
Action::SwitchPresetWindowHeightBack => {
self.niri.layout.toggle_window_height(None, false);
}
Action::SwitchPresetWindowHeightById(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.toggle_window_height(Some(&window));
self.niri.layout.toggle_window_height(Some(&window), true);
}
}
Action::SwitchPresetWindowHeightBackById(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.toggle_window_height(Some(&window), false);
}
}
Action::CenterColumn => {
Expand Down
50 changes: 39 additions & 11 deletions src/layout/floating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,33 +624,47 @@ impl<W: LayoutElement> FloatingSpace<W> {
}
}

pub fn toggle_window_width(&mut self, id: Option<&W::Id>) {
pub fn toggle_window_width(&mut self, id: Option<&W::Id>, forwards: bool) {
let Some(id) = id.or(self.active_window_id.as_ref()).cloned() else {
return;
};
let idx = self.idx_of(&id).unwrap();

let available_size = self.working_area.size.w;

let len = self.options.preset_column_widths.len();
let tile = &mut self.tiles[idx];
let preset_idx = if let Some(idx) = tile.floating_preset_width_idx {
(idx + 1) % self.options.preset_column_widths.len()
(idx + if forwards { 1 } else { len - 1 }) % len
} else {
let current_window = tile.window_expected_or_current_size().w;
let current_tile = tile.tile_expected_or_current_size().w;

self.options
let mut it = self
.options
.preset_column_widths
.iter()
.position(|preset| {
let resolved = resolve_preset_size(*preset, available_size);
.map(|preset| resolve_preset_size(*preset, available_size));

if forwards {
it.position(|resolved| {
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => current_tile + 1. < resolved,
ResolvedSize::Window(resolved) => current_window + 1. < resolved,
}
})
.unwrap_or(0)
} else {
it.rposition(|resolved| {
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => resolved + 1. < current_tile,
ResolvedSize::Window(resolved) => resolved + 1. < current_window,
}
})
.unwrap_or(len - 1)
}
};

let preset = self.options.preset_column_widths[preset_idx];
Expand All @@ -670,33 +684,47 @@ impl<W: LayoutElement> FloatingSpace<W> {
true
}

pub fn toggle_window_height(&mut self, id: Option<&W::Id>) {
pub fn toggle_window_height(&mut self, id: Option<&W::Id>, forwards: bool) {
let Some(id) = id.or(self.active_window_id.as_ref()).cloned() else {
return;
};
let idx = self.idx_of(&id).unwrap();

let available_size = self.working_area.size.h;

let len = self.options.preset_window_heights.len();
let tile = &mut self.tiles[idx];
let preset_idx = if let Some(idx) = tile.floating_preset_height_idx {
(idx + 1) % self.options.preset_window_heights.len()
(idx + if forwards { 1 } else { len - 1 }) % len
} else {
let current_window = tile.window_expected_or_current_size().h;
let current_tile = tile.tile_expected_or_current_size().h;

self.options
let mut it = self
.options
.preset_window_heights
.iter()
.position(|preset| {
let resolved = resolve_preset_size(*preset, available_size);
.map(|preset| resolve_preset_size(*preset, available_size));

if forwards {
it.position(|resolved| {
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => current_tile + 1. < resolved,
ResolvedSize::Window(resolved) => current_window + 1. < resolved,
}
})
.unwrap_or(0)
} else {
it.rposition(|resolved| {
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => resolved + 1. < current_tile,
ResolvedSize::Window(resolved) => resolved + 1. < current_window,
}
})
.unwrap_or(len - 1)
}
};

let preset = self.options.preset_window_heights[preset_idx];
Expand Down Expand Up @@ -762,7 +790,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
let idx = self.idx_of(id).unwrap();

let tile = &mut self.tiles[idx];
tile.floating_preset_width_idx = None;
tile.floating_preset_height_idx = None;

let available_size = self.working_area.size.h;
let win = tile.window();
Expand Down
12 changes: 6 additions & 6 deletions src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3179,14 +3179,14 @@ impl<W: LayoutElement> Layout<W> {
self.options = options;
}

pub fn toggle_width(&mut self) {
pub fn toggle_width(&mut self, forwards: bool) {
let Some(workspace) = self.active_workspace_mut() else {
return;
};
workspace.toggle_width();
workspace.toggle_width(forwards);
}

pub fn toggle_window_width(&mut self, window: Option<&W::Id>) {
pub fn toggle_window_width(&mut self, window: Option<&W::Id>, forwards: bool) {
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
if window.is_none() || window == Some(move_.tile.window().id()) {
return;
Expand All @@ -3206,10 +3206,10 @@ impl<W: LayoutElement> Layout<W> {
let Some(workspace) = workspace else {
return;
};
workspace.toggle_window_width(window);
workspace.toggle_window_width(window, forwards);
}

pub fn toggle_window_height(&mut self, window: Option<&W::Id>) {
pub fn toggle_window_height(&mut self, window: Option<&W::Id>, forwards: bool) {
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
if window.is_none() || window == Some(move_.tile.window().id()) {
return;
Expand All @@ -3229,7 +3229,7 @@ impl<W: LayoutElement> Layout<W> {
let Some(workspace) = workspace else {
return;
};
workspace.toggle_window_height(window);
workspace.toggle_window_height(window, forwards);
}

pub fn toggle_full_width(&mut self) {
Expand Down
Loading