aboutsummaryrefslogtreecommitdiff
path: root/niri-ipc
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-05-05 10:19:47 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-05-05 10:19:47 +0400
commit65b9c74f624b4a78c2247135bf1a96dcac0bd009 (patch)
treed4b960d3aac247df759ada124a2ffa050ae8ee9f /niri-ipc
parent2dff67447082f3c000b7eb68b4826f5b3db7397b (diff)
downloadniri-65b9c74f624b4a78c2247135bf1a96dcac0bd009.tar.gz
niri-65b9c74f624b4a78c2247135bf1a96dcac0bd009.tar.bz2
niri-65b9c74f624b4a78c2247135bf1a96dcac0bd009.zip
Implement niri msg output
Diffstat (limited to 'niri-ipc')
-rw-r--r--niri-ipc/src/lib.rs153
1 files changed, 153 insertions, 0 deletions
diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs
index 74d04aa0..c721ac9b 100644
--- a/niri-ipc/src/lib.rs
+++ b/niri-ipc/src/lib.rs
@@ -20,6 +20,17 @@ pub enum Request {
FocusedWindow,
/// Perform an action.
Action(Action),
+ /// Change output configuration temporarily.
+ ///
+ /// The configuration is changed temporarily and not saved into the config file. If the output
+ /// configuration subsequently changes in the config file, these temporary changes will be
+ /// forgotten.
+ Output {
+ /// Output name.
+ output: String,
+ /// Configuration to apply.
+ action: OutputAction,
+ },
/// Respond with an error (for testing error handling).
ReturnError,
}
@@ -245,6 +256,103 @@ pub enum LayoutSwitchTarget {
Prev,
}
+/// Output actions that niri can perform.
+// Variants in this enum should match the spelling of the ones in niri-config. Most thigs from
+// niri-config should be present here.
+#[derive(Serialize, Deserialize, Debug, Clone)]
+#[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 OutputAction {
+ /// Turn off the output.
+ Off,
+ /// Turn on the output.
+ On,
+ /// Set the output mode.
+ Mode {
+ /// Mode to set, or "auto" for automatic selection.
+ ///
+ /// Run `niri msg outputs` to see the avaliable modes.
+ #[cfg_attr(feature = "clap", arg())]
+ mode: ModeToSet,
+ },
+ /// Set the output scale.
+ Scale {
+ /// Scale factor to set.
+ #[cfg_attr(feature = "clap", arg())]
+ scale: f64,
+ },
+ /// Set the output transform.
+ Transform {
+ /// Transform to set, counter-clockwise.
+ #[cfg_attr(feature = "clap", arg())]
+ transform: Transform,
+ },
+ /// Set the output position.
+ Position {
+ /// Position to set, or "auto" for automatic selection.
+ #[cfg_attr(feature = "clap", command(subcommand))]
+ position: PositionToSet,
+ },
+ /// Toggle variable refresh rate.
+ Vrr {
+ /// Whether to enable variable refresh rate.
+ #[cfg_attr(
+ feature = "clap",
+ arg(
+ value_name = "ON|OFF",
+ action = clap::ArgAction::Set,
+ value_parser = clap::builder::BoolishValueParser::new(),
+ ),
+ )]
+ enable: bool,
+ },
+}
+
+/// Output mode to set.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+pub enum ModeToSet {
+ /// Niri will pick the mode automatically.
+ Automatic,
+ /// Specific mode.
+ Specific(ConfiguredMode),
+}
+
+/// Output mode as set in the config file.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+pub struct ConfiguredMode {
+ /// Width in physical pixels.
+ pub width: u16,
+ /// Height in physical pixels.
+ pub height: u16,
+ /// Refresh rate.
+ pub refresh: Option<f64>,
+}
+
+/// Output position to set.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+#[cfg_attr(feature = "clap", derive(clap::Subcommand))]
+#[cfg_attr(feature = "clap", command(subcommand_value_name = "POSITION"))]
+#[cfg_attr(feature = "clap", command(subcommand_help_heading = "Position Values"))]
+pub enum PositionToSet {
+ /// Position the output automatically.
+ #[cfg_attr(feature = "clap", command(name = "auto"))]
+ Automatic,
+ /// Set a specific position.
+ #[cfg_attr(feature = "clap", command(name = "set"))]
+ Specific(ConfiguredPosition),
+}
+
+/// Output position as set in the config file.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq)]
+#[cfg_attr(feature = "clap", derive(clap::Args))]
+pub struct ConfiguredPosition {
+ /// Logical X position.
+ pub x: i32,
+ /// Logical Y position.
+ pub y: i32,
+}
+
/// Connected output.
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Output {
@@ -304,6 +412,7 @@ pub struct LogicalOutput {
/// Output transform, which goes counter-clockwise.
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
+#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum Transform {
/// Untransformed.
Normal,
@@ -319,10 +428,13 @@ pub enum Transform {
/// Flipped horizontally.
Flipped,
/// Rotated by 90° and flipped horizontally.
+ #[cfg_attr(feature = "clap", value(name("flipped-90")))]
Flipped90,
/// Flipped vertically.
+ #[cfg_attr(feature = "clap", value(name("flipped-180")))]
Flipped180,
/// Rotated by 270° and flipped horizontally.
+ #[cfg_attr(feature = "clap", value(name("flipped-270")))]
Flipped270,
}
@@ -407,3 +519,44 @@ impl FromStr for Transform {
}
}
}
+
+impl FromStr for ModeToSet {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ if s.eq_ignore_ascii_case("auto") {
+ return Ok(Self::Automatic);
+ }
+
+ let mode = s.parse()?;
+ Ok(Self::Specific(mode))
+ }
+}
+
+impl FromStr for ConfiguredMode {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let Some((width, rest)) = s.split_once('x') else {
+ return Err("no 'x' separator found");
+ };
+
+ let (height, refresh) = match rest.split_once('@') {
+ Some((height, refresh)) => (height, Some(refresh)),
+ None => (rest, None),
+ };
+
+ let width = width.parse().map_err(|_| "error parsing width")?;
+ let height = height.parse().map_err(|_| "error parsing height")?;
+ let refresh = refresh
+ .map(str::parse)
+ .transpose()
+ .map_err(|_| "error parsing refresh rate")?;
+
+ Ok(Self {
+ width,
+ height,
+ refresh,
+ })
+ }
+}