Skip to content

Commit 8b81313

Browse files
committed
Using xdg crate.
- Using xdg to find config files on Linux/BSD systems. - Quality of life improvements
1 parent d718b3d commit 8b81313

7 files changed

Lines changed: 64 additions & 61 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ rust-ini = "0.18"
2525
ashpd = { git = "https://github.com/bilelmoussaoui/ashpd", branch = "master" }
2626
crossbeam = "0.8.2"
2727
tokio = { version = "1.23.0", features = ["full"] }
28+
xdg = "2.4.1"
2829

2930
[target.'cfg(windows)'.dependencies]
3031
winreg = "0.10"

src/freedesktop/detect.rs

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,59 @@
11
use anyhow::Context;
22
use detect_desktop_environment::DesktopEnvironment;
33
use ini::Ini;
4-
use std::path::{Path, PathBuf};
54

65
use crate::Mode;
76

8-
const XDG_KDEGLOBALS: &str = "/etc/xdg/kdeglobals";
7+
use super::{CINNAMON, GNOME, MATE};
98

10-
fn detect_gtk(pattern: &str) -> Mode {
11-
match dconf_rs::get_string(pattern) {
12-
Ok(theme) => Mode::from(theme.to_lowercase().contains("dark")),
9+
pub fn detect() -> Mode {
10+
match legacy_detect() {
11+
Ok(mode) => mode,
1312
Err(_) => Mode::Default,
1413
}
1514
}
1615

17-
fn detect_kde(path: &str) -> anyhow::Result<Mode> {
18-
let cfg = Ini::load_from_file(path)?;
19-
let section = cfg.section(Some("Colors:Window")).with_context(|| "Failed to get section Colors:Window")?;
20-
let values = section.get("BackgroundNormal").with_context(|| "Failed to get BackgroundNormal inside Colors:Window")?;
21-
let rgb = values
22-
.split(',')
23-
.map(|s| s.parse::<u32>().unwrap_or(255))
24-
.collect::<Vec<u32>>();
25-
let rgb = if rgb.len() >= 3 {
26-
rgb
27-
} else {
28-
vec![255, 255, 255]
29-
};
30-
let (r, g, b) = (rgb[0], rgb[1], rgb[2]);
31-
Ok(Mode::from_rgb(r, g, b))
32-
}
33-
3416
fn legacy_detect() -> anyhow::Result<Mode> {
3517
let mode = match DesktopEnvironment::detect() {
36-
DesktopEnvironment::Kde => {
37-
let path = if Path::new(XDG_KDEGLOBALS).exists() {
38-
PathBuf::from(XDG_KDEGLOBALS)
39-
} else {
40-
dirs::home_dir().unwrap().join(".config/kdeglobals")
41-
};
42-
detect_kde(path.to_str().unwrap())?
43-
}
44-
DesktopEnvironment::Cinnamon => detect_gtk("/org/cinnamon/desktop/interface/gtk-theme"),
45-
DesktopEnvironment::Gnome => detect_gtk("/org/gnome/desktop/interface/gtk-theme"),
46-
DesktopEnvironment::Mate => detect_gtk("/org/mate/desktop/interface/gtk-theme"),
47-
DesktopEnvironment::Unity => detect_gtk("/org/gnome/desktop/interface/gtk-theme"),
18+
DesktopEnvironment::Kde => kde_detect()?,
19+
DesktopEnvironment::Cinnamon => dconf_detect(CINNAMON),
20+
DesktopEnvironment::Gnome => dconf_detect(GNOME),
21+
DesktopEnvironment::Mate => dconf_detect(MATE),
22+
DesktopEnvironment::Unity => dconf_detect(GNOME),
4823
_ => Mode::Default,
4924
};
5025
Ok(mode)
5126
}
5227

53-
pub fn detect() -> Mode {
54-
match legacy_detect() {
55-
Ok(mode) => mode,
28+
fn dconf_detect(path: &str) -> Mode {
29+
match dconf_rs::get_string(path) {
30+
Ok(theme) => Mode::from(Some(theme.to_lowercase().contains("dark"))),
5631
Err(_) => Mode::Default,
5732
}
5833
}
5934

35+
fn kde_detect() -> anyhow::Result<Mode> {
36+
let xdg = xdg::BaseDirectories::new()?;
37+
let path = xdg.find_config_file("kdeglobals")
38+
.context("Path not found")?;
39+
let cfg = Ini::load_from_file(path)?;
40+
let properties = cfg.section(Some("Colors:Window"))
41+
.context("Failed to get section Colors:Window")?;
42+
let background = properties.get("BackgroundNormal")
43+
.context("Failed to get BackgroundNormal inside Colors:Window")?;
44+
let rgb = rgb_from_string(background)?;
45+
Ok(Mode::from_rgb(&rgb))
46+
}
47+
48+
fn rgb_from_string(rgb: &str) -> anyhow::Result<Vec<u32>> {
49+
rgb.split(',')
50+
.map(|s| s.parse::<u32>().unwrap_or_else(|_| 255))
51+
.try_fold(vec![255, 255, 255], |mut acc, x| {
52+
if acc.len() < 3 {
53+
acc.push(x);
54+
Ok(acc)
55+
} else {
56+
Err(anyhow::anyhow!("Too many elements"))
57+
}
58+
})
59+
}

src/freedesktop/mod.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
1-
use ashpd::desktop::settings::{Settings, ColorScheme};
2-
3-
use crate::Mode;
4-
51
pub mod detect;
62
pub mod notify;
73

8-
async fn get_freedesktop_color_scheme() -> anyhow::Result<Mode> {
9-
let proxy = Settings::new().await?;
10-
let color_scheme = proxy.color_scheme().await?;
11-
let mode = match color_scheme {
12-
ColorScheme::PreferDark => Mode::Dark,
13-
ColorScheme::PreferLight => Mode::Light,
14-
ColorScheme::NoPreference => Mode::Default,
15-
};
16-
Ok(mode)
17-
}
4+
const MATE: &str = "/org/mate/desktop/interface/gtk-theme";
5+
const GNOME: &str = "/org/gnome/desktop/interface/gtk-theme";
6+
const CINNAMON: &str = "/org/cinnamon/desktop/interface/gtk-theme";

src/freedesktop/notify.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use ashpd::desktop::settings::{Settings, ColorScheme};
44

55
use crate::{Mode, detect};
66

7-
use super::get_freedesktop_color_scheme;
8-
97
pub async fn notify(tx: Sender<crate::Mode>) -> anyhow::Result<()> {
108
if get_freedesktop_color_scheme().await.is_ok() {
119
tokio::spawn(freedesktop_watch(tx));
@@ -16,6 +14,17 @@ pub async fn notify(tx: Sender<crate::Mode>) -> anyhow::Result<()> {
1614
Ok(())
1715
}
1816

17+
async fn get_freedesktop_color_scheme() -> anyhow::Result<Mode> {
18+
let proxy = Settings::new().await?;
19+
let color_scheme = proxy.color_scheme().await?;
20+
let mode = match color_scheme {
21+
ColorScheme::PreferDark => Mode::Dark,
22+
ColorScheme::PreferLight => Mode::Light,
23+
ColorScheme::NoPreference => Mode::Default,
24+
};
25+
Ok(mode)
26+
}
27+
1928
async fn freedesktop_watch(tx: Sender<Mode>) -> anyhow::Result<()> {
2029
let proxy = Settings::new().await?;
2130
while let Ok(color_scheme) = proxy.receive_color_scheme_changed().await {

src/lib.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,19 @@ pub enum Mode {
7777
}
7878

7979
impl Mode {
80-
fn from(b: bool) -> Self {
81-
if b {
82-
Mode::Dark
80+
fn from(mode: Option<bool>) -> Self {
81+
if let Some(mode) = mode {
82+
if mode {
83+
Mode::Dark
84+
} else {
85+
Mode::Light
86+
}
8387
} else {
84-
Mode::Light
88+
Mode::Default
8589
}
8690
}
87-
fn from_rgb(r: u32, g: u32, b: u32) -> Self {
88-
let window_background_gray = (r * 11 + g * 16 + b * 5) / 32;
91+
fn from_rgb(rgb: &[u32]) -> Self {
92+
let window_background_gray = (rgb[0] * 11 + rgb[1] * 16 + rgb[2] * 5) / 32;
8993
if window_background_gray < 192 {
9094
Self::Dark
9195
} else {

src/macos/detect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ fn is_dark_mode_enabled() -> bool {
5252
}
5353

5454
pub fn detect() -> crate::Mode {
55-
Mode::from(is_dark_mode_enabled())
55+
Mode::from(Some(is_dark_mode_enabled()))
5656
}

src/windows/detect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub fn detect() -> Mode {
88
let hkcu = RegKey::predef(winreg::enums::HKEY_CURRENT_USER);
99
if let Ok(subkey) = hkcu.open_subkey(SUBKEY) {
1010
if let Ok(dword) = subkey.get_value::<u32, _>(VALUE) {
11-
return Mode::from(dword == 0);
11+
return Mode::from(Some(dword == 0));
1212
}
1313
}
1414
Mode::Light

0 commit comments

Comments
 (0)