Compare commits

...

3 Commits

  1. 26
      src/cmds.rs
  2. 29
      src/config.rs
  3. 24
      src/demon.rs

@ -27,7 +27,10 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::atomic;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::RwLock;
use std::time::Duration;
use std::time::Instant;
use swayipc as s;
pub fn run_sway_command_1(cmd: &str) {
@ -161,6 +164,8 @@ pub enum SwayrCommand {
#[clap(subcommand)]
windows: ConsiderWindows,
},
/// End current next-prev sequence without doing anything else
EndSequence,
/// Move the currently focused window or container to the selected
/// workspace.
MoveFocusedToWorkspace,
@ -223,6 +228,7 @@ impl SwayrCommand {
pub struct ExecSwayrCmdArgs<'a> {
pub cmd: &'a SwayrCommand,
pub extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
pub sequence_timeout: Option<Duration>,
}
impl DisplayFormat for SwayrCommand {
@ -244,6 +250,9 @@ fn always_true(_x: &t::DisplayNode) -> bool {
static IN_NEXT_PREV_WINDOW_SEQ: atomic::AtomicBool =
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) {
let props = args.extra_props;
@ -251,14 +260,25 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
if args.cmd.is_prev_next_window_variant() {
let before =
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();
for val in map.values_mut() {
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 {
IN_NEXT_PREV_WINDOW_SEQ.store(false, atomic::Ordering::SeqCst);
*NEXT_PREV_WINDOW_SEQ_TIMEOUT.lock().unwrap() = None;
}
match args.cmd {
@ -391,6 +411,9 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
&*props.read().unwrap(),
)
}
SwayrCommand::EndSequence => {
// IN_NEXT_PREV_WINDOW_SEQ set to false above
}
SwayrCommand::TileWorkspace { floating } => {
tile_current_workspace(floating, false)
}
@ -468,6 +491,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
exec_swayr_cmd(ExecSwayrCmdArgs {
cmd: c,
extra_props: props,
sequence_timeout: args.sequence_timeout,
});
}
}

@ -23,11 +23,12 @@ use std::fs::OpenOptions;
use std::io::{Read, Write};
use std::path::Path;
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Config {
menu: Option<Menu>,
format: Option<Format>,
layout: Option<Layout>,
sequence: Option<Sequence>,
}
fn tilde_expand_file_names(file_names: Vec<String>) -> Vec<String> {
@ -159,15 +160,23 @@ impl Config {
.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.")
}
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)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Menu {
executable: Option<String>,
args: Option<Vec<String>>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Format {
output_format: Option<String>,
workspace_format: Option<String>,
@ -181,12 +190,17 @@ pub struct Format {
fallback_icon: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Layout {
auto_tile: Option<bool>,
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 {
pub fn auto_tile_min_window_width_per_output_width_as_map(
&self,
@ -294,12 +308,19 @@ impl Default for Layout {
}
}
impl Default for Sequence {
fn default() -> Self {
Sequence { timeout: Some(0) }
}
}
impl Default for Config {
fn default() -> Self {
Config {
menu: Some(Menu::default()),
format: Some(Format::default()),
layout: Some(Layout::default()),
sequence: Some(Sequence::default()),
}
}
}

@ -26,18 +26,22 @@ use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::Arc;
use std::sync::RwLock;
use std::thread;
use std::time::Duration;
use swayipc as s;
pub fn run_demon() {
let config = config::load_config();
let extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>> =
Arc::new(RwLock::new(HashMap::new()));
let config_for_ev_handler = config.clone();
let extra_props_for_ev_handler = extra_props.clone();
thread::spawn(move || {
monitor_sway_events(extra_props_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> {
@ -50,8 +54,8 @@ fn connect_and_subscribe() -> s::Fallible<s::EventStream> {
pub fn monitor_sway_events(
extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
config: config::Config,
) {
let config = config::load_config();
let mut focus_counter = 0;
let mut resets = 0;
let max_resets = 10;
@ -227,18 +231,28 @@ fn remove_extra_props(
pub fn serve_client_requests(
extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
config: config::Config,
) {
match std::fs::remove_file(util::get_swayr_socket_path()) {
Ok(()) => log::debug!("Deleted stale socket from previous run."),
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()) {
Ok(listener) => {
for stream in listener.incoming() {
match stream {
Ok(stream) => {
handle_client_request(stream, extra_props.clone());
handle_client_request(
stream,
extra_props.clone(),
timeout,
);
}
Err(err) => {
log::error!("Error handling client request: {}", err);
@ -256,6 +270,7 @@ pub fn serve_client_requests(
fn handle_client_request(
mut stream: UnixStream,
extra_props: Arc<RwLock<HashMap<i64, t::ExtraProps>>>,
sequence_timeout: Option<Duration>,
) {
let mut cmd_str = String::new();
if stream.read_to_string(&mut cmd_str).is_ok() {
@ -263,6 +278,7 @@ fn handle_client_request(
cmds::exec_swayr_cmd(cmds::ExecSwayrCmdArgs {
cmd: &cmd,
extra_props,
sequence_timeout,
});
} else {
log::error!(

Loading…
Cancel
Save