1use crate::{
5 constants::{
6 DE_GNOME,
7 DE_GNOME_CLASSIC,
8 DE_XFCE4,
9 DE_CINNAMON,
10 DE_MATE,
11 DE_BUDGIE,
12 DE_UNITY
13 },
14
15 properties::{
16 parse_prop_file_values,
17 get_config_dirs
18 },
19
20 settings::{
21 Variant,
22
23 get_xfconf,
24 get_xfconf_first_match,
25 get_gnome_setting
26 }
27};
28
29#[derive(Default)]
30pub struct GtkResult {
31 pub theme: String,
32 pub icons: String,
33 pub font: String,
34 pub cursor: String,
35 pub cursor_size: String,
36 pub wallpaper: String
37}
38
39impl GtkResult {
40 fn all_set(&self) -> bool {
41 !self.theme.is_empty() && !self.icons.is_empty() && !self.font.is_empty()
42 }
43}
44
45fn detect_gtk_from_settings(de_name: &str) -> GtkResult {
46 let mut result: GtkResult = GtkResult::default();
47
48 if de_name.eq_ignore_ascii_case(DE_XFCE4) {
49 if let Some(theme) = get_xfconf("xsettings", "/Net/ThemeName").as_str() {
50 (&mut result).theme = theme.to_string();
51 }
52
53 if let Some(icons) = get_xfconf("xsettings", "/Net/IconThemeName").as_str() {
54 (&mut result).icons = icons.to_string();
55 }
56
57 if let Some(font) = get_xfconf("xsettings", "/Gtk/FontName").as_str() {
58 (&mut result).font = font.to_string();
59 }
60
61 if let Some(cursor) = get_xfconf("xsettings", "/Gtk/CursorThemeName").as_str() {
62 (&mut result).cursor = cursor.to_string();
63 }
64
65 if let Some(size) = get_xfconf("xsettings", "/Gtk/CursorThemeSize").as_int() {
66 (&mut result).cursor_size = size.to_string();
67 }
68
69 let wallpaper: Variant = get_xfconf_first_match("xfce4-desktop", "/backdrop/screen0", |prop: &str| {
70 prop.contains("/workspace0/last-image")
71 });
72
73 if let Some(wp) = wallpaper.as_str() {
74 (&mut result).wallpaper = wp.to_string();
75 }
76 } else if de_name.eq_ignore_ascii_case(DE_CINNAMON) {
77 if let Some(theme) = get_gnome_setting("/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", None, "gtk-theme").as_str() {
78 (&mut result).theme = theme.to_string();
79 }
80
81 if let Some(icons) = get_gnome_setting("/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", None, "icon-theme").as_str() {
82 (&mut result).icons = icons.to_string();
83 }
84
85 if let Some(font) = get_gnome_setting("/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", None, "font-name").as_str() {
86 (&mut result).font = font.to_string();
87 }
88
89 if let Some(cursor) = get_gnome_setting("/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", None, "cursor-theme").as_str() {
90 (&mut result).cursor = cursor.to_string();
91 }
92
93 if let Some(size) = get_gnome_setting("/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", None, "cursor-size").as_int() {
94 (&mut result).cursor_size = size.to_string();
95 }
96
97 if let Some(wp) = get_gnome_setting("/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", None, "picture-uri").as_str() {
98 (&mut result).wallpaper = wp.to_string();
99 }
100 } else if de_name.eq_ignore_ascii_case(DE_MATE) {
101 if let Some(theme) = get_gnome_setting("/org/mate/interface/gtk-theme", "org.mate.interface", None, "gtk-theme").as_str() {
102 (&mut result).theme = theme.to_string();
103 }
104
105 if let Some(icons) = get_gnome_setting("/org/mate/interface/icon-theme", "org.mate.interface", None, "icon-theme").as_str() {
106 (&mut result).icons = icons.to_string();
107 }
108
109 if let Some(font) = get_gnome_setting("/org/mate/interface/font-name", "org.mate.interface", None, "font-name").as_str() {
110 (&mut result).font = font.to_string();
111 }
112
113 if let Some(cursor) = get_gnome_setting("/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", None, "cursor-theme").as_str() {
114 (&mut result).cursor = cursor.to_string();
115 }
116
117 if let Some(size) = get_gnome_setting("/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", None, "cursor-size").as_int() {
118 (&mut result).cursor_size = size.to_string();
119 }
120
121 if let Some(wp) = get_gnome_setting("/org/mate/desktop/background", "org.mate.background", None, "picture-filename").as_str() {
122 (&mut result).wallpaper = wp.to_string();
123 }
124 } else if de_name.eq_ignore_ascii_case(DE_GNOME) || de_name.eq_ignore_ascii_case(DE_GNOME_CLASSIC) || de_name.eq_ignore_ascii_case(DE_UNITY) || de_name.eq_ignore_ascii_case(DE_BUDGIE) {
125 if let Some(theme) = get_gnome_setting("/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", None, "gtk-theme").as_str() {
126 (&mut result).theme = theme.to_string();
127 }
128
129 if let Some(icons) = get_gnome_setting("/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", None, "icon-theme").as_str() {
130 (&mut result).icons = icons.to_string();
131 }
132
133 if let Some(font) = get_gnome_setting("/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", None, "font-name").as_str() {
134 (&mut result).font = font.to_string();
135 }
136
137 if let Some(cursor) = get_gnome_setting("/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", None, "cursor-theme").as_str() {
138 (&mut result).cursor = cursor.to_string();
139 }
140
141 if let Some(size) = get_gnome_setting("/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", None, "cursor-size").as_int() {
142 (&mut result).cursor_size = size.to_string();
143 }
144
145 if let Some(wp) = get_gnome_setting("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", None, "picture-uri").as_str() {
146 (&mut result).wallpaper = wp.to_string();
147 }
148 }
149
150 result
151}
152
153fn detect_gtk_from_config_file(filename: &str, result: &mut GtkResult) -> () {
154 let mut queries: Vec<(&str, String)> = vec![
155 ("gtk-theme-name =", String::new()),
156 ("gtk-icon-theme-name =", String::new()),
157 ("gtk-font-name =", String::new()),
158 ("gtk-cursor-theme-name =", String::new()),
159 ("gtk-cursor-theme-size =", String::new())
160 ];
161
162 if parse_prop_file_values(filename, &mut queries) {
163 if result.theme.is_empty() && !queries[0].1.is_empty() {
164 result.theme = queries[0].1.clone();
165 }
166
167 if result.icons.is_empty() && !queries[1].1.is_empty() {
168 result.icons = queries[1].1.clone();
169 }
170
171 if result.font.is_empty() && !queries[2].1.is_empty() {
172 result.font = queries[2].1.clone();
173 }
174
175 if result.cursor.is_empty() && !queries[3].1.is_empty() {
176 result.cursor = queries[3].1.clone();
177 }
178
179 if result.cursor_size.is_empty() && !queries[4].1.is_empty() {
180 result.cursor_size = queries[4].1.clone();
181 }
182 }
183}
184
185fn detect_gtk_from_config_dir(config_dir: &str, version: &str, result: &mut GtkResult) -> () {
186 let files: [String; 4] = [
187 format!("{}gtk-{}.0/settings.ini", config_dir, version),
188 format!("{}gtk-{}.0/gtkrc", config_dir, version),
189 format!("{}gtkrc-{}.0", config_dir, version),
190 format!("{}.gtkrc-{}.0", config_dir, version)
191 ];
192
193 for file in &files {
194 detect_gtk_from_config_file(file, result);
195
196 if result.all_set() {
197 return;
198 }
199 }
200}
201
202fn detect_gtk_impl(version: &str, de_name: Option<&str>) -> GtkResult {
203 let mut result: GtkResult = if let Some(de) = de_name {
204 detect_gtk_from_settings(de)
205 } else {
206 GtkResult::default()
207 };
208
209 if result.all_set() {
210 return result;
211 }
212
213 let config_dirs: Vec<String> = get_config_dirs();
214
215 for config_dir in &config_dirs {
216 detect_gtk_from_config_dir(config_dir, version, &mut result);
217
218 if result.all_set() {
219 break;
220 }
221 }
222
223 result
224}
225
226pub fn detect_gtk2(de_name: Option<&str>) -> GtkResult {
227 detect_gtk_impl("2", de_name)
228}
229
230pub fn detect_gtk3(de_name: Option<&str>) -> GtkResult {
231 detect_gtk_impl("3", de_name)
232}
233
234pub fn detect_gtk4(de_name: Option<&str>) -> GtkResult {
235 detect_gtk_impl("4", de_name)
236}