Avoid call to g_thread_init() with GLib >= 2.32.
[lxde/lxappearance.git] / src / lxappearance.c
CommitLineData
0cd84ed6 1/*
3a7d812e 2 * lxappearance.c
0cd84ed6
HJYP
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
3a7d812e 26#include "lxappearance.h"
15c155a6 27
0cd84ed6
HJYP
28#include <gtk/gtk.h>
29#include <glib/gi18n.h>
15c155a6
HJYP
30
31#include <X11/X.h>
32#include <X11/Xatom.h>
33#include <X11/Xlib.h>
34#include <gdk/gdkx.h>
ae63f687 35#include <string.h>
15c155a6 36
c847cfdc 37#if ENABLE_DBUS
924e9daf 38#include <dbus/dbus.h>
c847cfdc 39#endif
924e9daf 40
0cd84ed6 41#include "widget-theme.h"
71ce58a7 42#include "color-scheme.h"
0cd84ed6
HJYP
43#include "icon-theme.h"
44#include "cursor-theme.h"
2d9128f0 45#include "font.h"
e597424e 46#include "other.h"
756f0a66 47#include "plugin.h"
0cd84ed6 48
15c155a6
HJYP
49LXAppearance app = {0};
50
51Atom lxsession_atom = 0;
ae63f687 52static const char* lxsession_name = NULL;
15c155a6 53
924e9daf
JL
54/* Dbus functions Copy from lxsession-logout
55 TODO Create a library fro this ?
56*/
57
58static gboolean check_lxde_dbus()
59{
c847cfdc 60#if ENABLE_DBUS
924e9daf
JL
61 DBusError error;
62 dbus_error_init(&error);
63 DBusConnection * connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
64 if (connection == NULL)
65 {
66 g_warning(G_STRLOC ": Failed to connect to the session message bus: %s", error.message);
67 dbus_error_free(&error);
68 return FALSE;
69 }
70
a50b8ed7 71 dbus_bool_t ret = dbus_bus_name_has_owner(connection,"org.lxde.SessionManager",NULL);
924e9daf 72
a50b8ed7 73 if (ret == TRUE)
924e9daf
JL
74 {
75 return TRUE;
76 }
77 else
78 {
79 return FALSE;
80 }
c847cfdc
JL
81#else
82 return FALSE;
83#endif
924e9daf
JL
84}
85
15c155a6
HJYP
86static void check_lxsession()
87{
073c0729 88 lxsession_atom = XInternAtom( GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), "_LXSESSION", True );
15c155a6
HJYP
89 if( lxsession_atom != None )
90 {
073c0729
JL
91 XGrabServer( GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) );
92 if( XGetSelectionOwner( GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), lxsession_atom ) )
ae63f687 93 {
15c155a6 94 app.use_lxsession = TRUE;
ae63f687
HJYP
95 lxsession_name = g_getenv("DESKTOP_SESSION");
96 }
073c0729 97 XUngrabServer( GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) );
15c155a6 98 }
924e9daf
JL
99
100 /* Check Lxsession also with dbus */
101 if (check_lxde_dbus())
102 {
103 app.use_lxsession = TRUE;
104 lxsession_name = g_getenv("DESKTOP_SESSION");
105 }
106
15c155a6
HJYP
107}
108
0cd84ed6
HJYP
109static GOptionEntry option_entries[] =
110{
111 { NULL }
112};
113
ae63f687
HJYP
114static void save_cursor_theme_name()
115{
116 char* dir_path;
117 if(!app.cursor_theme || !g_strcmp0(app.cursor_theme, "default"))
118 return;
119
120 dir_path = g_build_filename(g_get_home_dir(), ".icons/default", NULL);
121 if(0 == g_mkdir_with_parents(dir_path, 0700))
122 {
123 char* index_theme = g_build_filename(dir_path, "index.theme", NULL);
124 char* content = g_strdup_printf(
f63c8576 125 "# This file is written by LXAppearance. Do not edit.\n"
ae63f687
HJYP
126 "[Icon Theme]\n"
127 "Name=Default\n"
128 "Comment=Default Cursor Theme\n"
79ec4790 129 "Inherits=%s\n", app.cursor_theme ? app.cursor_theme : "");
ae63f687
HJYP
130 g_file_set_contents(index_theme, content, -1, NULL);
131 g_free(content);
132 g_free(index_theme);
133 }
134 g_free(dir_path);
135
136 /*
137 dir_path = g_build_filename(g_get_home_dir(), ".Xdefaults", NULL);
138 Xcursor.theme: name
139 Xcursor.size: [size]
140 g_file_set_contents(dir_path, "", -1, NULL);
141 g_free(dir_path);
142 */
143}
144
145static void reload_all_programs()
15c155a6 146{
b4438824
JL
147#if GTK_CHECK_VERSION(3, 0, 0)
148
149/* TODO Port this to something else than gdk_event_send_clientmessage_toall */
150
151#else
ae63f687
HJYP
152 GdkEventClient event;
153 event.type = GDK_CLIENT_EVENT;
154 event.send_event = TRUE;
155 event.window = NULL;
15c155a6 156
ae63f687
HJYP
157 if( app.use_lxsession )
158 {
159 event.message_type = gdk_atom_intern_static_string("_LXSESSION");
160 event.data.b[0] = 0; /* LXS_RELOAD */
161 }
162 else
163 {
164 /* if( icon_only )
165 event.message_type = gdk_atom_intern("_GTK_LOAD_ICONTHEMES", FALSE);
166 */
167 event.message_type = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
168 }
169 event.data_format = 8;
170 gdk_event_send_clientmessage_toall((GdkEvent *)&event);
b4438824 171#endif
ae63f687
HJYP
172}
173
174static void lxappearance_save_gtkrc()
175{
176 static const char* tb_styles[]={
177 "GTK_TOOLBAR_ICONS",
178 "GTK_TOOLBAR_TEXT",
179 "GTK_TOOLBAR_BOTH",
180 "GTK_TOOLBAR_BOTH_HORIZ"
181 };
182 static const char* tb_icon_sizes[]={
183 "GTK_ICON_SIZE_INVALID",
184 "GTK_ICON_SIZE_MENU",
185 "GTK_ICON_SIZE_SMALL_TOOLBAR",
186 "GTK_ICON_SIZE_LARGE_TOOLBAR",
187 "GTK_ICON_SIZE_BUTTON",
188 "GTK_ICON_SIZE_DND",
189 "GTK_ICON_SIZE_DIALOG"
190 };
191
3518acea 192 char* file_path = g_build_filename(g_get_home_dir(), ".gtkrc-2.0", NULL);
c92e9c11 193 GString* content = g_string_sized_new(512);
79ec4790 194 g_string_append(content,
ae63f687 195 "# DO NOT EDIT! This file will be overwritten by LXAppearance.\n"
79ec4790
HJYP
196 "# Any customization should be done in ~/.gtkrc-2.0.mine instead.\n\n");
197 if(app.widget_theme)
198 g_string_append_printf(content,
199 "gtk-theme-name=\"%s\"\n", app.widget_theme);
200 if(app.icon_theme)
201 g_string_append_printf(content,
202 "gtk-icon-theme-name=\"%s\"\n", app.icon_theme);
203 if(app.default_font)
204 g_string_append_printf(content,
205 "gtk-font-name=\"%s\"\n", app.default_font);
206 if(app.cursor_theme)
207 g_string_append_printf(content,
208 "gtk-cursor-theme-name=\"%s\"\n", app.cursor_theme);
209 save_cursor_theme_name();
210
211 g_string_append_printf(content,
212 "gtk-cursor-theme-size=%d\n"
ae63f687
HJYP
213 "gtk-toolbar-style=%s\n"
214 "gtk-toolbar-icon-size=%s\n"
36827f45
HJYP
215 "gtk-button-images=%d\n"
216 "gtk-menu-images=%d\n"
9bb12c12 217#if GTK_CHECK_VERSION(2, 14, 0)
36827f45 218 "gtk-enable-event-sounds=%d\n"
79ec4790 219 "gtk-enable-input-feedback-sounds=%d\n"
9bb12c12 220#endif
2d9128f0
JL
221 "gtk-xft-antialias=%d\n"
222 "gtk-xft-hinting=%d\n"
223
79ec4790 224 , app.cursor_theme_size,
ae63f687
HJYP
225 tb_styles[app.toolbar_style],
226 tb_icon_sizes[app.toolbar_icon_size],
36827f45
HJYP
227 app.button_images ? 1 : 0,
228 app.menu_images ? 1 : 0,
9bb12c12 229#if GTK_CHECK_VERSION(2, 14, 0)
36827f45 230 app.enable_event_sound ? 1 : 0,
2d9128f0 231 app.enable_input_feedback ? 1 : 0,
9bb12c12 232#endif
2d9128f0
JL
233 app.enable_antialising ? 1 : 0,
234 app.enable_hinting ? 1 : 0
c92e9c11
HJYP
235 );
236
2d9128f0
JL
237 if(app.hinting_style)
238 g_string_append_printf(content,
b8648654 239 "gtk-xft-hintstyle=\"%s\"\n", app.hinting_style);
2d9128f0
JL
240
241 if(app.font_rgba)
242 g_string_append_printf(content,
b8648654 243 "gtk-xft-rgba=\"%s\"\n", app.font_rgba);
2d9128f0 244
eee70cc4
AG
245#if 0
246 /* unfortunately we cannot set colors without XSETTINGS daemon,
247 themes will override any custom settings in .gtkrc-2.0 file */
248 /* FIXME: we should support other xsettings daemons too */
c92e9c11
HJYP
249 if(app.color_scheme)
250 {
251 char* escaped = g_strescape(app.color_scheme, NULL);
252 g_string_append_printf(content,
203587a3 253 "gtk-color-scheme=\"%s\"\n",
c92e9c11
HJYP
254 escaped);
255 g_free(escaped);
256 }
eee70cc4 257#endif
c92e9c11
HJYP
258
259 g_string_append_printf(content,
260 "include \"%s/.gtkrc-2.0.mine\"\n",
ae63f687
HJYP
261 g_get_home_dir());
262
c92e9c11 263 g_file_set_contents(file_path, content->str, content->len, NULL);
c26fee92 264
924e9daf
JL
265 /* Save also in GTK3 folder
266 Content shold be different from the gtk2 one
267 */
b3957344 268 GKeyFile *content_gtk3 = g_key_file_new();
924e9daf 269 char* file_path_gtk3 = g_build_filename(g_get_user_config_dir(), "gtk-3.0", NULL);
b3957344 270 char* file_path_settings = g_build_filename(file_path_gtk3, "settings.ini", NULL);
c26fee92
JL
271
272 if (!g_file_test(file_path_gtk3, G_FILE_TEST_IS_DIR))
273 {
274 g_mkdir_with_parents(file_path_gtk3, 0755);
275 }
276
b3957344
AG
277 g_key_file_load_from_file(content_gtk3, file_path_settings, /* ignoring errors */
278 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, NULL);
924e9daf
JL
279
280 if(app.widget_theme)
b3957344
AG
281 g_key_file_set_string(content_gtk3, "Settings",
282 "gtk-theme-name", app.widget_theme);
924e9daf 283 if(app.icon_theme)
b3957344
AG
284 g_key_file_set_string(content_gtk3, "Settings",
285 "gtk-icon-theme-name", app.icon_theme);
924e9daf 286 if(app.default_font)
b3957344
AG
287 g_key_file_set_string(content_gtk3, "Settings",
288 "gtk-font-name", app.default_font);
924e9daf 289 if(app.cursor_theme)
b3957344
AG
290 g_key_file_set_string(content_gtk3, "Settings",
291 "gtk-cursor-theme-name", app.cursor_theme);
924e9daf
JL
292 save_cursor_theme_name();
293
b3957344
AG
294 g_key_file_set_integer(content_gtk3, "Settings",
295 "gtk-cursor-theme-size", app.cursor_theme_size);
296 g_key_file_set_string(content_gtk3, "Settings",
297 "gtk-toolbar-style", tb_styles[app.toolbar_style]);
298 g_key_file_set_string(content_gtk3, "Settings",
299 "gtk-toolbar-icon-size", tb_icon_sizes[app.toolbar_icon_size]);
300 g_key_file_set_boolean(content_gtk3, "Settings",
301 "gtk-button-images", app.button_images);
302 g_key_file_set_boolean(content_gtk3, "Settings",
303 "gtk-menu-images", app.menu_images);
924e9daf 304#if GTK_CHECK_VERSION(2, 14, 0)
b3957344
AG
305 g_key_file_set_boolean(content_gtk3, "Settings",
306 "gtk-enable-event-sounds", app.enable_event_sound);
307 g_key_file_set_boolean(content_gtk3, "Settings",
308 "gtk-enable-input-feedback-sounds", app.enable_input_feedback);
924e9daf 309#endif
b3957344
AG
310 g_key_file_set_boolean(content_gtk3, "Settings",
311 "gtk-xft-antialias", app.enable_antialising);
312 g_key_file_set_boolean(content_gtk3, "Settings",
313 "gtk-xft-hinting", app.enable_hinting);
924e9daf
JL
314
315 if(app.hinting_style)
b3957344
AG
316 g_key_file_set_string(content_gtk3, "Settings",
317 "gtk-xft-hintstyle", app.hinting_style);
924e9daf
JL
318
319 if(app.font_rgba)
b3957344
AG
320 g_key_file_set_string(content_gtk3, "Settings",
321 "gtk-xft-rgba", app.font_rgba);
924e9daf 322
eee70cc4
AG
323#if 0
324 /* unfortunately we cannot set colors without XSETTINGS daemon,
325 themes will override any custom settings in .gtkrc-2.0 file */
326 /* FIXME: we should support other xsettings daemons too */
924e9daf
JL
327 if(app.color_scheme)
328 {
329 char* escaped = g_strescape(app.color_scheme, NULL);
330 g_string_append_printf(content_gtk3,
331 "gtk-color-scheme=%s\n",
332 escaped);
333 g_free(escaped);
334 }
eee70cc4 335#endif
924e9daf 336
b3957344
AG
337#if GLIB_CHECK_VERSION(2, 40, 0)
338 g_key_file_save_to_file(content_gtk3, file_path_settings, NULL);
339#else
340 char *contents;
341 gsize s;
342
343 contents = g_key_file_to_data(content_gtk3, &s, NULL);
344 if (contents)
345 g_file_set_contents(file_path_settings, contents, s, NULL);
346 g_free(contents);
347#endif
c26fee92 348
b3957344
AG
349 g_free(file_path_gtk3);
350 g_free(file_path_settings);
c92e9c11 351 g_string_free(content, TRUE);
b3957344 352 g_key_file_free(content_gtk3);
ae63f687 353 g_free(file_path);
15c155a6
HJYP
354}
355
356static void lxappearance_save_lxsession()
357{
ae63f687
HJYP
358 char* rel_path = g_strconcat("lxsession/", lxsession_name, "/desktop.conf", NULL);
359 char* user_config_file = g_build_filename(g_get_user_config_dir(), rel_path, NULL);
360 char* buf;
8a35b255 361 gsize len;
ae63f687
HJYP
362 GKeyFile* kf = g_key_file_new();
363
364 if(!g_key_file_load_from_file(kf, user_config_file, G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
365 {
366 /* the user config file doesn't exist, create its parent dir */
367 len = strlen(user_config_file) - strlen("/desktop.conf");
368 user_config_file[len] = '\0';
369 g_debug("user_config_file = %s", user_config_file);
370 g_mkdir_with_parents(user_config_file, 0700);
371 user_config_file[len] = '/';
372
df6716ee
HJYP
373 g_key_file_load_from_dirs(kf, rel_path, (const char**)g_get_system_config_dirs(), NULL,
374 G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL);
ae63f687
HJYP
375 }
376
377 g_free(rel_path);
15c155a6 378
ae63f687
HJYP
379 g_key_file_set_string( kf, "GTK", "sNet/ThemeName", app.widget_theme );
380 g_key_file_set_string( kf, "GTK", "sGtk/FontName", app.default_font );
381
c92e9c11 382 g_key_file_set_string( kf, "GTK", "sGtk/ColorScheme", app.color_scheme ? app.color_scheme : "" );
71ce58a7 383
ae63f687
HJYP
384 g_key_file_set_string( kf, "GTK", "sNet/IconThemeName", app.icon_theme );
385
386 g_key_file_set_string( kf, "GTK", "sGtk/CursorThemeName", app.cursor_theme );
387 g_key_file_set_integer( kf, "GTK", "iGtk/CursorThemeSize", app.cursor_theme_size );
388 save_cursor_theme_name();
389
390 g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarStyle", app.toolbar_style );
391 g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarIconSize", app.toolbar_icon_size );
392
9bb12c12
HJYP
393 g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarStyle", app.toolbar_style );
394 g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarIconSize", app.toolbar_icon_size );
395
6b54b65a
HJYP
396 g_key_file_set_integer( kf, "GTK", "iGtk/ButtonImages", app.button_images );
397 g_key_file_set_integer( kf, "GTK", "iGtk/MenuImages", app.menu_images );
398
399#if GTK_CHECK_VERSION(2, 14, 0)
9bb12c12
HJYP
400 /* "Net/SoundThemeName\0" "gtk-sound-theme-name\0" */
401 g_key_file_set_integer( kf, "GTK", "iNet/EnableEventSounds", app.enable_event_sound);
402 g_key_file_set_integer( kf, "GTK", "iNet/EnableInputFeedbackSounds", app.enable_input_feedback);
403#endif
2d9128f0
JL
404 g_key_file_set_integer( kf, "GTK", "iXft/Antialias", app.enable_antialising);
405 g_key_file_set_integer( kf, "GTK", "iXft/Hinting", app.enable_hinting);
b8648654
JL
406 g_key_file_set_string( kf, "GTK", "sXft/HintStyle", app.hinting_style);
407 g_key_file_set_string( kf, "GTK", "sXft/RGBA", app.font_rgba);
9bb12c12 408
ae63f687
HJYP
409 buf = g_key_file_to_data( kf, &len, NULL );
410 g_key_file_free(kf);
411
412 g_file_set_contents(user_config_file, buf, len, NULL);
413 g_free(buf);
414 g_free(user_config_file);
15c155a6
HJYP
415}
416
417static void on_dlg_response(GtkDialog* dlg, int res, gpointer user_data)
418{
419 switch(res)
420 {
421 case GTK_RESPONSE_APPLY:
422
423 if(app.use_lxsession)
424 lxappearance_save_lxsession();
425 else
426 lxappearance_save_gtkrc();
427
ae63f687
HJYP
428 reload_all_programs();
429
15c155a6 430 app.changed = FALSE;
df6716ee 431 gtk_dialog_set_response_sensitive(GTK_DIALOG(app.dlg), GTK_RESPONSE_APPLY, FALSE);
15c155a6
HJYP
432 break;
433 case 1: /* about dialog */
434 {
435 GtkBuilder* b = gtk_builder_new();
436 if(gtk_builder_add_from_file(b, PACKAGE_UI_DIR "/about.ui", NULL))
437 {
438 GtkWidget* dlg = GTK_WIDGET(gtk_builder_get_object(b, "dlg"));
df6716ee 439 gtk_dialog_run(GTK_DIALOG(dlg));
15c155a6
HJYP
440 gtk_widget_destroy(dlg);
441 }
442 g_object_unref(b);
443 }
444 break;
445 default:
446 gtk_main_quit();
447 }
448}
449
450static void settings_init()
451{
e597424e
HJYP
452 GtkSettings* settings = gtk_settings_get_default();
453 g_object_get(settings,
454 "gtk-theme-name", &app.widget_theme,
ae63f687 455 "gtk-font-name", &app.default_font,
e597424e
HJYP
456 "gtk-icon-theme-name", &app.icon_theme,
457 "gtk-cursor-theme-name", &app.cursor_theme,
4e409096 458 "gtk-cursor-theme-size", &app.cursor_theme_size,
e597424e
HJYP
459 "gtk-toolbar-style", &app.toolbar_style,
460 "gtk-toolbar-icon-size", &app.toolbar_icon_size,
6b54b65a
HJYP
461 "gtk-button-images", &app.button_images,
462 "gtk-menu-images", &app.menu_images,
9bb12c12
HJYP
463#if GTK_CHECK_VERSION(2, 14, 0)
464 "gtk-enable-event-sounds", &app.enable_event_sound,
465 "gtk-enable-input-feedback-sounds", &app.enable_input_feedback,
466#endif
2d9128f0
JL
467 "gtk-xft-antialias", &app.enable_antialising,
468 "gtk-xft-hinting", &app.enable_hinting,
469 "gtk-xft-hintstyle", &app.hinting_style,
470 "gtk-xft-rgba", &app.font_rgba,
e597424e 471 NULL);
15c155a6 472 /* try to figure out cursor theme used. */
15c155a6
HJYP
473 if(!app.cursor_theme || g_strcmp0(app.cursor_theme, "default") == 0)
474 {
475 /* get the real theme name from default. */
476 GKeyFile* kf = g_key_file_new();
477 char* fpath = g_build_filename(g_get_home_dir(), ".icons/default/index.theme", NULL);
478 gboolean ret = g_key_file_load_from_file(kf, fpath, 0, NULL);
479 g_free(fpath);
480
481 if(!ret)
482 ret = g_key_file_load_from_data_dirs(kf, "icons/default/index.theme", NULL, 0, NULL);
483
484 if(ret)
485 {
e597424e 486 g_free(app.cursor_theme);
15c155a6
HJYP
487 app.cursor_theme = g_key_file_get_string(kf, "Icon Theme", "Inherits", NULL);
488 g_debug("cursor theme name: %s", app.cursor_theme);
489 }
490 g_key_file_free(kf);
491 }
c92e9c11
HJYP
492
493 app.color_scheme_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
494 /* try to load custom color scheme if available */
495 if(app.use_lxsession)
496 {
497 char* rel_path = g_strconcat("lxsession/", lxsession_name, "/desktop.conf", NULL);
498 char* user_config_file = g_build_filename(g_get_user_config_dir(), rel_path, NULL);
499 GKeyFile* kf = g_key_file_new();
500 if(g_key_file_load_from_file(kf, user_config_file, 0, NULL))
501 app.color_scheme = g_key_file_get_string(kf, "GTK", "sGtk/ColorScheme", NULL);
df6716ee 502 else if(g_key_file_load_from_dirs(kf, rel_path, (const char**)g_get_system_config_dirs(), NULL, 0, NULL))
c92e9c11
HJYP
503 app.color_scheme = g_key_file_get_string(kf, "GTK", "sGtk/ColorScheme", NULL);
504 g_key_file_free(kf);
505 g_free(rel_path);
506 g_free(user_config_file);
507
508 if(app.color_scheme)
509 {
510 if(*app.color_scheme)
511 color_scheme_str_to_hash(app.color_scheme_hash, app.color_scheme);
512 else
513 {
514 g_free(app.color_scheme);
515 app.color_scheme = NULL;
516 }
517 }
518 }
eee70cc4
AG
519#if 0
520 /* unfortunately we cannot set colors without XSETTINGS daemon,
521 themes will override any custom settings in .gtkrc-2.0 file */
522 /* FIXME: we should support other xsettings daemons too */
c92e9c11
HJYP
523 else
524 {
525 char* gtkrc_file = g_build_filename(g_get_home_dir(), ".gtkrc-2.0", NULL);
526 gtkrc_file_get_color_scheme(gtkrc_file, app.color_scheme_hash);
527 g_free(gtkrc_file);
528 if(g_hash_table_size(app.color_scheme_hash) > 0)
529 app.color_scheme = color_scheme_hash_to_str(app.color_scheme_hash);
530 }
eee70cc4 531#endif
15c155a6
HJYP
532}
533
0cd84ed6
HJYP
534int main(int argc, char** argv)
535{
536 GError* err = NULL;
537 GtkBuilder* b;
0cd84ed6
HJYP
538
539 /* gettext support */
540#ifdef ENABLE_NLS
541 bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
542 bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
543 textdomain ( GETTEXT_PACKAGE );
544#endif
545
fd9f7e8d 546#if !GLIB_CHECK_VERSION(2, 32, 0)
ff19d42c 547 g_thread_init(NULL);
fd9f7e8d 548#endif
0cd84ed6
HJYP
549 /* initialize GTK+ and parse the command line arguments */
550 if( G_UNLIKELY( ! gtk_init_with_args( &argc, &argv, "", option_entries, GETTEXT_PACKAGE, &err ) ) )
551 {
552 g_print( "Error: %s\n", err->message );
553 return 1;
554 }
555
1123e741
HJYP
556 app.abi_version = LXAPPEARANCE_ABI_VERSION;
557
15c155a6
HJYP
558 /* check if we're under LXSession */
559 check_lxsession();
560
0cd84ed6
HJYP
561 /* create GUI here */
562 b = gtk_builder_new();
563 if(!gtk_builder_add_from_file(b, PACKAGE_UI_DIR "/lxappearance.ui", NULL))
564 return 1;
565
6b54b65a
HJYP
566 /* NOTE: GUI must be created prior to loading settings from GtkSettings object.
567 * Some properties of GtkSettings class are installed by some other gtk classes.
568 * For example, "gtk-menu-images" property is actually installed by initialization
569 * of GtkImageMenuItem class. If we load the GUI first, then when the menu items
570 * are created, this property gets correctly registered. So later it can be read. */
571
572 /* load config values */
573 settings_init();
574
e597424e
HJYP
575 app.dlg = GTK_WIDGET(gtk_builder_get_object(b, "dlg"));
576
0cd84ed6 577 widget_theme_init(b);
71ce58a7 578 color_scheme_init(b);
0cd84ed6
HJYP
579 icon_theme_init(b);
580 cursor_theme_init(b);
2d9128f0 581 font_init(b);
e597424e 582 other_init(b);
756f0a66
HJYP
583 /* the page for window manager plugins */
584 app.wm_page = GTK_WIDGET(gtk_builder_get_object(b, "wm_page"));
585
ff19d42c
HJYP
586 plugins_init(b);
587
15c155a6 588 g_signal_connect(app.dlg, "response", G_CALLBACK(on_dlg_response), NULL);
0cd84ed6 589
15c155a6 590 gtk_window_present(GTK_WINDOW(app.dlg));
0cd84ed6
HJYP
591 g_object_unref(b);
592
593 gtk_main();
594
756f0a66
HJYP
595 plugins_finalize();
596
0cd84ed6
HJYP
597 return 0;
598}
15c155a6
HJYP
599
600void lxappearance_changed()
601{
602 if(!app.changed)
603 {
604 app.changed = TRUE;
df6716ee 605 gtk_dialog_set_response_sensitive(GTK_DIALOG(app.dlg), GTK_RESPONSE_APPLY, TRUE);
15c155a6
HJYP
606 }
607}
2d9128f0
JL
608
609void on_check_button_toggled(GtkToggleButton* btn, gpointer user_data)
610{
611 gboolean* val = (gboolean*)user_data;
612 gboolean new_val = gtk_toggle_button_get_active(btn);
613 if(new_val != *val)
614 {
615 *val = new_val;
616 lxappearance_changed();
617 }
618}