2019-12-09 15:10:53 +01:00
|
|
|
use std::env::var;
|
|
|
|
use std::fs::remove_file;
|
2019-12-08 10:07:39 +01:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
2019-12-10 18:57:46 +01:00
|
|
|
use clap::{crate_version, load_yaml, App};
|
2019-12-08 10:07:39 +01:00
|
|
|
use swayipc::reply::Event::Window;
|
|
|
|
use swayipc::reply::WindowChange;
|
2019-12-09 13:39:03 +01:00
|
|
|
use swayipc::{Connection, EventType};
|
2019-12-08 10:07:39 +01:00
|
|
|
|
|
|
|
type Res<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
|
|
|
|
2019-12-09 13:39:03 +01:00
|
|
|
fn get_current_focused_id() -> Res<i64> {
|
|
|
|
Connection::new()?
|
|
|
|
.get_tree()?
|
2019-12-08 10:07:39 +01:00
|
|
|
.find_focused_as_ref(|n| n.focused)
|
2019-12-09 13:39:03 +01:00
|
|
|
.map(|n| n.id)
|
|
|
|
.ok_or_else(|| Err("Failed to get current Focused ID").unwrap())
|
2019-12-08 10:07:39 +01:00
|
|
|
}
|
|
|
|
|
2019-12-09 15:10:53 +01:00
|
|
|
fn handle_signal(last_focused: &Arc<Mutex<i64>>) -> Res<()> {
|
|
|
|
Connection::new()?.run_command(format!("[con_id={}] focus", last_focused.lock().unwrap()))?;
|
|
|
|
Ok(())
|
2019-12-09 13:39:03 +01:00
|
|
|
}
|
|
|
|
|
2019-12-09 15:10:53 +01:00
|
|
|
fn unbind_key() -> Res<()> {
|
2020-01-20 08:43:12 +01:00
|
|
|
let yml = load_yaml!("args.yml");
|
|
|
|
let args = App::from_yaml(yml).version(crate_version!()).get_matches();
|
|
|
|
let key_combo = args.value_of("combo").unwrap_or("Mod1+Tab");
|
|
|
|
|
2019-12-09 15:10:53 +01:00
|
|
|
let pid_file = format!(
|
|
|
|
"{}/sway-alttab.pid",
|
|
|
|
var("XDG_RUNTIME_DIR").unwrap_or("/tmp".to_string())
|
|
|
|
);
|
|
|
|
Connection::new()?.run_command(format!(
|
2020-01-20 08:43:12 +01:00
|
|
|
"unbindsym {} exec pkill -USR1 -F {}",
|
|
|
|
key_combo, pid_file
|
2019-12-09 15:10:53 +01:00
|
|
|
))?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn bind_key() -> Res<()> {
|
2019-12-10 18:57:46 +01:00
|
|
|
let yml = load_yaml!("args.yml");
|
|
|
|
let args = App::from_yaml(yml).version(crate_version!()).get_matches();
|
|
|
|
let key_combo = args.value_of("combo").unwrap_or("Mod1+Tab");
|
|
|
|
|
2019-12-09 15:10:53 +01:00
|
|
|
let pid_file = format!(
|
|
|
|
"{}/sway-alttab.pid",
|
|
|
|
var("XDG_RUNTIME_DIR").unwrap_or("/tmp".to_string())
|
|
|
|
);
|
2019-12-10 18:57:46 +01:00
|
|
|
|
|
|
|
Connection::new()?.run_command(format!(
|
|
|
|
"bindsym {} exec pkill -USR1 -F {}",
|
|
|
|
key_combo, pid_file
|
|
|
|
))?;
|
2019-12-09 15:10:53 +01:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn start_daemon() -> Res<()> {
|
|
|
|
let dir = var("XDG_RUNTIME_DIR").unwrap_or("/tmp".to_string());
|
|
|
|
|
|
|
|
unsafe { signal_hook::register(signal_hook::SIGTERM, cleanup)? };
|
|
|
|
unsafe { signal_hook::register(signal_hook::SIGINT, cleanup)? };
|
|
|
|
|
|
|
|
Ok(daemonize::Daemonize::new()
|
|
|
|
.pid_file(format!("{}/sway-alttab.pid", dir))
|
|
|
|
.chown_pid_file(true)
|
|
|
|
.working_directory(dir)
|
|
|
|
.start()?)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cleanup() {
|
|
|
|
let dir = var("XDG_RUNTIME_DIR").unwrap_or("/tmp".to_string());
|
|
|
|
remove_file(format!("{}/sway-alttab.pid", dir)).unwrap();
|
|
|
|
unbind_key().unwrap();
|
|
|
|
println!("Exiting sway-alttab");
|
2019-12-08 10:07:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Res<()> {
|
2019-12-09 13:39:03 +01:00
|
|
|
let last_focus = Arc::new(Mutex::new(0));
|
|
|
|
let mut cur_focus = get_current_focused_id()?;
|
|
|
|
let clone = Arc::clone(&last_focus);
|
|
|
|
|
2019-12-09 15:10:53 +01:00
|
|
|
unsafe {
|
|
|
|
signal_hook::register(signal_hook::SIGUSR1, move || {
|
|
|
|
handle_signal(&clone).unwrap();
|
|
|
|
})?
|
|
|
|
};
|
|
|
|
|
|
|
|
start_daemon()?;
|
|
|
|
|
|
|
|
bind_key()?;
|
|
|
|
|
|
|
|
let subs = [EventType::Window];
|
|
|
|
let mut events = Connection::new()?.subscribe(&subs)?;
|
2019-12-09 13:39:03 +01:00
|
|
|
|
|
|
|
loop {
|
|
|
|
let event = events.next();
|
|
|
|
if let Some(Ok(Window(ev))) = event {
|
|
|
|
if ev.change == WindowChange::Focus {
|
|
|
|
let mut last = last_focus.lock().unwrap();
|
|
|
|
*last = cur_focus;
|
|
|
|
cur_focus = ev.container.id;
|
2019-12-08 10:07:39 +01:00
|
|
|
}
|
2020-11-04 19:55:46 +01:00
|
|
|
} else {
|
|
|
|
cleanup();
|
2019-12-08 10:07:39 +01:00
|
|
|
}
|
2019-12-09 13:39:03 +01:00
|
|
|
}
|
2019-12-08 10:07:39 +01:00
|
|
|
}
|