Skip to content

Commit

Permalink
Merge pull request #42 from donovanglover/refactor
Browse files Browse the repository at this point in the history
chore: Refactor
  • Loading branch information
donovanglover authored Jan 9, 2024
2 parents 8ccbade + 00e5966 commit 296b752
Show file tree
Hide file tree
Showing 10 changed files with 418 additions and 341 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ assert_cmd = "2.0.12"
rustympkglib = "0.1.1"
serde = "1.0.190"
toml = "0.8.6"

[lints.rust]
unsafe_code = "forbid"
missing_docs = "deny"
4 changes: 3 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Generates man pages and shell completions for hyprnome.
include!("src/cli.rs");

use clap::Command;
Expand All @@ -16,7 +18,7 @@ fn generate_man_pages(cmd: Command) {
create_dir_all(&man_dir).unwrap();

let man = Man::new(cmd);
let mut buffer: Vec<u8> = Default::default();
let mut buffer: Vec<u8> = vec![];

man.render(&mut buffer).expect("Man page generation failed");
write(man_dir.join(NAME.to_owned() + ".1"), buffer).expect("Failed to write man page");
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
max_width = 200
40 changes: 32 additions & 8 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,41 @@ fn styles() -> Styles {

#[derive(Parser)]
#[command(author, version, about, long_about = LONG_ABOUT, styles = styles())]
pub struct Cli {
struct Cli {
/// Go to the previous workspace instead of the next
///
/// By default hyprnome will advance to the next workspace. --previous is necessary
/// when you want to go backwards in the list of occupied workspaces.
#[arg(short, long, default_value_t = false)]
pub previous: bool,
previous: bool,

/// Move the active window to the dispatched workspace
///
/// This flag lets you move windows across workspaces without having to worry about
/// the current workspace you're in.
#[arg(short, long, default_value_t = false)]
pub _move: bool,
_move: bool,

/// Don't create empty workspaces in the given direction
///
/// This prevents empty workspaces from being created when no occupied workspaces
/// remain in the given direction.
#[arg(short, long, default_value_t = false)]
pub no_empty: bool,
no_empty: bool,

/// Don't create empty workspaces to the left
///
/// NOTE: This flag is deprecated and has been replaced with --no-empty. The flag is
/// kept for backwards compatibility with v0.1.0, but is hidden by default.
#[arg(long, default_value_t = false, hide = true)]
pub no_empty_before: bool,
no_empty_before: bool,

/// Don't create empty workspaces to the right
///
/// NOTE: This flag is deprecated and has been replaced with --no-empty. The flag is
/// kept for backwards compatibility with v0.1.0, but is hidden by default.
#[arg(short = 'N', long, default_value_t = false, hide = true)]
pub no_empty_after: bool,
no_empty_after: bool,

/// Don't auto-close special workspaces when switching workspaces
///
Expand Down Expand Up @@ -102,9 +102,33 @@ pub struct Cli {
/// Summary: This flag is available so users can choose the old behavior, however automatically
/// closing special workspaces (the default) does have its benefits.
#[arg(short, long, default_value_t = false)]
pub keep_special: bool,
keep_special: bool,

/// Print debugging information
#[arg(short, long, default_value_t = false)]
pub verbose: bool,
verbose: bool,
}

/// Log information with --verbose
pub fn log(text: &str) {
let Cli { verbose, .. } = Cli::parse();

if verbose {
println!("{text}");
}
}

/// Gets an ID to dispatch based on the current workspace state and cli options
pub fn get_options() -> (bool, bool, bool, bool, bool, bool) {
let Cli {
_move,
keep_special,
previous,
no_empty,
no_empty_before,
no_empty_after,
..
} = Cli::parse();

(_move, keep_special, previous, no_empty, no_empty_before, no_empty_after)
}
67 changes: 67 additions & 0 deletions src/hyprland.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use hyprland::data::Client;
use hyprland::data::Monitors;
use hyprland::data::Workspace;
use hyprland::data::Workspaces;
use hyprland::dispatch::{Dispatch, DispatchType, WorkspaceIdentifierWithSpecial};
use hyprland::prelude::*;
use hyprnome::WorkspaceState;

pub fn get_state() -> hyprland::Result<WorkspaceState> {
let monitors = Monitors::get()?;
let workspaces = Workspaces::get()?.filter(|workspace| workspace.id > 0);
let current_id = Workspace::get_active()?.id;

let monitor_ids: Vec<i32> = workspaces
.clone()
.filter(|workspace| {
if let Some(monitor) = monitors.clone().find(|monitor| monitor.focused) {
workspace.monitor == monitor.name
} else {
false
}
})
.map(|workspace| workspace.id)
.collect();

let occupied_ids: Vec<i32> = workspaces.map(|workspace| workspace.id).collect();

Ok(WorkspaceState::new(current_id, monitor_ids, occupied_ids))
}

/// Gets whether the current workspace is a special workspace or not.
///
/// This function works by getting which workspace the active window is in.
///
/// The if statement is used to make sure this function works when no window
/// is the active window.
pub fn is_special() -> hyprland::Result<bool> {
if let Some(client) = Client::get_active()? {
let Client { workspace, .. } = client;

return Ok(workspace.name.contains("special"));
}

Ok(false)
}

pub fn change_workspace(id: i32, _move: bool, keep_special: bool) -> hyprland::Result<()> {
let id = WorkspaceIdentifierWithSpecial::Id(id);

if _move {
let was_special = is_special()?;

hyprland::dispatch!(MoveToWorkspace, id, None)?;

if !keep_special && was_special {
hyprland::dispatch!(ToggleSpecialWorkspace, None)
} else {
Ok(())
}
} else {
if !keep_special && is_special()? {
hyprland::dispatch!(ToggleSpecialWorkspace, None)?;
}

hyprland::dispatch!(Workspace, id)
}
}
Loading

0 comments on commit 296b752

Please sign in to comment.