feat: add separate toggle for temp/gamma
This commit is contained in:
parent
753588c6d3
commit
16b9811f00
3 changed files with 147 additions and 84 deletions
|
@ -82,14 +82,32 @@ Values in hours (0–23):
|
||||||
Unix socket at `/tmp/hinoirisetr.sock` accepts newline-terminated commands:
|
Unix socket at `/tmp/hinoirisetr.sock` accepts newline-terminated commands:
|
||||||
|
|
||||||
- **disable**
|
- **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**
|
- **enable**
|
||||||
Resume automatic adjustments.
|
Resume automatic adjustments.
|
||||||
|
|
||||||
|
- **enable_temp**
|
||||||
|
Resume automatic temperature adjustments.
|
||||||
|
|
||||||
|
- **enable_gamma**
|
||||||
|
Resume automatic gamma adjustments.
|
||||||
|
|
||||||
- **toggle**
|
- **toggle**
|
||||||
Switch between enabled/disabled states.
|
Switch between enabled/disabled states.
|
||||||
|
|
||||||
|
- **toggle_temp**
|
||||||
|
Switch between enabled/disabled temperature adjustments.
|
||||||
|
|
||||||
|
- **toggle_gamma**
|
||||||
|
Switch between enabled/disabled gamma adjustments.
|
||||||
|
|
||||||
- **status**
|
- **status**
|
||||||
Returns current state:
|
Returns current state:
|
||||||
`dimming is <enabled|disabled> – temp: <K>K, gamma: <%>`
|
`dimming is <enabled|disabled> – temp: <K>K, gamma: <%>`
|
||||||
|
|
18
src/lib.rs
18
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
|
/// Apply given temperature (Kelvin) and gamma (%) via hyprctl commands
|
||||||
pub fn apply_settings(temp: u16, gamma: u16, config: &Config) {
|
pub fn apply_temp(temp: u16, config: &Config) {
|
||||||
trace!("apply_settings({temp}, {gamma})");
|
trace!("apply_temp({temp})");
|
||||||
let last_temp = LAST_TEMP.load(Ordering::SeqCst);
|
let last_temp = LAST_TEMP.load(Ordering::SeqCst);
|
||||||
let last_gamma = LAST_GAMMA.load(Ordering::SeqCst);
|
if last_temp == temp {
|
||||||
if last_temp == temp && last_gamma == gamma {
|
|
||||||
trace!("Settings unchanged, skipping application");
|
trace!("Settings unchanged, skipping application");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug!("applying temperature: {temp}");
|
debug!("applying temperature: {temp}");
|
||||||
debug!("applying gamma: {gamma}");
|
|
||||||
|
|
||||||
if temp != last_temp {
|
if temp != last_temp {
|
||||||
match config.temp_backend {
|
match config.temp_backend {
|
||||||
|
@ -467,6 +465,16 @@ pub fn apply_settings(temp: u16, gamma: u16, config: &Config) {
|
||||||
}
|
}
|
||||||
LAST_TEMP.store(temp, Ordering::SeqCst);
|
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 {
|
if gamma != last_gamma {
|
||||||
match config.gamma_backend {
|
match config.gamma_backend {
|
||||||
|
|
193
src/main.rs
193
src/main.rs
|
@ -9,8 +9,8 @@ use std::time::{Duration, UNIX_EPOCH};
|
||||||
use hinoirisetr::notify::InitializedNotificationSystem;
|
use hinoirisetr::notify::InitializedNotificationSystem;
|
||||||
use hinoirisetr::time::Time;
|
use hinoirisetr::time::Time;
|
||||||
use hinoirisetr::{
|
use hinoirisetr::{
|
||||||
Config, GammaBackend, TempBackend, apply_settings, compute_settings, debug, error, info,
|
Config, GammaBackend, TempBackend, apply_gamma, apply_temp, compute_settings, debug, error,
|
||||||
reset_cache, trace, warn,
|
info, reset_cache, trace, warn,
|
||||||
};
|
};
|
||||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||||
use tokio::net::UnixListener;
|
use tokio::net::UnixListener;
|
||||||
|
@ -34,36 +34,43 @@ async fn config_reloader(notify: Arc<Notify>) {
|
||||||
loop {
|
loop {
|
||||||
trace!("config poll tick");
|
trace!("config poll tick");
|
||||||
let config_path = get_config_path();
|
let config_path = get_config_path();
|
||||||
if config_path.exists() {
|
if config_path.exists()
|
||||||
if let Ok(current_modified) = std::fs::metadata(&config_path)
|
&& let Ok(current_modified) = std::fs::metadata(&config_path)
|
||||||
.and_then(|m| m.modified())
|
.and_then(|m| m.modified())
|
||||||
.map(|t| t.duration_since(UNIX_EPOCH).unwrap().as_secs())
|
.map(|t| t.duration_since(UNIX_EPOCH).unwrap().as_secs())
|
||||||
{
|
{
|
||||||
let last: u64 = LAST_MODIFIED.load(Ordering::SeqCst);
|
let last: u64 = LAST_MODIFIED.load(Ordering::SeqCst);
|
||||||
if 0 != last {
|
if 0 != last {
|
||||||
if current_modified > last {
|
if current_modified > last {
|
||||||
trace!("{current_modified}");
|
trace!("{current_modified}");
|
||||||
trace!("{last}");
|
trace!("{last}");
|
||||||
debug!("Config file modified, reloading...");
|
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;
|
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;
|
sleep(Duration::from_secs(5)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn socket_server(disabled: Arc<AtomicBool>, notify: Arc<Notify>) {
|
async fn socket_server(
|
||||||
|
disabled_temp: Arc<AtomicBool>,
|
||||||
|
disabled_gamma: Arc<AtomicBool>,
|
||||||
|
notify: Arc<Notify>,
|
||||||
|
) {
|
||||||
let listener = UnixListener::bind(SOCKET_PATH).expect("Failed to bind socket");
|
let listener = UnixListener::bind(SOCKET_PATH).expect("Failed to bind socket");
|
||||||
|
|
||||||
match std::fs::set_permissions(SOCKET_PATH, std::fs::Permissions::from_mode(0o600)) {
|
match std::fs::set_permissions(SOCKET_PATH, std::fs::Permissions::from_mode(0o600)) {
|
||||||
Ok(_) => {trace!("socket file permissions set");},
|
Ok(_) => {
|
||||||
Err(e) => {error!("Failed to set socket file permissions: {e}");},
|
trace!("socket file permissions set");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to set socket file permissions: {e}");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("socket server bound");
|
trace!("socket server bound");
|
||||||
|
@ -85,55 +92,64 @@ async fn socket_server(disabled: Arc<AtomicBool>, notify: Arc<Notify>) {
|
||||||
|
|
||||||
if let Ok(Some(line)) = lines.next_line().await {
|
if let Ok(Some(line)) = lines.next_line().await {
|
||||||
match line.trim() {
|
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" => {
|
"disable" => {
|
||||||
trace!("disable dispatched");
|
trace!("disable dispatched");
|
||||||
let config = *config_guard().await;
|
disabled_temp.store(true, Ordering::SeqCst);
|
||||||
let disabled_clone = Arc::clone(&disabled);
|
disabled_gamma.store(true, Ordering::SeqCst);
|
||||||
let notify_state = match hinoirisetr::notify::InitializedNotificationSystem::new(
|
|
||||||
"hinoirisetr",
|
|
||||||
) {
|
|
||||||
Ok(not) => NotifyState::Enabled(not),
|
|
||||||
Err(_) => NotifyState::Disabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
disabled.store(true, Ordering::SeqCst);
|
|
||||||
notify.notify_one();
|
notify.notify_one();
|
||||||
debug!("dimming is disabled");
|
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");
|
trace!("enable dispatched");
|
||||||
disabled.store(false, Ordering::SeqCst);
|
disabled_temp.store(false, Ordering::SeqCst);
|
||||||
notify.notify_one();
|
notify.notify_one();
|
||||||
debug!("dimming is enabled");
|
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" => {
|
"toggle" => {
|
||||||
trace!("toggle dispatched");
|
trace!("toggle dispatched");
|
||||||
let now = !disabled.load(Ordering::SeqCst);
|
let now = !disabled_temp.load(Ordering::SeqCst);
|
||||||
disabled.store(now, Ordering::SeqCst);
|
disabled_temp.store(now, Ordering::SeqCst);
|
||||||
|
disabled_gamma.store(now, Ordering::SeqCst);
|
||||||
notify.notify_one();
|
notify.notify_one();
|
||||||
debug!("dimming is {}", if now { "enabled" } else { "disabled" });
|
debug!("dimming is {}", if now { "enabled" } else { "disabled" });
|
||||||
}
|
}
|
||||||
|
@ -143,14 +159,17 @@ async fn socket_server(disabled: Arc<AtomicBool>, notify: Arc<Notify>) {
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await);
|
let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await);
|
||||||
let status = format!(
|
let status = format!(
|
||||||
"dimming is {} - temp: {}K, gamma: {}%",
|
"dimming - temp: {}, gamma: {}",
|
||||||
if disabled.load(Ordering::SeqCst) {
|
if disabled_temp.load(Ordering::SeqCst) {
|
||||||
"disabled"
|
"disabled".to_string()
|
||||||
} else {
|
} else {
|
||||||
"enabled"
|
format!("{cur_temp}K")
|
||||||
},
|
},
|
||||||
cur_temp,
|
if disabled_gamma.load(Ordering::SeqCst) {
|
||||||
cur_gamma
|
"disabled".to_string()
|
||||||
|
} else {
|
||||||
|
format!("{cur_gamma}%")
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = writer.write(status.as_bytes()).await {
|
if let Err(e) = writer.write(status.as_bytes()).await {
|
||||||
|
@ -170,11 +189,19 @@ async fn socket_server(disabled: Arc<AtomicBool>, notify: Arc<Notify>) {
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await);
|
let (cur_temp, cur_gamma) = compute_settings(now, &*config_guard().await);
|
||||||
|
|
||||||
let body = if disabled.load(Ordering::SeqCst) {
|
let status = format!(
|
||||||
"disabled".to_string()
|
"dimming - temp: {}, gamma: {}",
|
||||||
} else {
|
if disabled_temp.load(Ordering::SeqCst) {
|
||||||
format!("temp: {cur_temp}K, gamma: {cur_gamma}%")
|
"disabled".to_string()
|
||||||
};
|
} else {
|
||||||
|
format!("{cur_temp}K")
|
||||||
|
},
|
||||||
|
if disabled_gamma.load(Ordering::SeqCst) {
|
||||||
|
"disabled".to_string()
|
||||||
|
} else {
|
||||||
|
format!("{cur_gamma}%")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
match notification {
|
match notification {
|
||||||
NotifyState::Enabled(ref not) => {
|
NotifyState::Enabled(ref not) => {
|
||||||
|
@ -182,7 +209,7 @@ async fn socket_server(disabled: Arc<AtomicBool>, notify: Arc<Notify>) {
|
||||||
let timeout = config_guard().await.notification_timeout;
|
let timeout = config_guard().await.notification_timeout;
|
||||||
match not.show_notification(
|
match not.show_notification(
|
||||||
"Sunsetting",
|
"Sunsetting",
|
||||||
&body,
|
&status,
|
||||||
"notification-icon",
|
"notification-icon",
|
||||||
timeout as i32,
|
timeout as i32,
|
||||||
) {
|
) {
|
||||||
|
@ -231,7 +258,8 @@ async fn main() {
|
||||||
std::process::exit(1);
|
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());
|
let notify = Arc::new(Notify::new());
|
||||||
|
|
||||||
// load config
|
// load config
|
||||||
|
@ -305,10 +333,11 @@ async fn main() {
|
||||||
|
|
||||||
// Spawn control socket server
|
// 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);
|
let notify = Arc::clone(¬ify);
|
||||||
tokio::spawn(async move {
|
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 now = get_time();
|
||||||
let (temp, gamma) = compute_settings(now, &*config_guard().await);
|
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}%");
|
trace!("initial settings applied: {temp}K, {gamma}%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,16 +377,23 @@ async fn main() {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = async {
|
_ = async {
|
||||||
loop {
|
loop {
|
||||||
if disabled.load(Ordering::SeqCst) {
|
let now = get_time();
|
||||||
apply_settings(
|
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.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.gamma_day,
|
||||||
&*config_guard().await,
|
&*config_guard().await,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let now = get_time();
|
apply_gamma(gamma, &*config_guard().await);
|
||||||
let (temp, gamma) = compute_settings(now, &*config_guard().await);
|
|
||||||
apply_settings(temp, gamma, &*config_guard().await);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notify.notified().await;
|
notify.notified().await;
|
||||||
|
|
Loading…
Reference in a new issue