From 16b9811f000d23a51943713edecc001244d6d75b Mon Sep 17 00:00:00 2001 From: Vladimir Rubin Date: Sat, 14 Jun 2025 20:30:05 +0300 Subject: [PATCH] feat: add separate toggle for temp/gamma --- manpages/hinoirisetr.1.md | 20 +++- src/lib.rs | 18 +++- src/main.rs | 193 +++++++++++++++++++++++--------------- 3 files changed, 147 insertions(+), 84 deletions(-) diff --git a/manpages/hinoirisetr.1.md b/manpages/hinoirisetr.1.md index cfedce7..7c7762e 100644 --- a/manpages/hinoirisetr.1.md +++ b/manpages/hinoirisetr.1.md @@ -82,14 +82,32 @@ Values in hours (0–23): Unix socket at `/tmp/hinoirisetr.sock` accepts newline-terminated commands: - **disable** - Pause automatic adjustments; keeps current settings. + Pause automatic adjustments; sets day settings. + +- **disable_temp** + Pause automatic temperature adjustments; sets day settings. + +- **disable_gamma** + Pause automatic gamma adjustments; sets day settings. - **enable** Resume automatic adjustments. +- **enable_temp** + Resume automatic temperature adjustments. + +- **enable_gamma** + Resume automatic gamma adjustments. + - **toggle** Switch between enabled/disabled states. +- **toggle_temp** + Switch between enabled/disabled temperature adjustments. + +- **toggle_gamma** + Switch between enabled/disabled gamma adjustments. + - **status** Returns current state: `dimming is – temp: K, gamma: <%>` diff --git a/src/lib.rs b/src/lib.rs index 02b1946..543f028 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -429,16 +429,14 @@ pub fn compute_settings(now: Time, config: &Config) -> (u16, u16) { } /// Apply given temperature (Kelvin) and gamma (%) via hyprctl commands -pub fn apply_settings(temp: u16, gamma: u16, config: &Config) { - trace!("apply_settings({temp}, {gamma})"); +pub fn apply_temp(temp: u16, config: &Config) { + trace!("apply_temp({temp})"); let last_temp = LAST_TEMP.load(Ordering::SeqCst); - let last_gamma = LAST_GAMMA.load(Ordering::SeqCst); - if last_temp == temp && last_gamma == gamma { + if last_temp == temp { trace!("Settings unchanged, skipping application"); return; } debug!("applying temperature: {temp}"); - debug!("applying gamma: {gamma}"); if temp != last_temp { match config.temp_backend { @@ -467,6 +465,16 @@ pub fn apply_settings(temp: u16, gamma: u16, config: &Config) { } LAST_TEMP.store(temp, Ordering::SeqCst); } +} + +pub fn apply_gamma(gamma: u16, config: &Config) { + trace!("apply_gamma({gamma})"); + let last_gamma = LAST_GAMMA.load(Ordering::SeqCst); + if last_gamma == gamma { + trace!("Settings unchanged, skipping application"); + return; + } + debug!("applying gamma: {gamma}"); if gamma != last_gamma { match config.gamma_backend { diff --git a/src/main.rs b/src/main.rs index 1a97e39..8cafccf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,8 @@ use std::time::{Duration, UNIX_EPOCH}; use hinoirisetr::notify::InitializedNotificationSystem; use hinoirisetr::time::Time; use hinoirisetr::{ - Config, GammaBackend, TempBackend, apply_settings, compute_settings, debug, error, info, - reset_cache, trace, warn, + Config, GammaBackend, TempBackend, apply_gamma, apply_temp, compute_settings, debug, error, + info, reset_cache, trace, warn, }; use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; use tokio::net::UnixListener; @@ -34,36 +34,43 @@ async fn config_reloader(notify: Arc) { loop { trace!("config poll tick"); let config_path = get_config_path(); - if config_path.exists() { - if let Ok(current_modified) = std::fs::metadata(&config_path) + if config_path.exists() + && let Ok(current_modified) = std::fs::metadata(&config_path) .and_then(|m| m.modified()) .map(|t| t.duration_since(UNIX_EPOCH).unwrap().as_secs()) - { - let last: u64 = LAST_MODIFIED.load(Ordering::SeqCst); - if 0 != last { - if current_modified > last { - trace!("{current_modified}"); - trace!("{last}"); - debug!("Config file modified, reloading..."); - reload_config(Arc::clone(¬ify)).await; - } - } else { - // File is new, reload to capture initial state - debug!("Config file detected, reloading..."); + { + let last: u64 = LAST_MODIFIED.load(Ordering::SeqCst); + if 0 != last { + if current_modified > last { + trace!("{current_modified}"); + trace!("{last}"); + debug!("Config file modified, reloading..."); reload_config(Arc::clone(¬ify)).await; } + } else { + // File is new, reload to capture initial state + debug!("Config file detected, reloading..."); + reload_config(Arc::clone(¬ify)).await; } } sleep(Duration::from_secs(5)).await; } } -async fn socket_server(disabled: Arc, notify: Arc) { +async fn socket_server( + disabled_temp: Arc, + disabled_gamma: Arc, + notify: Arc, +) { let listener = UnixListener::bind(SOCKET_PATH).expect("Failed to bind socket"); match std::fs::set_permissions(SOCKET_PATH, std::fs::Permissions::from_mode(0o600)) { - Ok(_) => {trace!("socket file permissions set");}, - Err(e) => {error!("Failed to set socket file permissions: {e}");}, + Ok(_) => { + trace!("socket file permissions set"); + } + Err(e) => { + error!("Failed to set socket file permissions: {e}"); + } }; trace!("socket server bound"); @@ -85,55 +92,64 @@ async fn socket_server(disabled: Arc, notify: Arc) { if let Ok(Some(line)) = lines.next_line().await { match line.trim() { + "disable_temp" => { + trace!("disable_gamma dispatched"); + + disabled_temp.store(true, Ordering::SeqCst); + notify.notify_one(); + debug!("temp dimming is disabled"); + } + "disable_gamma" => { + trace!("disable_gamma dispatched"); + disabled_gamma.store(true, Ordering::SeqCst); + notify.notify_one(); + debug!("gamma dimming is disabled"); + } "disable" => { trace!("disable dispatched"); - let config = *config_guard().await; - let disabled_clone = Arc::clone(&disabled); - let notify_state = match hinoirisetr::notify::InitializedNotificationSystem::new( - "hinoirisetr", - ) { - Ok(not) => NotifyState::Enabled(not), - Err(_) => NotifyState::Disabled, - }; - - disabled.store(true, Ordering::SeqCst); + disabled_temp.store(true, Ordering::SeqCst); + disabled_gamma.store(true, Ordering::SeqCst); notify.notify_one(); debug!("dimming is disabled"); - - // Spawn a background task to remind after timeout - println!("{}", config.disable_timeout); - if config.disable_timeout != 0 { - debug!("Spawning dimming timeout task"); - tokio::spawn(async move { - let timeout_secs = config.disable_timeout; - tokio::time::sleep(Duration::from_secs(timeout_secs.into())).await; - - if disabled_clone.load(Ordering::SeqCst) { - warn!("You've had dimming disabled for too long!"); - - // Show notification - if let NotifyState::Enabled(ref not) = notify_state { - let _ = not.show_notification( - "Dimming Reminder", - "You have dimming disabled!", - "notification-icon", - (config.notification_timeout as i32) * 5, - ); - } - } - }); - } } - "enable" => { + "enable_temp" => { trace!("enable dispatched"); - disabled.store(false, Ordering::SeqCst); + disabled_temp.store(false, Ordering::SeqCst); notify.notify_one(); debug!("dimming is enabled"); } + "enable_gamma" => { + trace!("enable_gamma dispatched"); + disabled_gamma.store(false, Ordering::SeqCst); + notify.notify_one(); + debug!("gamma dimming is enabled"); + } + "enable" => { + trace!("enable dispatched"); + disabled_temp.store(false, Ordering::SeqCst); + disabled_gamma.store(false, Ordering::SeqCst); + notify.notify_one(); + debug!("dimming is enabled"); + } + "toggle_temp" => { + trace!("toggle dispatched"); + let now = !disabled_temp.load(Ordering::SeqCst); + disabled_temp.store(now, Ordering::SeqCst); + notify.notify_one(); + debug!("temp dimming is {}", if now { "enabled" } else { "disabled" }); + } + "toggle_gamma" => { + trace!("toggle_gamma dispatched"); + let now = !disabled_gamma.load(Ordering::SeqCst); + disabled_gamma.store(now, Ordering::SeqCst); + notify.notify_one(); + debug!("gamma dimming is {}", if now { "enabled" } else { "disabled" }); + } "toggle" => { trace!("toggle dispatched"); - let now = !disabled.load(Ordering::SeqCst); - disabled.store(now, Ordering::SeqCst); + let now = !disabled_temp.load(Ordering::SeqCst); + disabled_temp.store(now, Ordering::SeqCst); + disabled_gamma.store(now, Ordering::SeqCst); notify.notify_one(); debug!("dimming is {}", if now { "enabled" } else { "disabled" }); } @@ -143,14 +159,17 @@ async fn socket_server(disabled: Arc, notify: Arc) { let now = get_time(); let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await); let status = format!( - "dimming is {} - temp: {}K, gamma: {}%", - if disabled.load(Ordering::SeqCst) { - "disabled" + "dimming - temp: {}, gamma: {}", + if disabled_temp.load(Ordering::SeqCst) { + "disabled".to_string() } else { - "enabled" + format!("{cur_temp}K") }, - cur_temp, - cur_gamma + if disabled_gamma.load(Ordering::SeqCst) { + "disabled".to_string() + } else { + format!("{cur_gamma}%") + } ); if let Err(e) = writer.write(status.as_bytes()).await { @@ -170,11 +189,19 @@ async fn socket_server(disabled: Arc, notify: Arc) { let now = get_time(); let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await); - let body = if disabled.load(Ordering::SeqCst) { - "disabled".to_string() - } else { - format!("temp: {cur_temp}K, gamma: {cur_gamma}%") - }; + let status = format!( + "dimming - temp: {}, gamma: {}", + if disabled_temp.load(Ordering::SeqCst) { + "disabled".to_string() + } else { + format!("{cur_temp}K") + }, + if disabled_gamma.load(Ordering::SeqCst) { + "disabled".to_string() + } else { + format!("{cur_gamma}%") + } + ); match notification { NotifyState::Enabled(ref not) => { @@ -182,7 +209,7 @@ async fn socket_server(disabled: Arc, notify: Arc) { let timeout = config_guard().await.notification_timeout; match not.show_notification( "Sunsetting", - &body, + &status, "notification-icon", timeout as i32, ) { @@ -231,7 +258,8 @@ async fn main() { std::process::exit(1); } - let disabled = Arc::new(AtomicBool::new(false)); + let disabled_temp = Arc::new(AtomicBool::new(false)); + let disabled_gamma = Arc::new(AtomicBool::new(false)); let notify = Arc::new(Notify::new()); // load config @@ -305,10 +333,11 @@ async fn main() { // Spawn control socket server { - let disabled = Arc::clone(&disabled); + let disabled_temp = Arc::clone(&disabled_temp); + let disabled_gamma = Arc::clone(&disabled_gamma); let notify = Arc::clone(¬ify); tokio::spawn(async move { - socket_server(disabled, notify).await; + socket_server(disabled_temp, disabled_gamma, notify).await; }); } @@ -339,7 +368,8 @@ async fn main() { { let now = get_time(); let (temp, gamma) = compute_settings(now, &*config_guard().await); - apply_settings(temp, gamma, &*config_guard().await); + apply_temp(temp, &*config_guard().await); + apply_gamma(gamma, &*config_guard().await); trace!("initial settings applied: {temp}K, {gamma}%"); } @@ -347,16 +377,23 @@ async fn main() { tokio::select! { _ = async { loop { - if disabled.load(Ordering::SeqCst) { - apply_settings( + let now = get_time(); + let (temp, gamma) = compute_settings(now, &*config_guard().await); + if disabled_temp.load(Ordering::SeqCst) { + apply_temp( config_guard().await.temp_day, + &*config_guard().await, + ); + } else { + apply_temp(temp, &*config_guard().await); + } + if disabled_gamma.load(Ordering::SeqCst) { + apply_gamma( config_guard().await.gamma_day, &*config_guard().await, ); } else { - let now = get_time(); - let (temp, gamma) = compute_settings(now, &*config_guard().await); - apply_settings(temp, gamma, &*config_guard().await); + apply_gamma(gamma, &*config_guard().await); } notify.notified().await;