1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 handlers.h for ObConf, the configuration tool for Openbox
4 Copyright (c) 2003-2007 Dana Jansens
5 Copyright (c) 2003 Tim Riley
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "openbox/render.h"
30 static gboolean mapping;
32 static GtkListStore *desktop_store;
33 static int num_desktops;
34 static GList *desktop_names;
35 static GtkListStore *theme_store;
37 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
38 const gchar *path_string,
39 const gchar *new_text,
42 static void on_theme_names_selection_changed(GtkTreeSelection *sel,
46 void setup_behavior_tab()
48 GtkWidget *winresist, *edgeresist;
49 GtkWidget *winresist_l, *edgeresist_l;
50 GtkSizeGroup *group1, *group2;
52 winresist = glade_xml_get_widget(glade, "resist_window");
53 edgeresist = glade_xml_get_widget(glade, "resist_edge");
54 group1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
56 gtk_size_group_add_widget(group1, winresist);
57 gtk_size_group_add_widget(group1, edgeresist);
59 winresist_l = glade_xml_get_widget(glade, "resist_window_label");
60 edgeresist_l = glade_xml_get_widget(glade, "resist_edge_label");
61 group2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
63 gtk_size_group_add_widget(group2, winresist_l);
64 gtk_size_group_add_widget(group2, edgeresist_l);
69 GtkWidget *posi, *dir;
70 GtkWidget *posi_l, *dir_l;
71 GtkSizeGroup *group1, *group2;
73 posi = glade_xml_get_widget(glade, "dock_position");
74 dir = glade_xml_get_widget(glade, "dock_direction");
75 group1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
77 gtk_size_group_add_widget(group1, posi);
78 gtk_size_group_add_widget(group1, dir);
80 posi_l = glade_xml_get_widget(glade, "dock_position_label");
81 dir_l = glade_xml_get_widget(glade, "dock_direction_label");
82 group2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
84 gtk_size_group_add_widget(group2, posi_l);
85 gtk_size_group_add_widget(group2, dir_l);
90 gboolean on_main_window_delete_event(GtkWidget *w, GdkEvent *e, gpointer d)
96 void on_close_clicked()
101 void on_about_clicked()
106 parent = glade_xml_get_widget(glade, "main_window");
107 about = glade_xml_get_widget(glade, "about_window");
109 gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(parent));
110 gtk_widget_show(about);
113 void on_about_close_clicked()
117 about = glade_xml_get_widget(glade, "about_window");
119 gtk_widget_hide(about);
122 void on_about_window_delete_event()
126 about = glade_xml_get_widget(glade, "about_window");
128 gtk_widget_hide(about);
131 void setup_focus_mouse(GtkWidget *w)
137 b = tree_get_bool("focus/followMouse", FALSE);
138 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), b);
141 GtkWidget *delay = glade_xml_get_widget(glade, "focus_delay");
142 GtkWidget *delay_l = glade_xml_get_widget(glade, "focus_delay_label");
143 GtkWidget *delay_u = glade_xml_get_widget(glade,
144 "focus_delay_label_units");
145 GtkWidget *raise = glade_xml_get_widget(glade, "focus_raise");
146 GtkWidget *last = glade_xml_get_widget(glade, "focus_last");
147 gtk_widget_set_sensitive(delay, b);
148 gtk_widget_set_sensitive(delay_l, b);
149 gtk_widget_set_sensitive(delay_u, b);
150 gtk_widget_set_sensitive(raise, b);
151 gtk_widget_set_sensitive(last, b);
157 void setup_focus_delay(GtkWidget *w)
160 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
161 tree_get_int("focus/focusDelay", 0));
165 void setup_focus_raise(GtkWidget *w)
168 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
169 tree_get_bool("focus/raiseOnFocus", FALSE));
173 void setup_focus_last(GtkWidget *w)
176 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
177 tree_get_bool("focus/focusLast", FALSE));
181 void setup_focus_new(GtkWidget *w)
184 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
185 tree_get_bool("focus/focusNew", TRUE));
189 void setup_place_mouse(GtkWidget *w)
194 s = tree_get_string("placement/policy", "Smart");
195 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
196 !g_ascii_strcasecmp(s, "UnderMouse"));
201 void setup_resist_window(GtkWidget *w)
204 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
205 tree_get_int("resistance/strength", 10));
209 void setup_resist_edge(GtkWidget *w)
212 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
213 tree_get_int("resistance/screen_edge_strength",
218 void setup_resize_contents(GtkWidget *w)
221 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
222 tree_get_bool("resize/drawContents", TRUE));
226 void setup_dock_position(GtkWidget *w)
233 s = tree_get_string("dock/position", "TopLeft");
236 if (!strcasecmp(s, "Top"))
237 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 1);
238 else if (!strcasecmp(s, "TopRight"))
239 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 2);
240 else if (!strcasecmp(s, "Left"))
241 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 3);
242 else if (!strcasecmp(s, "Right"))
243 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 4);
244 else if (!strcasecmp(s, "BottomLeft"))
245 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 5);
246 else if (!strcasecmp(s, "Bottom"))
247 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 6);
248 else if (!strcasecmp(s, "BottomRight"))
249 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 7);
250 else if (!strcasecmp(s, "Floating")) {
251 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 8);
254 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0);
259 s = glade_xml_get_widget(glade, "dock_float_x");
260 gtk_widget_set_sensitive(s, f);
261 s = glade_xml_get_widget(glade, "dock_float_y");
262 gtk_widget_set_sensitive(s, f);
263 s = glade_xml_get_widget(glade, "dock_float_label");
264 gtk_widget_set_sensitive(s, f);
265 s = glade_xml_get_widget(glade, "dock_float_label_x");
266 gtk_widget_set_sensitive(s, f);
272 void setup_dock_float_x(GtkWidget *w)
276 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
277 tree_get_int("dock/floatingX", 0));
282 void setup_dock_float_y(GtkWidget *w)
286 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
287 tree_get_int("dock/floatingY", 0));
292 void setup_dock_stacking(GtkWidget *top, GtkWidget *normal, GtkWidget *bottom)
298 s = tree_get_string("dock/stacking", "Top");
300 if(!strcasecmp(s, "Normal"))
301 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(normal), TRUE);
302 else if(!strcasecmp(s, "Bottom"))
303 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bottom), TRUE);
305 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(top), TRUE);
311 void setup_dock_direction(GtkWidget *w)
317 s = tree_get_string("dock/direction", "Vertical");
319 if (!strcasecmp(s, "Horizontal"))
320 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 1);
322 gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0);
328 void setup_dock_hide(GtkWidget *w)
334 b = tree_get_bool("dock/autoHide", FALSE);
335 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), b);
338 GtkWidget *delay = glade_xml_get_widget(glade, "dock_hide_delay");
339 GtkWidget *delay_l = glade_xml_get_widget(glade, "dock_hide_label");
340 GtkWidget *delay_u = glade_xml_get_widget(glade,
341 "dock_hide_label_units");
342 gtk_widget_set_sensitive(delay, b);
343 gtk_widget_set_sensitive(delay_l, b);
344 gtk_widget_set_sensitive(delay_u, b);
350 void setup_dock_hide_delay(GtkWidget *w)
354 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
355 tree_get_int("dock/hideDelay", 300));
360 static void add_theme_dir(const gchar *dirname)
365 if ((dir = g_dir_open(dirname, 0, NULL))) {
366 while ((n = g_dir_read_name(dir))) {
369 full = g_build_filename(dirname, n, "openbox-3",
371 if (!g_file_test(full,
372 G_FILE_TEST_IS_REGULAR |
373 G_FILE_TEST_IS_SYMLINK))
379 themes = g_list_append(themes, g_strdup(n));
386 static void reset_theme_names(GtkWidget *w)
393 name = tree_get_string("theme/name", "TheBear");
395 for (it = themes; it; it = g_list_next(it))
400 p = g_build_filename(g_get_home_dir(), ".themes", NULL);
406 for (it = parse_xdg_data_dir_paths(); it; it = g_slist_next(it)) {
407 p = g_build_filename(it->data, "themes", NULL);
413 add_theme_dir(THEMEDIR);
415 themes = g_list_sort(themes, (GCompareFunc) strcasecmp);
417 /* return to regular scheduled programming */
419 for (it = themes; it; it = next) {
422 next = g_list_next(it);
424 /* remove duplicates */
425 if (next && !strcmp(it->data, next->data)) {
427 themes = g_list_delete_link(themes, it);
431 gtk_list_store_append(theme_store, &iter);
432 gtk_list_store_set(theme_store, &iter,
437 if(!strcmp(name, it->data)) {
439 path = gtk_tree_path_new_from_indices(i, -1);
440 gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);
450 void setup_theme_names(GtkWidget *w)
452 GtkCellRenderer *render;
453 GtkTreeViewColumn *column;
454 GtkTreeSelection *select;
459 theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
460 gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store));
461 g_object_unref (theme_store);
463 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
464 GTK_SELECTION_SINGLE);
466 render = gtk_cell_renderer_text_new();
467 column = gtk_tree_view_column_new_with_attributes
468 ("Name", render, "text", 0, NULL);
469 gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
471 /* setup the selection handler */
472 select = gtk_tree_view_get_selection(GTK_TREE_VIEW (w));
473 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
474 g_signal_connect (G_OBJECT(select), "changed",
475 G_CALLBACK(on_theme_names_selection_changed),
478 reset_theme_names(w);
483 void setup_title_layout(GtkWidget *w)
489 layout = tree_get_string("theme/titleLayout", "NLIMC");
490 gtk_entry_set_text(GTK_ENTRY(w), layout);
496 void setup_desktop_num(GtkWidget *w)
500 num_desktops = tree_get_int("desktops/number", 4);
501 gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), num_desktops);
506 void setup_window_border(GtkWidget *w)
512 border = tree_get_bool("theme/keepBorder", TRUE);
513 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), border);
518 static void setup_font(GtkWidget *w, const gchar *place)
520 gchar *fontstring, *node;
521 gchar *name, **names;
528 node = g_strdup_printf("theme/font:place=%s/name", place);
529 name = tree_get_string(node, "Sans");
532 node = g_strdup_printf("theme/font:place=%s/size", place);
533 size = tree_get_string(node, "8");
536 node = g_strdup_printf("theme/font:place=%s/weight", place);
537 weight = tree_get_string(node, "");
540 node = g_strdup_printf("theme/font:place=%s/slant", place);
541 slant = tree_get_string(node, "");
544 /* get only the first font in the string */
545 names = g_strsplit(name, ",", 0);
547 name = g_strdup(names[0]);
550 /* don't use "normal" in the gtk string */
551 if (!g_ascii_strcasecmp(weight, "normal")) {
552 g_free(weight); weight = g_strdup("");
554 if (!g_ascii_strcasecmp(slant, "normal")) {
555 g_free(slant); slant = g_strdup("");
558 fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size);
559 gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring);
569 void setup_font_active(GtkWidget *w)
571 setup_font(w, "ActiveWindow");
574 void setup_font_inactive(GtkWidget *w)
576 setup_font(w, "InactiveWindow");
579 void setup_font_menu_header(GtkWidget *w)
581 setup_font(w, "MenuHeader");
584 void setup_font_menu_item(GtkWidget *w)
586 setup_font(w, "MenuItem");
589 void setup_font_display(GtkWidget *w)
591 setup_font(w, "OnScreenDisplay");
595 static void reset_desktop_names()
602 gtk_list_store_clear(desktop_store);
604 for (lit = desktop_names; lit; lit = g_list_next(lit))
606 g_list_free(desktop_names);
607 desktop_names = NULL;
610 n = tree_get_node("desktops/names", NULL)->children;
614 if (!xmlStrcmp(n->name, (const xmlChar*)"name")) {
615 name = parse_string(doc, n);
617 desktop_names = g_list_append(desktop_names, name);
619 gtk_list_store_append(desktop_store, &it);
620 gtk_list_store_set(desktop_store, &it,
621 0, (name[0] ? name : _("(Unnamed desktop)")),
630 while (i < num_desktops) {
631 gchar *name = g_strdup("");
633 desktop_names = g_list_append(desktop_names, name);
635 gtk_list_store_append(desktop_store, &it);
636 gtk_list_store_set(desktop_store, &it,
637 0, _("(Unnamed desktop)"),
644 void setup_desktop_names(GtkWidget *w)
646 GtkCellRenderer *render;
647 GtkTreeViewColumn *column;
651 desktop_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
652 gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(desktop_store));
653 g_object_unref (desktop_store);
655 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
656 GTK_SELECTION_SINGLE);
658 render = gtk_cell_renderer_text_new();
659 g_signal_connect(render, "edited",
660 G_CALLBACK (on_desktop_names_cell_edited),
663 column = gtk_tree_view_column_new_with_attributes
664 ("Name", render, "text", 0, "editable", 1, NULL);
665 gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
667 reset_desktop_names();
673 /***********************************************************************/
675 void on_window_border_toggled(GtkToggleButton *w, gpointer data)
681 b = gtk_toggle_button_get_active(w);
682 tree_set_bool("theme/keepBorder", b);
685 static void on_font_set(GtkFontButton *w, const gchar *place)
689 const gchar *size = NULL;
690 const gchar *bold = NULL;
691 const gchar *italic = NULL;
695 font = g_strdup(gtk_font_button_get_font_name(w));
696 while ((c = strrchr(font, ' '))) {
697 if (!bold && !italic && !size && atoi(c+1))
699 else if (!bold && !italic && !g_ascii_strcasecmp(c+1, "italic"))
701 else if (!bold && !g_ascii_strcasecmp(c+1, "bold"))
707 if (!bold) bold = "Normal";
708 if (!italic) italic = "Normal";
710 node = g_strdup_printf("theme/font:place=%s/name", place);
711 tree_set_string(node, font);
714 node = g_strdup_printf("theme/font:place=%s/size", place);
715 tree_set_string(node, size);
718 node = g_strdup_printf("theme/font:place=%s/weight", place);
719 tree_set_string(node, bold);
722 node = g_strdup_printf("theme/font:place=%s/slant", place);
723 tree_set_string(node, italic);
729 void on_font_active_font_set(GtkFontButton *w, gpointer data)
731 on_font_set(w, "ActiveWindow");
734 void on_font_inactive_font_set(GtkFontButton *w, gpointer data)
736 on_font_set(w, "InactiveWindow");
739 void on_font_menu_header_font_set(GtkFontButton *w, gpointer data)
741 on_font_set(w, "MenuHeader");
744 void on_font_menu_item_font_set(GtkFontButton *w, gpointer data)
746 on_font_set(w, "MenuItem");
749 void on_font_display_font_set(GtkFontButton *w, gpointer data)
751 on_font_set(w, "OnScreenDisplay");
754 void on_focus_mouse_toggled(GtkToggleButton *w, gpointer data)
760 b = gtk_toggle_button_get_active(w);
761 tree_set_bool("focus/followMouse", b);
764 GtkWidget *delay = glade_xml_get_widget(glade, "focus_delay");
765 GtkWidget *delay_l = glade_xml_get_widget(glade, "focus_delay_label");
766 GtkWidget *delay_u = glade_xml_get_widget(glade,
767 "focus_delay_label_units");
768 GtkWidget *raise = glade_xml_get_widget(glade, "focus_raise");
769 GtkWidget *last = glade_xml_get_widget(glade, "focus_last");
770 gtk_widget_set_sensitive(delay, b);
771 gtk_widget_set_sensitive(delay_l, b);
772 gtk_widget_set_sensitive(delay_u, b);
773 gtk_widget_set_sensitive(raise, b);
774 gtk_widget_set_sensitive(last, b);
778 void on_focus_delay_value_changed(GtkSpinButton *w, gpointer data)
782 tree_set_int("focus/focusDelay",
783 gtk_spin_button_get_value_as_int(w));
786 void on_focus_raise_toggled(GtkToggleButton *w, gpointer data)
790 tree_set_bool("focus/raiseOnFocus", gtk_toggle_button_get_active(w));
793 void on_focus_last_toggled(GtkToggleButton *w, gpointer data)
797 tree_set_bool("focus/focusLast", gtk_toggle_button_get_active(w));
800 void on_focus_new_toggled(GtkToggleButton *w, gpointer data)
804 tree_set_bool("focus/focusNew", gtk_toggle_button_get_active(w));
807 void on_place_mouse_toggled(GtkToggleButton *w, gpointer data)
811 tree_set_string("placement/policy",
812 (gtk_toggle_button_get_active(w) ?
813 "UnderMouse" : "Smart"));
816 void on_resist_window_value_changed(GtkSpinButton *w, gpointer data)
820 tree_set_int("resistance/strength", gtk_spin_button_get_value_as_int(w));
823 void on_resist_edge_value_changed(GtkSpinButton *w, gpointer data)
827 tree_set_int("resistance/screen_edge_strength",
828 gtk_spin_button_get_value_as_int(w));
831 void on_resize_contents_toggled(GtkToggleButton *w, gpointer data)
835 tree_set_bool("resize/drawContents", gtk_toggle_button_get_active(w));
838 void on_dock_top_left_activate(GtkMenuItem *w, gpointer data)
842 tree_set_string("dock/position", "TopLeft");
846 s = glade_xml_get_widget(glade, "dock_float_x");
847 gtk_widget_set_sensitive(s, FALSE);
848 s = glade_xml_get_widget(glade, "dock_float_y");
849 gtk_widget_set_sensitive(s, FALSE);
850 s = glade_xml_get_widget(glade, "dock_float_label");
851 gtk_widget_set_sensitive(s, FALSE);
852 s = glade_xml_get_widget(glade, "dock_float_label_x");
853 gtk_widget_set_sensitive(s, FALSE);
857 void on_dock_top_activate(GtkMenuItem *w, gpointer data)
861 tree_set_string("dock/position", "Top");
865 s = glade_xml_get_widget(glade, "dock_float_x");
866 gtk_widget_set_sensitive(s, FALSE);
867 s = glade_xml_get_widget(glade, "dock_float_y");
868 gtk_widget_set_sensitive(s, FALSE);
869 s = glade_xml_get_widget(glade, "dock_float_label");
870 gtk_widget_set_sensitive(s, FALSE);
871 s = glade_xml_get_widget(glade, "dock_float_label_x");
872 gtk_widget_set_sensitive(s, FALSE);
876 void on_dock_top_right_activate(GtkMenuItem *w, gpointer data)
880 tree_set_string("dock/position", "TopRight");
884 s = glade_xml_get_widget(glade, "dock_float_x");
885 gtk_widget_set_sensitive(s, FALSE);
886 s = glade_xml_get_widget(glade, "dock_float_y");
887 gtk_widget_set_sensitive(s, FALSE);
888 s = glade_xml_get_widget(glade, "dock_float_label");
889 gtk_widget_set_sensitive(s, FALSE);
890 s = glade_xml_get_widget(glade, "dock_float_label_x");
891 gtk_widget_set_sensitive(s, FALSE);
895 void on_dock_left_activate(GtkMenuItem *w, gpointer data)
899 tree_set_string("dock/position", "Left");
903 s = glade_xml_get_widget(glade, "dock_float_x");
904 gtk_widget_set_sensitive(s, FALSE);
905 s = glade_xml_get_widget(glade, "dock_float_y");
906 gtk_widget_set_sensitive(s, FALSE);
907 s = glade_xml_get_widget(glade, "dock_float_label");
908 gtk_widget_set_sensitive(s, FALSE);
909 s = glade_xml_get_widget(glade, "dock_float_label_x");
910 gtk_widget_set_sensitive(s, FALSE);
914 void on_dock_right_activate(GtkMenuItem *w, gpointer data)
918 tree_set_string("dock/position", "Right");
922 s = glade_xml_get_widget(glade, "dock_float_x");
923 gtk_widget_set_sensitive(s, FALSE);
924 s = glade_xml_get_widget(glade, "dock_float_y");
925 gtk_widget_set_sensitive(s, FALSE);
926 s = glade_xml_get_widget(glade, "dock_float_label");
927 gtk_widget_set_sensitive(s, FALSE);
928 s = glade_xml_get_widget(glade, "dock_float_label_x");
929 gtk_widget_set_sensitive(s, FALSE);
934 void on_dock_bottom_left_activate(GtkMenuItem *w, gpointer data)
938 tree_set_string("dock/position", "BottomLeft");
942 s = glade_xml_get_widget(glade, "dock_float_x");
943 gtk_widget_set_sensitive(s, FALSE);
944 s = glade_xml_get_widget(glade, "dock_float_y");
945 gtk_widget_set_sensitive(s, FALSE);
946 s = glade_xml_get_widget(glade, "dock_float_label");
947 gtk_widget_set_sensitive(s, FALSE);
948 s = glade_xml_get_widget(glade, "dock_float_label_x");
949 gtk_widget_set_sensitive(s, FALSE);
953 void on_dock_bottom_activate(GtkMenuItem *w, gpointer data)
957 tree_set_string("dock/position", "Bottom");
961 s = glade_xml_get_widget(glade, "dock_float_x");
962 gtk_widget_set_sensitive(s, FALSE);
963 s = glade_xml_get_widget(glade, "dock_float_y");
964 gtk_widget_set_sensitive(s, FALSE);
965 s = glade_xml_get_widget(glade, "dock_float_label");
966 gtk_widget_set_sensitive(s, FALSE);
967 s = glade_xml_get_widget(glade, "dock_float_label_x");
968 gtk_widget_set_sensitive(s, FALSE);
972 void on_dock_bottom_right_activate(GtkMenuItem *w, gpointer data)
976 tree_set_string("dock/position", "BottomRight");
980 s = glade_xml_get_widget(glade, "dock_float_x");
981 gtk_widget_set_sensitive(s, FALSE);
982 s = glade_xml_get_widget(glade, "dock_float_y");
983 gtk_widget_set_sensitive(s, FALSE);
984 s = glade_xml_get_widget(glade, "dock_float_label");
985 gtk_widget_set_sensitive(s, FALSE);
986 s = glade_xml_get_widget(glade, "dock_float_label_x");
987 gtk_widget_set_sensitive(s, FALSE);
991 void on_dock_floating_activate(GtkMenuItem *w, gpointer data)
995 tree_set_string("dock/position", "Floating");
999 s = glade_xml_get_widget(glade, "dock_float_x");
1000 gtk_widget_set_sensitive(s, TRUE);
1001 s = glade_xml_get_widget(glade, "dock_float_y");
1002 gtk_widget_set_sensitive(s, TRUE);
1003 s = glade_xml_get_widget(glade, "dock_float_label");
1004 gtk_widget_set_sensitive(s, TRUE);
1005 s = glade_xml_get_widget(glade, "dock_float_label_x");
1006 gtk_widget_set_sensitive(s, TRUE);
1010 void on_dock_float_x_value_changed(GtkSpinButton *w, gpointer data)
1012 if (mapping) return;
1014 tree_set_int("dock/floatingX", gtk_spin_button_get_value_as_int(w));
1017 void on_dock_float_y_value_changed(GtkSpinButton *w, gpointer data)
1019 if (mapping) return;
1021 tree_set_int("dock/floatingY", gtk_spin_button_get_value_as_int(w));
1024 void on_dock_stacking_top_toggled(GtkToggleButton *w, gpointer data)
1026 if (mapping) return;
1028 if(gtk_toggle_button_get_active(w))
1029 tree_set_string("dock/stacking", "Top");
1032 void on_dock_stacking_normal_toggled(GtkToggleButton *w, gpointer data)
1034 if (mapping) return;
1036 if(gtk_toggle_button_get_active(w))
1037 tree_set_string("dock/stacking", "Normal");
1040 void on_dock_stacking_bottom_toggled(GtkToggleButton *w, gpointer data)
1042 if (mapping) return;
1044 if(gtk_toggle_button_get_active(w))
1045 tree_set_string("dock/stacking", "Bottom");
1048 void on_dock_horizontal_activate(GtkMenuItem *w, gpointer data)
1050 if (mapping) return;
1052 tree_set_string("dock/direction", "Horizontal");
1055 void on_dock_vertical_activate(GtkMenuItem *w, gpointer data)
1057 if (mapping) return;
1059 tree_set_string("dock/direction", "Vertical");
1062 void on_dock_hide_toggled(GtkToggleButton *w, gpointer data)
1064 if (mapping) return;
1066 tree_set_bool("dock/autoHide", gtk_toggle_button_get_active(w));
1068 GtkWidget *delay = glade_xml_get_widget(glade, "dock_hide_delay");
1069 GtkWidget *delay_l = glade_xml_get_widget(glade, "dock_hide_label");
1070 GtkWidget *delay_u = glade_xml_get_widget(glade,
1071 "dock_hide_label_units");
1072 gtk_widget_set_sensitive(delay, gtk_toggle_button_get_active(w));
1073 gtk_widget_set_sensitive(delay_l, gtk_toggle_button_get_active(w));
1074 gtk_widget_set_sensitive(delay_u, gtk_toggle_button_get_active(w));
1078 void on_dock_hide_delay_value_changed(GtkSpinButton *w, gpointer data)
1080 if (mapping) return;
1082 tree_set_int("dock/hideDelay",
1083 gtk_spin_button_get_value_as_int(w));
1086 void on_theme_name_changed(GtkOptionMenu *w, gpointer data)
1090 if (mapping) return;
1092 name = g_list_nth_data(themes, gtk_option_menu_get_history(w));
1095 tree_set_string("theme/name", name);
1098 void on_theme_names_selection_changed(GtkTreeSelection *sel, gpointer data)
1101 GtkTreeModel *model;
1104 if (mapping) return;
1106 if(gtk_tree_selection_get_selected(sel, &model, &iter)) {
1107 gtk_tree_model_get(model, &iter, 0, &name, -1);
1111 tree_set_string("theme/name", name);
1114 void on_title_layout_changed(GtkEntry *w, gpointer data)
1118 gboolean n, d, s, l, i, m, c;
1120 if (mapping) return;
1122 layout = g_strdup(gtk_entry_get_text(w));
1124 n = d = s = l = i = m = c = FALSE;
1126 for (it = layout; *it; ++it) {
1164 /* drop the letter */
1165 for (it2 = it; *it2; ++it2)
1173 gtk_entry_set_text(w, layout);
1174 tree_set_string("theme/titleLayout", layout);
1178 static void set_desktop_names()
1183 gint num = 0, last = -1;
1185 n = tree_get_node("desktops/names", NULL);
1186 while ((c = n->children)) {
1191 for (lit = desktop_names; lit; lit = g_list_next(lit)) {
1192 if (((gchar*)lit->data)[0]) /* not empty */
1198 for (lit = desktop_names; lit && num <= last; lit = g_list_next(lit)) {
1199 xmlNewTextChild(n, NULL, "name", lit->data);
1204 /* make openbox re-set the property */
1205 XDeleteProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
1206 XInternAtom(GDK_DISPLAY(), "_NET_DESKTOP_NAMES", FALSE));
1209 static void set_desktop_number()
1213 tree_set_int("desktops/number", num_desktops);
1215 ce.xclient.type = ClientMessage;
1216 ce.xclient.message_type = XInternAtom(GDK_DISPLAY(),
1217 "_NET_NUMBER_OF_DESKTOPS",
1219 ce.xclient.display = GDK_DISPLAY();
1220 ce.xclient.window = GDK_ROOT_WINDOW();
1221 ce.xclient.format = 32;
1222 ce.xclient.data.l[0] = num_desktops;
1223 ce.xclient.data.l[1] = 0;
1224 ce.xclient.data.l[2] = 0;
1225 ce.xclient.data.l[3] = 0;
1226 ce.xclient.data.l[4] = 0;
1227 XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE,
1228 SubstructureNotifyMask | SubstructureRedirectMask,
1232 void on_desktop_num_value_changed(GtkSpinButton *w, gpointer data)
1234 if (mapping) return;
1236 num_desktops = gtk_spin_button_get_value(w);
1238 set_desktop_number();
1240 reset_desktop_names();
1243 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
1244 const gchar *path_string,
1245 const gchar *new_text,
1254 if (mapping) return;
1256 path = gtk_tree_path_new_from_string (path_string);
1257 gtk_tree_model_get_iter(GTK_TREE_MODEL(desktop_store), &it, path);
1259 gtk_tree_model_get(GTK_TREE_MODEL(desktop_store), &it, 0, &old_text, -1);
1262 i = gtk_tree_path_get_indices(path)[0];
1263 lit = g_list_nth(desktop_names, i);
1266 lit->data = g_strdup(new_text);
1267 if (new_text[0]) /* not empty */
1268 gtk_list_store_set(desktop_store, &it, 0, lit->data, -1);
1270 gtk_list_store_set(desktop_store, &it, 0, _("(Unnamed desktop)"), -1);
1272 set_desktop_names();
1275 void on_install_theme_clicked(GtkButton *w, gpointer data)
1280 GtkFileFilter *filter;
1282 d = gtk_file_chooser_dialog_new(_("Choose an Openbox theme"),
1283 GTK_WINDOW(mainwin),
1284 GTK_FILE_CHOOSER_ACTION_OPEN,
1285 GTK_STOCK_OK, GTK_RESPONSE_OK,
1286 GTK_STOCK_CANCEL, GTK_RESPONSE_NONE,
1289 gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(d), FALSE);
1290 filter = gtk_file_filter_new();
1291 gtk_file_filter_set_name(filter, _("Openbox theme archives"));
1292 gtk_file_filter_add_pattern(filter, "*.obt");
1293 //gtk_file_filter_add_pattern(filter, "*.tgz");
1294 //gtk_file_filter_add_pattern(filter, "*.tar.gz");
1295 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(d), filter);
1297 r = gtk_dialog_run(GTK_DIALOG(d));
1298 if (r == GTK_RESPONSE_OK)
1299 path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
1300 gtk_widget_destroy(d);
1303 /* decipher the theme name from the file name */
1304 gchar *fname = g_path_get_basename(path);
1305 gchar *themename = NULL;
1306 gint len = strlen(fname);
1309 (fname[len-4] == '.' && fname[len-3] == 'o' &&
1310 fname[len-2] == 'b' && fname[len-1] == 't')/* ||
1311 (fname[len-4] == '.' && fname[len-3] == 't' &&
1312 fname[len-2] == 'g' && fname[len-1] == 'z')*/)
1314 fname[len-4] = '\0';
1315 themename = strdup(fname);
1320 (fname[len-7] == '.' && fname[len-6] == 't' &&
1321 fname[len-5] == 'a' && fname[len-4] == 'r' &&
1322 fname[len-3] == '.' && fname[len-2] == 'g' &&
1323 fname[len-1] == 'z'))
1325 fname[len-7] = '\0';
1326 themename = strdup(fname);
1331 if (themename == NULL) {
1334 w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
1335 GTK_DIALOG_DESTROY_WITH_PARENT |
1339 _("Unable to determine the theme's name rom \"%s\". File name should be ThemeName.obt."),
1341 gtk_dialog_run(GTK_DIALOG(w));
1342 gtk_widget_destroy(w);
1348 if (install_theme(path, themename)) {
1354 w = glade_xml_get_widget(glade, "theme_names");
1356 reset_theme_names(w);
1359 /* go to the newly installed theme */
1360 for (it = themes, i = 0; it; it = g_list_next(it), ++i)
1361 if (!strcmp(it->data, themename)) break;
1363 path = gtk_tree_path_new_from_indices(i, -1);
1364 gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE);