Skip to content

Commit

Permalink
Async notify
Browse files Browse the repository at this point in the history
`notify` is now an async function.
Modified example to use `tokio`
Renamed `Mode::rgb` to `Mode::from_rgb`
`freedesktop_watch` now uses `ashpd` beta.
Changed signature for `notify` function in macOS and Windows files.
  • Loading branch information
edfloreshz committed Jan 18, 2022
1 parent 7b8826c commit e993c1b
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 50 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ anyhow = "1.0.52"
detect-desktop-environment = "0.2.0"
dconf_rs = "0.3.0"
dirs = "4.0.0"
zbus = "2.0.0"
ashpd = "0.1.0"
zbus_macros = "2.0.1"
async_ashpd = { package = "ashpd", version = "0.2.0-beta-1" }
tokio = { version = "1.15.0", features = ["full"] }
crossbeam = "0.8.1"
zvariant = "3.0.0"
rust-ini = "0.17"

Expand Down
7 changes: 4 additions & 3 deletions examples/notify.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
fn main() -> anyhow::Result<()> {
dark_light::notify(&change_color_scheme)
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dark_light::notify(&change_color_scheme).await
}

fn change_color_scheme(mode: dark_light::Mode) {
println!("Changing to {:?}", mode)
}
}
4 changes: 2 additions & 2 deletions src/freedesktop/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ fn detect_kde(path: &str) -> anyhow::Result<Mode> {
.split(',')
.map(|s| s.parse::<u32>().unwrap_or(255))
.collect::<Vec<u32>>();
let rgb = if rgb.len() > 2 {
let rgb = if rgb.len() >= 3 {
rgb
} else {
vec![255, 255, 255]
};
let (r, g, b) = (rgb[0], rgb[1], rgb[2]);
Ok(Mode::rgb(r, g, b))
Ok(Mode::from_rgb(r, g, b))
}

fn legacy_detect() -> anyhow::Result<Mode> {
Expand Down
86 changes: 48 additions & 38 deletions src/freedesktop/notify.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
use zbus::names::MemberName;
use zvariant::{OwnedValue, Value};
use std::{sync::mpsc::{self, Sender, Receiver}, thread, ops::Deref, convert::TryFrom};
use std::thread;
use async_ashpd::Error;
use async_ashpd::desktop::settings::{SettingsProxy, ColorScheme};
use async_ashpd::zbus::Connection;
use crossbeam::channel::{self, Sender};

use crate::Mode;

use super::{get_freedesktop_color_scheme, detect::detect};

pub fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
let (tx, rx): (Sender<Mode>, Receiver<Mode>) = mpsc::channel();
struct Settings<'a> {
proxy: &'a SettingsProxy<'a>
}

impl<'a> Settings<'a> {
fn new(proxy: &'a SettingsProxy<'a>) -> Self {
Self {
proxy
}
}
async fn receive(&self) -> std::result::Result<ColorScheme, Error> {
self.proxy.receive_color_scheme_changed().await
}
}

pub async fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
let (tx, rx) = channel::unbounded();
let connection = Connection::session().await?;
let proxy = SettingsProxy::new(&connection).await?;
let settings = Settings::new(&proxy);
if get_freedesktop_color_scheme().is_ok() {
freedesktop_watch(tx)?;
loop {
let tx = tx.clone();
freedesktop_watch(tx, &settings).await?;
match rx.recv() {
Ok(mode) => callback(mode),
Err(_) => {},
}
}
} else {
non_freedesktop_watch(tx)?;
}
loop {
match rx.recv() {
Ok(mode) => callback(mode),
Err(_) => {},
loop {
match rx.recv() {
Ok(mode) => callback(mode),
Err(_) => {},
}
}
}
}

async fn freedesktop_watch<'a>(tx: Sender<Mode>, settings: &'a Settings<'a>) -> anyhow::Result<()> {
let color_scheme = match settings.receive().await? {
ColorScheme::PreferDark => Mode::Dark,
ColorScheme::PreferLight => Mode::Light,
ColorScheme::NoPreference => Mode::Default,
};
tx.send(color_scheme).unwrap();
Ok(())
}

fn non_freedesktop_watch(tx: Sender<Mode>) -> anyhow::Result<()> {
let mut mode = detect();
thread::spawn(move || {
Expand All @@ -34,31 +71,4 @@ fn non_freedesktop_watch(tx: Sender<Mode>) -> anyhow::Result<()> {
}
});
Ok(())
}

fn freedesktop_watch(tx: Sender<Mode>) -> anyhow::Result<()> {
let connection = zbus::blocking::Connection::session()?;
let proxy = zbus::blocking::Proxy::new(
&connection,
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.Settings",
)?;
thread::spawn(move || -> anyhow::Result<()> {
for signal in proxy.receive_signal(&MemberName::try_from("SettingChanged")?)? {
let msg = signal.deref();
let msg_header = signal.header()?;
if msg_header.message_type()? == zbus::MessageType::Signal && msg_header.member()? == Some(&MemberName::try_from("SettingChanged")?) {
let response = msg.body::<(String, String, OwnedValue)>()?;
let mode = match response.2.downcast_ref::<Value>().unwrap().downcast_ref::<u32>().unwrap() {
1 => Mode::Dark,
2 => Mode::Light,
_ => Mode::Default,
};
tx.send(mode).unwrap();
}
}
Ok(())
});
Ok(())
}
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Mode {
Mode::Light
}
}
fn rgb(r: u32, g: u32, b: u32) -> Self {
fn from_rgb(r: u32, g: u32, b: u32) -> Self {
let window_background_gray = (r * 11 + g * 16 + b * 5) / 32;
if window_background_gray < 192 {
Self::Dark
Expand All @@ -84,6 +84,6 @@ pub fn detect() -> Mode {
platform::detect::detect()
}

pub fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
platform::notify::notify(callback)
pub async fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
platform::notify::notify(callback).await
}
2 changes: 1 addition & 1 deletion src/macos/notify.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::Mode;

pub fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
pub async fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
todo!()
}
2 changes: 1 addition & 1 deletion src/windows/notify.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::Mode;

pub fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
pub async fn notify(callback: &dyn Fn(Mode)) -> anyhow::Result<()> {
todo!()
}

0 comments on commit e993c1b

Please sign in to comment.