Skip to content

Commit

Permalink
Merge pull request #6 from donovanglover/add/dialog-events
Browse files Browse the repository at this point in the history
feat: Add --dialog-dim
  • Loading branch information
donovanglover authored Aug 13, 2023
2 parents 5e6ef05 + 262fb9f commit 4e04865
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Options:
-n, --no-dim-when-only Don't dim when switching to a workspace that only has one visible window
-i, --ignore-entering-special Don't dim when opening a special workspace
-I, --ignore-leaving-special Don't dim when closing a special workspace
-D, --dialog-dim [<STRENGTH>] Dim windows if they're the same class and floating (strength_default: 0.7)
-v, --verbose Show information about what hyprdim is doing
-h, --help Print help (see more with '--help')
-V, --version Print version
Expand Down
2 changes: 2 additions & 0 deletions completions/_hyprdim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ _hyprdim() {
'--fade=[Fade animation speed from 0 (instantaneous) to 255 (very slow)]:FADE: ' \
'-b+[Bezier curve used for the animation]:BEZIER: ' \
'--bezier=[Bezier curve used for the animation]:BEZIER: ' \
'-D+[Dim windows if they'\''re the same class and floating (strength_default\: 0.7)]' \
'--dialog-dim=[Dim windows if they'\''re the same class and floating (strength_default\: 0.7)]' \
'-p[Prevent dim_inactive from being disabled by \`hyprctl reload\` etc]' \
'--persist[Prevent dim_inactive from being disabled by \`hyprctl reload\` etc]' \
'-n[Don'\''t dim when switching to a workspace that only has one visible window]' \
Expand Down
10 changes: 9 additions & 1 deletion completions/hyprdim.bash
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ _hyprdim() {

case "${cmd}" in
hyprdim)
opts="-s -d -f -b -p -n -i -I -v -h -V --strength --duration --fade --bezier --persist --no-dim-when-only --ignore-entering-special --ignore-leaving-special --verbose --help --version"
opts="-s -d -f -b -p -n -i -I -D -v -h -V --strength --duration --fade --bezier --persist --no-dim-when-only --ignore-entering-special --ignore-leaving-special --dialog-dim --verbose --help --version"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down Expand Up @@ -57,6 +57,14 @@ _hyprdim() {
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--dialog-dim)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-D)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
Expand Down
1 change: 1 addition & 0 deletions completions/hyprdim.fish
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ complete -c hyprdim -s s -l strength -d 'A value from 0 (no dim) to 1 (maximum d
complete -c hyprdim -s d -l duration -d 'How many milliseconds to wait before removing dim' -r
complete -c hyprdim -s f -l fade -d 'Fade animation speed from 0 (instantaneous) to 255 (very slow)' -r
complete -c hyprdim -s b -l bezier -d 'Bezier curve used for the animation' -r
complete -c hyprdim -s D -l dialog-dim -d 'Dim windows if they\'re the same class and floating (strength_default: 0.7)' -r
complete -c hyprdim -s p -l persist -d 'Prevent dim_inactive from being disabled by `hyprctl reload` etc'
complete -c hyprdim -s n -l no-dim-when-only -d 'Don\'t dim when switching to a workspace that only has one visible window'
complete -c hyprdim -s i -l ignore-entering-special -d 'Don\'t dim when opening a special workspace'
Expand Down
13 changes: 12 additions & 1 deletion man/hyprdim.1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.SH NAME
hyprdim \- Automatically dim windows in Hyprland when switching between them.
.SH SYNOPSIS
\fBhyprdim\fR [\fB\-s\fR|\fB\-\-strength\fR] [\fB\-d\fR|\fB\-\-duration\fR] [\fB\-f\fR|\fB\-\-fade\fR] [\fB\-b\fR|\fB\-\-bezier\fR] [\fB\-p\fR|\fB\-\-persist\fR] [\fB\-n\fR|\fB\-\-no\-dim\-when\-only\fR] [\fB\-i\fR|\fB\-\-ignore\-entering\-special\fR] [\fB\-I\fR|\fB\-\-ignore\-leaving\-special\fR] [\fB\-v\fR|\fB\-\-verbose\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR]
\fBhyprdim\fR [\fB\-s\fR|\fB\-\-strength\fR] [\fB\-d\fR|\fB\-\-duration\fR] [\fB\-f\fR|\fB\-\-fade\fR] [\fB\-b\fR|\fB\-\-bezier\fR] [\fB\-p\fR|\fB\-\-persist\fR] [\fB\-n\fR|\fB\-\-no\-dim\-when\-only\fR] [\fB\-i\fR|\fB\-\-ignore\-entering\-special\fR] [\fB\-I\fR|\fB\-\-ignore\-leaving\-special\fR] [\fB\-D\fR|\fB\-\-dialog\-dim\fR] [\fB\-v\fR|\fB\-\-verbose\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR]
.SH DESCRIPTION
.PP
hyprdim is a daemon that automatically dims windows in Hyprland[1] when
Expand Down Expand Up @@ -74,6 +74,17 @@ Don\*(Aqt dim when closing a special workspace

This is useful if you have multiple windows in your main workspace and usually don\*(Aqt switch between them.
.TP
\fB\-D\fR, \fB\-\-dialog\-dim\fR=\fISTRENGTH\fR
Dim windows if they\*(Aqre the same class and floating (strength_default: 0.7)

This option is particularly useful for dimming dialog boxes started by applications since those tend to have the same class and be floating.

The dim is a permanent dim while working in the floating window of the same class.

Note that the dim is removed when switching workspaces or doing any other event.

Optionally specify a strength value to change how much dim is applied to dialog windows. The default strength value is 0.7.
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Show information about what hyprdim is doing
.TP
Expand Down
14 changes: 14 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ pub struct Cli {
#[arg(short = 'I', long, default_value_t = false)]
pub ignore_leaving_special: bool,

/// Dim windows if they're the same class and floating (strength_default: 0.7)
///
/// This option is particularly useful for dimming dialog boxes started by applications
/// since those tend to have the same class and be floating.
///
/// The dim is a permanent dim while working in the floating window of the same class.
///
/// Note that the dim is removed when switching workspaces or doing any other event.
///
/// Optionally specify a strength value to change how much dim is applied to dialog windows.
/// The default strength value is 0.7.
#[arg(short = 'D', long, value_name = "STRENGTH", default_value = None, default_missing_value = "0.7", num_args = 0..=1)]
pub dialog_dim: Option<f64>,

/// Show information about what hyprdim is doing
#[arg(short, long, default_value_t = false)]
pub verbose: bool,
Expand Down
32 changes: 29 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub fn log(text: &str) {
/// enough, dimming is disabled.
pub fn spawn_dim_thread(
num_threads: Arc<Mutex<u16>>,
is_set_dim: Arc<Mutex<bool>>,
strength: f64,
persist: bool,
duration: u64,
Expand All @@ -43,17 +44,33 @@ pub fn spawn_dim_thread(
thread::sleep(time::Duration::from_millis(duration));
*num_threads.lock().unwrap() -= 1;

// If this is the last thread, remove dim
// If this is the last thread and we're not setting dim, remove dim
if *num_threads.lock().unwrap() == 0 {
Keyword::set("decoration:dim_strength", 0)?;
if *is_set_dim.lock().unwrap() {
log("info: Last thread, but not removing dim since permanent dim is active");
} else {
Keyword::set("decoration:dim_strength", 0)?;

log("info: Removed dim (last thread)");
log("info: Removed dim (last thread)");
}
}

Ok(())
});
}

pub fn set_dim(strength: f64, persist: bool) -> hyprland::Result<()> {
if persist {
Keyword::set("decoration:dim_inactive", "yes")?;
};

Keyword::set("decoration:dim_strength", strength)?;

log("info: Set a permanent dim (until next event) without spawning thread");

Ok(())
}

/// Gets whether the current workspace is a special workspace or not.
///
/// This function works by getting which workspace the active window is in.
Expand Down Expand Up @@ -89,3 +106,12 @@ pub fn special_only_has_one_visible_window() -> bool {

false
}

pub fn is_floating() -> bool {
if let Some(client) = Client::get_active().unwrap() {
let Client { floating, .. } = client;
return floating;
}

false
}
34 changes: 30 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use clap::Parser;
use cli::Cli;
use hyprdim::is_floating;
use hyprdim::is_special;
use hyprdim::log;
use hyprdim::set_dim;
use hyprdim::spawn_dim_thread;
use hyprdim::special_only_has_one_visible_window;
use hyprland::data::Workspace;
Expand Down Expand Up @@ -47,6 +49,7 @@ fn main() -> hyprland::Result<()> {
no_dim_when_only,
ignore_entering_special,
ignore_leaving_special,
dialog_dim,
..
} = Cli::parse();

Expand All @@ -58,6 +61,8 @@ fn main() -> hyprland::Result<()> {
// Keep track of state
let num_threads: Arc<Mutex<u16>> = Arc::new(Mutex::new(0));
let last_address: Arc<Mutex<Option<Address>>> = Arc::new(Mutex::new(None));
let last_class: Arc<Mutex<Option<String>>> = Arc::new(Mutex::new(None));
let is_set_dim: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
let in_special_workspace: Arc<Mutex<bool>> = Arc::new(Mutex::new(is_special()));

// Initialize with dim so the user sees something, but only if the user wants dim
Expand All @@ -68,16 +73,17 @@ fn main() -> hyprland::Result<()> {
Keyword::set("decoration:dim_strength", 0)?;
Keyword::set("decoration:dim_inactive", "yes")?;
} else {
spawn_dim_thread(num_threads.clone(), strength, persist, duration, true);
spawn_dim_thread(num_threads.clone(), is_set_dim.clone(), strength, persist, duration, true);
}

// On active window changes
event_listener.add_active_window_change_handler(move |data| {
// Ignore the event if no window_address was given
let Some(WindowEventData { window_address, .. }) = data else { return };
let Some(WindowEventData { window_address, window_class, .. }) = data else { return };

// Clone inside since u16 does not implement copy
// Clone inside since primitives don't implement copy
let num_threads = num_threads.clone();
let is_set_dim = is_set_dim.clone();

// If the last address is the same as the new window, don't dim
if let Some(ref old_address) = *last_address.lock().unwrap() {
Expand All @@ -86,7 +92,16 @@ fn main() -> hyprland::Result<()> {
}
}

let mut same_class = false;

if let Some(ref old_class) = *last_class.lock().unwrap() {
if format!("{old_class}") == format!("{window_class}") {
same_class = true;
}
}

*last_address.lock().unwrap() = Some(window_address.clone());
*last_class.lock().unwrap() = Some(window_class.clone());

// Get the state of the current parent workspace
let parent_workspace = Workspace::get_active().unwrap();
Expand Down Expand Up @@ -118,6 +133,16 @@ fn main() -> hyprland::Result<()> {
}
}

// Enable dim when using a floating windows with the same class as the last window,
// but only if the user specified the argument to do so.
if let Some(dialog_strength) = dialog_dim {
if same_class && is_floating() {
*is_set_dim.lock().unwrap() = true;
set_dim(dialog_strength, persist).unwrap();
return;
}
}

// Don't dim when switching to another workspace with only one window
if no_dim_when_only {
if (parent_workspace.windows == 1 || parent_workspace.fullscreen)
Expand All @@ -133,7 +158,8 @@ fn main() -> hyprland::Result<()> {
}
}

spawn_dim_thread(num_threads, strength, persist, duration, false);
*is_set_dim.lock().unwrap() = false;
spawn_dim_thread(num_threads, is_set_dim, strength, persist, duration, false);
});

thread::spawn(move || -> hyprland::Result<()> {
Expand Down

0 comments on commit 4e04865

Please sign in to comment.