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