17cefa4aa1a6b2f79999e66ef58c876c8297f7ac
[debian/lxappearance.git] / src / main-dlg.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <gtk/gtk.h>
6 #include <gdk/gdkx.h>
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12
13 /* for kill & waitpid */
14 #include <sys/types.h>
15 #include <signal.h>
16 #include <sys/wait.h>
17
18 #include "main-dlg.h"
19 #include "main-dlg-ui.h"
20 #include "glade-support.h"
21
22 enum {
23 COL_DISP_NAME,
24 COL_NAME,
25 N_COLS
26 };
27
28 #define GET_WIDGET_WITH_TYPE(name, type) name = type( lookup_widget( dlg, #name ))
29
30 #define INIT_LIST(name, prop) \
31 GET_WIDGET_WITH_TYPE( name##_view, GTK_TREE_VIEW ); \
32 name##_list = init_tree_view( name##_view, G_CALLBACK(on_list_sel_changed), prop); \
33 load_##name##s( name##_list, name##_name );
34
35 #define enable_apply() gtk_dialog_set_response_sensitive(GTK_DIALOG (main_dlg), GTK_RESPONSE_APPLY, TRUE )
36 #define disable_apply() gtk_dialog_set_response_sensitive(GTK_DIALOG (main_dlg), GTK_RESPONSE_APPLY, FALSE )
37
38 extern gboolean under_lxsession; /* wether we are under lxsession */
39
40 extern GtkWidget* main_dlg; /* defined in main.c */
41
42 static GtkTreeView* gtk_theme_view = NULL;
43 static GtkListStore* gtk_theme_list = NULL;
44
45 static GtkTreeView* icon_theme_view = NULL;
46 static GtkListStore* icon_theme_list = NULL;
47
48 static GtkTreeView* cursor_theme_view = NULL;
49 static GtkListStore* cursor_theme_list = NULL;
50
51 static char* gtk_theme_name = NULL;
52 static char* icon_theme_name = NULL;
53 static char* font_name = NULL;
54 static char* cursor_theme_name = NULL;
55 static gint cursor_theme_size = 0;
56 static GtkToolbarStyle tb_style = GTK_TOOLBAR_BOTH;
57
58 extern char tmp_rc_file[];
59 static char* rc_file = NULL;
60
61 /*
62 static GtkTreeView* font_view = NULL;
63 static GtkListStore* font_list = NULL;
64 */
65 static GtkWidget* demo_box = NULL;
66 static GtkWidget* demo_socket = NULL;
67 static GPid demo_pid = 0;
68
69 static const char* session_name = NULL;
70
71 extern Atom lxsession_atom; /* defined in main.c */
72
73 static void reload_demo_process()
74 {
75 char* argv[5];
76 char wid[16];
77
78 if( demo_pid > 0 ) /* kill old demo */
79 {
80 int stat;
81 kill( demo_pid, SIGTERM );
82 waitpid( demo_pid, &stat, 0 );
83 demo_pid = 0;
84 }
85
86 g_snprintf( wid, 16, "%ld", gtk_socket_get_id(GTK_SOCKET (demo_socket)) );
87
88 argv[0] = g_get_prgname();
89 argv[1] = "demo";
90 argv[2] = wid;
91 argv[3] = tmp_rc_file;
92 argv[4] = NULL;
93 g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &demo_pid, NULL );
94
95 /* reloading demo means the current selected theme is changed */
96 enable_apply();
97 }
98
99 static void write_rc_file( const char* path )
100 {
101 FILE* f;
102 static char* tb_styles[] = {
103 "GTK_TOOLBAR_ICONS",
104 "GTK_TOOLBAR_TEXT",
105 "GTK_TOOLBAR_BOTH",
106 "GTK_TOOLBAR_BOTH_HORIZ"
107 };
108
109 if( f = fopen( path, "w" ) )
110 {
111 fputs( "# DO NOT EDIT! This file will be overwritten by LXAppearance.\n"
112 "# Any customization should be done in ~/.gtkrc-2.0.mine\n\n", f );
113
114 fprintf( f, "gtk-theme-name=\"%s\"\n", gtk_theme_name );
115 fprintf( f, "gtk-icon-theme-name=\"%s\"\n", icon_theme_name );
116 fprintf( f, "gtk-font-name=\"%s\"\n", font_name );
117 fprintf( f, "gtk-toolbar-style=%d\n", tb_style );
118 fprintf( f, "gtk-cursor-theme-name=\"%s\"\n", cursor_theme_name );
119 fprintf( f, "gtk-cursor-theme-size=%d\n", cursor_theme_size );
120
121 fprintf( f, "include \"%s/.gtkrc-2.0.mine\"\n", g_get_home_dir() );
122
123 fclose( f );
124 }
125 }
126
127 static void create_lxsession_config_dir()
128 {
129 char* dir = g_build_filename( g_get_user_config_dir(), "lxsession", session_name, NULL );
130 g_mkdir_with_parents( dir, 0755 );
131 g_free( dir );
132 }
133
134 static void write_lxsession_config()
135 {
136 FILE* f;
137 char* file, *data;
138 gsize len;
139 GKeyFile* kf = g_key_file_new();
140 gboolean ret;
141
142 file = g_build_filename( g_get_user_config_dir(), "lxsession", session_name, "desktop.conf", NULL );
143 ret = g_key_file_load_from_file( kf, file, G_KEY_FILE_KEEP_COMMENTS, NULL );
144
145 if( ! ret )
146 {
147 const gchar* const * dir;
148 const gchar* const * dirs = g_get_system_config_dirs();
149 create_lxsession_config_dir();
150
151 /* load system-wide config file */
152 for( dir = dirs; *dir; ++dir )
153 {
154 char* path = g_build_filename( *dir, "lxsession", session_name, "desktop.conf", NULL );
155 ret = g_key_file_load_from_file( kf, path, G_KEY_FILE_KEEP_COMMENTS, NULL );
156 g_free( path );
157 if( ret )
158 break;
159 }
160 }
161
162 g_key_file_set_string( kf, "GTK", "sNet/ThemeName", gtk_theme_name );
163 g_key_file_set_string( kf, "GTK", "sNet/IconThemeName", icon_theme_name );
164 g_key_file_set_string( kf, "GTK", "sGtk/FontName", font_name );
165 g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarStyle", tb_style );
166 g_key_file_set_string( kf, "GTK", "sGtk/CursorThemeName", cursor_theme_name );
167 g_key_file_set_integer( kf, "GTK", "iGtk/CursorThemeSize", cursor_theme_size );
168
169 data = g_key_file_to_data( kf, &len, NULL );
170 g_key_file_free( kf );
171
172 if( f = fopen( file, "w" ) )
173 {
174 fwrite( data, sizeof(char), len, f );
175 fclose( f );
176 }
177 g_free( data );
178 }
179
180 static void reload_theme()
181 {
182
183 gtk_rc_reparse_all();
184 }
185
186 static void on_list_sel_changed( GtkTreeSelection* sel, const char* prop )
187 {
188 GtkTreeIter it;
189 GtkTreeModel* model;
190 if( gtk_tree_selection_get_selected( sel, &model, &it ) )
191 {
192 char* name;
193 gtk_tree_model_get( model, &it, COL_NAME, &name, -1 );
194
195 if( model == GTK_TREE_MODEL (gtk_theme_list) ) /* gtk+ theme */
196 {
197 if( name && gtk_theme_name && 0 == strcmp( name, gtk_theme_name ) )
198 goto out;
199 g_free( gtk_theme_name );
200 gtk_theme_name = name;
201
202 if( under_lxsession )
203 g_object_set( gtk_settings_get_default(), "gtk-theme-name", name, NULL );
204 }
205 else if( model == GTK_TREE_MODEL (icon_theme_list) ) /* icon theme */
206 {
207 if( name && icon_theme_name && 0 == strcmp( name, icon_theme_name ) )
208 goto out;
209 g_free( icon_theme_name );
210 icon_theme_name = name;
211
212 if( under_lxsession )
213 g_object_set( gtk_settings_get_default(), "gtk-icon-theme-name", name, NULL );
214 }
215 else if( model == GTK_TREE_MODEL (cursor_theme_list) ) /* cursor theme */
216 {
217 if( name && cursor_theme_name && 0 == strcmp( name, cursor_theme_name ) )
218 goto out;
219 g_free( cursor_theme_name );
220 cursor_theme_name = g_strdup(name);
221 //gdk_x11_display_set_cursor_theme ( gdk_display_get_default (), name, cursor_theme_size );
222
223 if( under_lxsession )
224 g_object_set( gtk_settings_get_default(), "gtk-cursor-theme-name", name, NULL );
225 }
226
227 if( under_lxsession )
228 {
229 enable_apply();
230 }
231 else
232 {
233 write_rc_file( tmp_rc_file );
234 //gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
235 reload_demo_process();
236 }
237 return;
238 out:
239 g_free( name );
240 }
241 }
242
243 static gint sort_func( GtkTreeModel* model, GtkTreeIter* it1, GtkTreeIter* it2, gpointer data )
244 {
245 char* str1, *str2;
246 int ret;
247 gtk_tree_model_get( model, it1, COL_DISP_NAME, &str1, -1 );
248 gtk_tree_model_get( model, it2, COL_DISP_NAME, &str2, -1 );
249 ret = g_utf8_collate( str1, str2 );
250 g_free( str1 );
251 g_free( str2 );
252 return ret;
253 }
254
255 static GtkListStore* init_tree_view( GtkTreeView* view, GCallback on_sel_changed, const char* prop )
256 {
257 GtkTreeViewColumn* col;
258 GtkListStore* list;
259 GtkTreeSelection* sel;
260 int text_col = strcmp(prop, "gtk-theme-name") && strcmp(prop, "gtk-cursor-theme-name") ? COL_DISP_NAME : COL_NAME;
261
262 col = gtk_tree_view_column_new_with_attributes( NULL, gtk_cell_renderer_text_new(),
263 "text", text_col, NULL );
264 gtk_tree_view_append_column( view, col );
265
266 sel = gtk_tree_view_get_selection(view);
267 g_signal_connect( sel, "changed", on_sel_changed, GINT_TO_POINTER(prop) );
268
269 list = gtk_list_store_new( N_COLS, G_TYPE_STRING, G_TYPE_STRING );
270 gtk_tree_sortable_set_sort_func( (GtkTreeSortable*)list, text_col, sort_func, NULL, NULL );
271 gtk_tree_view_set_model( view, (GtkTreeModel*)list );
272 g_object_unref( list );
273 return list;
274 }
275
276 typedef gboolean (*ThemeFunc)(const char* file, const char* dir, const char* name, GtkListStore* list, GtkTreeIter* it);
277
278 static void load_themes_from_dir( GtkListStore* list,
279 const char* dir_path,
280 const char* lookup,
281 GtkTreeSelection* sel,
282 const char* init_sel,
283 ThemeFunc theme_func )
284 {
285 GDir* dir;
286 if( dir = g_dir_open( dir_path, 0, NULL ) )
287 {
288 const char* name;
289 while( name = g_dir_read_name( dir ) )
290 {
291 char* file = g_build_filename( dir_path, name, lookup, NULL );
292 if( g_file_test( file, G_FILE_TEST_EXISTS ) )
293 {
294 gboolean add = TRUE;
295 GtkTreeIter it;
296
297 /* prevent duplication */
298 if( gtk_tree_model_get_iter_first(GTK_TREE_MODEL (list), &it ) )
299 {
300 char* _name;
301 do {
302 _name = NULL;
303 gtk_tree_model_get(GTK_TREE_MODEL (list), &it, COL_NAME, &_name, -1);
304 if( _name && strcmp(_name, name) == 0 )
305 {
306 add = FALSE;
307 g_free(_name);
308 break;
309 }
310 g_free(_name);
311 }
312 while( gtk_tree_model_iter_next(GTK_TREE_MODEL (list), &it ) );
313 }
314
315 if( add )
316 {
317 gtk_list_store_append( list, &it );
318 gtk_list_store_set( list, &it, COL_NAME, name, -1 );
319
320 if( theme_func )
321 {
322 if( ! theme_func(file, (char *) dir, name, list, &it) )
323 add = FALSE;
324 }
325
326 if( add )
327 {
328 if( 0 == strcmp( name, init_sel ) )
329 {
330 GtkTreeView* view;
331 GtkTreePath* tp;
332 gtk_tree_selection_select_iter( sel, &it );
333 view = gtk_tree_selection_get_tree_view( sel );
334 tp = gtk_tree_model_get_path( (GtkTreeModel*)list, &it );
335 gtk_tree_view_scroll_to_cell( view, tp, NULL, FALSE, 0, 0 );
336 gtk_tree_path_free( tp );
337 }
338 }
339 else
340 gtk_list_store_remove( list, &it );
341 }
342 }
343 g_free( file );
344 }
345 g_dir_close( dir );
346 }
347 }
348
349 static void load_from_data_dirs( GtkListStore* list,
350 const char* relative_path,
351 const char* lookup,
352 GtkTreeSelection* sel,
353 const char* init_sel,
354 ThemeFunc theme_func )
355 {
356 const char* const *dirs = g_get_system_data_dirs();
357 const char* const *dir;
358 char* dir_path;
359 for( dir = dirs; *dir; ++dir )
360 {
361 dir_path = g_build_filename( *dir, relative_path, NULL );
362 load_themes_from_dir( list, dir_path, lookup, sel, init_sel, theme_func );
363 g_free( dir_path );
364 }
365 dir_path = g_build_filename( g_get_user_data_dir(), relative_path, NULL );
366 load_themes_from_dir( list, dir_path, lookup, sel, init_sel, theme_func );
367 g_free( dir_path );
368 }
369
370 static gboolean icon_theme_func(const char* file, const char* dir, const char* name, GtkListStore* list, GtkTreeIter* it)
371 {
372 GKeyFile* kf;
373 char* disp_name = NULL;
374 if( g_str_has_prefix( name, "default." ) )
375 return FALSE;
376
377 kf = g_key_file_new();
378 if( g_key_file_load_from_file(kf, file, 0, NULL) )
379 {
380 if( g_key_file_has_key(kf, "Icon Theme", "Directories", NULL)
381 && ! g_key_file_get_boolean(kf, "Icon Theme", "Hidden", NULL) )
382 {
383 disp_name = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
384 gtk_list_store_set( list, it, COL_DISP_NAME, disp_name ? disp_name : name, -1 );
385 }
386 }
387 g_key_file_free(kf);
388 return disp_name != NULL;
389 }
390
391 static gboolean cursor_theme_func(const char* dir, const char* name, const char* lookup)
392 {
393 char* ret = NULL;
394 /*
395 GKeyFile* kf = g_key_file_new();
396 if( g_key_file_load_from_file(kf, lookup, 0, NULL) )
397 {
398 if( g_key_file_has_key(kf, "Icon Theme", "Directories", NULL) )
399 {
400 ret = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
401 }
402 }
403 g_key_file_free(kf);
404 */
405 return ret != NULL;
406 }
407
408 static void load_gtk_themes( GtkListStore* list, const char* cur_sel )
409 {
410 char* path;
411 GtkTreeSelection* sel = gtk_tree_view_get_selection( gtk_theme_view );
412 load_from_data_dirs( list, "themes", "gtk-2.0", sel, cur_sel, NULL );
413 path = g_build_filename( g_get_home_dir(), ".themes", NULL );
414 load_themes_from_dir( list, path, "gtk-2.0", sel, cur_sel, NULL );
415 g_free( path );
416 gtk_tree_sortable_set_sort_column_id( (GtkTreeSortable*)list, 0, GTK_SORT_ASCENDING );
417 }
418
419 static void load_icon_themes( GtkListStore* list, const char* cur_sel )
420 {
421 char* path;
422 GtkTreeSelection* sel = gtk_tree_view_get_selection( icon_theme_view );
423 load_from_data_dirs( list, "icons", "index.theme", sel, cur_sel, icon_theme_func );
424 path = g_build_filename( g_get_home_dir(), ".icons", NULL );
425 load_themes_from_dir( list, path, "index.theme", sel, cur_sel, icon_theme_func );
426 g_free( path );
427 gtk_tree_sortable_set_sort_column_id( (GtkTreeSortable*)list, 0, GTK_SORT_ASCENDING );
428 }
429
430 static void load_cursor_themes( GtkListStore* list, const char* cur_sel )
431 {
432 char* path;
433 GtkTreeSelection* sel = gtk_tree_view_get_selection( cursor_theme_view );
434 load_from_data_dirs( list, "icons", "cursors", sel, cur_sel, NULL );
435 path = g_build_filename( g_get_home_dir(), ".icons", NULL );
436 load_themes_from_dir( list, path, "cursors", sel, cur_sel, NULL );
437 g_free( path );
438 gtk_tree_sortable_set_sort_column_id( (GtkTreeSortable*)list, 0, GTK_SORT_ASCENDING );
439 }
440 /*
441 static void load_fonts( GtkListStore* list )
442 {
443
444 }
445 */
446
447 gboolean center_win( GtkWidget* dlg )
448 {
449 gtk_widget_show( dlg );
450 return FALSE;
451 }
452
453 static void on_demo_loaded( GtkSocket* socket, GtkWidget* dlg )
454 {
455 /* sleep for 0.8 sec for loading of the demo window */
456 /* FIXME: we need a better way to do this, such as IPC */
457 g_timeout_add_full( G_PRIORITY_LOW, 800, (GSourceFunc)center_win, dlg, NULL );
458 g_signal_handlers_disconnect_by_func( socket, on_demo_loaded, dlg );
459 }
460
461 void main_dlg_init( GtkWidget* dlg )
462 {
463 char* files[] = { tmp_rc_file, NULL };
464 char** def_files = gtk_rc_get_default_files();
465 char** file;
466
467 if( under_lxsession )
468 {
469 session_name = g_getenv("DESKTOP_SESSION");
470 }
471 else
472 {
473 /* no lxsession-settings daemon, use gtkrc-2.0 */
474 for( file = def_files; *file; ++file )
475 {
476 if( 0 == access( *file, W_OK ) )
477 rc_file = *file;
478 }
479 if( rc_file )
480 rc_file = g_strdup( rc_file );
481 else
482 rc_file = g_build_filename( g_get_home_dir(), ".gtkrc-2.0", NULL );
483 }
484
485 g_object_get( gtk_settings_get_default(),
486 "gtk-theme-name", &gtk_theme_name,
487 "gtk-icon-theme-name", &icon_theme_name,
488 "gtk-font-name", &font_name,
489 "gtk-toolbar-style", &tb_style,
490 "gtk-cursor-theme-name", &cursor_theme_name,
491 "gtk-cursor-theme-size", &cursor_theme_size,
492 NULL );
493
494 if( ! gtk_theme_name )
495 gtk_theme_name = g_strdup( "Raleigh" );
496 if( ! icon_theme_name )
497 icon_theme_name = g_strdup( "hicolor" );
498 if( ! cursor_theme_name )
499 cursor_theme_name = g_strdup( "default" );
500 if( ! font_name )
501 font_name = g_strdup( "Sans 10" );
502 if( ! cursor_theme_size )
503 cursor_theme_size = 16;
504
505 /* no lxsession-settings daemon, use gtkrc-2.0 */
506 if( ! under_lxsession )
507 write_rc_file( tmp_rc_file );
508
509 INIT_LIST( gtk_theme, "gtk-theme-name" )
510 INIT_LIST( icon_theme, "gtk-icon-theme-name" )
511 INIT_LIST( cursor_theme, "gtk-cursor-theme-name" )
512 gtk_font_button_set_font_name( (GtkFontButton*)lookup_widget(dlg, "font"), font_name );
513 gtk_range_set_value( GTK_RANGE(lookup_widget(dlg, "cursor_theme_size")), cursor_theme_size );
514
515 gtk_combo_box_set_active( (GtkComboBox*)lookup_widget(dlg, "tb_style"), tb_style < 4 ? tb_style : 3 );
516
517 GET_WIDGET_WITH_TYPE( demo_box, GTK_WIDGET );
518 gtk_widget_show( demo_box );
519
520 if( under_lxsession )
521 {
522 /* XSettings daemon of lxsession is running, gtkrc is useless.
523 * We should set properties of GtkSettings object on the fly.
524 * This will cause problems with some themes, but we have no choice.
525 */
526 show_demo( (GdkNativeWindow)demo_box );
527 gtk_widget_show_all( dlg );
528 }
529 else
530 {
531 /* no lxsession-settings daemon, use gtkrc-2.0 and load preview in another process */
532 demo_socket = gtk_socket_new();
533 g_signal_connect( demo_socket, "plug-added", G_CALLBACK(on_demo_loaded), dlg );
534 g_signal_connect( demo_socket, "plug-removed", G_CALLBACK(gtk_true), NULL );
535 gtk_widget_show( demo_socket );
536 gtk_container_add( (GtkContainer*)demo_box, demo_socket );
537
538 gtk_widget_realize( dlg );
539 reload_demo_process();
540 }
541
542 disable_apply();
543 }
544
545 static void reload_all_programs( gboolean icon_only )
546 {
547 GdkEventClient event;
548 event.type = GDK_CLIENT_EVENT;
549 event.send_event = TRUE;
550 event.window = NULL;
551
552 if( under_lxsession )
553 {
554 /*
555 char* argv[]={"lxsession", "-r", NULL};
556 g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, NULL, NULL);
557 return;
558 */
559 event.message_type = gdk_atom_intern_static_string("_LXSESSION");
560 event.data.b[0] = 0; /* LXS_RELOAD */
561 }
562 else
563 {
564 if( icon_only )
565 event.message_type = gdk_atom_intern("_GTK_LOAD_ICONTHEMES", FALSE);
566 else
567 event.message_type = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
568 }
569 event.data_format = 8;
570 gdk_event_send_clientmessage_toall((GdkEvent *)&event);
571 }
572
573 void
574 on_apply_clicked (GtkButton *button,
575 gpointer user_data)
576 {
577 if( under_lxsession )
578 write_lxsession_config();
579 else
580 write_rc_file( rc_file );
581
582 reload_all_programs( FALSE );
583 disable_apply();
584 }
585
586
587 void
588 on_font_changed (GtkFontButton *fontbutton,
589 gpointer user_data)
590 {
591 const char* name = gtk_font_button_get_font_name(fontbutton);
592 if( name && font_name && 0 == strcmp( name, font_name ) )
593 return;
594 g_free( font_name );
595 font_name = g_strdup( name );
596
597 if( under_lxsession )
598 {
599 g_object_set( gtk_settings_get_default(), "gtk-font-name", font_name, NULL );
600
601 enable_apply();
602 }
603 else
604 {
605 write_rc_file( tmp_rc_file );
606 reload_demo_process();
607 }
608 }
609
610 void
611 on_install_theme_clicked (GtkButton *button,
612 gpointer user_data)
613 {
614 GtkFileFilter* filter = gtk_file_filter_new();
615 GtkWidget* fc = gtk_file_chooser_dialog_new( _("Select an icon theme"), NULL,
616 GTK_FILE_CHOOSER_ACTION_OPEN,
617 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
618 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL );
619
620 gtk_file_filter_add_pattern( filter, "*.tar.gz" );
621 gtk_file_filter_add_pattern( filter, "*.tar.bz2" );
622 gtk_file_filter_set_name( filter, _("*.tar.gz, *.tar.bz2 (Icon Theme)") );
623
624 gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(fc), filter );
625 gtk_file_chooser_set_filter( GTK_FILE_CHOOSER(fc), filter );
626
627 if( gtk_dialog_run( (GtkDialog*)fc ) == GTK_RESPONSE_OK )
628 {
629 char* file = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(fc) );
630 char* argv[]={
631 PACKAGE_DATA_DIR"/lxappearance/install-icon-theme.sh",
632 file, NULL };
633 int status = 0;
634 char* stdo = NULL;
635 if( g_spawn_sync( NULL, argv, NULL, 0, NULL, NULL, &stdo, NULL, &status, NULL ) && 0 == status )
636 {
637 char* sep = stdo ? strchr( stdo, '\n' ) : NULL;
638 if( sep )
639 *sep = '\0';
640
641 /* reload all icon themes */
642 gtk_list_store_clear( icon_theme_list );
643 load_icon_themes( icon_theme_list, stdo ? stdo : "" );
644
645 /* reload all cursor themes */
646 gtk_list_store_clear( cursor_theme_list );
647 load_cursor_themes( cursor_theme_list, stdo ? stdo : "" );
648 }
649 g_free( file );
650 }
651
652 gtk_widget_destroy( fc );
653 }
654
655
656 void
657 on_remove_theme_clicked (GtkButton *button,
658 gpointer user_data)
659 {
660
661 }
662
663 void
664 on_cursor_size_changed (GtkHScale *cursorsizescale,
665 gpointer user_data)
666 {
667 cursor_theme_size = gtk_range_get_value( GTK_RANGE(cursorsizescale) );
668
669 if( under_lxsession )
670 {
671 g_object_set( gtk_settings_get_default(), "gtk-cursor-theme-size", cursor_theme_size, NULL );
672 enable_apply();
673 }
674 else
675 {
676 write_rc_file( tmp_rc_file );
677 reload_demo_process();
678 }
679 }
680
681 void
682 on_tb_style_changed (GtkComboBox *combobox,
683 gpointer user_data)
684 {
685 int sel = gtk_combo_box_get_active( combobox );
686 if( sel == tb_style || sel < 0 )
687 return;
688 tb_style = sel;
689
690 if( under_lxsession )
691 {
692 g_object_set( gtk_settings_get_default(), "gtk-toolbar-style", tb_style, NULL );
693 enable_apply();
694 }
695 else
696 {
697 write_rc_file( tmp_rc_file );
698 reload_demo_process();
699 }
700 }
701