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