~tsdh/public-inbox

swayr: Implement window and container stealing v3 PROPOSED

Rouven Czerwinski: 1
 Implement window and container stealing

 2 files changed, 55 insertions(+), 0 deletions(-)
#870632 running arch.yml
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~tsdh/public-inbox/patches/36430/mbox | git am -3
Learn more about email & git

[PATCH swayr v3] Implement window and container stealing Export this patch

This allows the user to steal a window or container from another
workspace into the current workspace. Very useful to get an open
document which you know is on some workspace, but needs to be moved into
the current one.
---
v3:
- remove get_window_and_containers() tree method
- use get_workspaces_containers_and_windows() for
  steal_window_or_container()

v2:
- implement command to also select containers
- add logging messages to select_and_steal()
- add README entries
- add a new get_window_and_containers() tree method

 README.md         |  6 ++++++
 swayr/src/cmds.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/README.md b/README.md
index a21fe09..b4fd1ae 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,12 @@ output, etc.) and act on that.

* `switch-window` displays all windows in the order urgent first, then
  last-recently-used, focused last and focuses the selected.
* `steal-window` displays all windows in order urgent first, the
   last-recently-used, focused last and moves the window into the current
   workspace.
* `steal-window-or-container` displays all windows and containers in order
   urgent first, the last-recently-used, focused last and moves the window or
   container into the current workspace.
* `switch-workspace` displays all workspaces in LRU order and switches to the
  selected one.
* `switch-output` shows all outputs in the menu and focuses the selected one.
diff --git a/swayr/src/cmds.rs b/swayr/src/cmds.rs
index 090b77a..598ab64 100644
--- a/swayr/src/cmds.rs
+++ b/swayr/src/cmds.rs
@@ -150,6 +150,12 @@ pub enum SwayrCommand {
    },
    /// Focus the selected window.
    SwitchWindow,
    /// Steal the selected window from another workspace into the current
    /// workspace.
    StealWindow,
    /// Steal the selected window or container from another workspace into the
    /// current workspace.
    StealWindowOrContainer,
    /// Switch to the selected workspace.
    SwitchWorkspace,
    /// Switch to the selected workspace.
@@ -440,6 +446,8 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
            )
        }
        SwayrCommand::SwitchWindow => switch_window(fdata),
        SwayrCommand::StealWindow => steal_window(fdata),
        SwayrCommand::StealWindowOrContainer => steal_window_or_container(fdata),
        SwayrCommand::SwitchWorkspace => switch_workspace(fdata),
        SwayrCommand::SwitchOutput => switch_output(),
        SwayrCommand::SwitchWorkspaceOrWindow => {
@@ -580,6 +588,8 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
                SwayrCommand::SwapFocusedWith,
                SwayrCommand::QuitWorkspaceOrWindow,
                SwayrCommand::SwitchWindow,
                SwayrCommand::StealWindow,
                SwayrCommand::StealWindowOrContainer,
                SwayrCommand::SwitchWorkspace,
                SwayrCommand::SwitchOutput,
                SwayrCommand::SwitchWorkspaceOrWindow,
@@ -648,6 +658,11 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
    *last_command = args.cmd.clone();
}

fn steal_window_by_id(id: i64) -> i64 {
    run_sway_command(&[format!("[con_id={}]", id).as_str(), "move to workspace current"]);
    id
}

fn focus_window_by_id(id: i64) -> i64 {
    run_sway_command(&[format!("[con_id={}]", id).as_str(), "focus"]);
    id
@@ -887,12 +902,46 @@ fn select_and_focus(prompt: &str, choices: &[t::DisplayNode]) {
    }
}

fn select_and_steal(prompt: &str, choices: &[t::DisplayNode]) {
    match util::select_from_menu(prompt, choices) {
        Ok(tn) => match tn.node.get_type() {
            ipc::Type::Window | ipc::Type::Container => {
                steal_window_by_id(tn.node.id);
            },
            ipc::Type::Workspace => {
                log::info!("Can't steal whole workspace")
            }
            t => {
                log::error!("Cannot handle {:?} in select_and_steal", t)
            }
        },
        Err(non_matching_input) => {
            log::error!("Cannot handle {:?} in select and steal", non_matching_input)
        }
    }
}

pub fn switch_window(fdata: &FocusData) {
    let root = ipc::get_root_node(true);
    let tree = t::get_tree(&root);
    select_and_focus("Select window", &tree.get_windows(fdata));
}

pub fn steal_window(fdata: &FocusData) {
    let root = ipc::get_root_node(true);
    let tree = t::get_tree(&root);
    select_and_steal("Select window", &tree.get_windows(fdata));
}

pub fn steal_window_or_container(fdata: &FocusData) {
    let root = ipc::get_root_node(true);
    let tree = t::get_tree(&root);
    select_and_steal(
        "Select window or container",
        &tree.get_workspaces_containers_and_windows(fdata)
    );
}

pub fn switch_workspace(fdata: &FocusData) {
    let root = ipc::get_root_node(false);
    let tree = t::get_tree(&root);
-- 
2.38.0
Rouven Czerwinski <rouven@czerwinskis.de> writes:

Hey Rouven,