~tsdh/swayr

02db59896f9ae9f88bd5fd5de23d2356520ee5f0 — Tassilo Horn a month ago 3f090e2
Allow to specify all or only current workspace windows with next/prev-window cmds
2 files changed, 106 insertions(+), 28 deletions(-)

M src/cmds.rs
M src/con.rs
M src/cmds.rs => src/cmds.rs +105 -27
@@ 38,6 38,14 @@ pub enum ConsiderFloating {
    ExcludeFloating,
}

#[derive(Clap, Debug, Deserialize, Serialize, PartialEq)]
pub enum ConsiderWindows {
    /// Consider windows of all workspaces.
    AllWorkspaces,
    /// Consider windows of only the current workspaces.
    CurrentWorkspace,
}

#[derive(Clap, Debug, Deserialize, Serialize)]
pub enum SwayrCommand {
    /// Switch to next urgent window (if any) or to last recently used window.


@@ 45,17 53,35 @@ pub enum SwayrCommand {
    /// Focus the selected window.
    SwitchWindow,
    /// Focus the next window.
    NextWindow,
    NextWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Focus the previous window.
    PrevWindow,
    PrevWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Focus the next window of a tiled container.
    NextTiledWindow,
    NextTiledWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Focus the previous window of a tiled container.
    PrevTiledWindow,
    PrevTiledWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Focus the next window of a tabbed or stacked container.
    NextTabbedOrStackedWindow,
    NextTabbedOrStackedWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Focus the previous window of a tabbed or stacked container.
    PrevTabbedOrStackedWindow,
    PrevTabbedOrStackedWindow {
        #[clap(subcommand)]
        windows: ConsiderWindows,
    },
    /// Quit the selected window.
    QuitWindow,
    /// Switch to the selected workspace.


@@ 119,38 145,48 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
        SwayrCommand::SwitchWindow => {
            switch_window(Some(&*props.read().unwrap()))
        }
        SwayrCommand::NextWindow => focus_next_window_in_direction(
        SwayrCommand::NextWindow { windows } => focus_next_window_in_direction(
            Direction::Forward,
            windows,
            Some(&*props.read().unwrap()),
            Box::new(always_true),
        ),
        SwayrCommand::PrevWindow => focus_next_window_in_direction(
        SwayrCommand::PrevWindow { windows } => focus_next_window_in_direction(
            Direction::Backward,
            windows,
            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 => {
        SwayrCommand::NextTiledWindow { windows } => {
            focus_next_window_in_direction(
                Direction::Forward,
                windows,
                Some(&*props.read().unwrap()),
                Box::new(|w: &con::Window| w.is_child_of_tiled_container()),
            )
        }
        SwayrCommand::PrevTiledWindow { windows } => {
            focus_next_window_in_direction(
                Direction::Backward,
                windows,
                Some(&*props.read().unwrap()),
                Box::new(|w: &con::Window| w.is_child_of_tiled_container()),
            )
        }
        SwayrCommand::NextTabbedOrStackedWindow { windows } => {
            focus_next_window_in_direction(
                Direction::Forward,
                windows,
                Some(&*props.read().unwrap()),
                Box::new(|w: &con::Window| {
                    w.is_child_of_tabbed_or_stacked_container()
                }),
            )
        }
        SwayrCommand::PrevTabbedOrStackedWindow => {
        SwayrCommand::PrevTabbedOrStackedWindow { windows } => {
            focus_next_window_in_direction(
                Direction::Backward,
                windows,
                Some(&*props.read().unwrap()),
                Box::new(|w: &con::Window| {
                    w.is_child_of_tabbed_or_stacked_container()


@@ 221,10 257,42 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
                    SwayrCommand::ShuffleTileWorkspace {
                        floating: ConsiderFloating::IncludeFloating,
                    },
                    SwayrCommand::NextWindow,
                    SwayrCommand::PrevWindow,
                    SwayrCommand::NextTiledWindow,
                    SwayrCommand::PrevTiledWindow,
                    SwayrCommand::NextWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::NextWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                    SwayrCommand::PrevWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::PrevWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                    SwayrCommand::NextTiledWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::NextTiledWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                    SwayrCommand::PrevTiledWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::PrevTiledWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                    SwayrCommand::NextTabbedOrStackedWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::NextTabbedOrStackedWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                    SwayrCommand::PrevTabbedOrStackedWindow {
                        windows: ConsiderWindows::AllWorkspaces,
                    },
                    SwayrCommand::PrevTabbedOrStackedWindow {
                        windows: ConsiderWindows::CurrentWorkspace,
                    },
                ],
            ) {
                exec_swayr_cmd(ExecSwayrCmdArgs {


@@ 282,15 350,25 @@ pub enum Direction {
    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(
    dir: Direction,
    consider_wins: &ConsiderWindows,
    extra_props: Option<&HashMap<i64, con::ExtraProps>>,
    pred: Box<dyn Fn(&con::Window) -> bool>,
) {
    let root = get_tree();
    let windows = con::get_windows(&root, false, None);
    let root = match consider_wins {
        ConsiderWindows::AllWorkspaces => &root,
        ConsiderWindows::CurrentWorkspace => {
            con::get_workspaces(&root, false, extra_props)
                .iter()
                .find(|w| w.is_current())
                .expect("No current workspace!")
                .node
        }
    };

    let windows = con::get_windows(root, false, extra_props);

    if windows.len() < 2 {
        return;

M src/con.rs => src/con.rs +1 -1
@@ 436,7 436,7 @@ pub fn select_workspace_or_window<'a>(
}

pub struct Workspace<'a> {
    node: &'a s::Node,
    pub node: &'a s::Node,
    extra_props: Option<ExtraProps>,
    pub windows: Vec<Window<'a>>,
}