]> icculus.org git repositories - dana/openbox.git/blob - openbox/config.c
add an option for if the popup is used for desktop cycling. defaults on.
[dana/openbox.git] / openbox / config.c
1 #include "config.h"
2 #include "keyboard.h"
3 #include "mouse.h"
4 #include "prop.h"
5 #include "parser/parse.h"
6
7 gboolean config_focus_new;
8 gboolean config_focus_follow;
9 gboolean config_focus_last;
10 gboolean config_focus_last_on_desktop;
11 gboolean config_focus_popup;
12 gboolean config_desktop_popup;
13
14 char *config_theme;
15
16 gchar *config_title_layout;
17
18 int     config_desktops_num;
19 GSList *config_desktops_names;
20
21 gboolean config_redraw_resize;
22
23 ObStackingLayer config_dock_layer;
24 gboolean        config_dock_floating;
25 ObDirection     config_dock_pos;
26 gint            config_dock_x;
27 gint            config_dock_y;
28 ObOrientation   config_dock_orient;
29 gboolean        config_dock_hide;
30 guint           config_dock_hide_timeout;
31
32 gint config_mouse_threshold;
33 gint config_mouse_dclicktime;
34
35 /*
36
37 <keybind key="C-x">
38   <action name="ChangeDesktop">
39     <desktop>3</desktop>
40   </action>
41 </keybind>
42
43 */
44
45 static void parse_key(xmlDocPtr doc, xmlNodePtr node, GList *keylist)
46 {
47     char *key;
48     ObAction *action;
49     xmlNodePtr n, nact;
50     GList *it;
51
52     n = parse_find_node("keybind", node);
53     while (n) {
54         if (parse_attr_string("key", n, &key)) {
55             keylist = g_list_append(keylist, key);
56
57             parse_key(doc, n->xmlChildrenNode, keylist);
58
59             it = g_list_last(keylist);
60             g_free(it->data);
61             keylist = g_list_delete_link(keylist, it);
62         }
63         n = parse_find_node("keybind", n->next);
64     }
65     if (keylist) {
66         nact = parse_find_node("action", node);
67         while (nact) {
68             if ((action = action_parse(doc, nact))) {
69                 /* validate that its okay for a key binding */
70                 if (action->func == action_moveresize &&
71                     action->data.moveresize.corner !=
72                     prop_atoms.net_wm_moveresize_move_keyboard &&
73                     action->data.moveresize.corner !=
74                     prop_atoms.net_wm_moveresize_size_keyboard) {
75                     action_free(action);
76                     action = NULL;
77                 }
78
79                 if (action)
80                     keyboard_bind(keylist, action);
81             }
82             nact = parse_find_node("action", nact->next);
83         }
84     }
85 }
86
87 static void parse_keyboard(xmlDocPtr doc, xmlNodePtr node, void *d)
88 {
89     parse_key(doc, node->xmlChildrenNode, NULL);
90 }
91
92 static int threshold;
93 static int dclicktime;
94 /*
95
96 <context name="Titlebar"> 
97   <mousebind button="Left" action="Press">
98     <action name="Raise"></action>
99   </mousebind>
100 </context>
101
102 */
103
104 static void parse_mouse(xmlDocPtr doc, xmlNodePtr node, void *d)
105 {
106     xmlNodePtr n, nbut, nact;
107     char *buttonstr;
108     char *contextstr;
109     ObMouseAction mact;
110     ObAction *action;
111
112     node = node->xmlChildrenNode;
113     
114     if ((n = parse_find_node("dragThreshold", node)))
115         threshold = parse_int(doc, n);
116     if ((n = parse_find_node("doubleClickTime", node)))
117         dclicktime = parse_int(doc, n);
118
119     n = parse_find_node("context", node);
120     while (n) {
121         if (!parse_attr_string("name", n, &contextstr))
122             goto next_n;
123         nbut = parse_find_node("mousebind", n->xmlChildrenNode);
124         while (nbut) {
125             if (!parse_attr_string("button", nbut, &buttonstr))
126                 goto next_nbut;
127             if (parse_attr_contains("press", nbut, "action"))
128                 mact = MouseAction_Press;
129             else if (parse_attr_contains("release", nbut, "action"))
130                 mact = MouseAction_Release;
131             else if (parse_attr_contains("click", nbut, "action"))
132                 mact = MouseAction_Click;
133             else if (parse_attr_contains("doubleclick", nbut,"action"))
134                 mact = MouseAction_DClick;
135             else if (parse_attr_contains("drag", nbut, "action"))
136                 mact = MouseAction_Motion;
137             else
138                 goto next_nbut;
139             nact = parse_find_node("action", nbut->xmlChildrenNode);
140             while (nact) {
141                 if ((action = action_parse(doc, nact))) {
142                     /* validate that its okay for a mouse binding*/
143                     if (mact == MouseAction_Motion) {
144                         if (action->func != action_moveresize ||
145                             action->data.moveresize.corner ==
146                             prop_atoms.net_wm_moveresize_move_keyboard ||
147                             action->data.moveresize.corner ==
148                             prop_atoms.net_wm_moveresize_size_keyboard) {
149                             action_free(action);
150                             action = NULL;
151                         }
152                     } else {
153                         if (action->func == action_moveresize &&
154                             action->data.moveresize.corner !=
155                             prop_atoms.net_wm_moveresize_move_keyboard &&
156                             action->data.moveresize.corner !=
157                             prop_atoms.net_wm_moveresize_size_keyboard) {
158                             action_free(action);
159                             action = NULL;
160                         }
161                     }
162                     if (action)
163                         mouse_bind(buttonstr, contextstr, mact, action);
164                 }
165                 nact = parse_find_node("action", nact->next);
166             }
167             g_free(buttonstr);
168         next_nbut:
169             nbut = parse_find_node("mousebind", nbut->next);
170         }
171         g_free(contextstr);
172     next_n:
173         n = parse_find_node("context", n->next);
174     }
175 }
176
177 static void parse_focus(xmlDocPtr doc, xmlNodePtr node, void *d)
178 {
179     xmlNodePtr n;
180
181     node = node->xmlChildrenNode;
182     
183     if ((n = parse_find_node("focusNew", node)))
184         config_focus_new = parse_bool(doc, n);
185     if ((n = parse_find_node("followMouse", node)))
186         config_focus_follow = parse_bool(doc, n);
187     if ((n = parse_find_node("focusLast", node)))
188         config_focus_last = parse_bool(doc, n);
189     if ((n = parse_find_node("focusLastOnDesktop", node)))
190         config_focus_last_on_desktop = parse_bool(doc, n);
191     if ((n = parse_find_node("cyclingDialog", node)))
192         config_focus_popup = parse_bool(doc, n);
193 }
194
195 static void parse_theme(xmlDocPtr doc, xmlNodePtr node, void *d)
196 {
197     xmlNodePtr n;
198
199     node = node->xmlChildrenNode;
200
201     if ((n = parse_find_node("theme", node))) {
202         g_free(config_theme);
203         config_theme = parse_string(doc, n);
204     }
205     if ((n = parse_find_node("titlelayout", node))) {
206         g_free(config_title_layout);
207         config_title_layout = parse_string(doc, n);
208     }
209 }
210
211 static void parse_desktops(xmlDocPtr doc, xmlNodePtr node, void *d)
212 {
213     xmlNodePtr n;
214
215     node = node->xmlChildrenNode;
216     
217     if ((n = parse_find_node("number", node)))
218         config_desktops_num = parse_int(doc, n);
219     if ((n = parse_find_node("names", node))) {
220         GSList *it;
221         xmlNodePtr nname;
222
223         for (it = config_desktops_names; it; it = it->next)
224             g_free(it->data);
225         g_slist_free(config_desktops_names);
226         config_desktops_names = NULL;
227
228         nname = parse_find_node("name", n->xmlChildrenNode);
229         while (nname) {
230             config_desktops_names = g_slist_append(config_desktops_names,
231                                                    parse_string(doc, nname));
232             nname = parse_find_node("name", nname->next);
233         }
234     }
235     if ((n = parse_find_node("cyclingDialog", node)))
236         config_desktop_popup = parse_bool(doc, n);
237 }
238
239 static void parse_resize(xmlDocPtr doc, xmlNodePtr node, void *d)
240 {
241     xmlNodePtr n;
242
243     node = node->xmlChildrenNode;
244     
245     if ((n = parse_find_node("drawContents", node)))
246         config_redraw_resize = parse_bool(doc, n);
247 }
248
249 static void parse_dock(xmlDocPtr doc, xmlNodePtr node, void *d)
250 {
251     xmlNodePtr n;
252
253     node = node->xmlChildrenNode;
254
255     if ((n = parse_find_node("position", node))) {
256         if (parse_contains("TopLeft", doc, n))
257             config_dock_floating = FALSE,
258             config_dock_pos = OB_DIRECTION_NORTHWEST;
259         else if (parse_contains("Top", doc, n))
260             config_dock_floating = FALSE,
261             config_dock_pos = OB_DIRECTION_NORTH;
262         else if (parse_contains("TopRight", doc, n))
263             config_dock_floating = FALSE,
264             config_dock_pos = OB_DIRECTION_NORTHEAST;
265         else if (parse_contains("Right", doc, n))
266             config_dock_floating = FALSE,
267             config_dock_pos = OB_DIRECTION_EAST;
268         else if (parse_contains("BottomRight", doc, n))
269             config_dock_floating = FALSE,
270             config_dock_pos = OB_DIRECTION_SOUTHEAST;
271         else if (parse_contains("Bottom", doc, n))
272             config_dock_floating = FALSE,
273             config_dock_pos = OB_DIRECTION_SOUTH;
274         else if (parse_contains("BottomLeft", doc, n))
275             config_dock_floating = FALSE,
276             config_dock_pos = OB_DIRECTION_SOUTHWEST;
277         else if (parse_contains("Left", doc, n))
278             config_dock_floating = FALSE,
279             config_dock_pos = OB_DIRECTION_WEST;
280         else if (parse_contains("Floating", doc, n))
281             config_dock_floating = TRUE;
282     }
283     if (config_dock_floating) {
284         if ((n = parse_find_node("floatingX", node)))
285             config_dock_x = parse_int(doc, n);
286         if ((n = parse_find_node("floatingY", node)))
287             config_dock_y = parse_int(doc, n);
288     }
289     if ((n = parse_find_node("stacking", node))) {
290         if (parse_contains("top", doc, n))
291             config_dock_layer = OB_STACKING_LAYER_TOP;
292         else if (parse_contains("normal", doc, n))
293             config_dock_layer = OB_STACKING_LAYER_NORMAL;
294         else if (parse_contains("bottom", doc, n))
295             config_dock_layer = OB_STACKING_LAYER_BELOW;
296     }
297     if ((n = parse_find_node("direction", node))) {
298         if (parse_contains("horizontal", doc, n))
299             config_dock_orient = OB_ORIENTATION_HORZ;
300         else if (parse_contains("vertical", doc, n))
301             config_dock_orient = OB_ORIENTATION_VERT;
302     }
303     if ((n = parse_find_node("autoHide", node)))
304         config_dock_hide = parse_bool(doc, n);
305     if ((n = parse_find_node("hideTimeout", node)))
306         config_dock_hide_timeout = parse_int(doc, n);
307 }
308
309 void config_startup()
310 {
311     config_focus_new = TRUE;
312     config_focus_follow = FALSE;
313     config_focus_last = TRUE;
314     config_focus_last_on_desktop = TRUE;
315     config_focus_popup = TRUE;
316
317     parse_register("focus", parse_focus, NULL);
318
319     config_theme = NULL;
320
321     config_title_layout = g_strdup("NLIMC");
322
323     parse_register("theme", parse_theme, NULL);
324
325     config_desktops_num = 4;
326     config_desktops_names = NULL;
327     config_desktop_popup = TRUE;
328
329     parse_register("desktops", parse_desktops, NULL);
330
331     config_redraw_resize = TRUE;
332
333     parse_register("resize", parse_resize, NULL);
334
335     config_dock_layer = OB_STACKING_LAYER_TOP;
336     config_dock_pos = OB_DIRECTION_NORTHEAST;
337     config_dock_floating = FALSE;
338     config_dock_x = 0;
339     config_dock_y = 0;
340     config_dock_orient = OB_ORIENTATION_VERT;
341     config_dock_hide = FALSE;
342     config_dock_hide_timeout = 3000;
343
344     parse_register("dock", parse_dock, NULL);
345
346     parse_register("keyboard", parse_keyboard, NULL);
347
348     config_mouse_threshold = 3;
349     config_mouse_dclicktime = 200;
350
351     parse_register("mouse", parse_mouse, NULL);
352 }
353
354 void config_shutdown()
355 {
356     GSList *it;
357
358     g_free(config_theme);
359
360     for (it = config_desktops_names; it; it = it->next)
361         g_free(it->data);
362     g_slist_free(config_desktops_names);
363 }