Switch to notify-rust, enable dismiss check

This commit is contained in:
Alexander Bantyev 2020-10-25 00:42:06 +03:00
parent 6ac095c9be
commit 86d9fe73f0
Signed by: balsoft
GPG Key ID: E081FF12ADCB4AD5
9 changed files with 354 additions and 151 deletions

362
Cargo.lock generated
View File

@ -15,6 +15,18 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.0.1"
@ -41,6 +53,12 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]] [[package]]
name = "battery" name = "battery"
version = "0.7.6" version = "0.7.6"
@ -59,9 +77,26 @@ dependencies = [
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "block"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]] [[package]]
name = "blurz" name = "blurz"
@ -73,18 +108,43 @@ dependencies = [
"hex", "hex",
] ]
[[package]]
name = "cc"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]] [[package]]
name = "configparser" name = "configparser"
version = "1.0.0" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe1d7dcda7d1da79e444bdfba1465f2f849a58b07774e1df473ee77030cb47a7" checksum = "fe1d7dcda7d1da79e444bdfba1465f2f849a58b07774e1df473ee77030cb47a7"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.7.0" version = "0.7.0"
@ -101,6 +161,17 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.5.0" version = "0.5.0"
@ -165,6 +236,17 @@ dependencies = [
"syn 0.11.11", "syn 0.11.11",
] ]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "enum-kinds" name = "enum-kinds"
version = "0.4.1" version = "0.4.1"
@ -225,30 +307,14 @@ dependencies = [
] ]
[[package]] [[package]]
name = "gdk-pixbuf" name = "getrandom"
version = "0.3.0" version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16160d212ae91abe9f3324c3fb233929ba322dde63585d15cda3336f8c529ed1" checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [ dependencies = [
"gdk-pixbuf-sys", "cfg-if",
"glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
] "wasi 0.9.0+wasi-snapshot-preview1",
[[package]]
name = "gdk-pixbuf-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "798f97101eea8180da363d0e80e07ec7ec6d1809306601c0100c1de5bc8b4f52"
dependencies = [
"bitflags",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
] ]
[[package]] [[package]]
@ -257,55 +323,6 @@ version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
[[package]]
name = "gio-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a303bbf7a5e75ab3b627117ff10e495d1b9e97e1d68966285ac2b1f6270091bc"
dependencies = [
"bitflags",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "glib"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9b0452824cc63066940f01adc721804919f0b76cdba3cfab977b00b87f16d4a"
dependencies = [
"bitflags",
"glib-sys",
"gobject-sys",
"lazy_static",
"libc",
]
[[package]]
name = "glib-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9693049613ff52b93013cc3d2590366d8e530366d288438724b73f6c7dc4be8"
dependencies = [
"bitflags",
"libc",
"pkg-config",
]
[[package]]
name = "gobject-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60d507c87a71b1143c66ed21a969be9b99a76df234b342d733e787e6c9c7d7c2"
dependencies = [
"bitflags",
"glib-sys",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.3.1" version = "0.3.1"
@ -354,34 +371,6 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "libnotify"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10506a4f8bc6f8f7ccc6fde3a8290378d7aed3d1a26dca606a73e2ffe140cc2d"
dependencies = [
"gdk-pixbuf",
"gdk-pixbuf-sys",
"glib",
"glib-sys",
"gobject-sys",
"libnotify-sys",
]
[[package]]
name = "libnotify-sys"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0a716b9b7d24ed10f1eb431e1527fa13c9a4bf2d4fa68bb3e54da1d0747383c"
dependencies = [
"bitflags",
"gdk-pixbuf-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "libpulse-binding" name = "libpulse-binding"
version = "2.16.2" version = "2.16.2"
@ -404,6 +393,18 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "mac-notification-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb6b71a9a89cd38b395d994214297447e8e63b1ba5708a9a2b0b1048ceda76"
dependencies = [
"cc",
"chrono",
"dirs",
"objc-foundation",
]
[[package]] [[package]]
name = "mach" name = "mach"
version = "0.3.2" version = "0.3.2"
@ -413,6 +414,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.4.2" version = "0.4.2"
@ -437,6 +447,27 @@ dependencies = [
"from_variants", "from_variants",
] ]
[[package]]
name = "notify-rust"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "144acee6a0543dc74893e4b8a33936b5b0a94cc2d4ab024afd0c6daff7afc3c0"
dependencies = [
"dbus 0.8.4",
"mac-notification-sys",
"winrt-notification",
]
[[package]]
name = "num-integer"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [
"autocfg",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.12" version = "0.2.12"
@ -446,6 +477,35 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "objc"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
dependencies = [
"block",
"objc",
"objc_id",
]
[[package]]
name = "objc_id"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
dependencies = [
"objc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.20.0" version = "0.20.0"
@ -518,6 +578,35 @@ dependencies = [
"proc-macro2 1.0.21", "proc-macro2 1.0.21",
] ]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]]
name = "rust-argon2"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.16" version = "0.1.16"
@ -553,7 +642,8 @@ name = "simple-osd-common"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"configparser", "configparser",
"libnotify", "dbus 0.8.4",
"notify-rust",
"xdg", "xdg",
] ]
@ -574,6 +664,22 @@ dependencies = [
"simple-osd-common", "simple-osd-common",
] ]
[[package]]
name = "strum"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca6e4730f517e041e547ffe23d29daab8de6b73af4b6ae2a002108169f5e7da"
[[package]]
name = "strum_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3384590878eb0cab3b128e844412e2d010821e7e091211b9d87324173ada7db8"
dependencies = [
"quote 0.3.15",
"syn 0.11.11",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.11.11" version = "0.11.11"
@ -639,6 +745,17 @@ dependencies = [
"unicode-xid 0.2.1", "unicode-xid 0.2.1",
] ]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.12.0" version = "1.12.0"
@ -679,6 +796,18 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -701,8 +830,39 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winrt"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e30cba82e22b083dc5a422c2ee77e20dc7927271a0dc981360c57c1453cb48d"
dependencies = [
"winapi",
]
[[package]]
name = "winrt-notification"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c31a65da50d792c6f9bd2e3216249566c4fb1d2d34f9b7d2d66d2e93f62a242"
dependencies = [
"strum",
"strum_macros",
"winapi",
"winrt",
"xml-rs",
]
[[package]] [[package]]
name = "xdg" name = "xdg"
version = "2.2.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
[[package]]
name = "xml-rs"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621"
dependencies = [
"bitflags",
]

View File

@ -208,14 +208,14 @@ fn main() -> battery::Result<()> {
battery.time_to_full().map(|ttf| { battery.time_to_full().map(|ttf| {
osd.title = Some(format!("Charging, {} until full", format_duration(ttf.value))); osd.title = Some(format!("Charging, {} until full", format_duration(ttf.value)));
osd.urgency = Urgency::Low; osd.urgency = Urgency::Low;
osd.update(); osd.update().unwrap();
}); });
} }
State::Low => { State::Low => {
battery.time_to_empty().map(|tte| { battery.time_to_empty().map(|tte| {
osd.title = Some(format!("Low battery, {} remaining", format_duration(tte.value))); osd.title = Some(format!("Low battery, {} remaining", format_duration(tte.value)));
osd.urgency = Urgency::Normal; osd.urgency = Urgency::Normal;
osd.update(); osd.update().unwrap();
}); });
}, },
State::Normal | State::Critical => { } State::Normal | State::Critical => { }
@ -226,7 +226,7 @@ fn main() -> battery::Result<()> {
battery.time_to_empty().map(|tte| { battery.time_to_empty().map(|tte| {
osd.title = Some(format!("Critically low battery, {} remaining", format_duration(tte.value))); osd.title = Some(format!("Critically low battery, {} remaining", format_duration(tte.value)));
osd.urgency = Urgency::Critical; osd.urgency = Urgency::Critical;
osd.update(); osd.update().unwrap();
}); });
} }

View File

@ -36,7 +36,7 @@ fn main() {
if device_name != last_device_name { if device_name != last_device_name {
osd.title = Some(format!("Bluetooth: connected to {}", device_name)); osd.title = Some(format!("Bluetooth: connected to {}", device_name));
osd.update(); osd.update().unwrap();
} }
last_device_name = device_name; last_device_name = device_name;

View File

@ -30,7 +30,7 @@ fn main() {
if b != last_b { if b != last_b {
osd.contents = OSDContents::Progress(b/m, OSDProgressText::Percentage); osd.contents = OSDContents::Progress(b/m, OSDProgressText::Percentage);
osd.update(); osd.update().unwrap();
} }
last_b = b; last_b = b;

View File

@ -7,6 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
libnotify = "1.0.3" notify-rust = "4"
configparser = "1.0.0" configparser = "1.0.0"
xdg = "2.1" xdg = "2.1"
dbus = "0.8.4"

View File

@ -1,9 +1,10 @@
// This is free and unencumbered software released into the public domain. // This is free and unencumbered software released into the public domain.
// balsoft 2020 // balsoft 2020
extern crate libnotify; extern crate notify_rust;
extern crate xdg; extern crate xdg;
extern crate configparser; extern crate configparser;
extern crate dbus;
pub static APPNAME: &str = "simple-osd"; pub static APPNAME: &str = "simple-osd";
@ -83,18 +84,13 @@ pub mod config {
} }
} }
pub mod notify { pub mod notify {
use libnotify::Notification; use notify_rust::{Notification, NotificationHandle};
pub use libnotify::Urgency; use dbus::ffidisp::{Connection, BusType};
use std::thread;
pub use notify_rust::Urgency;
use crate::config::Config; use crate::config::Config;
use std::default::Default; use std::default::Default;
fn init_if_not_already() {
if ! libnotify::is_initted() {
println!("Initializing libnotify");
libnotify::init(crate::APPNAME).unwrap()
}
}
pub enum OSDProgressText { pub enum OSDProgressText {
Percentage, Percentage,
Text(Option<String>) Text(Option<String>)
@ -111,6 +107,12 @@ pub mod notify {
} }
} }
struct CustomHandle {
pub id: u32,
pub connection: Connection,
pub notification: Notification
}
pub struct OSD { pub struct OSD {
pub title: Option<String>, pub title: Option<String>,
@ -132,13 +134,12 @@ pub mod notify {
end: String, end: String,
// Internal notification // Internal notification
notification: Notification notification: Notification,
id: Option<u32>
} }
impl OSD { impl OSD {
pub fn new() -> OSD { pub fn new() -> OSD {
init_if_not_already();
let mut config = Config::new("common"); let mut config = Config::new("common");
let timeout = config.get("notification", "default timeout").unwrap_or(-1); // -1 means the default timeout of the notification server let timeout = config.get("notification", "default timeout").unwrap_or(-1); // -1 means the default timeout of the notification server
@ -151,20 +152,35 @@ pub mod notify {
let start = config.get_default("progressbar", "start", String::new()); let start = config.get_default("progressbar", "start", String::new());
let end = config.get_default("progressbar", "end", String::new()); let end = config.get_default("progressbar", "end", String::new());
let notification = Notification::new("", None, None); let notification = Notification::new();
return OSD { return OSD {
title: None, icon: None, title: None, icon: None,
contents: OSDContents::default(), contents: OSDContents::default(),
urgency: Urgency::Normal, urgency: Urgency::Normal, id: None,
timeout, timeout,
length, full, empty, start, end, length, full, empty, start, end,
notification notification
}; };
} }
fn get_full_text(&self) -> Option<String> { fn construct_fake_handle(id: u32, notification: Notification) -> NotificationHandle {
match &self.contents { let h = CustomHandle
{ id: id,
connection: Connection::get_private(BusType::Session).unwrap(),
notification: notification };
unsafe {
let handle : NotificationHandle = std::mem::transmute(h);
return handle;
}
}
fn fake_handle(&mut self) -> NotificationHandle {
Self::construct_fake_handle(self.id.unwrap_or(0), self.notification.clone())
}
pub fn update(&mut self) -> Result<(), String> {
let text = match &self.contents {
OSDContents::Simple(text) => text.clone(), OSDContents::Simple(text) => text.clone(),
OSDContents::Progress(value, text) => { OSDContents::Progress(value, text) => {
let mut s = String::new(); let mut s = String::new();
@ -197,28 +213,37 @@ pub mod notify {
Some(s) Some(s)
} }
};
self.id.map(|i| self.notification.id(i));
let handle = self.notification
.summary(self.title.as_deref().unwrap_or(""))
.body(&text.unwrap_or("".to_string()))
.icon(self.icon.as_deref().unwrap_or(""))
.urgency(self.urgency)
.finalize()
.show()
.or(Err("Failed to show the notification"))?;
self.id = Some(handle.id());
Ok(())
}
pub fn on_close<F: 'static>(&mut self, callback: F) where F: std::ops::FnOnce() + Send {
if let Some(id) = self.id {
let notification = self.notification.clone();
thread::spawn(move || {
let fake_handle = Self::construct_fake_handle(id, notification);
fake_handle.on_close(callback);
});
} else {
callback();
} }
} }
fn try_update(&mut self) -> Result<(), String> {
self.notification.update(self.title.as_deref().unwrap_or(""), self.get_full_text().as_deref(), self.icon.as_deref()).unwrap();
self.notification.set_urgency(self.urgency);
self.notification.show().or(Err("Failed to show the notification".to_string()))
}
pub fn update(&mut self) {
// The notification server may restart, and in that case the notification becomes invalid;
// We need to handle that situation.
self.try_update().unwrap_or_else(|_| {
libnotify::uninit();
init_if_not_already();
self.notification = Notification::new("", None, None);
self.try_update().unwrap();
});
}
pub fn close(&mut self) { pub fn close(&mut self) {
self.notification.close().unwrap_or_else(|_| { eprintln!("Failed to close the notification"); }); self.fake_handle().close();
} }
} }
} }

View File

@ -20,11 +20,11 @@
"crates-io-index": { "crates-io-index": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1600641984, "lastModified": 1603572719,
"narHash": "sha256-u2juQ6LmitgAlj/lztMhjw6i0dIFEUdyVfYYIABWw90=", "narHash": "sha256-58j3Y9P4Rsa2rrY/tc7DqXQeI93NPzDedDq4RChkGMY=",
"owner": "rust-lang", "owner": "rust-lang",
"repo": "crates.io-index", "repo": "crates.io-index",
"rev": "6adca9dd72305e56efc0bd516b6324d2542f71d1", "rev": "e7aefc38a0eb2633731c0f78d493f2c040ec3011",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -2,6 +2,7 @@ pub extern crate simple_osd_common as osd;
pub extern crate mpris; pub extern crate mpris;
pub use std::sync::{Arc, Mutex}; pub use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::ops::{Deref}; use std::ops::{Deref};
@ -97,11 +98,12 @@ mod volume_changes {
pub(super) struct VolumeMonitor { pub(super) struct VolumeMonitor {
mainloop: Arc<Mutex<Mainloop>>, mainloop: Arc<Mutex<Mainloop>>,
#[allow(dead_code)]
context: Arc<Mutex<Context>> context: Arc<Mutex<Context>>
} }
impl VolumeMonitor { impl VolumeMonitor {
pub fn new(config: Arc<Mutex<Config>>, trigger: Arc<Mutex<SystemTime>>) -> VolumeMonitor { pub fn new(config: Arc<Mutex<Config>>, trigger: Arc<Mutex<SystemTime>>, dismissed: Arc<Mutex<AtomicBool>>) -> VolumeMonitor {
let mainloop = Arc::new(Mutex::new let mainloop = Arc::new(Mutex::new
(Mainloop::new().expect("Failed to create mainloop"))); (Mainloop::new().expect("Failed to create mainloop")));
@ -143,6 +145,7 @@ mod volume_changes {
let subscribe_callback = move |facility, operation, _index| { let subscribe_callback = move |facility, operation, _index| {
if facility == Some(Facility::Sink) && operation == Some(Operation::Changed) { if facility == Some(Facility::Sink) && operation == Some(Operation::Changed) {
*trigger.lock().unwrap() = SystemTime::now(); *trigger.lock().unwrap() = SystemTime::now();
dismissed.lock().unwrap().store(false, Ordering::Relaxed);
} }
}; };
@ -165,6 +168,8 @@ mod volume_changes {
fn main() { fn main() {
let config = Arc::new(Mutex::new(Config::new("mpris"))); let config = Arc::new(Mutex::new(Config::new("mpris")));
let mut osd = OSD::new(); let mut osd = OSD::new();
let mut waiting_on_close = false;
let dismissed = Arc::new(Mutex::new(AtomicBool::new(false)));
let player = PlayerFinder::new().unwrap().find_active().unwrap(); let player = PlayerFinder::new().unwrap().find_active().unwrap();
@ -177,7 +182,7 @@ fn main() {
#[cfg(feature = "display_on_volume_changes")] #[cfg(feature = "display_on_volume_changes")]
let vc = if update_on_volume_change { let vc = if update_on_volume_change {
Some(volume_changes::VolumeMonitor::new(config.clone(), trigger.clone())) Some(volume_changes::VolumeMonitor::new(config.clone(), trigger.clone(), dismissed.clone()))
} else { None }; } else { None };
drop(update_on_volume_change); drop(update_on_volume_change);
@ -196,11 +201,12 @@ fn main() {
if title != old_title || playback_status != old_playback_status { if title != old_title || playback_status != old_playback_status {
*trigger.lock().unwrap() = SystemTime::now(); *trigger.lock().unwrap() = SystemTime::now();
dismissed.lock().unwrap().store(false, Ordering::Relaxed);
} }
let elapsed = trigger.lock().unwrap().elapsed().unwrap_or(Duration::from_secs(timeout + 1)); let elapsed = trigger.lock().unwrap().elapsed().unwrap_or(Duration::from_secs(timeout + 1));
if elapsed.as_secs() < timeout && playback_status != PlaybackStatus::Stopped { if elapsed.as_secs() < timeout && playback_status != PlaybackStatus::Stopped && ! dismissed.lock().unwrap().load(Ordering::Relaxed) {
let metadata = progress.metadata(); let metadata = progress.metadata();
let artists = metadata.artists().and_then(|artists| format_artists(artists)).unwrap_or("Unknown".to_string()); let artists = metadata.artists().and_then(|artists| format_artists(artists)).unwrap_or("Unknown".to_string());
let position = progress.position(); let position = progress.position();
@ -216,8 +222,19 @@ fn main() {
PlaybackStatus::Paused => Some("media-playback-pause".to_string()), PlaybackStatus::Paused => Some("media-playback-pause".to_string()),
_ => None _ => None
}; };
osd.update(); osd.update().unwrap();
} else { osd.close() } if ! waiting_on_close {
waiting_on_close = true;
let dismissed_clone = dismissed.clone();
osd.on_close(move || {
dismissed_clone.lock().unwrap().store(true, Ordering::Relaxed);
});
}
} else {
waiting_on_close = false;
osd.close()
}
old_title = title; old_title = title;
old_playback_status = playback_status; old_playback_status = playback_status;

View File

@ -67,7 +67,7 @@ fn main() {
let muted_message = if i.mute { " [MUTED]" } else { "" }; let muted_message = if i.mute { " [MUTED]" } else { "" };
osd.borrow_mut().title = Some(format!("Volume on {}{}", sink_name, muted_message)); osd.borrow_mut().title = Some(format!("Volume on {}{}", sink_name, muted_message));
osd.borrow_mut().contents = OSDContents::Progress(volume.0 as f32 / 65536., OSDProgressText::Percentage); osd.borrow_mut().contents = OSDContents::Progress(volume.0 as f32 / 65536., OSDProgressText::Percentage);
osd.borrow_mut().update(); osd.borrow_mut().update().unwrap();
} }
}; };