comments
[dana/obconf.git] / src / desktops.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    desktops.c for ObConf, the configuration tool for Openbox
4    Copyright (c) 2003-2007   Dana Jansens
5    Copyright (c) 2003        Tim Riley
6
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.
11
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.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "main.h"
21 #include "tree.h"
22 #include "gettext.h"
23
24 #include <gdk/gdkx.h>
25
26 static gboolean mapping = FALSE;
27
28 static GtkListStore *desktop_store;
29 static int num_desktops;
30 static GList *desktop_names;
31
32 static void desktops_read_names();
33 static void desktops_write_names();
34 static void desktops_write_number();
35 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
36                                          const gchar *path_string,
37                                          const gchar *new_text,
38                                          gpointer data);
39 static void enable_stuff();
40
41 void desktops_setup_tab()
42 {
43     GtkWidget *w;
44     GtkCellRenderer *render;
45     GtkTreeViewColumn *column;
46     gint i;
47
48     mapping = TRUE;
49
50     w = get_widget("desktop_num");
51     num_desktops = tree_get_int("desktops/number", 4);
52     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), num_desktops);
53
54     w = get_widget("desktop_names");
55     desktop_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
56     gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(desktop_store));
57     g_object_unref (desktop_store);
58
59     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
60                                 GTK_SELECTION_SINGLE);
61
62     render = gtk_cell_renderer_text_new();
63     g_signal_connect(render, "edited",
64                      G_CALLBACK (on_desktop_names_cell_edited),
65                      NULL);
66
67     column = gtk_tree_view_column_new_with_attributes
68         ("Name", render, "text", 0, "editable", 1, NULL);
69     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
70
71     desktops_read_names();
72
73     i = tree_get_int("desktops/popupTime", 875);
74
75     w = get_widget("desktop_popup");
76     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), i != 0);
77
78     w = get_widget("desktop_popup_time");
79     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), i ? i : 875);
80
81     enable_stuff();
82
83     mapping = FALSE;
84 }
85
86 static void enable_stuff()
87 {
88     GtkWidget *w;
89     gboolean b;
90
91     w = get_widget("desktop_popup");
92     b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
93     w = get_widget("desktop_popup_time");
94     gtk_widget_set_sensitive(w, b);
95 }
96
97 void on_desktop_num_value_changed(GtkSpinButton *w, gpointer data)
98 {
99     if (mapping) return;
100
101     num_desktops = gtk_spin_button_get_value(w);
102
103     desktops_write_number();
104     desktops_read_names();
105 }
106
107 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
108                                          const gchar *path_string,
109                                          const gchar *new_text,
110                                          gpointer data)
111 {
112     GtkTreePath *path;
113     GtkTreeIter it;
114     gchar *old_text;
115     GList *lit;
116     gint i;
117
118     if (mapping) return;
119
120     path = gtk_tree_path_new_from_string (path_string);
121     gtk_tree_model_get_iter(GTK_TREE_MODEL(desktop_store), &it, path);
122
123     gtk_tree_model_get(GTK_TREE_MODEL(desktop_store), &it, 0, &old_text, -1);
124     g_free(old_text);
125
126     i = gtk_tree_path_get_indices(path)[0];
127     lit = g_list_nth(desktop_names, i);
128
129     g_free(lit->data);
130     lit->data = g_strdup(new_text);
131     if (new_text[0]) /* not empty */
132         gtk_list_store_set(desktop_store, &it, 0, lit->data, -1);
133     else
134         gtk_list_store_set(desktop_store, &it, 0, _("(Unnamed desktop)"), -1);
135
136     desktops_write_names();
137 }
138
139 static void desktops_read_names()
140 {
141     GtkTreeIter it;
142     xmlNodePtr n;
143     gint i;
144     GList *lit;
145
146     gtk_list_store_clear(desktop_store);
147
148     for (lit = desktop_names; lit; lit = g_list_next(lit))
149         g_free(lit->data);
150     g_list_free(desktop_names);
151     desktop_names = NULL;
152
153     i = 0;
154     n = tree_get_node("desktops/names", NULL)->children;
155     while (n) {
156         gchar *name;
157
158         if (!xmlStrcmp(n->name, (const xmlChar*)"name")) {
159             name = parse_string(doc, n);
160
161             desktop_names = g_list_append(desktop_names, name);
162
163             gtk_list_store_append(desktop_store, &it);
164             gtk_list_store_set(desktop_store, &it,
165                                0, (name[0] ? name : _("(Unnamed desktop)")),
166                                1, TRUE,
167                                -1);
168             ++i;
169         }
170
171         n = n->next;
172     }
173
174     while (i < num_desktops) {
175         gchar *name = g_strdup("");
176
177         desktop_names = g_list_append(desktop_names, name);
178
179         gtk_list_store_append(desktop_store, &it);
180         gtk_list_store_set(desktop_store, &it,
181                            0, _("(Unnamed desktop)"),
182                            1, TRUE,
183                            -1);
184         ++i;
185     }
186 }
187
188 static void desktops_write_names()
189 {
190     gchar **s;
191     GList *lit;
192     xmlNodePtr n, c;
193     gint num = 0, last = -1;
194
195     n = tree_get_node("desktops/names", NULL);
196     while ((c = n->children)) {
197         xmlUnlinkNode(c);
198         xmlFreeNode(c);
199     }
200
201     for (lit = desktop_names; lit; lit = g_list_next(lit)) {
202         if (((gchar*)lit->data)[0]) /* not empty */
203             last = num;
204         ++num;
205     }
206
207     num = 0;
208     for (lit = desktop_names; lit && num <= last; lit = g_list_next(lit)) {
209         xmlNewTextChild(n, NULL, "name", lit->data);
210         ++num;
211     }
212     tree_apply();
213
214     /* make openbox re-set the property */
215     XDeleteProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
216                     gdk_x11_get_xatom_by_name("_NET_DESKTOP_NAMES"));
217 }
218
219 static void desktops_write_number()
220 {
221     XEvent ce;
222
223     tree_set_int("desktops/number", num_desktops);
224
225     ce.xclient.type = ClientMessage;
226     ce.xclient.message_type =
227         gdk_x11_get_xatom_by_name("_NET_NUMBER_OF_DESKTOPS");
228     ce.xclient.display = GDK_DISPLAY();
229     ce.xclient.window = GDK_ROOT_WINDOW();
230     ce.xclient.format = 32;
231     ce.xclient.data.l[0] = num_desktops;
232     ce.xclient.data.l[1] = 0;
233     ce.xclient.data.l[2] = 0;
234     ce.xclient.data.l[3] = 0;
235     ce.xclient.data.l[4] = 0;
236     XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE,
237                SubstructureNotifyMask | SubstructureRedirectMask,
238                &ce);
239 }
240
241 void on_desktop_popup_toggled(GtkToggleButton *w, gpointer data)
242 {
243     if (mapping) return;
244
245     if (gtk_toggle_button_get_active(w)) {
246         GtkWidget *w2;
247
248         w2 = get_widget("desktop_popup_time");
249         tree_set_int("desktops/popupTime",
250                      gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(w2)));
251     }
252     else
253         tree_set_int("desktops/popupTime", 0);
254     enable_stuff();
255 }
256
257 void on_desktop_popup_time_value_changed(GtkSpinButton *w, gpointer data)
258 {
259     if (mapping) return;
260
261     tree_set_int("desktops/popupTime", gtk_spin_button_get_value_as_int(w));
262 }