diff --git a/src/bin/swayr.rs b/src/bin/swayr.rs index ed106a3..1e040c9 100644 --- a/src/bin/swayr.rs +++ b/src/bin/swayr.rs @@ -24,6 +24,8 @@ enum SwayrCommand { QuitWindow, /// Switch workspace with LRU display order SwitchWorkspace, + /// Select and execute a swaymsg command + ExecuteSwaymsgCommand, } fn main() { @@ -32,5 +34,6 @@ fn main() { SwayrCommand::SwitchWindow => client::switch_window(), SwayrCommand::QuitWindow => client::quit_window(), SwayrCommand::SwitchWorkspace => client::switch_workspace(), + SwayrCommand::ExecuteSwaymsgCommand => client::exec_swaymsg_command(), } } diff --git a/src/client.rs b/src/client.rs index d34bacc..5fb9ece 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,6 @@ use crate::con; use crate::util; +use std::fmt; pub fn switch_window() { let root = con::get_tree(); @@ -7,7 +8,7 @@ pub fn switch_window() { windows.sort(); if let Some(window) = con::select_window("Switch to window", &windows) { - util::swaymsg(vec![ + util::swaymsg(&[ format!("[con_id={}]", window.get_id()).as_str(), "focus", ]); @@ -22,7 +23,7 @@ pub fn switch_workspace() { if let Some(workspace) = con::select_workspace("Switch to workspace", &workspaces) { - util::swaymsg(vec!["workspace", "number", workspace.get_name()]); + util::swaymsg(&["workspace", "number", workspace.get_name()]); } } @@ -32,9 +33,123 @@ pub fn quit_window() { windows.sort_by(|a, b| a.cmp(b).reverse()); if let Some(window) = con::select_window("Quit window", &windows) { - util::swaymsg(vec![ + util::swaymsg(&[ format!("[con_id={}]", window.get_id()).as_str(), "kill", ]); } } + +fn get_swaymsg_commands<'a>() -> Vec> { + let mut cmds = vec![]; + cmds.push(vec!["exit"]); + cmds.push(vec!["floating", "toggle"]); + cmds.push(vec!["focus", "child"]); + cmds.push(vec!["focus", "parent"]); + + for b in &["none", "normal", "csd", "pixel"] { + cmds.push(vec!["border", b]); + } + + cmds.push(vec!["focus", "tiling"]); + cmds.push(vec!["focus", "floating"]); + cmds.push(vec!["focus", "mode_toggle"]); + + cmds.push(vec!["fullscreen", "toggle"]); + + for x in &["focus", "fullscreen", "open", "none", "visible"] { + cmds.push(vec!["inhibit_idle", x]) + } + + for l in &["default", "splith", "splitv", "stacking", "tiling"] { + cmds.push(vec!["layout", l]) + } + + cmds.push(vec!["reload"]); + + for e in &["enable", "disable"] { + cmds.push(vec!["shortcuts", "inhibitor", e]) + } + + cmds.push(vec!["sticky", "toggle"]); + + for x in &["yes", "no", "always"] { + cmds.push(vec!["focus_follows_mouse", x]) + } + + for x in &["smart", "urgent", "focus", "none"] { + cmds.push(vec!["focus_on_window_activation", x]) + } + + for x in &["yes", "no", "force", "workspace"] { + cmds.push(vec!["focus_wrapping", x]) + } + + for x in &[ + "none", + "vertical", + "horizontal", + "both", + "smart", + "smart_no_gaps", + ] { + cmds.push(vec!["hide_edge_borders", x]) + } + + cmds.push(vec!["kill"]); + + for x in &["on", "no_gaps", "off"] { + cmds.push(vec!["smart_borders", x]) + } + + for x in &["on", "off"] { + cmds.push(vec!["smart_gaps", x]) + } + + for x in &["output", "container", "none"] { + cmds.push(vec!["mouse_warping", x]) + } + + for x in &["smart", "ignore", "leave_fullscreen"] { + cmds.push(vec!["popup_during_fullscreen", x]) + } + + for x in &["yes", "no"] { + cmds.push(vec!["show_marks", x]); + cmds.push(vec!["workspace_auto_back_and_forth", x]); + } + + cmds.push(vec!["tiling_drag", "toggle"]); + + for x in &["left", "center", "right"] { + cmds.push(vec!["title_align", x]); + } + + for x in &["enable", "disable", "allow", "deny"] { + cmds.push(vec!["urgent", x]) + } + + cmds.sort(); + + cmds.iter() + .map(|v| SwaymsgCmd { cmd: v.to_vec() }) + .collect() +} + +struct SwaymsgCmd<'a> { + cmd: Vec<&'a str>, +} + +impl<'a> fmt::Display for SwaymsgCmd<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{}", self.cmd.join(" ")) + } +} + +pub fn exec_swaymsg_command() { + let cmds = get_swaymsg_commands(); + let cmd = util::wofi_select("Execute swaymsg command", &cmds); + if let Some(cmd) = cmd { + util::swaymsg(&cmd.cmd); + } +} diff --git a/src/con.rs b/src/con.rs index 7b55643..84b8dca 100644 --- a/src/con.rs +++ b/src/con.rs @@ -6,7 +6,7 @@ use std::fmt; use std::os::unix::net::UnixStream; pub fn get_tree() -> ipc::Node { - let output = util::swaymsg(vec!["-t", "get_tree"]); + let output = util::swaymsg(&["-t", "get_tree"]); let result = serde_json::from_str(output.as_str()); match result { diff --git a/src/ipc.rs b/src/ipc.rs index 0a2a247..b7c0dd6 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -225,12 +225,12 @@ pub enum WorkspaceEventType { pub enum ConEvent { WindowEvent { change: WindowEventType, - container: Node, + container: Box, }, WorkspaceEvent { change: WorkspaceEventType, - current: Node, - old: Node, + current: Box, + old: Box, }, } diff --git a/src/util.rs b/src/util.rs index c01f6a5..4fab3e2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -17,7 +17,7 @@ pub fn get_swayr_socket_path() -> String { ) } -pub fn swaymsg(args: Vec<&str>) -> String { +pub fn swaymsg(args: &[&str]) -> String { let mut cmd = proc::Command::new("swaymsg"); for a in args { cmd.arg(a);