feat: add more backends

This commit is contained in:
Vladimir Rubin 2025-05-02 23:02:27 +03:00
parent 3bc6d195fe
commit 6ca50ac2bb
Signed by: vavakado
GPG key ID: CAB744727F36B524
5 changed files with 116 additions and 32 deletions

2
Cargo.lock generated
View file

@ -244,7 +244,7 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]] [[package]]
name = "hinoirisetr" name = "hinoirisetr"
version = "0.3.1" version = "0.4.0"
dependencies = [ dependencies = [
"libloading", "libloading",
"smol", "smol",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "hinoirisetr" name = "hinoirisetr"
version = "0.3.1" version = "0.4.0"
authors = ["Vladimir Rubin <vavakado@proton.me>"] authors = ["Vladimir Rubin <vavakado@proton.me>"]
description = "A daemon to dim the screen at night" description = "A daemon to dim the screen at night"
license = "MIT" license = "MIT"

View file

@ -42,7 +42,7 @@
packages.default = pkgs.rustPlatform.buildRustPackage { packages.default = pkgs.rustPlatform.buildRustPackage {
pname = "hinoirisetr"; pname = "hinoirisetr";
version = "0.3.1"; version = "0.4.0";
src = ./.; src = ./.;

View file

@ -27,12 +27,26 @@ pub struct Config {
pub notification_timeout: u32, pub notification_timeout: u32,
pub gamma_backend: GammaBackend, pub gamma_backend: GammaBackend,
pub temp_backend: TempBackend,
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum GammaBackend { pub enum GammaBackend {
Hyprctl, Hyprctl,
Ddcutil, Ddcutil,
Xsct,
Redshift,
Gammastep,
None,
}
#[derive(Debug, Copy, Clone)]
pub enum TempBackend {
Hyprctl,
Redshift,
Xsct,
Gammastep,
None,
} }
impl Default for Config { impl Default for Config {
@ -48,6 +62,7 @@ impl Default for Config {
sunrise_end: 7, sunrise_end: 7,
notification_timeout: 5000, notification_timeout: 5000,
gamma_backend: GammaBackend::Hyprctl, gamma_backend: GammaBackend::Hyprctl,
temp_backend: TempBackend::Hyprctl,
} }
} }
} }
@ -60,6 +75,7 @@ pub enum ConfigError {
InvalidTime(String), InvalidTime(String),
InvalidGamma(String), InvalidGamma(String),
InvalidGammaBackend(String), InvalidGammaBackend(String),
InvalidTempBackend(String),
} }
impl From<std::io::Error> for ConfigError { impl From<std::io::Error> for ConfigError {
@ -108,8 +124,20 @@ impl Config {
"gamma_backend" => match value.to_lowercase().as_str() { "gamma_backend" => match value.to_lowercase().as_str() {
"hyprctl" => config.gamma_backend = GammaBackend::Hyprctl, "hyprctl" => config.gamma_backend = GammaBackend::Hyprctl,
"ddcutil" => config.gamma_backend = GammaBackend::Ddcutil, "ddcutil" => config.gamma_backend = GammaBackend::Ddcutil,
"gammastep" => config.gamma_backend = GammaBackend::Gammastep,
"xsct" => config.gamma_backend = GammaBackend::Xsct,
"redshift" => config.gamma_backend = GammaBackend::Redshift,
"none" => config.gamma_backend = GammaBackend::None,
_ => return Err(ConfigError::InvalidGammaBackend(value.to_string())), _ => return Err(ConfigError::InvalidGammaBackend(value.to_string())),
}, },
"temp_backend" => match value.to_lowercase().as_str() {
"hyprctl" => config.temp_backend = TempBackend::Hyprctl,
"gammastep" => config.temp_backend = TempBackend::Gammastep,
"xsct" => config.temp_backend = TempBackend::Xsct,
"redshift" => config.temp_backend = TempBackend::Redshift,
"none" => config.temp_backend = TempBackend::None,
_ => return Err(ConfigError::InvalidTempBackend(value.to_string())),
},
_ => {} _ => {}
}, },
"gamma" => match key_trimmed { "gamma" => match key_trimmed {
@ -244,17 +272,37 @@ 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, backend: GammaBackend) { pub fn apply_settings(temp: u16, gamma: u16, config: &Config) {
trace!("apply_settings({temp}, {gamma})"); trace!("apply_settings({temp}, {gamma})");
debug!("applying temperature: {temp}"); debug!("applying temperature: {temp}");
debug!("applying gamma: {gamma}"); debug!("applying gamma: {gamma}");
let _ = Command::new("hyprctl") match config.temp_backend {
.args(["hyprsunset", "temperature", &temp.to_string()]) TempBackend::Hyprctl => {
.output(); let _ = Command::new("hyprctl")
trace!("hyprctl hyprsunset temperature {temp}"); .args(["hyprsunset", "temperature", &temp.to_string()])
.output();
trace!("hyprctl hyprsunset temperature {temp}");
}
TempBackend::Redshift => {
let _ = Command::new("redshift")
.args(["-o", "-t", &temp.to_string()])
.output();
trace!("redshift -o -t {temp}");
}
TempBackend::Xsct => {
let _ = Command::new("xsct").args([&temp.to_string()]).output();
trace!("xsct {temp}");
}
TempBackend::None => {}
TempBackend::Gammastep => {
let _ = Command::new("gammastep")
.args(["-O", &temp.to_string()])
.output();
},
}
match backend { match config.gamma_backend {
GammaBackend::Hyprctl => { GammaBackend::Hyprctl => {
let _ = Command::new("hyprctl") let _ = Command::new("hyprctl")
.args(["hyprsunset", "gamma", &gamma.to_string()]) .args(["hyprsunset", "gamma", &gamma.to_string()])
@ -267,5 +315,37 @@ pub fn apply_settings(temp: u16, gamma: u16, backend: GammaBackend) {
.output(); .output();
trace!("ddcutil setvcp 10 {gamma}"); trace!("ddcutil setvcp 10 {gamma}");
} }
GammaBackend::Gammastep => {
let _ = Command::new("gammastep")
.args(["-O", "6500", "-g", &(&gamma/100).to_string()])
.output();
trace!("gammastep -O 6500 -g {gamma}");
}
GammaBackend::Xsct => {
let output = Command::new("xsct").output().expect("xsct failed");
let stdout = String::from_utf8_lossy(&output.stdout);
let mut ttemp = 6000;
for line in stdout.lines() {
if line.contains("temperature") {
// example: "Screen 0: temperature ~ 6000 0.598234"
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() >= 6 {
ttemp = parts[4].parse::<u16>().unwrap();
}
}
}
let _ = Command::new("xsct")
.args([&ttemp.to_string(), &(&gamma/100).to_string()])
.output();
trace!("xsct {ttemp} {gamma}");
}
GammaBackend::Redshift => {
let _ = Command::new("redshift")
.args(["-O", "6500", "-g", &(&gamma/100).to_string()])
.output();
trace!("redshift -O 6500 -g {gamma}");
},
GammaBackend::None => {}
} }
} }

View file

@ -7,7 +7,9 @@ use std::time::{Duration, UNIX_EPOCH};
use hinoirisetr::notify::InitializedNotificationSystem; use hinoirisetr::notify::InitializedNotificationSystem;
use hinoirisetr::time::Time; use hinoirisetr::time::Time;
use hinoirisetr::{apply_settings, compute_settings, debug, error, info, trace, warn, Config, GammaBackend}; use hinoirisetr::{
apply_settings, compute_settings, debug, error, info, trace, warn, Config, GammaBackend, TempBackend
};
use smol::Timer; use smol::Timer;
use smol::channel::{Sender, unbounded}; use smol::channel::{Sender, unbounded};
use smol::io::{AsyncBufReadExt, BufReader}; use smol::io::{AsyncBufReadExt, BufReader};
@ -211,28 +213,23 @@ fn main() {
Config::default() Config::default()
}; };
// TODO: add a map to not check for binaries twice?
// TODO: add more temp backends and remove this
if !is_binary_available("hyprctl") {
error!("hyprctl is not available, exiting.");
std::process::exit(1);
}
match cfg.gamma_backend { match cfg.gamma_backend {
GammaBackend::Hyprctl => { GammaBackend::Hyprctl => check_binary("hyprctl"),
if !is_binary_available("hyprctl") { GammaBackend::Ddcutil => check_binary("ddcutil"),
error!("hyprctl is not available, exiting."); GammaBackend::Xsct => check_binary("xsct"),
std::process::exit(1); GammaBackend::Redshift => check_binary("redshift"),
} GammaBackend::Gammastep => check_binary("gammastep"),
} GammaBackend::None => {}
GammaBackend::Ddcutil => {
if !is_binary_available("ddcutil") {
error!("ddcutil is not available, exiting.");
std::process::exit(1);
}
}
} }
match cfg.temp_backend {
TempBackend::Hyprctl => check_binary("hyprctl"),
TempBackend::Gammastep => check_binary("gammastep"),
TempBackend::Xsct => check_binary("xsct"),
TempBackend::Redshift => check_binary("redshift"),
TempBackend::None => {}
}
CONFIG.set(Arc::new(RwLock::new(cfg))).unwrap(); CONFIG.set(Arc::new(RwLock::new(cfg))).unwrap();
@ -288,7 +285,7 @@ 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.gamma_backend); apply_settings(temp, gamma, &*config_guard().await);
trace!("initial settings applied: {temp}K, {gamma}%"); trace!("initial settings applied: {temp}K, {gamma}%");
} }
@ -298,12 +295,12 @@ fn main() {
apply_settings( apply_settings(
config_guard().await.temp_day, config_guard().await.temp_day,
config_guard().await.gamma_day, config_guard().await.gamma_day,
config_guard().await.gamma_backend, &*config_guard().await,
); );
} else { } else {
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.gamma_backend); apply_settings(temp, gamma, &*config_guard().await);
} }
let _ = notify_r.recv().await; let _ = notify_r.recv().await;
@ -404,3 +401,10 @@ fn config_handle() -> Arc<RwLock<Config>> {
fn get_time() -> Time { fn get_time() -> Time {
Time::now().expect("Failed to get local time") Time::now().expect("Failed to get local time")
} }
fn check_binary(binary: &str) {
if !is_binary_available(binary) {
error!("{binary} is not available, exiting.");
std::process::exit(1);
}
}