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