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