diff options
| author | rustysec <russ@infocyte.com> | 2024-05-22 16:16:03 -0700 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-05-26 21:29:22 +0400 |
| commit | ae7fb4c4f405aa0ff49930040d414581a812d938 (patch) | |
| tree | ed87cf6c57a3332f4077fae0dd49a0d0d2f97662 /src/ipc | |
| parent | 4746a0da7dffde6befcb3c80609fa3d31bffc29c (diff) | |
| download | niri-ae7fb4c4f405aa0ff49930040d414581a812d938.tar.gz niri-ae7fb4c4f405aa0ff49930040d414581a812d938.tar.bz2 niri-ae7fb4c4f405aa0ff49930040d414581a812d938.zip | |
Add niri msg focused-output
Diffstat (limited to 'src/ipc')
| -rw-r--r-- | src/ipc/client.rs | 203 | ||||
| -rw-r--r-- | src/ipc/server.rs | 25 |
2 files changed, 138 insertions, 90 deletions
diff --git a/src/ipc/client.rs b/src/ipc/client.rs index f97cc80a..3192925f 100644 --- a/src/ipc/client.rs +++ b/src/ipc/client.rs @@ -12,6 +12,7 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> { Msg::Version => Request::Version, Msg::Outputs => Request::Outputs, Msg::FocusedWindow => Request::FocusedWindow, + Msg::FocusedOutput => Request::FocusedOutput, Msg::Action { action } => Request::Action(action.clone()), Msg::Output { output, action } => Request::Output { output: output.clone(), @@ -117,96 +118,7 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> { outputs.sort_unstable_by(|a, b| a.0.cmp(&b.0)); for (connector, output) in outputs.into_iter() { - let Output { - name, - make, - model, - physical_size, - modes, - current_mode, - vrr_supported, - vrr_enabled, - logical, - } = output; - - println!(r#"Output "{connector}" ({make} - {model} - {name})"#); - - if let Some(current) = current_mode { - let mode = *modes - .get(current) - .context("invalid response: current mode does not exist")?; - let Mode { - width, - height, - refresh_rate, - is_preferred, - } = mode; - let refresh = refresh_rate as f64 / 1000.; - let preferred = if is_preferred { " (preferred)" } else { "" }; - println!(" Current mode: {width}x{height} @ {refresh:.3} Hz{preferred}"); - } else { - println!(" Disabled"); - } - - if vrr_supported { - let enabled = if vrr_enabled { "enabled" } else { "disabled" }; - println!(" Variable refresh rate: supported, {enabled}"); - } else { - println!(" Variable refresh rate: not supported"); - } - - if let Some((width, height)) = physical_size { - println!(" Physical size: {width}x{height} mm"); - } else { - println!(" Physical size: unknown"); - } - - if let Some(logical) = logical { - let LogicalOutput { - x, - y, - width, - height, - scale, - transform, - } = logical; - println!(" Logical position: {x}, {y}"); - println!(" Logical size: {width}x{height}"); - println!(" Scale: {scale}"); - - let transform = match transform { - Transform::Normal => "normal", - Transform::_90 => "90° counter-clockwise", - Transform::_180 => "180°", - Transform::_270 => "270° counter-clockwise", - Transform::Flipped => "flipped horizontally", - Transform::Flipped90 => "90° counter-clockwise, flipped horizontally", - Transform::Flipped180 => "flipped vertically", - Transform::Flipped270 => "270° counter-clockwise, flipped horizontally", - }; - println!(" Transform: {transform}"); - } - - println!(" Available modes:"); - for (idx, mode) in modes.into_iter().enumerate() { - let Mode { - width, - height, - refresh_rate, - is_preferred, - } = mode; - let refresh = refresh_rate as f64 / 1000.; - - let is_current = Some(idx) == current_mode; - let qualifier = match (is_current, is_preferred) { - (true, true) => " (current, preferred)", - (true, false) => " (current)", - (false, true) => " (preferred)", - (false, false) => "", - }; - - println!(" {width}x{height}@{refresh:.3}{qualifier}"); - } + print_output(connector, output)?; println!(); } } @@ -239,6 +151,23 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> { println!("No window is focused."); } } + Msg::FocusedOutput => { + let Response::FocusedOutput(output) = response else { + bail!("unexpected response: expected FocusedOutput, got {response:?}"); + }; + + if json { + let output = serde_json::to_string(&output).context("error formatting response")?; + println!("{output}"); + return Ok(()); + } + + if let Some(output) = output { + print_output(output.name.clone(), output)?; + } else { + println!("No output is focused."); + } + } Msg::Action { .. } => { let Response::Handled = response else { bail!("unexpected response: expected Handled, got {response:?}"); @@ -313,3 +242,97 @@ pub fn handle_msg(msg: Msg, json: bool) -> anyhow::Result<()> { Ok(()) } + +fn print_output(connector: String, output: Output) -> anyhow::Result<()> { + let Output { + name, + make, + model, + physical_size, + modes, + current_mode, + vrr_supported, + vrr_enabled, + logical, + } = output; + + println!(r#"Output "{connector}" ({make} - {model} - {name})"#); + + if let Some(current) = current_mode { + let mode = *modes + .get(current) + .context("invalid response: current mode does not exist")?; + let Mode { + width, + height, + refresh_rate, + is_preferred, + } = mode; + let refresh = refresh_rate as f64 / 1000.; + let preferred = if is_preferred { " (preferred)" } else { "" }; + println!(" Current mode: {width}x{height} @ {refresh:.3} Hz{preferred}"); + } else { + println!(" Disabled"); + } + + if vrr_supported { + let enabled = if vrr_enabled { "enabled" } else { "disabled" }; + println!(" Variable refresh rate: supported, {enabled}"); + } else { + println!(" Variable refresh rate: not supported"); + } + + if let Some((width, height)) = physical_size { + println!(" Physical size: {width}x{height} mm"); + } else { + println!(" Physical size: unknown"); + } + + if let Some(logical) = logical { + let LogicalOutput { + x, + y, + width, + height, + scale, + transform, + } = logical; + println!(" Logical position: {x}, {y}"); + println!(" Logical size: {width}x{height}"); + println!(" Scale: {scale}"); + + let transform = match transform { + Transform::Normal => "normal", + Transform::_90 => "90° counter-clockwise", + Transform::_180 => "180°", + Transform::_270 => "270° counter-clockwise", + Transform::Flipped => "flipped horizontally", + Transform::Flipped90 => "90° counter-clockwise, flipped horizontally", + Transform::Flipped180 => "flipped vertically", + Transform::Flipped270 => "270° counter-clockwise, flipped horizontally", + }; + println!(" Transform: {transform}"); + } + + println!(" Available modes:"); + for (idx, mode) in modes.into_iter().enumerate() { + let Mode { + width, + height, + refresh_rate, + is_preferred, + } = mode; + let refresh = refresh_rate as f64 / 1000.; + + let is_current = Some(idx) == current_mode; + let qualifier = match (is_current, is_preferred) { + (true, true) => " (current, preferred)", + (true, false) => " (current)", + (false, true) => " (preferred)", + (false, false) => "", + }; + + println!(" {width}x{height}@{refresh:.3}{qualifier}"); + } + Ok(()) +} diff --git a/src/ipc/server.rs b/src/ipc/server.rs index 26958a7f..7987ca5c 100644 --- a/src/ipc/server.rs +++ b/src/ipc/server.rs @@ -208,6 +208,31 @@ async fn process(ctx: &ClientCtx, request: Request) -> Reply { let workspaces = result.map_err(|_| String::from("error getting workspace info"))?; Response::Workspaces(workspaces) } + Request::FocusedOutput => { + let (tx, rx) = async_channel::bounded(1); + ctx.event_loop.insert_idle(move |state| { + let active_output = state + .niri + .layout + .active_output() + .map(|output| output.name()); + + let output = active_output.and_then(|active_output| { + state + .backend + .ipc_outputs() + .lock() + .unwrap() + .get(&active_output) + .cloned() + }); + + let _ = tx.send_blocking(output); + }); + let result = rx.recv().await; + let output = result.map_err(|_| String::from("error getting active output info"))?; + Response::FocusedOutput(output) + } }; Ok(response) |
