New commands: {Next,Prev}{Tiled,TabbedOrStacked}Window

timeout_old
Tassilo Horn 3 years ago
parent b60ceb1458
commit 3f090e290c
  1. 12
      Cargo.lock
  2. 53
      src/cmds.rs
  3. 16
      src/con.rs

12
Cargo.lock generated

@ -150,9 +150,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.102" version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
[[package]] [[package]]
name = "memchr" name = "memchr"
@ -207,9 +207,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.9" version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -372,9 +372,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.77" version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

@ -48,6 +48,14 @@ pub enum SwayrCommand {
NextWindow, NextWindow,
/// Focus the previous window. /// Focus the previous window.
PrevWindow, PrevWindow,
/// Focus the next window of a tiled container.
NextTiledWindow,
/// Focus the previous window of a tiled container.
PrevTiledWindow,
/// Focus the next window of a tabbed or stacked container.
NextTabbedOrStackedWindow,
/// Focus the previous window of a tabbed or stacked container.
PrevTabbedOrStackedWindow,
/// Quit the selected window. /// Quit the selected window.
QuitWindow, QuitWindow,
/// Switch to the selected workspace. /// Switch to the selected workspace.
@ -98,6 +106,10 @@ impl DisplayFormat for SwayrCommand {
} }
} }
fn always_true(_x: &con::Window) -> bool {
true
}
pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
let props = args.extra_props; let props = args.extra_props;
match args.cmd { match args.cmd {
@ -110,11 +122,41 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
SwayrCommand::NextWindow => focus_next_window_in_direction( SwayrCommand::NextWindow => focus_next_window_in_direction(
Direction::Forward, Direction::Forward,
Some(&*props.read().unwrap()), Some(&*props.read().unwrap()),
Box::new(always_true),
), ),
SwayrCommand::PrevWindow => focus_next_window_in_direction( SwayrCommand::PrevWindow => focus_next_window_in_direction(
Direction::Backward, Direction::Backward,
Some(&*props.read().unwrap()), Some(&*props.read().unwrap()),
Box::new(always_true),
),
SwayrCommand::NextTiledWindow => focus_next_window_in_direction(
Direction::Forward,
Some(&*props.read().unwrap()),
Box::new(|w: &con::Window| w.is_child_of_tiled_container()),
),
SwayrCommand::PrevTiledWindow => focus_next_window_in_direction(
Direction::Backward,
Some(&*props.read().unwrap()),
Box::new(|w: &con::Window| w.is_child_of_tiled_container()),
), ),
SwayrCommand::NextTabbedOrStackedWindow => {
focus_next_window_in_direction(
Direction::Forward,
Some(&*props.read().unwrap()),
Box::new(|w: &con::Window| {
w.is_child_of_tabbed_or_stacked_container()
}),
)
}
SwayrCommand::PrevTabbedOrStackedWindow => {
focus_next_window_in_direction(
Direction::Backward,
Some(&*props.read().unwrap()),
Box::new(|w: &con::Window| {
w.is_child_of_tabbed_or_stacked_container()
}),
)
}
SwayrCommand::QuitWindow => quit_window(Some(&*props.read().unwrap())), SwayrCommand::QuitWindow => quit_window(Some(&*props.read().unwrap())),
SwayrCommand::SwitchWorkspace => { SwayrCommand::SwitchWorkspace => {
switch_workspace(Some(&*props.read().unwrap())) switch_workspace(Some(&*props.read().unwrap()))
@ -181,6 +223,8 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
}, },
SwayrCommand::NextWindow, SwayrCommand::NextWindow,
SwayrCommand::PrevWindow, SwayrCommand::PrevWindow,
SwayrCommand::NextTiledWindow,
SwayrCommand::PrevTiledWindow,
], ],
) { ) {
exec_swayr_cmd(ExecSwayrCmdArgs { exec_swayr_cmd(ExecSwayrCmdArgs {
@ -238,9 +282,12 @@ pub enum Direction {
Forward, Forward,
} }
// TODO: Maybe we should have a bool parameter telling if it should act on all
// windows or just the ones on the current workspace.
pub fn focus_next_window_in_direction( pub fn focus_next_window_in_direction(
dir: Direction, dir: Direction,
extra_props: Option<&HashMap<i64, con::ExtraProps>>, extra_props: Option<&HashMap<i64, con::ExtraProps>>,
pred: Box<dyn Fn(&con::Window) -> bool>,
) { ) {
let root = get_tree(); let root = get_tree();
let windows = con::get_windows(&root, false, None); let windows = con::get_windows(&root, false, None);
@ -249,7 +296,7 @@ pub fn focus_next_window_in_direction(
return; return;
} }
let pred: Box<dyn Fn(&con::Window) -> bool> = let is_focused_window: Box<dyn Fn(&con::Window) -> bool> =
if !windows.iter().any(|w| w.is_focused()) { if !windows.iter().any(|w| w.is_focused()) {
let last_focused_win_id = let last_focused_win_id =
con::get_windows(&root, false, extra_props) con::get_windows(&root, false, extra_props)
@ -268,8 +315,8 @@ pub fn focus_next_window_in_direction(
loop { loop {
let win = iter.next().unwrap(); let win = iter.next().unwrap();
if pred(win) { if is_focused_window(win) {
let win = iter.next().unwrap(); let win = iter.filter(|w| pred(w)).next().unwrap();
focus_window_by_id(win.get_id()); focus_window_by_id(win.get_id());
return; return;
} }

@ -157,6 +157,22 @@ impl Window<'_> {
pub fn is_floating(&self) -> bool { pub fn is_floating(&self) -> bool {
self.node.node_type == s::NodeType::FloatingCon self.node.node_type == s::NodeType::FloatingCon
} }
pub fn get_parent(&self) -> &s::Node {
NodeIter::new(self.workspace)
.find(|n| n.nodes.contains(self.node))
.expect("No parent node of a window!")
}
pub fn is_child_of_tiled_container(&self) -> bool {
let layout = &self.get_parent().layout;
layout == &s::NodeLayout::SplitH || layout == &s::NodeLayout::SplitV
}
pub fn is_child_of_tabbed_or_stacked_container(&self) -> bool {
let layout = &self.get_parent().layout;
layout == &s::NodeLayout::Tabbed || layout == &s::NodeLayout::Stacked
}
} }
impl PartialEq for Window<'_> { impl PartialEq for Window<'_> {

Loading…
Cancel
Save