Compare commits

..

2 commits

Author SHA1 Message Date
Alex Janka 8322bbc051 config: hot reloading 2024-07-30 16:27:09 +10:00
Alex Janka 943f371cf1 config: not oncelock 2024-07-30 16:15:15 +10:00
6 changed files with 236 additions and 18 deletions

160
Cargo.lock generated
View file

@ -87,6 +87,12 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.6.0" version = "2.6.0"
@ -120,6 +126,15 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "crossbeam-channel"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.20" version = "0.8.20"
@ -203,6 +218,27 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "filetime"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.4.1",
"windows-sys 0.52.0",
]
[[package]]
name = "fsevent-sys"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.30" version = "0.3.30"
@ -310,6 +346,26 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "inotify"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
dependencies = [
"bitflags 1.3.2",
"inotify-sys",
"libc",
]
[[package]]
name = "inotify-sys"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "is-terminal" name = "is-terminal"
version = "0.4.12" version = "0.4.12"
@ -327,6 +383,26 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "kqueue"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
dependencies = [
"kqueue-sys",
"libc",
]
[[package]]
name = "kqueue-sys"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
dependencies = [
"bitflags 1.3.2",
"libc",
]
[[package]] [[package]]
name = "lab" name = "lab"
version = "0.11.0" version = "0.11.0"
@ -345,7 +421,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.6.0",
"libc", "libc",
] ]
@ -386,6 +462,18 @@ dependencies = [
"adler", "adler",
] ]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.0.1" version = "1.0.1"
@ -398,6 +486,36 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "notify"
version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
dependencies = [
"bitflags 2.6.0",
"crossbeam-channel",
"filetime",
"fsevent-sys",
"inotify",
"kqueue",
"libc",
"log",
"mio 0.8.11",
"walkdir",
"windows-sys 0.48.0",
]
[[package]]
name = "notify-debouncer-mini"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d40b221972a1fc5ef4d858a2f671fb34c75983eb385463dff3780eeff6a9d43"
dependencies = [
"crossbeam-channel",
"log",
"notify",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.2" version = "0.36.2"
@ -437,7 +555,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.5.3",
"smallvec", "smallvec",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
@ -497,13 +615,22 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.3" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.6.0",
] ]
[[package]] [[package]]
@ -558,7 +685,7 @@ version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.6.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
@ -571,6 +698,15 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -653,12 +789,14 @@ dependencies = [
[[package]] [[package]]
name = "sway-flash-indicator" name = "sway-flash-indicator"
version = "0.3.1" version = "0.4.0"
dependencies = [ dependencies = [
"directories", "directories",
"futures-util", "futures-util",
"lab", "lab",
"log", "log",
"notify",
"notify-debouncer-mini",
"pretty_env_logger", "pretty_env_logger",
"serde", "serde",
"swayipc-async", "swayipc-async",
@ -741,7 +879,7 @@ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
"libc", "libc",
"mio", "mio 1.0.1",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
@ -817,6 +955,16 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View file

@ -1,6 +1,6 @@
[package] [package]
name = "sway-flash-indicator" name = "sway-flash-indicator"
version = "0.3.1" version = "0.4.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
@ -14,3 +14,5 @@ directories = "5.0.1"
toml = "0.8.15" toml = "0.8.15"
serde = { version = "1.0.204", features = ["derive"] } serde = { version = "1.0.204", features = ["derive"] }
thiserror = "1.0.63" thiserror = "1.0.63"
notify-debouncer-mini = "0.4.1"
notify = "6.1.1"

View file

@ -1,7 +1,7 @@
# Maintainer: Alex Janka <alex@alexjanka.com> # Maintainer: Alex Janka <alex@alexjanka.com>
pkgname=sway-flash-indicator pkgname=sway-flash-indicator
pkgver=0.3.1 pkgver=0.4.0
pkgrel=1 pkgrel=1
pkgdesc="flashes sway indicator border rather than always showing it" pkgdesc="flashes sway indicator border rather than always showing it"
arch=('x86_64' 'aarch64') arch=('x86_64' 'aarch64')

View file

@ -15,7 +15,41 @@ pub struct Config {
pub output_blocklist: Vec<String>, pub output_blocklist: Vec<String>,
} }
pub fn parse_config() -> Res<()> { pub struct ConfigHandle {
inner: tokio::sync::RwLock<Option<Config>>,
}
pub struct ConfigHandleHandle<'a>(tokio::sync::RwLockReadGuard<'a, Option<Config>>);
impl std::ops::Deref for ConfigHandleHandle<'_> {
type Target = Config;
fn deref(&self) -> &Self::Target {
self.0.as_ref().unwrap()
}
}
impl ConfigHandle {
pub(super) const fn new() -> Self {
Self {
inner: tokio::sync::RwLock::const_new(None),
}
}
async fn set(&self, config: Config) {
*self.inner.write().await = Some(config)
}
fn set_blocking(&self, config: Config) {
*self.inner.blocking_write() = Some(config);
}
pub async fn get(&self) -> ConfigHandleHandle {
ConfigHandleHandle(self.inner.read().await)
}
}
pub async fn parse_config() -> Res<()> {
let dirs = directories::ProjectDirs::from("com", "alexjanka", "sway-flash-indicator") let dirs = directories::ProjectDirs::from("com", "alexjanka", "sway-flash-indicator")
.ok_or(Error::NoMatchingConfig)?; .ok_or(Error::NoMatchingConfig)?;
@ -37,12 +71,49 @@ pub fn parse_config() -> Res<()> {
log::info!("wrote default to {config_path:?}"); log::info!("wrote default to {config_path:?}");
c c
}; };
let path = config_path.clone();
tokio::task::spawn(async move {
let mut debouncer = notify_debouncer_mini::new_debouncer(
std::time::Duration::from_secs(1),
move |res: notify_debouncer_mini::DebounceEventResult| match res {
Ok(events) => events.iter().for_each(|e| {
if e.kind == notify_debouncer_mini::DebouncedEventKind::Any {
if let Some(config) = read_config(&path) {
CONFIG.set_blocking(config);
} else {
log::error!("failed to parse config");
}
}
}),
Err(e) => println!("Error {:?}", e),
},
)
.unwrap();
crate::CONFIG.set(config)?; debouncer
.watcher()
.watch(&config_path, notify::RecursiveMode::Recursive)
.unwrap();
loop {
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
}
});
crate::CONFIG.set(config).await;
Ok(()) Ok(())
} }
fn read_config(path: &std::path::PathBuf) -> Option<Config> {
if path.try_exists().is_ok_and(|v| v) {
let v = toml::from_str(&std::fs::read_to_string(path).ok()?).ok()?;
log::info!("read config from {path:?}");
Some(v)
} else {
None
}
}
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self { Self {

View file

@ -4,7 +4,7 @@ pub async fn interpolate_task() -> Res<()> {
let mut connection = swayipc_async::Connection::new().await?; let mut connection = swayipc_async::Connection::new().await?;
let to = crate::DEFAULT_BORDER.get().ok_or(Error::NoMatchingConfig)?; let to = crate::DEFAULT_BORDER.get().ok_or(Error::NoMatchingConfig)?;
let config = CONFIG.get().ok_or(Error::NoMatchingConfig)?; let config = CONFIG.get().await;
let per_frame = 1.0 / config.frames_anim as f32; let per_frame = 1.0 / config.frames_anim as f32;
let (d_l, d_a, d_b) = ( let (d_l, d_a, d_b) = (
(to.l - config.flash_colour.l) * per_frame, (to.l - config.flash_colour.l) * per_frame,

View file

@ -1,4 +1,3 @@
use config::Config;
use futures_util::StreamExt; use futures_util::StreamExt;
use lab::Lab; use lab::Lab;
@ -13,8 +12,7 @@ pub mod prelude {
} }
use prelude::*; use prelude::*;
pub static CONFIG: config::ConfigHandle = config::ConfigHandle::new();
pub static CONFIG: tokio::sync::OnceCell<Config> = tokio::sync::OnceCell::const_new();
static DEFAULT_COLOURS: tokio::sync::OnceCell<String> = tokio::sync::OnceCell::const_new(); static DEFAULT_COLOURS: tokio::sync::OnceCell<String> = tokio::sync::OnceCell::const_new();
static DEFAULT_COLOURS_NO_INDICATOR: tokio::sync::OnceCell<String> = static DEFAULT_COLOURS_NO_INDICATOR: tokio::sync::OnceCell<String> =
@ -28,7 +26,7 @@ async fn main() -> Res<()> {
} }
pretty_env_logger::init(); pretty_env_logger::init();
config::parse_config()?; config::parse_config().await?;
let mut event_connection = swayipc_async::Connection::new().await?; let mut event_connection = swayipc_async::Connection::new().await?;
let mut autosplit_connection = swayipc_async::Connection::new().await?; let mut autosplit_connection = swayipc_async::Connection::new().await?;
@ -84,7 +82,7 @@ async fn main() -> Res<()> {
if let Err(e) = code_trigger( if let Err(e) = code_trigger(
&mut autosplit_connection, &mut autosplit_connection,
id, id,
&CONFIG.get().unwrap().output_blocklist, &CONFIG.get().await.output_blocklist,
) )
.await .await
{ {
@ -101,8 +99,7 @@ async fn main() -> Res<()> {
continue; continue;
} }
let ratio = (width as f64) / (height as f64); let ratio = (width as f64) / (height as f64);
let autosplit_ratio = let autosplit_ratio = CONFIG.get().await.autosplit_ratio;
CONFIG.get().ok_or(Error::NoMatchingConfig)?.autosplit_ratio;
if let Err(e) = if ratio > autosplit_ratio { if let Err(e) = if ratio > autosplit_ratio {
autosplit_connection.run_command("splith").await autosplit_connection.run_command("splith").await
} else { } else {