New command `switch-to-mark-or-urgent-or-lru-window` (#18)

Fixes: ~tsdh/swayr/18
timeout_old
Tassilo Horn 3 years ago
parent 40d880bc78
commit 90a0bd7cb9
  1. 11
      NEWS.md
  2. 10
      README.md
  3. 47
      src/cmds.rs

@ -1,3 +1,14 @@
swayr v0.16.0
=============
- There's the new command `switch-to-mark-or-urgent-or-lru-window` which
switches to a specific window matched by mark (`con_mark`) unless it's
already focused. In that case, it acts just like
`switch-to-urgent-or-lru-window`. For example, you can assign a "browser"
mark to your browser window (using a standard sway `for_window` rule). Then
you can provide "browser" as argument to this command to have a convenient
browser <-> last-recently-used window toggle.
swayr v0.15.0 swayr v0.15.0
============= =============

@ -16,7 +16,15 @@ Right now, there are these subcommands:
hint (if any) or to the last recently used window. hint (if any) or to the last recently used window.
* `switch-to-app-or-urgent-or-lru-window` switches to a specific window matched * `switch-to-app-or-urgent-or-lru-window` switches to a specific window matched
by application ID or window class unless it's already focused. In that case, by application ID or window class unless it's already focused. In that case,
it acts just like `switch-to-urgent-or-lru-window`. it acts just like `switch-to-urgent-or-lru-window`. For example, you can
provide "firefox" as argument to this command to have a convenient firefox
<-> last-recently-used window toggle.
* `switch-to-mark-or-urgent-or-lru-window` switches to a specific window
matched by mark (`con_mark`) unless it's already focused. In that case, it
acts just like `switch-to-urgent-or-lru-window`. For example, you can assign
a "browser" mark to your browser window (using a standard sway `for_window`
rule). Then you can provide "browser" as argument to this command to have a
convenient browser <-> last-recently-used window toggle.
* `switch-window` displays all windows in the order urgent first, then * `switch-window` displays all windows in the order urgent first, then
last-recently-used, focused last and focuses the selected. last-recently-used, focused last and focuses the selected.
* `switch-workspace` displays all workspaces in LRU order and switches to the * `switch-workspace` displays all workspaces in LRU order and switches to the

@ -68,9 +68,21 @@ pub enum SwayrCommand {
/// Switch to next urgent window (if any) or to last recently used window. /// Switch to next urgent window (if any) or to last recently used window.
SwitchToUrgentOrLRUWindow, SwitchToUrgentOrLRUWindow,
/// Switch to the given app (given by app_id or window class) if that's not /// Switch to the given app (given by app_id or window class) if that's not
/// currently focused. If it is, switch to the next urgent window (if any) /// focused already. If it is, switch to the next urgent window (if any)
/// or to last recently used window. /// or to last recently used window.
///
/// For example, you can provide "firefox" as argument to this command to
/// have a convenient firefox <-> last-recently-used window toggle.
SwitchToAppOrUrgentOrLRUWindow { name: String }, SwitchToAppOrUrgentOrLRUWindow { name: String },
/// Switch to the window with the given mark if that's not focused already.
/// If it is, switch to the next urgent window (if any) or to last recently
/// used window.
///
/// For example, you can assign a "browser" mark to your browser window
/// (using a standard sway `for_window` rule). Then you can provide
/// "browser" as argument to this command to have a convenient browser <->
/// last-recently-used window toggle.
SwitchToMarkOrUrgentOrLRUWindow { con_mark: String },
/// Focus the selected window. /// Focus the selected window.
SwitchWindow, SwitchWindow,
/// Switch to the selected workspace. /// Switch to the selected workspace.
@ -259,6 +271,12 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
&*props.read().unwrap(), &*props.read().unwrap(),
) )
} }
SwayrCommand::SwitchToMarkOrUrgentOrLRUWindow { con_mark } => {
switch_to_mark_or_urgent_or_lru_window(
Some(con_mark),
&*props.read().unwrap(),
)
}
SwayrCommand::SwitchWindow => switch_window(&*props.read().unwrap()), SwayrCommand::SwitchWindow => switch_window(&*props.read().unwrap()),
SwayrCommand::SwitchWorkspace => { SwayrCommand::SwitchWorkspace => {
switch_workspace(&*props.read().unwrap()) switch_workspace(&*props.read().unwrap())
@ -499,12 +517,31 @@ pub fn switch_to_app_or_urgent_or_lru_window(
let wins = tree.get_windows(); let wins = tree.get_windows();
let app_win = let app_win =
name.and_then(|n| wins.iter().find(|w| w.node.get_app_name() == n)); name.and_then(|n| wins.iter().find(|w| w.node.get_app_name() == n));
match app_win { focus_win_if_not_focused(app_win, wins.get(0))
Some(app_win) if !app_win.node.is_current() => {
focus_window_by_id(app_win.node.id)
} }
pub fn switch_to_mark_or_urgent_or_lru_window(
con_mark: Option<&str>,
extra_props: &HashMap<i64, t::ExtraProps>,
) {
let root = get_tree(false);
let tree = t::get_tree(&root, extra_props);
let wins = tree.get_windows();
let marked_win = con_mark.and_then(|mark| {
wins.iter()
.find(|w| w.node.marks.contains(&mark.to_owned()))
});
focus_win_if_not_focused(marked_win, wins.get(0))
}
pub fn focus_win_if_not_focused(
win: Option<&t::DisplayNode>,
other: Option<&t::DisplayNode>,
) {
match win {
Some(win) if !win.node.is_current() => focus_window_by_id(win.node.id),
_ => { _ => {
if let Some(win) = wins.get(0) { if let Some(win) = other {
focus_window_by_id(win.node.id) focus_window_by_id(win.node.id)
} else { } else {
log::debug!("No window to switch to.") log::debug!("No window to switch to.")

Loading…
Cancel
Save