1use crate::config::Config as ThconConfig;
30use crate::operation::Operation;
31use crate::themeable::{ConfigError, ConfigState, Themeable};
32use crate::AppConfig;
33use crate::Disableable;
34
35use anyhow::{Context, Result};
36use gio::SettingsExt;
37use serde::Deserialize;
38
39#[derive(Debug, Deserialize, Disableable, AppConfig)]
40pub struct _Config {
41 light: String,
42 dark: String,
43 #[serde(default)]
44 disabled: bool,
45}
46
47pub struct GnomeShell {}
48
49impl Themeable for GnomeShell {
50 fn config_state(&self, config: &ThconConfig) -> ConfigState {
51 ConfigState::with_manual_config(config.gnome_shell.as_ref().map(|c| c.inner.as_ref()))
52 }
53
54 fn switch(&self, config: &ThconConfig, operation: &Operation) -> Result<()> {
55 let config = match self.config_state(config) {
56 ConfigState::NoDefault => {
57 return Err(ConfigError::RequiresManualConfig("gnome_shell").into())
58 }
59 ConfigState::Default => unreachable!(),
60 ConfigState::Disabled => return Ok(()),
61 ConfigState::Enabled => config.gnome_shell.as_ref().unwrap().unwrap_inner_left(),
62 };
63
64 let theme = match operation {
65 Operation::Darken => &config.dark,
66 Operation::Lighten => &config.light,
67 };
68
69 let gsettings = gio::Settings::new("org.gnome.shell.extensions.user-theme");
70 gsettings
71 .set_string("name", theme)
72 .map(|_| gio::Settings::sync())
73 .with_context(|| format!("Unable to apply GNOME Shell user theme '{}'", theme))
74 }
75}