From c63d10b58a6c53cb375459f3bf0741d28f6fb2dc Mon Sep 17 00:00:00 2001 From: Arne Beer Date: Fri, 29 Dec 2023 16:16:43 +0100 Subject: [PATCH] Add swap functionality --- CHANGELOG.md | 1 + src/args.rs | 4 ++++ src/main.rs | 10 ++++++++++ src/wm_i3.rs | 14 ++++++++++++++ 4 files changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d8a9c2..6349973 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - ReleaseDate +- Add the `--swap` flag to swap the currently active window with the selected window. ## [1.4.0] - 2023-01-22 - Modernize all dependencies diff --git a/src/args.rs b/src/args.rs index 70940e2..c1f7dc2 100644 --- a/src/args.rs +++ b/src/args.rs @@ -222,6 +222,10 @@ pub struct AppConfig { /// List of keys to exit application, sequences separator is space, key separator is '+', eg Control_L+g Shift_L+f #[arg(short, long, value_parser(parse_exit_keys))] pub exit_keys: Vec, + + /// If this flag is set, the currently active window will swap with the selected window. + #[arg(short, long)] + pub swap: bool, } pub fn parse_args() -> AppConfig { diff --git a/src/main.rs b/src/main.rs index 47a1bc3..f73af1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -296,6 +296,16 @@ fn main() -> Result<()> { info!("Found matching window, focusing"); if app_config.print_only { println!("0x{:x}", rw.desktop_window.x_window_id.unwrap_or(0)); + } else if app_config.swap { + let Some(active_window) = + desktop_windows.iter().find(|window| window.is_focused) + else { + warn!("There's no active window."); + closed = true; + continue; + }; + wm::swap_windows(active_window, rw.desktop_window) + .context("Couldn't swap windows")?; } else { wm::focus_window(rw.desktop_window).context("Couldn't focus window")?; } diff --git a/src/wm_i3.rs b/src/wm_i3.rs index b3dd125..0538304 100644 --- a/src/wm_i3.rs +++ b/src/wm_i3.rs @@ -121,3 +121,17 @@ pub fn focus_window(window: &DesktopWindow) -> Result<()> { info!("Sending to i3: {:?}", command); Ok(()) } + +/// Focus a specific `window`. +pub fn swap_windows(active_window: &DesktopWindow, window: &DesktopWindow) -> Result<()> { + let mut connection = I3Connection::connect().context("Couldn't acquire i3 connection")?; + let command_str = format!( + "[con_id=\"{}\"] swap with container con_id {}", + active_window.id, window.id + ); + let command = connection + .run_command(&command_str) + .context("Couldn't communicate with i3")?; + info!("Sending to i3: {:?}", command); + Ok(()) +}