]> Dogcows Code - chaz/openbox/blob - openbox/config.c
update openbox to use the current parser interface in libobt
[chaz/openbox] / openbox / config.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 config.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
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 "config.h"
21 #include "keyboard.h"
22 #include "mouse.h"
23 #include "actions.h"
24 #include "translate.h"
25 #include "client.h"
26 #include "screen.h"
27 #include "openbox.h"
28 #include "gettext.h"
29
30 gboolean config_focus_new;
31 gboolean config_focus_follow;
32 guint config_focus_delay;
33 gboolean config_focus_raise;
34 gboolean config_focus_last;
35 gboolean config_focus_under_mouse;
36
37 ObPlacePolicy config_place_policy;
38 gboolean config_place_center;
39 gboolean config_place_active;
40
41 StrutPartial config_margins;
42
43 gchar *config_theme;
44 gboolean config_theme_keepborder;
45
46 gchar *config_title_layout;
47
48 gboolean config_animate_iconify;
49
50 RrFont *config_font_activewindow;
51 RrFont *config_font_inactivewindow;
52 RrFont *config_font_menuitem;
53 RrFont *config_font_menutitle;
54 RrFont *config_font_osd;
55
56 gint config_desktops_num;
57 GSList *config_desktops_names;
58 guint config_screen_firstdesk;
59 guint config_desktop_popup_time;
60
61 gboolean config_resize_redraw;
62 gint config_resize_popup_show;
63 ObResizePopupPos config_resize_popup_pos;
64 GravityPoint config_resize_popup_fixed;
65
66 ObStackingLayer config_dock_layer;
67 gboolean config_dock_floating;
68 gboolean config_dock_nostrut;
69 ObDirection config_dock_pos;
70 gint config_dock_x;
71 gint config_dock_y;
72 ObOrientation config_dock_orient;
73 gboolean config_dock_hide;
74 guint config_dock_hide_delay;
75 guint config_dock_show_delay;
76 guint config_dock_app_move_button;
77 guint config_dock_app_move_modifiers;
78
79 guint config_keyboard_reset_keycode;
80 guint config_keyboard_reset_state;
81
82 gint config_mouse_threshold;
83 gint config_mouse_dclicktime;
84 gint config_mouse_screenedgetime;
85
86 guint config_menu_hide_delay;
87 gboolean config_menu_middle;
88 guint config_submenu_show_delay;
89 gboolean config_menu_client_list_icons;
90
91 GSList *config_menu_files;
92
93 gint config_resist_win;
94 gint config_resist_edge;
95
96 GSList *config_per_app_settings;
97
98 ObAppSettings* config_create_app_settings(void)
99 {
100 ObAppSettings *settings = g_new0(ObAppSettings, 1);
101 settings->decor = -1;
102 settings->shade = -1;
103 settings->monitor = -1;
104 settings->focus = -1;
105 settings->desktop = 0;
106 settings->layer = -2;
107 settings->iconic = -1;
108 settings->skip_pager = -1;
109 settings->skip_taskbar = -1;
110 settings->fullscreen = -1;
111 settings->max_horz = -1;
112 settings->max_vert = -1;
113 return settings;
114 }
115
116 #define copy_if(setting, default) \
117 if (src->setting != default) dst->setting = src->setting
118 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
119 ObAppSettings *dst)
120 {
121 g_assert(src != NULL);
122 g_assert(dst != NULL);
123
124 copy_if(decor, -1);
125 copy_if(shade, -1);
126 copy_if(focus, -1);
127 copy_if(desktop, 0);
128 copy_if(layer, -2);
129 copy_if(iconic, -1);
130 copy_if(skip_pager, -1);
131 copy_if(skip_taskbar, -1);
132 copy_if(fullscreen, -1);
133 copy_if(max_horz, -1);
134 copy_if(max_vert, -1);
135
136 if (src->pos_given) {
137 dst->pos_given = TRUE;
138 dst->position = src->position;
139 dst->monitor = src->monitor;
140 }
141 }
142
143 static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
144 {
145 gchar *s = obt_parse_node_string(node);
146 if (!g_ascii_strcasecmp(s, "center"))
147 c->center = TRUE;
148 else {
149 if (s[0] == '-')
150 c->opposite = TRUE;
151 if (s[0] == '-' || s[0] == '+')
152 c->pos = atoi(s+1);
153 else
154 c->pos = atoi(s);
155 }
156 g_free(s);
157 }
158
159 /*
160 <applications>
161 <application name="aterm">
162 <decor>false</decor>
163 </application>
164 <application name="Rhythmbox">
165 <layer>above</layer>
166 <position>
167 <x>700</x>
168 <y>0</y>
169 <monitor>1</monitor>
170 </position>
171 .. there is a lot more settings available
172 </application>
173 </applications>
174 */
175
176 /* Manages settings for individual applications.
177 Some notes: monitor is the screen number in a multi monitor
178 (Xinerama) setup (starting from 0) or mouse, meaning the
179 monitor the pointer is on. Default: mouse.
180 Layer can be three values, above (Always on top), below
181 (Always on bottom) and everything else (normal behaviour).
182 Positions can be an integer value or center, which will
183 center the window in the specified axis. Position is within
184 the monitor, so <position><x>center</x></position><monitor>2</monitor>
185 will center the window on the second monitor.
186 */
187 static void parse_per_app_settings(xmlNodePtr node, gpointer d)
188 {
189 xmlNodePtr app = obt_parse_find_node(node->children, "application");
190 gchar *name = NULL, *class = NULL, *role = NULL;
191 gboolean name_set, class_set;
192 gboolean x_pos_given;
193
194 while (app) {
195 name_set = class_set = x_pos_given = FALSE;
196
197 class_set = obt_parse_attr_string(app, "class", &class);
198 name_set = obt_parse_attr_string(app, "name", &name);
199 if (class_set || name_set) {
200 xmlNodePtr n, c;
201 ObAppSettings *settings = config_create_app_settings();;
202
203 if (name_set)
204 settings->name = g_pattern_spec_new(name);
205
206 if (class_set)
207 settings->class = g_pattern_spec_new(class);
208
209 if (obt_parse_attr_string(app, "role", &role))
210 settings->role = g_pattern_spec_new(role);
211
212 if ((n = obt_parse_find_node(app->children, "decor")))
213 if (!obt_parse_node_contains(n, "default"))
214 settings->decor = obt_parse_node_bool(n);
215
216 if ((n = obt_parse_find_node(app->children, "shade")))
217 if (!obt_parse_node_contains(n, "default"))
218 settings->shade = obt_parse_node_bool(n);
219
220 if ((n = obt_parse_find_node(app->children, "position"))) {
221 if ((c = obt_parse_find_node(n->children, "x")))
222 if (!obt_parse_node_contains(c, "default")) {
223 config_parse_gravity_coord(c, &settings->position.x);
224 x_pos_given = TRUE;
225 }
226
227 if (x_pos_given && (c = obt_parse_find_node(n->children, "y")))
228 if (!obt_parse_node_contains("default", doc, c)) {
229 config_parse_gravity_coord(c, &settings->position.y);
230 settings->pos_given = TRUE;
231 }
232
233 if (settings->pos_given &&
234 (c = obt_parse_find_node(n->children, "monitor")))
235 if (!obt_parse_node_contains(c, "default")) {
236 gchar *s = obt_parse_node_string(c);
237 if (!g_ascii_strcasecmp(s, "mouse"))
238 settings->monitor = 0;
239 else
240 settings->monitor = obt_parse_node_int(c) + 1;
241 g_free(s);
242 }
243 }
244
245 if ((n = obt_parse_find_node(app->children, "focus")))
246 if (!obt_parse_node_contains(n, "default"))
247 settings->focus = obt_parse_node_bool(n);
248
249 if ((n = obt_parse_find_node(app->children, "desktop"))) {
250 if (!obt_parse_node_contains(n, "default")) {
251 gchar *s = obt_parse_node_string(n);
252 if (!g_ascii_strcasecmp(s, "all"))
253 settings->desktop = DESKTOP_ALL;
254 else {
255 gint i = obt_parse_node_int(n);
256 if (i > 0)
257 settings->desktop = i;
258 }
259 g_free(s);
260 }
261 }
262
263 if ((n = obt_parse_find_node(app->children, "layer")))
264 if (!obt_parse_node_contains(n, "default")) {
265 gchar *s = obt_parse_node_string(n);
266 if (!g_ascii_strcasecmp(s, "above"))
267 settings->layer = 1;
268 else if (!g_ascii_strcasecmp(s, "below"))
269 settings->layer = -1;
270 else
271 settings->layer = 0;
272 g_free(s);
273 }
274
275 if ((n = obt_parse_find_node(app->children, "iconic")))
276 if (!obt_parse_node_contains(n, "default"))
277 settings->iconic = obt_parse_node_bool(n);
278
279 if ((n = obt_parse_find_node(app->children, "skip_pager")))
280 if (!obt_parse_node_contains(n, "default"))
281 settings->skip_pager = obt_parse_node_bool(n);
282
283 if ((n = obt_parse_find_node(app->children, "skip_taskbar")))
284 if (!obt_parse_node_contains(n, "default"))
285 settings->skip_taskbar = obt_parse_node_bool(n);
286
287 if ((n = obt_parse_find_node(app->children, "fullscreen")))
288 if (!obt_parse_node_contains(n, "default"))
289 settings->fullscreen = obt_parse_node_bool(n);
290
291 if ((n = obt_parse_find_node(app->children, "maximized")))
292 if (!obt_parse_node_contains(n, "default")) {
293 gchar *s = obt_parse_node_string(n);
294 if (!g_ascii_strcasecmp(s, "horizontal")) {
295 settings->max_horz = TRUE;
296 settings->max_vert = FALSE;
297 } else if (!g_ascii_strcasecmp(s, "vertical")) {
298 settings->max_horz = FALSE;
299 settings->max_vert = TRUE;
300 } else
301 settings->max_horz = settings->max_vert =
302 obt_parse_node_bool(n);
303 g_free(s);
304 }
305
306 config_per_app_settings = g_slist_append(config_per_app_settings,
307 (gpointer) settings);
308 g_free(name);
309 g_free(class);
310 g_free(role);
311 name = class = role = NULL;
312 }
313
314 app = obt_parse_find_node(app->next, "application");
315 }
316 }
317
318 /*
319
320 <keybind key="C-x">
321 <action name="ChangeDesktop">
322 <desktop>3</desktop>
323 </action>
324 </keybind>
325
326 */
327
328 static void parse_key(xmlNodePtr node, GList *keylist)
329 {
330 gchar *key;
331 xmlNodePtr n;
332 gboolean is_chroot = FALSE;
333
334 if (!obt_parse_attr_string(node, "key", &key))
335 return;
336
337 obt_parse_attr_bool(node, "chroot", &is_chroot);
338
339 keylist = g_list_append(keylist, key);
340
341 if ((n = obt_parse_find_node(node->children, "keybind"))) {
342 while (n) {
343 parse_key(n, keylist);
344 n = obt_parse_find_node(n->next, "keybind");
345 }
346 }
347 else if ((n = obt_parse_find_node(node->children, "action"))) {
348 while (n) {
349 ObActionsAct *action;
350
351 action = actions_parse(n);
352 if (action)
353 keyboard_bind(keylist, action);
354 n = obt_parse_find_node(n->next, "action");
355 }
356 }
357
358 if (is_chroot)
359 keyboard_chroot(keylist);
360
361 g_free(key);
362 keylist = g_list_delete_link(keylist, g_list_last(keylist));
363 }
364
365 static void parse_keyboard(xmlNodePtr node, gpointer d)
366 {
367 xmlNodePtr n;
368 gchar *key;
369
370 keyboard_unbind_all();
371
372 if ((n = obt_parse_find_node(node->children, "chainQuitKey"))) {
373 key = obt_parse_node_string(n);
374 translate_key(key, &config_keyboard_reset_state,
375 &config_keyboard_reset_keycode);
376 g_free(key);
377 }
378
379 if ((n = obt_parse_find_node(node->children, "keybind")))
380 while (n) {
381 parse_key(n, NULL);
382 n = obt_parse_find_node(n->next, "keybind");
383 }
384 }
385
386 /*
387
388 <context name="Titlebar">
389 <mousebind button="Left" action="Press">
390 <action name="Raise"></action>
391 </mousebind>
392 </context>
393
394 */
395
396 static void parse_mouse(xmlNodePtr node, gpointer d)
397 {
398 xmlNodePtr n, nbut, nact;
399 gchar *buttonstr;
400 gchar *contextstr;
401 ObMouseAction mact;
402
403 mouse_unbind_all();
404
405 node = node->children;
406
407 if ((n = obt_parse_find_node(node, "dragThreshold")))
408 config_mouse_threshold = obt_parse_node_int(n);
409 if ((n = obt_parse_find_node(node, "doubleClickTime")))
410 config_mouse_dclicktime = obt_parse_node_int(n);
411 if ((n = obt_parse_find_node(node, "screenEdgeWarpTime")))
412 config_mouse_screenedgetime = obt_parse_node_int(n);
413
414 n = obt_parse_find_node(node, "context");
415 while (n) {
416 if (!obt_parse_attr_string(n, "name", &contextstr))
417 goto next_n;
418 nbut = obt_parse_find_node(n->children, "mousebind");
419 while (nbut) {
420 if (!obt_parse_attr_string(nbut, "button", &buttonstr))
421 goto next_nbut;
422 if (obt_parse_attr_contains(nbut, "action", "press")) {
423 mact = OB_MOUSE_ACTION_PRESS;
424 } else if (obt_parse_attr_contains(nbut, "action", "release")) {
425 mact = OB_MOUSE_ACTION_RELEASE;
426 } else if (obt_parse_attr_contains(nbut, "action", "click")) {
427 mact = OB_MOUSE_ACTION_CLICK;
428 } else if (obt_parse_attr_contains(nbut, "action","doubleclick")) {
429 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
430 } else if (obt_parse_attr_contains(nbut, "action", "drag")) {
431 mact = OB_MOUSE_ACTION_MOTION;
432 } else
433 goto next_nbut;
434 nact = obt_parse_find_node(nbut->children, "action");
435 while (nact) {
436 ObActionsAct *action;
437
438 if ((action = actions_parse(nact)))
439 mouse_bind(buttonstr, contextstr, mact, action);
440 nact = obt_parse_find_node(nact->next, "action");
441 }
442 g_free(buttonstr);
443 next_nbut:
444 nbut = obt_parse_find_node(nbut->next, "mousebind");
445 }
446 g_free(contextstr);
447 next_n:
448 n = obt_parse_find_node(n->next, "context");
449 }
450 }
451
452 static void parse_focus(xmlNodePtr node, gpointer d)
453 {
454 xmlNodePtr n;
455
456 node = node->children;
457
458 if ((n = obt_parse_find_node(node, "focusNew")))
459 config_focus_new = obt_parse_node_bool(n);
460 if ((n = obt_parse_find_node(node, "followMouse")))
461 config_focus_follow = obt_parse_node_bool(n);
462 if ((n = obt_parse_find_node(node, "focusDelay")))
463 config_focus_delay = obt_parse_node_int(n);
464 if ((n = obt_parse_find_node(node, "raiseOnFocus")))
465 config_focus_raise = obt_parse_node_bool(n);
466 if ((n = obt_parse_find_node(node, "focusLast")))
467 config_focus_last = obt_parse_node_bool(n);
468 if ((n = obt_parse_find_node(node, "underMouse")))
469 config_focus_under_mouse = obt_parse_node_bool(n);
470 }
471
472 static void parse_placement(xmlNodePtr node, gpointer d)
473 {
474 xmlNodePtr n;
475
476 node = node->children;
477
478 if ((n = obt_parse_find_node(node, "policy")))
479 if (obt_parse_node_contains(n, "UnderMouse"))
480 config_place_policy = OB_PLACE_POLICY_MOUSE;
481 if ((n = obt_parse_find_node(node, "center")))
482 config_place_center = obt_parse_node_bool(n);
483 if ((n = obt_parse_find_node(node, "active")))
484 config_place_active = obt_parse_node_bool(n);
485 }
486
487 static void parse_margins(xmlNodePtr node, gpointer d)
488 {
489 xmlNodePtr n;
490
491 node = node->children;
492
493 if ((n = obt_parse_find_node(node, "top")))
494 config_margins.top = MAX(0, obt_parse_node_int(n));
495 if ((n = obt_parse_find_node(node, "left")))
496 config_margins.left = MAX(0, obt_parse_node_int(n));
497 if ((n = obt_parse_find_node(node, "right")))
498 config_margins.right = MAX(0, obt_parse_node_int(n));
499 if ((n = obt_parse_find_node(node, "bottom")))
500 config_margins.bottom = MAX(0, obt_parse_node_int(n));
501 }
502
503 static void parse_theme(xmlNodePtr node, gpointer d)
504 {
505 xmlNodePtr n;
506
507 node = node->children;
508
509 if ((n = obt_parse_find_node(node, "name"))) {
510 gchar *c;
511
512 g_free(config_theme);
513 c = obt_parse_node_string(n);
514 config_theme = parse_expand_tilde(c);
515 g_free(c);
516 }
517 if ((n = obt_parse_find_node(node, "titleLayout"))) {
518 gchar *c, *d;
519
520 g_free(config_title_layout);
521 config_title_layout = obt_parse_node_string(n);
522
523 /* replace duplicates with spaces */
524 for (c = config_title_layout; *c != '\0'; ++c)
525 for (d = c+1; *d != '\0'; ++d)
526 if (*c == *d) *d = ' ';
527 }
528 if ((n = obt_parse_find_node(node, "keepBorder")))
529 config_theme_keepborder = obt_parse_node_bool(n);
530 if ((n = obt_parse_find_node(node, "animateIconify")))
531 config_animate_iconify = obt_parse_node_bool(n);
532
533 n = obt_parse_find_node(node, "font");
534 while (n) {
535 xmlNodePtr fnode;
536 RrFont **font;
537 gchar *name = g_strdup(RrDefaultFontFamily);
538 gint size = RrDefaultFontSize;
539 RrFontWeight weight = RrDefaultFontWeight;
540 RrFontSlant slant = RrDefaultFontSlant;
541
542 if (obt_parse_attr_contains(n, "place", "ActiveWindow"))
543 font = &config_font_activewindow;
544 else if (obt_parse_attr_contains(n, "place", "InactiveWindow"))
545 font = &config_font_inactivewindow;
546 else if (obt_parse_attr_contains(n, "place", "MenuHeader"))
547 font = &config_font_menutitle;
548 else if (obt_parse_attr_contains(n, "place", "MenuItem"))
549 font = &config_font_menuitem;
550 else if (obt_parse_attr_contains(n, "place", "OnScreenDisplay"))
551 font = &config_font_osd;
552 else
553 goto next_font;
554
555 if ((fnode = obt_parse_find_node(n->children, "name"))) {
556 g_free(name);
557 name = obt_parse_node_string(fnode);
558 }
559 if ((fnode = obt_parse_find_node(n->children, "size"))) {
560 int s = obt_parse_node_int(fnode);
561 if (s > 0) size = s;
562 }
563 if ((fnode = obt_parse_find_node(n->children, "weight"))) {
564 gchar *w = obt_parse_node_string(fnode);
565 if (!g_ascii_strcasecmp(w, "Bold"))
566 weight = RR_FONTWEIGHT_BOLD;
567 g_free(w);
568 }
569 if ((fnode = obt_parse_find_node(n->children, "slant"))) {
570 gchar *s = obt_parse_node_string(fnode);
571 if (!g_ascii_strcasecmp(s, "Italic"))
572 slant = RR_FONTSLANT_ITALIC;
573 if (!g_ascii_strcasecmp(s, "Oblique"))
574 slant = RR_FONTSLANT_OBLIQUE;
575 g_free(s);
576 }
577
578 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
579 g_free(name);
580 next_font:
581 n = obt_parse_find_node(n->next, "font");
582 }
583 }
584
585 static void parse_desktops(xmlNodePtr node, gpointer d)
586 {
587 xmlNodePtr n;
588
589 node = node->children;
590
591 if ((n = obt_parse_find_node(node, "number"))) {
592 gint d = obt_parse_node_int(n);
593 if (d > 0)
594 config_desktops_num = d;
595 }
596 if ((n = obt_parse_find_node(node, "firstdesk"))) {
597 gint d = obt_parse_node_int(n);
598 if (d > 0)
599 config_screen_firstdesk = (unsigned) d;
600 }
601 if ((n = obt_parse_find_node(node, "names"))) {
602 GSList *it;
603 xmlNodePtr nname;
604
605 for (it = config_desktops_names; it; it = it->next)
606 g_free(it->data);
607 g_slist_free(config_desktops_names);
608 config_desktops_names = NULL;
609
610 nname = obt_parse_find_node(n->children, "name");
611 while (nname) {
612 config_desktops_names =
613 g_slist_append(config_desktops_names,
614 obt_parse_node_string(nname));
615 nname = obt_parse_find_node(nname->next, "name");
616 }
617 }
618 if ((n = obt_parse_find_node(node, "popupTime")))
619 config_desktop_popup_time = obt_parse_node_int(n);
620 }
621
622 static void parse_resize(xmlNodePtr node, gpointer d)
623 {
624 xmlNodePtr n;
625
626 node = node->children;
627
628 if ((n = obt_parse_find_node(node, "drawContents")))
629 config_resize_redraw = obt_parse_node_bool(n);
630 if ((n = obt_parse_find_node(node, "popupShow"))) {
631 config_resize_popup_show = obt_parse_node_int(n);
632 if (obt_parse_node_contains(n, "Always"))
633 config_resize_popup_show = 2;
634 else if (obt_parse_node_contains(n, "Never"))
635 config_resize_popup_show = 0;
636 else if (obt_parse_node_contains(n, "Nonpixel"))
637 config_resize_popup_show = 1;
638 }
639 if ((n = obt_parse_find_node(node, "popupPosition"))) {
640 if (obt_parse_node_contains(n, "Top"))
641 config_resize_popup_pos = OB_RESIZE_POS_TOP;
642 else if (obt_parse_node_contains(n, "Center"))
643 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
644 else if (obt_parse_node_contains(n, "Fixed")) {
645 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
646
647 if ((n = obt_parse_find_node(node, "popupFixedPosition"))) {
648 xmlNodePtr n2;
649
650 if ((n2 = obt_parse_find_node(n->children, "x")))
651 config_parse_gravity_coord(n2,
652 &config_resize_popup_fixed.x);
653 if ((n2 = obt_parse_find_node(n->children, "y")))
654 config_parse_gravity_coord(n2,
655 &config_resize_popup_fixed.y);
656 }
657 }
658 }
659 }
660
661 static void parse_dock(xmlNodePtr node, gpointer d)
662 {
663 xmlNodePtr n;
664
665 node = node->children;
666
667 if ((n = obt_parse_find_node(node, "position"))) {
668 if (obt_parse_node_contains(n, "TopLeft"))
669 config_dock_floating = FALSE,
670 config_dock_pos = OB_DIRECTION_NORTHWEST;
671 else if (obt_parse_node_contains(n, "Top"))
672 config_dock_floating = FALSE,
673 config_dock_pos = OB_DIRECTION_NORTH;
674 else if (obt_parse_node_contains(n, "TopRight"))
675 config_dock_floating = FALSE,
676 config_dock_pos = OB_DIRECTION_NORTHEAST;
677 else if (obt_parse_node_contains(n, "Right"))
678 config_dock_floating = FALSE,
679 config_dock_pos = OB_DIRECTION_EAST;
680 else if (obt_parse_node_contains(n, "BottomRight"))
681 config_dock_floating = FALSE,
682 config_dock_pos = OB_DIRECTION_SOUTHEAST;
683 else if (obt_parse_node_contains(n, "Bottom"))
684 config_dock_floating = FALSE,
685 config_dock_pos = OB_DIRECTION_SOUTH;
686 else if (obt_parse_node_contains(n, "BottomLeft"))
687 config_dock_floating = FALSE,
688 config_dock_pos = OB_DIRECTION_SOUTHWEST;
689 else if (obt_parse_node_contains(n, "Left"))
690 config_dock_floating = FALSE,
691 config_dock_pos = OB_DIRECTION_WEST;
692 else if (obt_parse_node_contains(n, "Floating"))
693 config_dock_floating = TRUE;
694 }
695 if (config_dock_floating) {
696 if ((n = obt_parse_find_node(node, "floatingX")))
697 config_dock_x = obt_parse_node_int(n);
698 if ((n = obt_parse_find_node(node, "floatingY")))
699 config_dock_y = obt_parse_node_int(n);
700 } else {
701 if ((n = obt_parse_find_node(node, "noStrut")))
702 config_dock_nostrut = obt_parse_node_bool(n);
703 }
704 if ((n = obt_parse_find_node(node, "stacking"))) {
705 if (obt_parse_node_contains(n, "normal"))
706 config_dock_layer = OB_STACKING_LAYER_NORMAL;
707 else if (obt_parse_node_contains(n, "below"))
708 config_dock_layer = OB_STACKING_LAYER_BELOW;
709 else if (obt_parse_node_contains(n, "above"))
710 config_dock_layer = OB_STACKING_LAYER_ABOVE;
711 }
712 if ((n = obt_parse_find_node(node, "direction"))) {
713 if (obt_parse_node_contains(n, "horizontal"))
714 config_dock_orient = OB_ORIENTATION_HORZ;
715 else if (obt_parse_node_contains(n, "vertical"))
716 config_dock_orient = OB_ORIENTATION_VERT;
717 }
718 if ((n = obt_parse_find_node(node, "autoHide")))
719 config_dock_hide = obt_parse_node_bool(n);
720 if ((n = obt_parse_find_node(node, "hideDelay")))
721 config_dock_hide_delay = obt_parse_node_int(n);
722 if ((n = obt_parse_find_node(node, "showDelay")))
723 config_dock_show_delay = obt_parse_node_int(n);
724 if ((n = obt_parse_find_node(node, "moveButton"))) {
725 gchar *str = obt_parse_node_string(n);
726 guint b, s;
727 if (translate_button(str, &s, &b)) {
728 config_dock_app_move_button = b;
729 config_dock_app_move_modifiers = s;
730 } else {
731 g_message(_("Invalid button '%s' specified in config file"), str);
732 }
733 g_free(str);
734 }
735 }
736
737 static void parse_menu(xmlNodePtr node, gpointer d)
738 {
739 xmlNodePtr n;
740 for (node = node->children; node; node = node->next) {
741 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
742 gchar *c;
743
744 c = obt_parse_node_string(node);
745 config_menu_files = g_slist_append(config_menu_files,
746 parse_expand_tilde(c));
747 g_free(c);
748 }
749 if ((n = obt_parse_find_node(node, "hideDelay")))
750 config_menu_hide_delay = obt_parse_node_int(n);
751 if ((n = obt_parse_find_node(node, "middle")))
752 config_menu_middle = obt_parse_node_bool(n);
753 if ((n = obt_parse_find_node(node, "submenuShowDelay")))
754 config_submenu_show_delay = obt_parse_node_int(n);
755 if ((n = obt_parse_find_node(node, "applicationIcons")))
756 config_menu_client_list_icons = obt_parse_node_bool(n);
757 }
758 }
759
760 static void parse_resistance(xmlNodePtr node, gpointer d)
761 {
762 xmlNodePtr n;
763
764 node = node->children;
765 if ((n = obt_parse_find_node(node, "strength")))
766 config_resist_win = obt_parse_node_int(n);
767 if ((n = obt_parse_find_node(node, "screen_edge_strength")))
768 config_resist_edge = obt_parse_node_int(n);
769 }
770
771 typedef struct
772 {
773 const gchar *key;
774 const gchar *actname;
775 } ObDefKeyBind;
776
777 static void bind_default_keyboard(void)
778 {
779 ObDefKeyBind *it;
780 ObDefKeyBind binds[] = {
781 { "A-Tab", "NextWindow" },
782 { "S-A-Tab", "PreviousWindow" },
783 { "A-F4", "Close" },
784 { NULL, NULL }
785 };
786 for (it = binds; it->key; ++it) {
787 GList *l = g_list_append(NULL, g_strdup(it->key));
788 keyboard_bind(l, actions_parse_string(it->actname));
789 }
790 }
791
792 typedef struct
793 {
794 const gchar *button;
795 const gchar *context;
796 const ObMouseAction mact;
797 const gchar *actname;
798 } ObDefMouseBind;
799
800 static void bind_default_mouse(void)
801 {
802 ObDefMouseBind *it;
803 ObDefMouseBind binds[] = {
804 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
805 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
806 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
807 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
808 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
809 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
810 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
811 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
812 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
813 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
814 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
815 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
816 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
817 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
818 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
819 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
820 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
821 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
822 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
823 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
824 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
825 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
826 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
827 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
828 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
829 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
830 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
831 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
832 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
833 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
834 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
835 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
836 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
837 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
838 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
839 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
840 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
841 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
842 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
843 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
844 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
845 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
846 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
847 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
848 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
849 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
850 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
851 { NULL, NULL, 0, NULL }
852 };
853
854 for (it = binds; it->button; ++it)
855 mouse_bind(it->button, it->context, it->mact,
856 actions_parse_string(it->actname));
857 }
858
859 void config_startup(ObtParseInst *i)
860 {
861 config_focus_new = TRUE;
862 config_focus_follow = FALSE;
863 config_focus_delay = 0;
864 config_focus_raise = FALSE;
865 config_focus_last = TRUE;
866 config_focus_under_mouse = FALSE;
867
868 obt_parse_register(i, "focus", parse_focus, NULL);
869
870 config_place_policy = OB_PLACE_POLICY_SMART;
871 config_place_center = TRUE;
872 config_place_active = FALSE;
873
874 obt_parse_register(i, "placement", parse_placement, NULL);
875
876 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
877
878 obt_parse_register(i, "margins", parse_margins, NULL);
879
880 config_theme = NULL;
881
882 config_animate_iconify = TRUE;
883 config_title_layout = g_strdup("NLIMC");
884 config_theme_keepborder = TRUE;
885
886 config_font_activewindow = NULL;
887 config_font_inactivewindow = NULL;
888 config_font_menuitem = NULL;
889 config_font_menutitle = NULL;
890
891 obt_parse_register(i, "theme", parse_theme, NULL);
892
893 config_desktops_num = 4;
894 config_screen_firstdesk = 1;
895 config_desktops_names = NULL;
896 config_desktop_popup_time = 875;
897
898 obt_parse_register(i, "desktops", parse_desktops, NULL);
899
900 config_resize_redraw = TRUE;
901 config_resize_popup_show = 1; /* nonpixel increments */
902 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
903 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
904 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
905
906 obt_parse_register(i, "resize", parse_resize, NULL);
907
908 config_dock_layer = OB_STACKING_LAYER_ABOVE;
909 config_dock_pos = OB_DIRECTION_NORTHEAST;
910 config_dock_floating = FALSE;
911 config_dock_nostrut = FALSE;
912 config_dock_x = 0;
913 config_dock_y = 0;
914 config_dock_orient = OB_ORIENTATION_VERT;
915 config_dock_hide = FALSE;
916 config_dock_hide_delay = 300;
917 config_dock_show_delay = 300;
918 config_dock_app_move_button = 2; /* middle */
919 config_dock_app_move_modifiers = 0;
920
921 obt_parse_register(i, "dock", parse_dock, NULL);
922
923 translate_key("C-g", &config_keyboard_reset_state,
924 &config_keyboard_reset_keycode);
925
926 bind_default_keyboard();
927
928 obt_parse_register(i, "keyboard", parse_keyboard, NULL);
929
930 config_mouse_threshold = 8;
931 config_mouse_dclicktime = 200;
932 config_mouse_screenedgetime = 400;
933
934 bind_default_mouse();
935
936 obt_parse_register(i, "mouse", parse_mouse, NULL);
937
938 config_resist_win = 10;
939 config_resist_edge = 20;
940
941 obt_parse_register(i, "resistance", parse_resistance, NULL);
942
943 config_menu_hide_delay = 250;
944 config_menu_middle = FALSE;
945 config_submenu_show_delay = 0;
946 config_menu_client_list_icons = TRUE;
947 config_menu_files = NULL;
948
949 obt_parse_register(i, "menu", parse_menu, NULL);
950
951 config_per_app_settings = NULL;
952
953 obt_parse_register(i, "applications", parse_per_app_settings, NULL);
954 }
955
956 void config_shutdown(void)
957 {
958 GSList *it;
959
960 g_free(config_theme);
961
962 g_free(config_title_layout);
963
964 RrFontClose(config_font_activewindow);
965 RrFontClose(config_font_inactivewindow);
966 RrFontClose(config_font_menuitem);
967 RrFontClose(config_font_menutitle);
968
969 for (it = config_desktops_names; it; it = g_slist_next(it))
970 g_free(it->data);
971 g_slist_free(config_desktops_names);
972
973 for (it = config_menu_files; it; it = g_slist_next(it))
974 g_free(it->data);
975 g_slist_free(config_menu_files);
976
977 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
978 ObAppSettings *itd = (ObAppSettings *)it->data;
979 if (itd->name) g_pattern_spec_free(itd->name);
980 if (itd->role) g_pattern_spec_free(itd->role);
981 if (itd->class) g_pattern_spec_free(itd->class);
982 g_free(it->data);
983 }
984 g_slist_free(config_per_app_settings);
985 }
This page took 0.082691 seconds and 5 git commands to generate.