Skip to content

Commit

Permalink
Merge pull request #6 from H3rmt/5-sort-by-recently-used-windows
Browse files Browse the repository at this point in the history
adding args to allow for sorting by recent windows (#5)
  • Loading branch information
H3rmt authored Feb 3, 2024
2 parents 0187714 + bca8680 commit 6f99a2b
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 1,324 deletions.
1,185 changes: 19 additions & 1,166 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 8 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
[package]
name = "window_switcher"
description = "A CLI that allows switching between windows in Hyprland"
version = "0.2.1"
description = "A CLI that allows switching between windows in Hyprland \n(renamed to hyprswitch [https://crates.io/crates/hyprswitch])"
version = "0.3.0"
edition = "2021"
license = "MIT"
readme = "README.md"
documentation = "https://docs.rs/crate/window_switcher"
repository = "https://github.com/H3rmt/WindowSwitcher/"
keywords = ["hyprland", "hyprland"]
repository = "https://github.com/h3rmt/hyprswitch/"
keywords = ["hyprland"]
categories = ["command-line-utilities"]

[dependencies]
clap = { version = "^4.4.11", features = ["derive"] }
hyprland = "=0.3.11"
clap = { version = "^4.4.18", features = ["derive"] }
hyprland = "0.3.13"

[dev-dependencies]
random_color = "0.7.0"
svg = "0.14.0"
softbuffer = { version = "0.4.0", features = ["wayland", "wayland-dlopen"], default-features = false }
winit = { version = "0.29.4", features = ["wayland", "rwh_06"], default-features = false }
random_color = "0.8.0"
svg = "0.15.0"
29 changes: 15 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# WindowSwitcher
# hyprswitch

[![crates.io](https://img.shields.io/crates/v/window_switcher.svg)](https://crates.io/crates/window_switcher)
[![Docs](https://docs.rs/built/badge.svg)](https://docs.rs/window_switcher)
[![Tests](https://github.com/H3rmt/WindowSwitcher/actions/workflows/rust.yml/badge.svg)](https://github.com/H3rmt/WindowSwitcher/actions/workflows/rust.yml)
[![crates.io](https://img.shields.io/crates/v/hyprswitch.svg)](https://crates.io/crates/hyprswitch)
[![Docs](https://docs.rs/built/badge.svg)](https://docs.rs/hyprswitch)
[![Tests](https://github.com/h3rmt/hyprswitch/actions/workflows/rust.yml/badge.svg)](https://github.com/h3rmt/hyprswitch/actions/workflows/rust.yml)

A small rust CLI tool to switch between windows in hyperland.

Expand All @@ -11,7 +11,7 @@ It can switch through all windows or only windows of same class(= application) i

# Installation
`
cargo install window_switcher
cargo install hyprswitch
`

# Usage
Expand All @@ -22,36 +22,36 @@ Here are some samples:
- simple config
```
# switches to next window
bind = ALT, TAB, exec, $HOME/.cargo/bin/window_switcher
bind = ALT, TAB, exec, $HOME/.cargo/bin/hyprswitch
# switches to next window of same class
bind = ALT CTRL, TAB, exec, $HOME/.cargo/bin/window_switcher --same-class
bind = ALT CTRL, TAB, exec, $HOME/.cargo/bin/hyprswitch --same-class
# switches to next window in workspace
bind = SUPER, TAB, exec, $HOME/.cargo/bin/window_switcher --stay-workspace
bind = SUPER, TAB, exec, $HOME/.cargo/bin/hyprswitch --stay-workspace
```

- with reverse binds
```
# switches to next window
bind = ALT, TAB, exec, $HOME/.cargo/bin/window_switcher
bind = ALT, TAB, exec, $HOME/.cargo/bin/hyprswitch
# switches to next window in reverse order
bind = ALT SHIFT, TAB, exec, $HOME/.cargo/bin/window_switcher --reverse
bind = ALT SHIFT, TAB, exec, $HOME/.cargo/bin/hyprswitch --reverse
# switches to next window in workspace
bind = SUPER, TAB, exec, $HOME/.cargo/bin/window_switcher --stay-workspace
bind = SUPER, TAB, exec, $HOME/.cargo/bin/hyprswitch --stay-workspace
# switches to next window in workspace in reverse order
bind = SUPER, TAB, exec, $HOME/.cargo/bin/window_switcher --stay-workspace --reverse
bind = SUPER, TAB, exec, $HOME/.cargo/bin/hyprswitch --stay-workspace --reverse
# switches to next window of same class
bind = ALT CTRL, TAB, exec, $HOME/.cargo/bin/window_switcher --same-class
bind = ALT CTRL, TAB, exec, $HOME/.cargo/bin/hyprswitch --same-class
# switches to next window of same class in reverse order
bind = ALT CTRL SHIFT, TAB, exec, $HOME/.cargo/bin/window_switcher --reverse --same-class
bind = ALT CTRL SHIFT, TAB, exec, $HOME/.cargo/bin/hyprswitch --reverse --same-class
```

The script accepts 5 parameters:.
Expand All @@ -61,6 +61,7 @@ The script accepts 5 parameters:.
- `--ignore-workspace` Ignore workspaces and sort like one big workspace for each monitor
- `--ignore-monitor` Ignore monitors and sort like one big monitor, [workspaces must have offset of 10 for each monitor ](#ignore-monitors-flag)
- `--vertical-workspaces` will treat workspaces as vertical aligned (used with `--ignore-workspace`)
- `--sort-recent` will sort windows by recently visited instead of position

# Sorting of windows
See [tests](/tests) for more details on how windows get sorted
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ pub struct WorkspaceData {
pub y: u16,
}

pub type MonitorId = i64;
pub type MonitorId = i128;
29 changes: 19 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ struct Args {
#[arg(long, short)]
reverse: bool,

/// Sort windows by recently visited
#[arg(long)]
sort_recent: bool,

/// Restrict cycling of windows to current workspace
#[arg(long)]
stay_workspace: bool,
Expand Down Expand Up @@ -51,22 +55,22 @@ struct Args {
/// # Usage
///
/// * Switch between windows of same class
/// * `window_switcher --same-class`
/// * `hyprswitch --same-class`
/// * Switch backwards
/// * `window_switcher --reverse`
/// * `hyprswitch --reverse`
///
/// ## Special
///
/// * Cycles through window on current workspace
/// * `window_switcher --stay-workspace`
/// * `hyprswitch --stay-workspace`
///
/// * Ignore workspaces and sort like one big workspace
/// * `window_switcher --ignore-workspaces`
/// * `hyprswitch --ignore-workspaces`
/// * Ignore monitors and sort like one big monitor
/// * `window_switcher --ignore-monitors`
/// * `hyprswitch --ignore-monitors`
///
/// * Display workspaces vertically on monitors
/// * `window_switcher --vertical-workspaces`
/// * `hyprswitch --vertical-workspaces`
///
fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Args::parse();
Expand Down Expand Up @@ -164,7 +168,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if cli.verbose {
println!("clients: {:?}", clients.iter().enumerate().map(|(i, c)| (i, c.monitor, c.x(), c.y(), c.w(), c.h(), c.ws(), c.identifier())).collect::<Vec<(usize, MonitorId, u16, u16, u16, u16, WorkspaceId, String)>>());
}
clients = sort_clients(clients, cli.ignore_workspaces, cli.ignore_monitors);

if cli.sort_recent {
clients.sort_by(|a, b| a.focus_history_id.cmp(&b.focus_history_id));
} else {
clients = sort_clients(clients, cli.ignore_workspaces, cli.ignore_monitors);
}

if cli.verbose {
println!("clients: {:?}", clients.iter().enumerate().map(|(i, c)| (i, c.monitor, c.x(), c.y(), c.w(), c.h(), c.ws(), c.identifier())).collect::<Vec<(usize, MonitorId, u16, u16, u16, u16, WorkspaceId, String)>>());
Expand All @@ -173,8 +182,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let binding = Client::get_active()?;
let active = binding
.as_ref()
.unwrap_or(clients.get(0).expect("no active window and no windows"));
let active_address = active.address.to_string();
.unwrap_or(clients.first().expect("no active window and no windows"));
let active_address = active.address.clone();
let active_class = active.class.clone();
let active_workspace_id = active.workspace.id;

Expand All @@ -194,7 +203,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let mut current_window_index = clients
.iter()
.position(|r| r.address.to_string() == active_address)
.position(|r| r.address == active_address)
.expect("Active window not found?");

if cli.reverse {
Expand Down
4 changes: 2 additions & 2 deletions src/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::{MonitorData, MonitorId, WorkspaceData};
/// Sorts clients with complex sorting
///
/// * 'clients' - Vector of clients to sort
/// * 'ignore_workspaces' - Dont split clients into workspaces (treat all clients on monitor as one workspace)
/// * 'ignore_monitors' - Dont split clients into monitors (treat all clients as one monitor)
/// * 'ignore_workspaces' - Don't split clients into workspaces (treat all clients on monitor as one workspace)
/// * 'ignore_monitors' - Don't split clients into monitors (treat all clients as one monitor)
pub fn sort_clients<SC>(
clients: Vec<SC>,
ignore_workspaces: bool,
Expand Down
92 changes: 0 additions & 92 deletions src/windows.rs

This file was deleted.

6 changes: 3 additions & 3 deletions tests/many_windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Instant;

use hyprland::shared::WorkspaceId;

use window_switcher::{MonitorData, WorkspaceData};
use window_switcher::{MonitorData, MonitorId, WorkspaceData};
use window_switcher::sort::{sort_clients, update_clients};

use crate::common::{create_svg_from_client_tests, function, is_sorted, MockClient};
Expand Down Expand Up @@ -36,7 +36,7 @@ fn many_1() {
MockClient(7, 8, 2, 2, 0, 0, "7".to_string()),
];

let mut monitor_data: HashMap<i64, MonitorData> = HashMap::new();
let mut monitor_data: HashMap<MonitorId, MonitorData> = HashMap::new();
monitor_data.insert(0, MonitorData { x: 0, y: 0, width: 12, height: 10, combined_width: 12, combined_height: 10, workspaces_on_monitor: 1 });

let mut workspace_data: HashMap<WorkspaceId, WorkspaceData> = HashMap::new();
Expand Down Expand Up @@ -86,7 +86,7 @@ fn many_2() {
MockClient(10, 11, 2, 2, 0, 0, "9".to_string()),
];

let mut monitor_data: HashMap<i64, MonitorData> = HashMap::new();
let mut monitor_data: HashMap<MonitorId, MonitorData> = HashMap::new();
monitor_data.insert(0, MonitorData { x: 0, y: 0, width: 12, height: 10, combined_width: 12, combined_height: 10, workspaces_on_monitor: 1 });

let mut workspace_data: HashMap<WorkspaceId, WorkspaceData> = HashMap::new();
Expand Down
10 changes: 5 additions & 5 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod common {
use hyprland::shared::WorkspaceId;

use window_switcher::sort::{SortableClient, MONITOR_WORKSPACE_INDEX_OFFSET};
use window_switcher::MonitorData;
use window_switcher::{MonitorData, MonitorId};

use crate::svg::create_svg;

Expand All @@ -23,7 +23,7 @@ pub mod common {
pub u16,
pub u16,
pub WorkspaceId,
pub i64,
pub MonitorId,
pub String,
);

Expand All @@ -43,10 +43,10 @@ pub mod common {
fn ws(&self) -> WorkspaceId {
self.4
}
fn wsi(&self, monitor_count: i64) -> WorkspaceId {
fn wsi(&self, monitor_count: MonitorId) -> WorkspaceId {
self.4 - (MONITOR_WORKSPACE_INDEX_OFFSET * monitor_count as i32)
}
fn m(&self) -> i64 {
fn m(&self) -> MonitorId {
self.5
}
fn set_x(&mut self, x: u16) {
Expand All @@ -69,7 +69,7 @@ pub mod common {
pub fn create_svg_from_client_tests<SC>(
clients: &[SC],
filename: &str,
monitor_data: HashMap<i64, MonitorData>,
monitor_data: HashMap<MonitorId, MonitorData>,
) where
SC: SortableClient + Debug,
{
Expand Down
Loading

0 comments on commit 6f99a2b

Please sign in to comment.