Add timeout to next/prev window sequences (v2)

timeout_old
Taeyeon Mori 3 years ago
parent f907833d78
commit 4c61d6e76a
  1. 21
      src/cmds.rs
  2. 21
      src/config.rs
  3. 17
      src/demon.rs

@ -27,7 +27,10 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::atomic; use std::sync::atomic;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex;
use std::sync::RwLock; use std::sync::RwLock;
use std::time::Duration;
use std::time::Instant;
use swayipc as s; use swayipc as s;
pub fn run_sway_command_1(cmd: &str) { pub fn run_sway_command_1(cmd: &str) {
@ -225,6 +228,7 @@ impl SwayrCommand {
pub struct ExecSwayrCmdArgs<'a> { pub struct ExecSwayrCmdArgs<'a> {
pub cmd: &'a SwayrCommand, pub cmd: &'a SwayrCommand,
pub extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>, pub extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
pub sequence_timeout: Option<Duration>,
} }
impl DisplayFormat for SwayrCommand { impl DisplayFormat for SwayrCommand {
@ -246,6 +250,9 @@ fn always_true(_x: &t::DisplayNode) -> bool {
static IN_NEXT_PREV_WINDOW_SEQ: atomic::AtomicBool = static IN_NEXT_PREV_WINDOW_SEQ: atomic::AtomicBool =
atomic::AtomicBool::new(false); atomic::AtomicBool::new(false);
lazy_static! {
static ref NEXT_PREV_WINDOW_SEQ_TIMEOUT: Mutex<Option<Instant>> = Mutex::new(None);
}
pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
let props = args.extra_props; let props = args.extra_props;
@ -253,14 +260,25 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
if args.cmd.is_prev_next_window_variant() { if args.cmd.is_prev_next_window_variant() {
let before = let before =
IN_NEXT_PREV_WINDOW_SEQ.swap(true, atomic::Ordering::SeqCst); IN_NEXT_PREV_WINDOW_SEQ.swap(true, atomic::Ordering::SeqCst);
if !before { if !before
|| NEXT_PREV_WINDOW_SEQ_TIMEOUT
.lock()
.unwrap()
.map_or(false, |i| Instant::now() > i)
{
log::info!("Starting new next/prev sequence");
let mut map = props.write().unwrap(); let mut map = props.write().unwrap();
for val in map.values_mut() { for val in map.values_mut() {
val.last_focus_tick_for_next_prev_seq = val.last_focus_tick; val.last_focus_tick_for_next_prev_seq = val.last_focus_tick;
} }
} }
if let Some(timeout) = args.sequence_timeout {
*NEXT_PREV_WINDOW_SEQ_TIMEOUT.lock().unwrap() =
Some(Instant::now() + timeout);
}
} else { } else {
IN_NEXT_PREV_WINDOW_SEQ.store(false, atomic::Ordering::SeqCst); IN_NEXT_PREV_WINDOW_SEQ.store(false, atomic::Ordering::SeqCst);
*NEXT_PREV_WINDOW_SEQ_TIMEOUT.lock().unwrap() = None;
} }
match args.cmd { match args.cmd {
@ -473,6 +491,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
exec_swayr_cmd(ExecSwayrCmdArgs { exec_swayr_cmd(ExecSwayrCmdArgs {
cmd: c, cmd: c,
extra_props: props, extra_props: props,
sequence_timeout: args.sequence_timeout,
}); });
} }
} }

@ -28,6 +28,7 @@ pub struct Config {
menu: Option<Menu>, menu: Option<Menu>,
format: Option<Format>, format: Option<Format>,
layout: Option<Layout>, layout: Option<Layout>,
sequence: Option<Sequence>,
} }
fn tilde_expand_file_names(file_names: Vec<String>) -> Vec<String> { fn tilde_expand_file_names(file_names: Vec<String>) -> Vec<String> {
@ -159,6 +160,14 @@ impl Config {
.or_else(|| Layout::default().auto_tile_min_window_width_per_output_width_as_map()) .or_else(|| Layout::default().auto_tile_min_window_width_per_output_width_as_map())
.expect("No layout.auto_tile_min_window_width_per_output_width defined.") .expect("No layout.auto_tile_min_window_width_per_output_width defined.")
} }
pub fn get_sequence_timeout(&self) -> u64 {
self.sequence
.as_ref()
.and_then(|s| s.timeout)
.or_else(|| Sequence::default().timeout)
.expect("No sequence.timeout defined")
}
} }
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
@ -187,6 +196,11 @@ pub struct Layout {
auto_tile_min_window_width_per_output_width: Option<Vec<[i32; 2]>>, auto_tile_min_window_width_per_output_width: Option<Vec<[i32; 2]>>,
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Sequence {
timeout: Option<u64>,
}
impl Layout { impl Layout {
pub fn auto_tile_min_window_width_per_output_width_as_map( pub fn auto_tile_min_window_width_per_output_width_as_map(
&self, &self,
@ -294,12 +308,19 @@ impl Default for Layout {
} }
} }
impl Default for Sequence {
fn default() -> Self {
Sequence { timeout: Some(0) }
}
}
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Config { Config {
menu: Some(Menu::default()), menu: Some(Menu::default()),
format: Some(Format::default()), format: Some(Format::default()),
layout: Some(Layout::default()), layout: Some(Layout::default()),
sequence: Some(Sequence::default()),
} }
} }
} }

@ -26,6 +26,7 @@ use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::thread; use std::thread;
use std::time::Duration;
use swayipc as s; use swayipc as s;
pub fn run_demon() { pub fn run_demon() {
@ -40,7 +41,7 @@ pub fn run_demon() {
monitor_sway_events(extra_props_for_ev_handler, config_for_ev_handler); monitor_sway_events(extra_props_for_ev_handler, config_for_ev_handler);
}); });
serve_client_requests(extra_props); serve_client_requests(extra_props, config);
} }
fn connect_and_subscribe() -> s::Fallible<s::EventStream> { fn connect_and_subscribe() -> s::Fallible<s::EventStream> {
@ -230,18 +231,28 @@ fn remove_extra_props(
pub fn serve_client_requests( pub fn serve_client_requests(
extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
config: config::Config,
) { ) {
match std::fs::remove_file(util::get_swayr_socket_path()) { match std::fs::remove_file(util::get_swayr_socket_path()) {
Ok(()) => log::debug!("Deleted stale socket from previous run."), Ok(()) => log::debug!("Deleted stale socket from previous run."),
Err(e) => log::error!("Could not delete socket:\n{:?}", e), Err(e) => log::error!("Could not delete socket:\n{:?}", e),
} }
let timeout = match config.get_sequence_timeout() {
0 => None,
secs => Some(Duration::from_secs(secs)),
};
match UnixListener::bind(util::get_swayr_socket_path()) { match UnixListener::bind(util::get_swayr_socket_path()) {
Ok(listener) => { Ok(listener) => {
for stream in listener.incoming() { for stream in listener.incoming() {
match stream { match stream {
Ok(stream) => { Ok(stream) => {
handle_client_request(stream, extra_props.clone()); handle_client_request(
stream,
extra_props.clone(),
timeout,
);
} }
Err(err) => { Err(err) => {
log::error!("Error handling client request: {}", err); log::error!("Error handling client request: {}", err);
@ -259,6 +270,7 @@ pub fn serve_client_requests(
fn handle_client_request( fn handle_client_request(
mut stream: UnixStream, mut stream: UnixStream,
extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>, extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
sequence_timeout: Option<Duration>,
) { ) {
let mut cmd_str = String::new(); let mut cmd_str = String::new();
if stream.read_to_string(&mut cmd_str).is_ok() { if stream.read_to_string(&mut cmd_str).is_ok() {
@ -266,6 +278,7 @@ fn handle_client_request(
cmds::exec_swayr_cmd(cmds::ExecSwayrCmdArgs { cmds::exec_swayr_cmd(cmds::ExecSwayrCmdArgs {
cmd: &cmd, cmd: &cmd,
extra_props, extra_props,
sequence_timeout,
}); });
} else { } else {
log::error!( log::error!(

Loading…
Cancel
Save