From 7f3405dcf06fccaea8a4cb5bb6867896a1a9fd3a Mon Sep 17 00:00:00 2001 From: Joakim Hulthe Date: Wed, 20 Nov 2024 22:25:35 +0100 Subject: [PATCH] Add keyboard layout command --- Cargo.lock | 22 ++++++++++++---------- Cargo.toml | 2 +- src/hyprland.rs | 3 +++ src/main.rs | 9 ++++++--- src/niri.rs | 48 +++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8825390..ef9e2df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,8 +235,9 @@ dependencies = [ [[package]] name = "niri-ipc" -version = "0.1.6" -source = "git+https://github.com/YaLTeR/niri.git?rev=d96a66ddff1a6b88dbe3e23b049f7075533b216f#d96a66ddff1a6b88dbe3e23b049f7075533b216f" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa541cad3b426dd1ab72765ba71d1c20a1b8a17d80c692b099a759074f74242" dependencies = [ "serde", "serde_json", @@ -301,18 +302,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -321,11 +322,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -347,9 +349,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.65" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4cda6be..6290659 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,6 @@ clap = { version = "4.5.4", features = ["derive"] } once_cell = "1.19.0" serde = { version = "1.0.202", features = ["derive"] } serde_json = "1.0.117" -niri-ipc = { version = "0.1.6", git = "https://github.com/YaLTeR/niri.git", rev = "d96a66ddff1a6b88dbe3e23b049f7075533b216f" } +niri-ipc = "0.1.10" eyre = "0.6.12" color-eyre = "0.6.3" diff --git a/src/hyprland.rs b/src/hyprland.rs index 59ea16d..1e29524 100644 --- a/src/hyprland.rs +++ b/src/hyprland.rs @@ -29,6 +29,9 @@ pub fn handle(command: WmCommand) -> eyre::Result<()> { WmCommand::KeyboardLayout { .. } => { bail!("not supported on Hyprland"); } + WmCommand::NextKeyboardLayout { .. } => { + bail!("not supported on Hyprland"); + } } Ok(()) diff --git a/src/main.rs b/src/main.rs index 7d27d77..b78443f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,12 +39,15 @@ enum WmCommand { /// Get the list of workspaces Workspaces {}, + /// Get the current keyboard layout KeyboardLayout { - /// Switch to the next keyboard layout - #[clap(long)] - next: bool, + #[clap(short, long)] + short: bool, }, + /// Switch to the next keyboard layout + NextKeyboardLayout {}, + SwitchWorkspace { to: u8, }, diff --git a/src/niri.rs b/src/niri.rs index bceb8cb..e49341d 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::{eww, WmCommand, Workspace}; use eyre::{bail, eyre, Context}; -use niri_ipc::{Socket, WorkspaceReferenceArg}; +use niri_ipc::{socket::Socket, WorkspaceReferenceArg}; pub fn handle(command: WmCommand) -> eyre::Result<()> { match command { @@ -16,12 +16,25 @@ pub fn handle(command: WmCommand) -> eyre::Result<()> { niri_ipc::Action::FocusWorkspace { reference: WorkspaceReferenceArg::Index(to), }, - ))? + )) + .map(|(reply, _)| reply)? .map_err(|e| eyre!("niri error: {e}"))?; eww::update_var("workspaces", &get_workspaces()?)?; } - WmCommand::KeyboardLayout { next: _ } => bail!("Not implemented"), + WmCommand::NextKeyboardLayout {} => { + let _reply = open_socket()? + .send(niri_ipc::Request::Action(niri_ipc::Action::SwitchLayout { + layout: niri_ipc::LayoutSwitchTarget::Next, + })) + .map(|(reply, _)| reply)? + .map_err(|e| eyre!("niri error: {e}"))?; + + eww::update_var("keyboard_layout", &get_keyboard_layout(true)?)?; + } + WmCommand::KeyboardLayout { short } => { + println!("{}", get_keyboard_layout(short)?); + } } Ok(()) @@ -29,7 +42,31 @@ pub fn handle(command: WmCommand) -> eyre::Result<()> { /// Open a socket to niri fn open_socket() -> eyre::Result { - niri_ipc::Socket::connect().wrap_err("Failed to open niri socket") + Socket::connect().wrap_err("Failed to open niri socket") +} + +/// Get a JSON-string containing info about workspaces +fn get_keyboard_layout(short: bool) -> eyre::Result { + let reply = open_socket()? + .send(niri_ipc::Request::KeyboardLayouts) + .map(|(reply, _)| reply)? + .map_err(|e| eyre!("niri error: {e}"))?; + + let niri_ipc::Response::KeyboardLayouts(layouts) = reply else { + bail!("Unexpected response from niri: {reply:?}"); + }; + + let current_layout = &layouts.names[usize::from(layouts.current_idx)]; + + Ok(if short { + current_layout + .chars() + .take(3) + .map(|c| c.to_ascii_uppercase()) + .collect() + } else { + current_layout.to_string() + }) } /// Get a JSON-string containing info about workspaces @@ -37,7 +74,8 @@ fn get_workspaces() -> eyre::Result { let socket = open_socket()?; let reply = socket - .send(niri_ipc::Request::Workspaces)? + .send(niri_ipc::Request::Workspaces) + .map(|(reply, _)| reply)? .map_err(|e| eyre!("niri error: {e}"))?; let niri_ipc::Response::Workspaces(workspaces) = reply else {