conflicting accels
[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
40 void desktops_setup_tab()
41 {
42     GtkWidget *w;
43     GtkCellRenderer *render;
44     GtkTreeViewColumn *column;
45
46     mapping = TRUE;
47
48     w = get_widget("desktop_num");
49     num_desktops = tree_get_int("desktops/number", 4);
50     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), num_desktops);
51
52     w = get_widget("desktop_names");
53     desktop_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
54     gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(desktop_store));
55     g_object_unref (desktop_store);
56
57     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
58                                 GTK_SELECTION_SINGLE);
59
60     render = gtk_cell_renderer_text_new();
61     g_signal_connect(render, "edited",
62                      G_CALLBACK (on_desktop_names_cell_edited),
63                      NULL);
64
65     column = gtk_tree_view_column_new_with_attributes
66         ("Name", render, "text", 0, "editable", 1, NULL);
67     gtk_tree_view_append_column(GTK_TREE_VIEW(w), column);
68
69     desktops_read_names();
70
71     mapping = FALSE;
72 }
73
74 void on_desktop_num_value_changed(GtkSpinButton *w, gpointer data)
75 {
76     if (mapping) return;
77
78     num_desktops = gtk_spin_button_get_value(w);
79
80     desktops_write_number();
81     desktops_read_names();
82 }
83
84 static void on_desktop_names_cell_edited(GtkCellRendererText *cell,
85                                          const gchar *path_string,
86                                          const gchar *new_text,
87                                          gpointer data)
88 {
89     GtkTreePath *path;
90     GtkTreeIter it;
91     gchar *old_text;
92     GList *lit;
93     gint i;
94
95     if (mapping) return;
96
97     path = gtk_tree_path_new_from_string (path_string);
98     gtk_tree_model_get_iter(GTK_TREE_MODEL(desktop_store), &it, path);
99
100     gtk_tree_model_get(GTK_TREE_MODEL(desktop_store), &it, 0, &old_text, -1);
101     g_free(old_text);
102
103     i = gtk_tree_path_get_indices(path)[0];
104     lit = g_list_nth(desktop_names, i);
105
106     g_free(lit->data);
107     lit->data = g_strdup(new_text);
108     if (new_text[0]) /* not empty */
109         gtk_list_store_set(desktop_store, &it, 0, lit->data, -1);
110     else
111         gtk_list_store_set(desktop_store, &it, 0, _("(Unnamed desktop)"), -1);
112
113     desktops_write_names();
114 }
115
116 static void desktops_read_names()
117 {
118     GtkTreeIter it;
119     xmlNodePtr n;
120     gint i;
121     GList *lit;
122
123     gtk_list_store_clear(desktop_store);
124
125     for (lit = desktop_names; lit; lit = g_list_next(lit))
126         g_free(lit->data);
127     g_list_free(desktop_names);
128     desktop_names = NULL;
129
130     i = 0;
131     n = tree_get_node("desktops/names", NULL)->children;
132     while (n) {
133         gchar *name;
134
135         if (!xmlStrcmp(n->name, (const xmlChar*)"name")) {
136             name = parse_string(doc, n);
137
138             desktop_names = g_list_append(desktop_names, name);
139
140             gtk_list_store_append(desktop_store, &it);
141             gtk_list_store_set(desktop_store, &it,
142                                0, (name[0] ? name : _("(Unnamed desktop)")),
143                                1, TRUE,
144                                -1);
145             ++i;
146         }
147
148         n = n->next;
149     }
150
151     while (i < num_desktops) {
152         gchar *name = g_strdup("");
153
154         desktop_names = g_list_append(desktop_names, name);
155
156         gtk_list_store_append(desktop_store, &it);
157         gtk_list_store_set(desktop_store, &it,
158                            0, _("(Unnamed desktop)"),
159                            1, TRUE,
160                            -1);
161         ++i;
162     }
163 }
164
165 static void desktops_write_names()
166 {
167     gchar **s;
168     GList *lit;
169     xmlNodePtr n, c;
170     gint num = 0, last = -1;
171
172     n = tree_get_node("desktops/names", NULL);
173     while ((c = n->children)) {
174         xmlUnlinkNode(c);
175         xmlFreeNode(c);
176     }
177
178     for (lit = desktop_names; lit; lit = g_list_next(lit)) {
179         if (((gchar*)lit->data)[0]) /* not empty */
180             last = num;
181         ++num;
182     }
183
184     num = 0;
185     for (lit = desktop_names; lit && num <= last; lit = g_list_next(lit)) {
186         xmlNewTextChild(n, NULL, "name", lit->data);
187         ++num;
188     }
189     tree_apply();
190
191     /* make openbox re-set the property */
192     XDeleteProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
193                     XInternAtom(GDK_DISPLAY(), "_NET_DESKTOP_NAMES", FALSE));
194 }
195
196 static void desktops_write_number()
197 {
198     XEvent ce;
199
200     tree_set_int("desktops/number", num_desktops);
201
202     ce.xclient.type = ClientMessage;
203     ce.xclient.message_type = XInternAtom(GDK_DISPLAY(),
204                                           "_NET_NUMBER_OF_DESKTOPS",
205                                           FALSE);
206     ce.xclient.display = GDK_DISPLAY();
207     ce.xclient.window = GDK_ROOT_WINDOW();
208     ce.xclient.format = 32;
209     ce.xclient.data.l[0] = num_desktops;
210     ce.xclient.data.l[1] = 0;
211     ce.xclient.data.l[2] = 0;
212     ce.xclient.data.l[3] = 0;
213     ce.xclient.data.l[4] = 0;
214     XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE,
215                SubstructureNotifyMask | SubstructureRedirectMask,
216                &ce);
217 }