split handlers.c into a bunch of files
[dana/obconf.git] / src / desktops.c
1 #include "main.h"
2 #include "tree.h"
3 #include "gettext.h"
4
5 #include <gdk/gdkx.h>
6
7 static gboolean mapping = FALSE;
8
9 static GtkListStore *desktop_store;
10 static int num_desktops;
11 static GList *desktop_names;
12
13 static void reset_desktop_names();
14 static void desktops_set_names();
15 static void desktops_set_number();
16 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
17                                          const gchar *path_string,
18                                          const gchar *new_text,
19                                          gpointer data);
20
21 void desktops_setup_num(GtkWidget *w)
22 {
23     mapping = TRUE;
24
25     num_desktops = tree_get_int("desktops/number", 4);
26     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), num_desktops);
27
28     mapping = FALSE;
29 }
30
31 void desktops_setup_names(GtkWidget *w)
32 {
33     GtkCellRenderer *render;
34     GtkTreeViewColumn *column;
35
36     mapping = TRUE;
37
38     desktop_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
39     gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(desktop_store));
40     g_object_unref (desktop_store);
41
42     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
43                                 GTK_SELECTION_SINGLE);
44
45     render = gtk_cell_renderer_text_new();
46     g_signal_connect(render, "edited",
47                      G_CALLBACK (on_desktop_names_cell_edited),
48                      NULL);
49
50     column = gtk_tree_view_column_new_with_attributes
51         ("Name", render, "text", 0, "editable", 1, NULL);
52     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
53
54     reset_desktop_names();
55
56     mapping = FALSE;
57 }
58
59 void on_desktop_num_value_changed(GtkSpinButton *w, gpointer data)
60 {
61     if (mapping) return;
62
63     num_desktops = gtk_spin_button_get_value(w);
64
65     desktops_set_number();
66
67     reset_desktop_names();
68 }
69
70 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
71                                          const gchar *path_string,
72                                          const gchar *new_text,
73                                          gpointer data)
74 {
75     GtkTreePath *path;
76     GtkTreeIter it;
77     gchar *old_text;
78     GList *lit;
79     gint i;
80
81     if (mapping) return;
82
83     path = gtk_tree_path_new_from_string (path_string);
84     gtk_tree_model_get_iter(GTK_TREE_MODEL(desktop_store), &it, path);
85
86     gtk_tree_model_get(GTK_TREE_MODEL(desktop_store), &it, 0, &old_text, -1);
87     g_free(old_text);
88
89     i = gtk_tree_path_get_indices(path)[0];
90     lit = g_list_nth(desktop_names, i);
91
92     g_free(lit->data);
93     lit->data = g_strdup(new_text);
94     if (new_text[0]) /* not empty */
95         gtk_list_store_set(desktop_store, &it, 0, lit->data, -1);
96     else
97         gtk_list_store_set(desktop_store, &it, 0, _("(Unnamed desktop)"), -1);
98
99     desktops_set_names();
100 }
101
102 static void reset_desktop_names()
103 {
104     GtkTreeIter it;
105     xmlNodePtr n;
106     gint i;
107     GList *lit;
108
109     gtk_list_store_clear(desktop_store);
110
111     for (lit = desktop_names; lit; lit = g_list_next(lit))
112         g_free(lit->data);
113     g_list_free(desktop_names);
114     desktop_names = NULL;
115
116     i = 0;
117     n = tree_get_node("desktops/names", NULL)->children;
118     while (n) {
119         gchar *name;
120
121         if (!xmlStrcmp(n->name, (const xmlChar*)"name")) {
122             name = parse_string(doc, n);
123
124             desktop_names = g_list_append(desktop_names, name);
125
126             gtk_list_store_append(desktop_store, &it);
127             gtk_list_store_set(desktop_store, &it,
128                                0, (name[0] ? name : _("(Unnamed desktop)")),
129                                1, TRUE,
130                                -1);
131             ++i;
132         }
133
134         n = n->next;
135     }
136
137     while (i < num_desktops) {
138         gchar *name = g_strdup("");
139
140         desktop_names = g_list_append(desktop_names, name);
141
142         gtk_list_store_append(desktop_store, &it);
143         gtk_list_store_set(desktop_store, &it,
144                            0, _("(Unnamed desktop)"),
145                            1, TRUE,
146                            -1);
147         ++i;
148     }
149 }
150
151 static void desktops_set_names()
152 {
153     gchar **s;
154     GList *lit;
155     xmlNodePtr n, c;
156     gint num = 0, last = -1;
157
158     n = tree_get_node("desktops/names", NULL);
159     while ((c = n->children)) {
160         xmlUnlinkNode(c);
161         xmlFreeNode(c);
162     }
163
164     for (lit = desktop_names; lit; lit = g_list_next(lit)) {
165         if (((gchar*)lit->data)[0]) /* not empty */
166             last = num;
167         ++num;
168     }
169
170     num = 0;
171     for (lit = desktop_names; lit && num <= last; lit = g_list_next(lit)) {
172         xmlNewTextChild(n, NULL, "name", lit->data);
173         ++num;
174     }
175     tree_apply();
176
177     /* make openbox re-set the property */
178     XDeleteProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
179                     XInternAtom(GDK_DISPLAY(), "_NET_DESKTOP_NAMES", FALSE));
180 }
181
182 static void desktops_set_number()
183 {
184     XEvent ce;
185
186     tree_set_int("desktops/number", num_desktops);
187
188     ce.xclient.type = ClientMessage;
189     ce.xclient.message_type = XInternAtom(GDK_DISPLAY(),
190                                           "_NET_NUMBER_OF_DESKTOPS",
191                                           FALSE);
192     ce.xclient.display = GDK_DISPLAY();
193     ce.xclient.window = GDK_ROOT_WINDOW();
194     ce.xclient.format = 32;
195     ce.xclient.data.l[0] = num_desktops;
196     ce.xclient.data.l[1] = 0;
197     ce.xclient.data.l[2] = 0;
198     ce.xclient.data.l[3] = 0;
199     ce.xclient.data.l[4] = 0;
200     XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE,
201                SubstructureNotifyMask | SubstructureRedirectMask,
202                &ce);
203 }