| 1 | //! System configuration. |
| 2 | use std::process::Command; |
| 3 | |
| 4 | /// Query system to see if dark theming should be preferred. |
| 5 | pub(crate) fn prefer_dark() -> bool { |
| 6 | // outputs something like: `variant variant uint32 1` |
| 7 | let stdout: Option = CommandOption::new(program:"dbus-send" ) |
| 8 | .arg("--reply-timeout=100" ) |
| 9 | .arg("--print-reply=literal" ) |
| 10 | .arg("--dest=org.freedesktop.portal.Desktop" ) |
| 11 | .arg("/org/freedesktop/portal/desktop" ) |
| 12 | .arg("org.freedesktop.portal.Settings.Read" ) |
| 13 | .arg("string:org.freedesktop.appearance" ) |
| 14 | .arg("string:color-scheme" ) |
| 15 | .output() |
| 16 | .ok() |
| 17 | .and_then(|out: Output| String::from_utf8(vec:out.stdout).ok()); |
| 18 | |
| 19 | if matches!(stdout, Some(ref s) if s.is_empty()) { |
| 20 | log::error!("XDG Settings Portal did not return response in time: timeout: 100ms, key: color-scheme" ); |
| 21 | } |
| 22 | |
| 23 | matches!(stdout, Some(s) if s.trim().ends_with("uint32 1" )) |
| 24 | } |
| 25 | |
| 26 | /// Query system configuration for buttons layout. |
| 27 | /// Should be updated to use standard xdg-desktop-portal specs once available |
| 28 | /// https://github.com/flatpak/xdg-desktop-portal/pull/996 |
| 29 | pub(crate) fn get_button_layout_config() -> Option<(String, String)> { |
| 30 | let config_string = Command::new("dbus-send" ) |
| 31 | .arg("--reply-timeout=100" ) |
| 32 | .arg("--print-reply=literal" ) |
| 33 | .arg("--dest=org.freedesktop.portal.Desktop" ) |
| 34 | .arg("/org/freedesktop/portal/desktop" ) |
| 35 | .arg("org.freedesktop.portal.Settings.Read" ) |
| 36 | .arg("string:org.gnome.desktop.wm.preferences" ) |
| 37 | .arg("string:button-layout" ) |
| 38 | .output() |
| 39 | .ok() |
| 40 | .and_then(|out| String::from_utf8(out.stdout).ok())?; |
| 41 | |
| 42 | let sides_split: Vec<_> = config_string |
| 43 | // Taking last word |
| 44 | .rsplit(' ' ) |
| 45 | .next()? |
| 46 | // Split by left/right side |
| 47 | .split(':' ) |
| 48 | // Only two sides |
| 49 | .take(2) |
| 50 | .collect(); |
| 51 | |
| 52 | match sides_split.as_slice() { |
| 53 | [left, right] => Some((left.to_string(), right.to_string())), |
| 54 | _ => None, |
| 55 | } |
| 56 | } |
| 57 | |