~tsdh/swayr

75fca3c94b67dc3246e020f39c22b77182139dde — Tassilo Horn a month ago ba5686e
Re-tile and shuffle-retile
4 files changed, 104 insertions(+), 19 deletions(-)

M Cargo.lock
M Cargo.toml
M src/cmds.rs
M src/layout.rs
M Cargo.lock => Cargo.lock +47 -0
@@ 168,6 168,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"

[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"

[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 210,6 216,46 @@ dependencies = [
]

[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
 "libc",
 "rand_chacha",
 "rand_core",
 "rand_hc",
]

[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
 "ppv-lite86",
 "rand_core",
]

[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
 "getrandom",
]

[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
 "rand_core",
]

[[package]]
name = "redox_syscall"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 317,6 363,7 @@ dependencies = [
 "clap",
 "directories",
 "lazy_static",
 "rand",
 "regex",
 "serde",
 "serde_json",

M Cargo.toml => Cargo.toml +1 -1
@@ 18,4 18,4 @@ toml = "0.5.8"
directories = "3.0"
regex = "1.5.4"
lazy_static = "1.4.0"

rand = "0.8.4"

M src/cmds.rs => src/cmds.rs +51 -11
@@ 20,14 20,15 @@ use crate::config as cfg;
use crate::layout;
use crate::util;
use crate::util::DisplayFormat;
use clap::Clap;
use rand;
use rand::prelude::SliceRandom;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::RwLock;
use swayipc as s;

use clap::Clap;

#[derive(Clap, Debug, Deserialize, Serialize, PartialEq)]
pub enum ConsiderFloating {
    /// Include floating windows.


@@ 60,6 61,12 @@ pub enum SwayrCommand {
        #[clap(subcommand)]
        floating: ConsiderFloating,
    },
    /// Retiles the windows on the current workspace, including or excluding
    /// floating windows.
    ShuffleRetileWorkspace {
        #[clap(subcommand)]
        floating: ConsiderFloating,
    },
    /// Select and execute a swaymsg command.
    ExecuteSwaymsgCommand,
    /// Select and execute a swayr command.


@@ 107,7 114,14 @@ pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
        }
        SwayrCommand::RetileWorkspace { floating } => retile_current_workspace(
            floating == &ConsiderFloating::IncludeFloating,
            false,
        ),
        SwayrCommand::ShuffleRetileWorkspace { floating } => {
            retile_current_workspace(
                floating == &ConsiderFloating::IncludeFloating,
                true,
            )
        }
        SwayrCommand::ExecuteSwaymsgCommand => exec_swaymsg_command(),
        SwayrCommand::ExecuteSwayrCommand => {
            if let Some(c) = util::select_from_menu(


@@ 282,16 296,42 @@ pub fn quit_workspace_or_window(
    }
}

fn retile_current_workspace(include_floating: bool) {
    let fns: Vec<Box<dyn Fn(&con::Window) -> String>> = vec![
        Box::new(|win: &con::Window| {
            format!("[con_id={}] move to workspace current", win.get_id())
        }),
        Box::new(|win: &con::Window| {
            format!("[con_id={}] floating disable", win.get_id())
fn retile_current_workspace(include_floating: bool, shuffle: bool) {
    match layout::relayout_current_workspace(
        include_floating,
        Box::new(move |wins, con: &mut s::Connection| {
            let mut placed_wins = vec![];
            let mut rng = rand::thread_rng();
            if shuffle {
                wins.shuffle(&mut rng);
            } else {
                wins.reverse()
            }
            for win in wins {
                std::thread::sleep(std::time::Duration::from_millis(25));
                con.run_command(format!(
                    "[con_id={}] move to workspace current",
                    win.get_id()
                ))?;
                std::thread::sleep(std::time::Duration::from_millis(25));
                con.run_command(format!(
                    "[con_id={}] floating disable",
                    win.get_id()
                ))?;
                placed_wins.push(win);
                if shuffle {
                    std::thread::sleep(std::time::Duration::from_millis(25));
                    if let Some(win) = placed_wins.choose(&mut rng) {
                        con.run_command(format!(
                            "[con_id={}] focus",
                            win.get_id()
                        ))?;
                    }
                }
            }
            Ok(())
        }),
    ];
    match layout::relayout_current_workspace(include_floating, fns) {
    ) {
        Ok(_) => (),
        Err(err) => eprintln!("Error retiling workspace: {:?}", err),
    }

M src/layout.rs => src/layout.rs +5 -7
@@ 127,7 127,9 @@ pub fn maybe_auto_tile(config: &config::Config) {

pub fn relayout_current_workspace(
    include_floating: bool,
    fns: Vec<Box<dyn Fn(&con::Window) -> String>>,
    insert_win_fn: Box<
        dyn Fn(&mut [&con::Window], &mut s::Connection) -> s::Fallible<()>,
    >,
) -> s::Fallible<()> {
    let root = cmds::get_tree();
    let workspaces = con::get_workspaces(&root, false, None);


@@ 149,13 151,9 @@ pub fn relayout_current_workspace(
                ))?;
            }

            while let Some(win) = moved_wins.pop() {
                for func in &fns {
                    std::thread::sleep(std::time::Duration::from_millis(25));
                    con.run_command(func(win))?;
                }
            }
            insert_win_fn(moved_wins.as_mut_slice(), &mut con)?;
            std::thread::sleep(std::time::Duration::from_millis(25));

            if let Some(win) = focused_win {
                con.run_command(format!("[con_id={}] focus", win.get_id()))?;
            }