New command switch-to-matching-or-urgent-or-lru-window

Implements: https://todo.sr.ht/~tsdh/swayr/21
main
Tassilo Horn 3 years ago
parent f0b0f71e38
commit 6aa7d05d07
  1. 62
      Cargo.lock
  2. 5
      README.md
  3. 9
      swayr/NEWS.md
  4. 68
      swayr/src/cmds.rs

62
Cargo.lock generated

@ -270,9 +270,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "lazy_static"
@ -288,9 +288,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.125"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "log"
@ -377,15 +377,15 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.10.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "ppv-lite86"
@ -419,11 +419,11 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
@ -467,9 +467,9 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.5.2"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
dependencies = [
"autocfg",
"crossbeam-deque",
@ -479,9 +479,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.9.2"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@ -511,9 +511,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.5.5"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
@ -522,15 +522,15 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.25"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "rt-format"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953eff237fc52cbb1a78d9ef62de48422a42c49c4db65b7e7e9d3aa500b1bdae"
checksum = "45087cee619d316fa4bd1675494acff4a5eaa0892fa53bc364bd246f13e452e2"
dependencies = [
"lazy_static",
"regex",
@ -538,9 +538,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "scopeguard"
@ -658,20 +658,20 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.93"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04066589568b72ec65f42d65a1a52436e954b168773148893c020269563decf2"
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "sysinfo"
version = "0.23.12"
version = "0.23.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56b1e20ee77901236c389ff74618a899ff5fd34719a7ff0fd1d64f0acca5179a"
checksum = "3977ec2e0520829be45c8a2df70db2bf364714d8a748316a10c3c35d4d2b01c9"
dependencies = [
"cfg-if",
"core-foundation-sys 0.8.3",
@ -743,10 +743,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "unicode-xid"
version = "0.2.3"
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]]
name = "uom"

@ -55,6 +55,11 @@ program.
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-to-matching-or-urgent-or-lru-window` switches to the (first) window
matching the given criterion (see section `CRITERIA` in `sway(5)`) if it
exists and is not already focused. Otherwise, switch to the next urgent
window (if any) or to the last recently used window.
#### Menu switchers

@ -1,3 +1,12 @@
swayr v0.19.0
=============
- There's a new command `switch-to-matching-or-urgent-or-lru-window` which
switches to the (first) window matching the given criteria (see section
`CRITERIA` in `sway(5)`) if it exists and is not already focused. Otherwise,
switch to the next urgent window (if any) or to the last recently used
window.
swayr v0.18.0
=============

@ -86,6 +86,11 @@ pub enum SwayrCommand {
/// "browser" as argument to this command to have a convenient browser <->
/// last-recently-used window toggle.
SwitchToMarkOrUrgentOrLRUWindow { con_mark: String },
/// Switch to the (first) window matching the given criteria (see section
/// `CRITERIA` in `sway(5)`) if it exists and is not already focused.
/// Otherwise, switch to the next urgent window (if any) or to the last
/// recently used window.
SwitchToMatchingOrUrgentOrLRUWindow { criteria: String },
/// Focus the selected window.
SwitchWindow,
/// Switch to the selected workspace.
@ -260,10 +265,13 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
switch_to_urgent_or_lru_window(fdata)
}
SwayrCommand::SwitchToAppOrUrgentOrLRUWindow { name } => {
switch_to_app_or_urgent_or_lru_window(Some(name), fdata)
switch_to_app_or_urgent_or_lru_window(name, fdata)
}
SwayrCommand::SwitchToMarkOrUrgentOrLRUWindow { con_mark } => {
switch_to_mark_or_urgent_or_lru_window(Some(con_mark), fdata)
switch_to_mark_or_urgent_or_lru_window(con_mark, fdata)
}
SwayrCommand::SwitchToMatchingOrUrgentOrLRUWindow { criteria } => {
switch_to_matching_or_urgent_or_lru_window(criteria, fdata)
}
SwayrCommand::SwitchWindow => switch_window(fdata),
SwayrCommand::SwitchWorkspace => switch_workspace(fdata),
@ -470,35 +478,67 @@ pub fn get_outputs() -> Vec<s::Output> {
}
pub fn switch_to_urgent_or_lru_window(fdata: &FocusData) {
switch_to_app_or_urgent_or_lru_window(None, fdata)
let root = ipc::get_root_node(false);
let tree = t::get_tree(&root);
let wins = tree.get_windows(fdata);
focus_win_if_not_focused(None, wins.get(0))
}
pub fn switch_to_app_or_urgent_or_lru_window(
name: Option<&str>,
fdata: &FocusData,
) {
pub fn switch_to_app_or_urgent_or_lru_window(name: &str, fdata: &FocusData) {
let root = ipc::get_root_node(false);
let tree = t::get_tree(&root);
let wins = tree.get_windows(fdata);
let app_win =
name.and_then(|n| wins.iter().find(|w| w.node.get_app_name() == n));
let app_win = wins.iter().find(|w| w.node.get_app_name() == name);
focus_win_if_not_focused(app_win, wins.get(0))
}
pub fn switch_to_mark_or_urgent_or_lru_window(
con_mark: Option<&str>,
con_mark: &str,
fdata: &FocusData,
) {
let root = ipc::get_root_node(false);
let tree = t::get_tree(&root);
let wins = tree.get_windows(fdata);
let marked_win = con_mark.and_then(|mark| {
wins.iter()
.find(|w| w.node.marks.contains(&mark.to_owned()))
});
let con_mark = &con_mark.to_owned();
let marked_win = wins.iter().find(|w| w.node.marks.contains(con_mark));
focus_win_if_not_focused(marked_win, wins.get(0))
}
fn switch_to_matching_or_urgent_or_lru_window(
criteria: &str,
fdata: &FocusData,
) {
// TODO: It would be great if sway had some command which given a criteria
// query returns the matching windows. Unfortunately, it doesn't have it
// right now. So we call `CRITERION focus` and check if focus has moved.
// If not, we do the "urgent or LRU" thing.
let root = ipc::get_root_node(false);
let tree = t::get_tree(&root);
let wins = tree.get_windows(fdata);
let prev_win_id = wins
.iter()
.find(|w| w.node.focused)
.map(|w| w.node.id)
.unwrap_or(-1);
run_sway_command(&[criteria, "focus"]);
// Wait until the focus event had time to arrive.
std::thread::sleep(std::time::Duration::from_millis(50));
let root = ipc::get_root_node(false);
let tree = t::get_tree(&root);
let wins = tree.get_windows(fdata);
let cur_win_id = wins
.iter()
.find(|w| w.node.focused)
.map(|w| w.node.id)
.unwrap_or(-1);
if prev_win_id == cur_win_id {
focus_win_if_not_focused(None, wins.get(0))
}
}
pub fn focus_win_if_not_focused(
win: Option<&t::DisplayNode>,
other: Option<&t::DisplayNode>,

Loading…
Cancel
Save