aboutsummaryrefslogtreecommitdiff
path: root/niri-ipc/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'niri-ipc/src/lib.rs')
-rw-r--r--niri-ipc/src/lib.rs241
1 files changed, 241 insertions, 0 deletions
diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs
index 129e8f57..5131388f 100644
--- a/niri-ipc/src/lib.rs
+++ b/niri-ipc/src/lib.rs
@@ -2,6 +2,7 @@
#![warn(missing_docs)]
use std::collections::HashMap;
+use std::str::FromStr;
use serde::{Deserialize, Serialize};
@@ -13,6 +14,8 @@ pub const SOCKET_PATH_ENV: &str = "NIRI_SOCKET";
pub enum Request {
/// Request information about connected outputs.
Outputs,
+ /// Perform an action.
+ Action(Action),
}
/// Response from niri to client.
@@ -24,6 +27,192 @@ pub enum Response {
Outputs(HashMap<String, Output>),
}
+/// Actions that niri can perform.
+// Variants in this enum should match the spelling of the ones in niri-config. Most, but not all,
+// variants from niri-config should be present here.
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
+#[cfg_attr(feature = "clap", derive(clap::Parser))]
+#[cfg_attr(feature = "clap", command(subcommand_value_name = "ACTION"))]
+#[cfg_attr(feature = "clap", command(subcommand_help_heading = "Actions"))]
+pub enum Action {
+ /// Exit niri.
+ Quit,
+ /// Power off all monitors via DPMS.
+ PowerOffMonitors,
+ /// Spawn a command.
+ Spawn {
+ /// Command to spawn.
+ #[cfg_attr(feature = "clap", arg(last = true, required = true))]
+ command: Vec<String>,
+ },
+ /// Open the screenshot UI.
+ Screenshot,
+ /// Screenshot the focused screen.
+ ScreenshotScreen,
+ /// Screenshot the focused window.
+ ScreenshotWindow,
+ /// Close the focused window.
+ CloseWindow,
+ /// Toggle fullscreen on the focused window.
+ FullscreenWindow,
+ /// Focus the column to the left.
+ FocusColumnLeft,
+ /// Focus the column to the right.
+ FocusColumnRight,
+ /// Focus the first column.
+ FocusColumnFirst,
+ /// Focus the last column.
+ FocusColumnLast,
+ /// Focus the window below.
+ FocusWindowDown,
+ /// Focus the window above.
+ FocusWindowUp,
+ /// Focus the window or the workspace above.
+ FocusWindowOrWorkspaceDown,
+ /// Focus the window or the workspace above.
+ FocusWindowOrWorkspaceUp,
+ /// Move the focused column to the left.
+ MoveColumnLeft,
+ /// Move the focused column to the right.
+ MoveColumnRight,
+ /// Move the focused column to the start of the workspace.
+ MoveColumnToFirst,
+ /// Move the focused column to the end of the workspace.
+ MoveColumnToLast,
+ /// Move the focused window down in a column.
+ MoveWindowDown,
+ /// Move the focused window up in a column.
+ MoveWindowUp,
+ /// Move the focused window down in a column or to the workspace below.
+ MoveWindowDownOrToWorkspaceDown,
+ /// Move the focused window up in a column or to the workspace above.
+ MoveWindowUpOrToWorkspaceUp,
+ /// Consume or expel the focused window left.
+ ConsumeOrExpelWindowLeft,
+ /// Consume or expel the focused window right.
+ ConsumeOrExpelWindowRight,
+ /// Consume the window to the right into the focused column.
+ ConsumeWindowIntoColumn,
+ /// Expel the focused window from the column.
+ ExpelWindowFromColumn,
+ /// Center the focused column on the screen.
+ CenterColumn,
+ /// Focus the workspace below.
+ FocusWorkspaceDown,
+ /// Focus the workspace above.
+ FocusWorkspaceUp,
+ /// Focus a workspace by index.
+ FocusWorkspace {
+ /// Index of the workspace to focus.
+ #[cfg_attr(feature = "clap", arg())]
+ index: u8,
+ },
+ /// Move the focused window to the workspace below.
+ MoveWindowToWorkspaceDown,
+ /// Move the focused window to the workspace above.
+ MoveWindowToWorkspaceUp,
+ /// Move the focused window to a workspace by index.
+ MoveWindowToWorkspace {
+ /// Index of the target workspace.
+ #[cfg_attr(feature = "clap", arg())]
+ index: u8,
+ },
+ /// Move the focused column to the workspace below.
+ MoveColumnToWorkspaceDown,
+ /// Move the focused column to the workspace above.
+ MoveColumnToWorkspaceUp,
+ /// Move the focused column to a workspace by index.
+ MoveColumnToWorkspace {
+ /// Index of the target workspace.
+ #[cfg_attr(feature = "clap", arg())]
+ index: u8,
+ },
+ /// Move the focused workspace down.
+ MoveWorkspaceDown,
+ /// Move the focused workspace up.
+ MoveWorkspaceUp,
+ /// Focus the monitor to the left.
+ FocusMonitorLeft,
+ /// Focus the monitor to the right.
+ FocusMonitorRight,
+ /// Focus the monitor below.
+ FocusMonitorDown,
+ /// Focus the monitor above.
+ FocusMonitorUp,
+ /// Move the focused window to the monitor to the left.
+ MoveWindowToMonitorLeft,
+ /// Move the focused window to the monitor to the right.
+ MoveWindowToMonitorRight,
+ /// Move the focused window to the monitor below.
+ MoveWindowToMonitorDown,
+ /// Move the focused window to the monitor above.
+ MoveWindowToMonitorUp,
+ /// Move the focused column to the monitor to the left.
+ MoveColumnToMonitorLeft,
+ /// Move the focused column to the monitor to the right.
+ MoveColumnToMonitorRight,
+ /// Move the focused column to the monitor below.
+ MoveColumnToMonitorDown,
+ /// Move the focused column to the monitor above.
+ MoveColumnToMonitorUp,
+ /// Change the height of the focused window.
+ SetWindowHeight {
+ /// How to change the height.
+ #[cfg_attr(feature = "clap", arg())]
+ change: SizeChange,
+ },
+ /// Switch between preset column widths.
+ SwitchPresetColumnWidth,
+ /// Toggle the maximized state of the focused column.
+ MaximizeColumn,
+ /// Change the width of the focused column.
+ SetColumnWidth {
+ /// How to change the width.
+ #[cfg_attr(feature = "clap", arg())]
+ change: SizeChange,
+ },
+ /// Switch between keyboard layouts.
+ SwitchLayout {
+ /// Layout to switch to.
+ #[cfg_attr(feature = "clap", arg())]
+ layout: LayoutSwitchTarget,
+ },
+ /// Show the hotkey overlay.
+ ShowHotkeyOverlay,
+ /// Move the focused workspace to the monitor to the left.
+ MoveWorkspaceToMonitorLeft,
+ /// Move the focused workspace to the monitor to the right.
+ MoveWorkspaceToMonitorRight,
+ /// Move the focused workspace to the monitor below.
+ MoveWorkspaceToMonitorDown,
+ /// Move the focused workspace to the monitor above.
+ MoveWorkspaceToMonitorUp,
+ /// Toggle a debug tint on windows.
+ ToggleDebugTint,
+}
+
+/// Change in window or column size.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+pub enum SizeChange {
+ /// Set the size in logical pixels.
+ SetFixed(i32),
+ /// Set the size as a proportion of the working area.
+ SetProportion(f64),
+ /// Add or subtract to the current size in logical pixels.
+ AdjustFixed(i32),
+ /// Add or subtract to the current size as a proportion of the working area.
+ AdjustProportion(f64),
+}
+
+/// Layout to switch to.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+pub enum LayoutSwitchTarget {
+ /// The next configured layout.
+ Next,
+ /// The previous configured layout.
+ Prev,
+}
+
/// Connected output.
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Output {
@@ -53,3 +242,55 @@ pub struct Mode {
/// Refresh rate in millihertz.
pub refresh_rate: u32,
}
+
+impl FromStr for SizeChange {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s.split_once('%') {
+ Some((value, empty)) => {
+ if !empty.is_empty() {
+ return Err("trailing characters after '%' are not allowed");
+ }
+
+ match value.bytes().next() {
+ Some(b'-' | b'+') => {
+ let value = value.parse().map_err(|_| "error parsing value")?;
+ Ok(Self::AdjustProportion(value))
+ }
+ Some(_) => {
+ let value = value.parse().map_err(|_| "error parsing value")?;
+ Ok(Self::SetProportion(value))
+ }
+ None => Err("value is missing"),
+ }
+ }
+ None => {
+ let value = s;
+ match value.bytes().next() {
+ Some(b'-' | b'+') => {
+ let value = value.parse().map_err(|_| "error parsing value")?;
+ Ok(Self::AdjustFixed(value))
+ }
+ Some(_) => {
+ let value = value.parse().map_err(|_| "error parsing value")?;
+ Ok(Self::SetFixed(value))
+ }
+ None => Err("value is missing"),
+ }
+ }
+ }
+ }
+}
+
+impl FromStr for LayoutSwitchTarget {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "next" => Ok(Self::Next),
+ "prev" => Ok(Self::Prev),
+ _ => Err(r#"invalid layout action, can be "next" or "prev""#),
+ }
+ }
+}