William Barsse: 1 Add `seq_inhibit` flag to swayrd configuration 4 files changed, 87 insertions(+), 40 deletions(-)
Hi Tassilo, Thanks for sorting it out! And until next time ;-)
I'm looking forward to new contributions of yours. BTW, I'd be interested in getting some more feedback on the changes in the "next" branch which are mainly concerned with the switch-to-urgent-or-lru-window command and friends. If you use those, I'd be interested to hear if they still work satisfactory for you. Basically, they used to be simple toggles but now cycle a possibly longer list of windows, e.g., if more than one window has an urgency hint or you use `swayr switch-to-app-or-urgent-or-lru-window firefox` or something alike but you have more than one firefox window open. Bye, Tassilo
Bye, William
William Barsse <william.barsse@gmail.com> writes:
Hi Tassilo, I do use `switch-to-urgent-or-lru-window` so I'll pay attention to its behavior, though I just rely on it to jump to whatever window raised the most recent urgent signal (i.e. `bindsym $mod+period exec $swayr switch-to-urgent-or-lru-window`). This probably disqualifies me as a reliable source of feedback for that feature ;-) Best, William
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~tsdh/public-inbox/patches/33530/mbox | git am -3Learn more about email & git
The `seq_inhibit` flag toggles whether swayrd disables LRU updates during window cycling command sequences. When the flag is set to `false` (the default) windows are locked-in to the LRU as long as they remain focused long enough. When the flag is `true` any window cycling command is considered to start a sequence during which no LRU updates are performed. The sequence ends upon reception of any non-window-cycling-command (and the window with the focus at that point in time is immediately locked-in). --- README.md | 19 +++++++++++++ swayr/src/cmds.rs | 66 +++++++++++++++++++++------------------------ swayr/src/config.rs | 22 ++++++++++++++- swayr/src/daemon.rs | 20 +++++++++++--- 4 files changed, 87 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 82b6c24..a589ce1 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,7 @@ lockin_delay = 750 [misc] auto_nop_delay = 3000 +seq_inhibit = false ``` In the following, all sections are explained. @@ -534,6 +535,24 @@ A more elegant solution using a key release binding is discussed at the end of the [Usage](#swayr-usage) section. However, that requires a PR to sway which has not been merged so far. +The `seq_inhibit` boolean controls how `swayrd` behaves during a _sequence_ of +[window cycling commands](#swayr-cycling-commands). + +- When the setting is `true`, `swayrd` will inhibit updates to the window LRU + order while a _sequence_ of window cycling commands is in progress. LRU updates + are reactivated when the _sequence_ ends. A _sequence_ is considered to + have ended when any non-window-cycling-command is received by `swayrd` + (e.g. a `nop` command). + + Note: LRU update inhibition also applies to focus changes made outside of + `swayr`, for instance by using sway commands directly. + +- When the setting is `false` (the default): `swayrd` will handle focus events + the same way regardless of whether a window cycling sequence is in progress or + not. + +Note that the key release binding solution lends itself to using +`seq_inhibit=true`. ### <a id="swayr-version-changes">Version changes</a> diff --git a/swayr/src/cmds.rs b/swayr/src/cmds.rs index b830376..a5c8320 100644 --- a/swayr/src/cmds.rs +++ b/swayr/src/cmds.rs @@ -287,7 +287,7 @@ impl SwayrCommand { pub struct ExecSwayrCmdArgs<'a> { pub cmd: &'a SwayrCommand, - pub focus_data: Option<&'a FocusData>, + pub focus_data: &'a FocusData, } impl DisplayFormat for SwayrCommand { @@ -349,6 +349,7 @@ static SWITCH_TO_MATCHING_DATA: Lazy<Mutex<SwitchToMatchingData>> = pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { log::info!("Running SwayrCommand {:?}", args.cmd); + let fdata = args.focus_data; let mut last_command = LAST_COMMAND.lock().expect("Could not lock mutex"); let mut switch_to_matching_data = SWITCH_TO_MATCHING_DATA @@ -361,12 +362,10 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_matching_data.reset(true); } - let fdata = || args.focus_data.expect("No focus data"); - if args.cmd.is_prev_next_window_variant() { - fdata().send(FocusMessage::TickUpdateInhibit); - } else if last_command.is_prev_next_window_variant() { - fdata().send(FocusMessage::TickUpdateActivate); + fdata.send(FocusMessage::TickUpdateInhibit); + } else { + fdata.send(FocusMessage::TickUpdateActivate); } match args.cmd { @@ -380,10 +379,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_matching_data.skip_lru = *skip_lru; switch_to_matching_data.skip_origin = *skip_origin; - switch_to_urgent_or_lru_window( - &mut switch_to_matching_data, - fdata(), - ) + switch_to_urgent_or_lru_window(&mut switch_to_matching_data, fdata) } SwayrCommand::SwitchToAppOrUrgentOrLRUWindow { name, @@ -398,7 +394,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_app_or_urgent_or_lru_window( name, &mut switch_to_matching_data, - fdata(), + fdata, ) } SwayrCommand::SwitchToMarkOrUrgentOrLRUWindow { @@ -414,7 +410,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_mark_or_urgent_or_lru_window( con_mark, &mut switch_to_matching_data, - fdata(), + fdata, ) } SwayrCommand::SwitchToMatchingOrUrgentOrLRUWindow { @@ -430,47 +426,45 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { switch_to_matching_or_urgent_or_lru_window( criteria, &mut switch_to_matching_data, - fdata(), + fdata, ) } - SwayrCommand::SwitchWindow => switch_window(fdata()), - SwayrCommand::SwitchWorkspace => switch_workspace(fdata()), + SwayrCommand::SwitchWindow => switch_window(fdata), + SwayrCommand::SwitchWorkspace => switch_workspace(fdata), SwayrCommand::SwitchOutput => switch_output(), SwayrCommand::SwitchWorkspaceOrWindow => { - switch_workspace_or_window(fdata()) + switch_workspace_or_window(fdata) } SwayrCommand::SwitchWorkspaceContainerOrWindow => { - switch_workspace_container_or_window(fdata()) - } - SwayrCommand::SwitchTo => switch_to(fdata()), - SwayrCommand::QuitWindow { kill } => quit_window(fdata(), *kill), - SwayrCommand::QuitWorkspaceOrWindow => { - quit_workspace_or_window(fdata()) + switch_workspace_container_or_window(fdata) } + SwayrCommand::SwitchTo => switch_to(fdata), + SwayrCommand::QuitWindow { kill } => quit_window(fdata, *kill), + SwayrCommand::QuitWorkspaceOrWindow => quit_workspace_or_window(fdata), SwayrCommand::QuitWorkspaceContainerOrWindow => { - quit_workspace_container_or_window(fdata()) + quit_workspace_container_or_window(fdata) } SwayrCommand::MoveFocusedToWorkspace => { - move_focused_to_workspace(fdata()) + move_focused_to_workspace(fdata) } - SwayrCommand::MoveFocusedTo => move_focused_to(fdata()), - SwayrCommand::SwapFocusedWith => swap_focused_with(fdata()), + SwayrCommand::MoveFocusedTo => move_focused_to(fdata), + SwayrCommand::SwapFocusedWith => swap_focused_with(fdata), SwayrCommand::NextWindow { windows } => focus_window_in_direction( Direction::Forward, windows, - fdata(), + fdata, always_true, ), SwayrCommand::PrevWindow { windows } => focus_window_in_direction( Direction::Backward, windows, - fdata(), + fdata, always_true, ), SwayrCommand::NextTiledWindow { windows } => focus_window_in_direction( Direction::Forward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| { !dn.node.is_floating() && dn.tree.is_child_of_tiled_container(dn.node.id) @@ -479,7 +473,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { SwayrCommand::PrevTiledWindow { windows } => focus_window_in_direction( Direction::Backward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| { !dn.node.is_floating() && dn.tree.is_child_of_tiled_container(dn.node.id) @@ -489,7 +483,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { focus_window_in_direction( Direction::Forward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| { !dn.node.is_floating() && dn @@ -502,7 +496,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { focus_window_in_direction( Direction::Backward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| { !dn.node.is_floating() && dn @@ -515,7 +509,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { focus_window_in_direction( Direction::Forward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| dn.node.is_floating(), ) } @@ -523,7 +517,7 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { focus_window_in_direction( Direction::Backward, windows, - fdata(), + fdata, |dn: &t::DisplayNode| dn.node.is_floating(), ) } @@ -531,14 +525,14 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { focus_window_of_same_layout_in_direction( Direction::Forward, windows, - fdata(), + fdata, ) } SwayrCommand::PrevWindowOfSameLayout { windows } => { focus_window_of_same_layout_in_direction( Direction::Backward, windows, - fdata(), + fdata, ) } SwayrCommand::TileWorkspace { floating } => { diff --git a/swayr/src/config.rs b/swayr/src/config.rs index 767bf60..816f972 100644 --- a/swayr/src/config.rs +++ b/swayr/src/config.rs @@ -60,10 +60,13 @@ pub struct Focus { lockin_delay: Option<u64>, } -#[derive(Debug, Serialize, Deserialize, Default)] +#[derive(Debug, Serialize, Deserialize)] pub struct Misc { /// Delay after which an automatic Nop command is sent. auto_nop_delay: Option<u64>, + + /// Inhibit LRU updates during sequences of window cycling commands + seq_inhibit: Option<bool>, } fn tilde_expand_file_names(file_names: Vec<String>) -> Vec<String> { @@ -212,6 +215,14 @@ impl Config { .and_then(|m| m.auto_nop_delay) .map(Duration::from_millis) } + + pub fn get_misc_seq_inhibit(&self) -> bool { + self.misc + .as_ref() + .and_then(|f| f.seq_inhibit) + .or_else(|| Misc::default().seq_inhibit) + .expect("No misc.seq_inhibit defined.") + } } impl Layout { @@ -329,6 +340,15 @@ impl Default for Focus { } } +impl Default for Misc { + fn default() -> Self { + Self { + auto_nop_delay: None, + seq_inhibit: Some(false), + } + } +} + impl Default for Config { fn default() -> Self { Config { diff --git a/swayr/src/daemon.rs b/swayr/src/daemon.rs index 6be7d8c..50db138 100644 --- a/swayr/src/daemon.rs +++ b/swayr/src/daemon.rs @@ -42,6 +42,7 @@ pub fn run_daemon() { let config = config::load_config(); let lockin_delay = config.get_focus_lockin_delay(); let auto_nop_delay = &config.get_misc_auto_nop_delay(); + let seq_inhibit = config.get_misc_seq_inhibit(); { let fdata = fdata.clone(); @@ -53,7 +54,7 @@ pub fn run_daemon() { { let fdata = fdata.clone(); thread::spawn(move || { - focus_lock_in_handler(focus_rx, fdata, lockin_delay); + focus_lock_in_handler(focus_rx, fdata, lockin_delay, seq_inhibit); }); } @@ -244,7 +245,7 @@ pub fn serve_client_requests( log::debug!("Executing auto-nop."); cmds::exec_swayr_cmd(cmds::ExecSwayrCmdArgs { cmd: &cmds::SwayrCommand::Nop, - focus_data: Some(&fdata), + focus_data: &fdata, }); inhibit = true; } @@ -287,7 +288,7 @@ fn handle_client_request(mut stream: UnixStream, fdata: &FocusData) { if let Ok(cmd) = serde_json::from_str::<cmds::SwayrCommand>(&cmd_str) { cmds::exec_swayr_cmd(cmds::ExecSwayrCmdArgs { cmd: &cmd, - focus_data: Some(fdata), + focus_data: fdata, }); } else { log::error!( @@ -326,6 +327,7 @@ fn focus_lock_in_handler( focus_chan: mpsc::Receiver<FocusMessage>, fdata: FocusData, lockin_delay: Duration, + seq_inhibit: bool, ) { // Focus event that has not yet been locked-in to the LRU order let mut pending_fev: Option<FocusEvent> = None; @@ -348,6 +350,12 @@ fn focus_lock_in_handler( }; let mut fev = match fmsg { + FocusMessage::TickUpdateInhibit + | FocusMessage::TickUpdateActivate + if !seq_inhibit => + { + continue + } FocusMessage::TickUpdateInhibit => { inhibit.set(); continue; @@ -379,6 +387,12 @@ fn focus_lock_in_handler( }; match fmsg { + FocusMessage::TickUpdateInhibit + | FocusMessage::TickUpdateActivate + if !seq_inhibit => + { + continue + } FocusMessage::TickUpdateInhibit => { // inhibit requested before currently focused container // was locked-in, set it as pending in case no other -- 2.35.3
builds.sr.ht <builds@sr.ht>swayr/patches/arch.yml: FAILED in 1m8s [Add `seq_inhibit` flag to swayrd configuration][0] from [William Barsse][1] [0]: https://lists.sr.ht/~tsdh/public-inbox/patches/33530 [1]: mailto:william.barsse@gmail.com ✗ #793682 FAILED swayr/patches/arch.yml https://builds.sr.ht/~tsdh/job/793682
Hi William, applied & pushed. Thanks a lot, Tassilo