mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Add center-window by-id action
This commit is contained in:
@@ -1225,6 +1225,9 @@ pub enum Action {
|
||||
ConsumeWindowIntoColumn,
|
||||
ExpelWindowFromColumn,
|
||||
CenterColumn,
|
||||
CenterWindow,
|
||||
#[knuffel(skip)]
|
||||
CenterWindowById(u64),
|
||||
FocusWorkspaceDown,
|
||||
FocusWorkspaceUp,
|
||||
FocusWorkspace(#[knuffel(argument)] WorkspaceReference),
|
||||
@@ -1368,6 +1371,8 @@ impl From<niri_ipc::Action> for Action {
|
||||
niri_ipc::Action::ConsumeWindowIntoColumn {} => Self::ConsumeWindowIntoColumn,
|
||||
niri_ipc::Action::ExpelWindowFromColumn {} => Self::ExpelWindowFromColumn,
|
||||
niri_ipc::Action::CenterColumn {} => Self::CenterColumn,
|
||||
niri_ipc::Action::CenterWindow { id: None } => Self::CenterWindow,
|
||||
niri_ipc::Action::CenterWindow { id: Some(id) } => Self::CenterWindowById(id),
|
||||
niri_ipc::Action::FocusWorkspaceDown {} => Self::FocusWorkspaceDown,
|
||||
niri_ipc::Action::FocusWorkspaceUp {} => Self::FocusWorkspaceUp,
|
||||
niri_ipc::Action::FocusWorkspace { reference } => {
|
||||
|
||||
@@ -292,6 +292,18 @@ pub enum Action {
|
||||
ExpelWindowFromColumn {},
|
||||
/// Center the focused column on the screen.
|
||||
CenterColumn {},
|
||||
/// Center a window on the screen.
|
||||
#[cfg_attr(
|
||||
feature = "clap",
|
||||
clap(about = "Center the focused window on the screen")
|
||||
)]
|
||||
CenterWindow {
|
||||
/// Id of the window to center.
|
||||
///
|
||||
/// If `None`, uses the focused window.
|
||||
#[cfg_attr(feature = "clap", arg(long))]
|
||||
id: Option<u64>,
|
||||
},
|
||||
/// Focus the workspace below.
|
||||
FocusWorkspaceDown {},
|
||||
/// Focus the workspace above.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
+11
-1
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user