1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 config.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "translate.h"
30 #include "obt/paths.h"
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 gboolean config_focus_dontstop;
40 ObPlacePolicy config_place_policy;
41 gboolean config_place_center;
42 ObPlaceMonitor config_place_monitor;
44 StrutPartial config_margins;
47 gboolean config_theme_keepborder;
48 guint config_theme_window_list_icon_size;
50 gchar *config_title_layout;
52 gboolean config_animate_iconify;
54 RrFont *config_font_activewindow;
55 RrFont *config_font_inactivewindow;
56 RrFont *config_font_menuitem;
57 RrFont *config_font_menutitle;
58 RrFont *config_font_osd;
60 guint config_desktops_num;
61 GSList *config_desktops_names;
62 guint config_screen_firstdesk;
63 guint config_desktop_popup_time;
65 gboolean config_resize_redraw;
66 gint config_resize_popup_show;
67 ObResizePopupPos config_resize_popup_pos;
68 GravityPoint config_resize_popup_fixed;
70 ObStackingLayer config_dock_layer;
71 gboolean config_dock_floating;
72 gboolean config_dock_nostrut;
73 ObDirection config_dock_pos;
76 ObOrientation config_dock_orient;
77 gboolean config_dock_hide;
78 guint config_dock_hide_delay;
79 guint config_dock_show_delay;
80 guint config_dock_app_move_button;
81 guint config_dock_app_move_modifiers;
83 guint config_keyboard_reset_keycode;
84 guint config_keyboard_reset_state;
86 gint config_mouse_threshold;
87 gint config_mouse_dclicktime;
88 gint config_mouse_screenedgetime;
90 guint config_menu_hide_delay;
91 gboolean config_menu_middle;
92 guint config_submenu_show_delay;
93 gboolean config_menu_client_list_icons;
94 gboolean config_menu_manage_desktops;
95 gboolean config_menu_user_show_icons;
97 GSList *config_menu_files;
99 gint config_resist_win;
100 gint config_resist_edge;
102 GSList *config_per_app_settings;
104 ObAppSettings* config_create_app_settings(void)
106 ObAppSettings *settings = g_new0(ObAppSettings, 1);
108 settings->decor = -1;
109 settings->shade = -1;
110 settings->monitor = -1;
111 settings->focus = -1;
112 settings->desktop = 0;
113 settings->layer = -2;
114 settings->iconic = -1;
115 settings->skip_pager = -1;
116 settings->skip_taskbar = -1;
117 settings->fullscreen = -1;
118 settings->max_horz = -1;
119 settings->max_vert = -1;
123 #define copy_if(setting, default) \
124 if (src->setting != default) dst->setting = src->setting
125 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
128 g_assert(src != NULL);
129 g_assert(dst != NULL);
131 copy_if(type, (ObClientType)-1);
138 copy_if(skip_pager, -1);
139 copy_if(skip_taskbar, -1);
140 copy_if(fullscreen, -1);
141 copy_if(max_horz, -1);
142 copy_if(max_vert, -1);
144 if (src->pos_given) {
145 dst->pos_given = TRUE;
146 dst->pos_force = src->pos_force;
147 dst->position = src->position;
148 dst->monitor = src->monitor;
152 static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
154 gchar *s = obt_parse_node_string(node);
155 if (!g_ascii_strcasecmp(s, "center"))
160 if (s[0] == '-' || s[0] == '+')
170 <application name="aterm">
173 <application name="Rhythmbox">
180 .. there is a lot more settings available
185 /* Manages settings for individual applications.
186 Some notes: monitor is the screen number in a multi monitor
187 (Xinerama) setup (starting from 0) or mouse, meaning the
188 monitor the pointer is on. Default: mouse.
189 Layer can be three values, above (Always on top), below
190 (Always on bottom) and everything else (normal behaviour).
191 Positions can be an integer value or center, which will
192 center the window in the specified axis. Position is within
193 the monitor, so <position><x>center</x></position><monitor>2</monitor>
194 will center the window on the second monitor.
196 static void parse_per_app_settings(xmlNodePtr node, gpointer d)
198 xmlNodePtr app = obt_parse_find_node(node->children, "application");
199 gchar *name = NULL, *class = NULL, *role = NULL, *type = NULL;
200 gboolean name_set, class_set, type_set;
201 gboolean x_pos_given;
204 name_set = class_set = type_set = x_pos_given = FALSE;
206 class_set = obt_parse_attr_string(app, "class", &class);
207 name_set = obt_parse_attr_string(app, "name", &name);
208 type_set = obt_parse_attr_string(app, "type", &type);
209 if (class_set || name_set) {
211 ObAppSettings *settings = config_create_app_settings();;
214 settings->name = g_pattern_spec_new(name);
217 settings->class = g_pattern_spec_new(class);
220 if (!g_ascii_strcasecmp(type, "normal"))
221 settings->type = OB_CLIENT_TYPE_NORMAL;
222 else if (!g_ascii_strcasecmp(type, "dialog"))
223 settings->type = OB_CLIENT_TYPE_DIALOG;
224 else if (!g_ascii_strcasecmp(type, "splash"))
225 settings->type = OB_CLIENT_TYPE_SPLASH;
226 else if (!g_ascii_strcasecmp(type, "utility"))
227 settings->type = OB_CLIENT_TYPE_UTILITY;
228 else if (!g_ascii_strcasecmp(type, "menu"))
229 settings->type = OB_CLIENT_TYPE_MENU;
230 else if (!g_ascii_strcasecmp(type, "toolbar"))
231 settings->type = OB_CLIENT_TYPE_TOOLBAR;
232 else if (!g_ascii_strcasecmp(type, "dock"))
233 settings->type = OB_CLIENT_TYPE_DOCK;
234 else if (!g_ascii_strcasecmp(type, "desktop"))
235 settings->type = OB_CLIENT_TYPE_DESKTOP;
238 if (obt_parse_attr_string(app, "role", &role))
239 settings->role = g_pattern_spec_new(role);
241 if ((n = obt_parse_find_node(app->children, "decor")))
242 if (!obt_parse_node_contains(n, "default"))
243 settings->decor = obt_parse_node_bool(n);
245 if ((n = obt_parse_find_node(app->children, "shade")))
246 if (!obt_parse_node_contains(n, "default"))
247 settings->shade = obt_parse_node_bool(n);
249 if ((n = obt_parse_find_node(app->children, "position"))) {
250 if ((c = obt_parse_find_node(n->children, "x")))
251 if (!obt_parse_node_contains(c, "default")) {
252 config_parse_gravity_coord(c, &settings->position.x);
256 if (x_pos_given && (c = obt_parse_find_node(n->children, "y")))
257 if (!obt_parse_node_contains(c, "default")) {
258 config_parse_gravity_coord(c, &settings->position.y);
259 settings->pos_given = TRUE;
262 if (settings->pos_given &&
263 (c = obt_parse_find_node(n->children, "monitor")))
264 if (!obt_parse_node_contains(c, "default")) {
265 gchar *s = obt_parse_node_string(c);
266 if (!g_ascii_strcasecmp(s, "mouse"))
267 settings->monitor = 0;
269 settings->monitor = obt_parse_node_int(c) + 1;
273 obt_parse_attr_bool(n, "force", &settings->pos_force);
276 if ((n = obt_parse_find_node(app->children, "focus")))
277 if (!obt_parse_node_contains(n, "default"))
278 settings->focus = obt_parse_node_bool(n);
280 if ((n = obt_parse_find_node(app->children, "desktop"))) {
281 if (!obt_parse_node_contains(n, "default")) {
282 gchar *s = obt_parse_node_string(n);
283 if (!g_ascii_strcasecmp(s, "all"))
284 settings->desktop = DESKTOP_ALL;
286 gint i = obt_parse_node_int(n);
288 settings->desktop = i;
294 if ((n = obt_parse_find_node(app->children, "layer")))
295 if (!obt_parse_node_contains(n, "default")) {
296 gchar *s = obt_parse_node_string(n);
297 if (!g_ascii_strcasecmp(s, "above"))
299 else if (!g_ascii_strcasecmp(s, "below"))
300 settings->layer = -1;
306 if ((n = obt_parse_find_node(app->children, "iconic")))
307 if (!obt_parse_node_contains(n, "default"))
308 settings->iconic = obt_parse_node_bool(n);
310 if ((n = obt_parse_find_node(app->children, "skip_pager")))
311 if (!obt_parse_node_contains(n, "default"))
312 settings->skip_pager = obt_parse_node_bool(n);
314 if ((n = obt_parse_find_node(app->children, "skip_taskbar")))
315 if (!obt_parse_node_contains(n, "default"))
316 settings->skip_taskbar = obt_parse_node_bool(n);
318 if ((n = obt_parse_find_node(app->children, "fullscreen")))
319 if (!obt_parse_node_contains(n, "default"))
320 settings->fullscreen = obt_parse_node_bool(n);
322 if ((n = obt_parse_find_node(app->children, "maximized")))
323 if (!obt_parse_node_contains(n, "default")) {
324 gchar *s = obt_parse_node_string(n);
325 if (!g_ascii_strcasecmp(s, "horizontal")) {
326 settings->max_horz = TRUE;
327 settings->max_vert = FALSE;
328 } else if (!g_ascii_strcasecmp(s, "vertical")) {
329 settings->max_horz = FALSE;
330 settings->max_vert = TRUE;
332 settings->max_horz = settings->max_vert =
333 obt_parse_node_bool(n);
337 config_per_app_settings = g_slist_append(config_per_app_settings,
338 (gpointer) settings);
342 name = class = role = NULL;
345 app = obt_parse_find_node(app->next, "application");
349 static void parse_hook(xmlNodePtr node, gpointer d)
356 if (!obt_parse_attr_string(node, "name", &name)) {
357 g_message(_("Hook in config file is missing a name"));
361 hook = hooks_hook_from_name(name);
363 g_message(_("Unknown hook \"%s\" in config file"), name);
365 if ((n = obt_parse_find_node(node->children, "action")))
367 ObActionsAct *action;
369 action = actions_parse(n);
371 hooks_add(hook, action);
372 n = obt_parse_find_node(n->next, "action");
379 static void parse_hooks(xmlNodePtr node, gpointer d)
383 if ((n = obt_parse_find_node(node->children, "hook")))
386 n = obt_parse_find_node(n->next, "hook");
393 <action name="ChangeDesktop">
400 static void parse_key(xmlNodePtr node, GList *keylist)
404 gboolean is_chroot = FALSE;
405 gboolean grab = TRUE;
407 if (!obt_parse_attr_string(node, "key", &key))
410 obt_parse_attr_bool(node, "chroot", &is_chroot);
411 obt_parse_attr_bool(node, "grab", &grab);
413 keylist = g_list_append(keylist, key);
415 if ((n = obt_parse_find_node(node->children, "keybind"))) {
417 parse_key(n, keylist);
418 n = obt_parse_find_node(n->next, "keybind");
421 else if ((n = obt_parse_find_node(node->children, "action"))) {
423 ObActionsAct *action;
425 action = actions_parse(n);
427 keyboard_bind(keylist, action, grab);
428 n = obt_parse_find_node(n->next, "action");
433 keyboard_chroot(keylist);
436 keylist = g_list_delete_link(keylist, g_list_last(keylist));
439 static void parse_keyboard(xmlNodePtr node, gpointer d)
444 keyboard_unbind_all();
446 if ((n = obt_parse_find_node(node->children, "chainQuitKey"))) {
447 key = obt_parse_node_string(n);
448 translate_key(key, &config_keyboard_reset_state,
449 &config_keyboard_reset_keycode);
453 if ((n = obt_parse_find_node(node->children, "keybind")))
456 n = obt_parse_find_node(n->next, "keybind");
462 <context name="Titlebar">
463 <mousebind button="Left" action="Press">
464 <action name="Raise"></action>
470 static void parse_mouse(xmlNodePtr node, gpointer d)
472 xmlNodePtr n, nbut, nact;
479 node = node->children;
481 if ((n = obt_parse_find_node(node, "dragThreshold")))
482 config_mouse_threshold = obt_parse_node_int(n);
483 if ((n = obt_parse_find_node(node, "doubleClickTime")))
484 config_mouse_dclicktime = obt_parse_node_int(n);
485 if ((n = obt_parse_find_node(node, "screenEdgeWarpTime")))
486 config_mouse_screenedgetime = obt_parse_node_int(n);
488 n = obt_parse_find_node(node, "context");
490 if (!obt_parse_attr_string(n, "name", &contextstr))
492 nbut = obt_parse_find_node(n->children, "mousebind");
494 if (!obt_parse_attr_string(nbut, "button", &buttonstr))
496 if (obt_parse_attr_contains(nbut, "action", "press")) {
497 mact = OB_MOUSE_ACTION_PRESS;
498 } else if (obt_parse_attr_contains(nbut, "action", "release")) {
499 mact = OB_MOUSE_ACTION_RELEASE;
500 } else if (obt_parse_attr_contains(nbut, "action", "click")) {
501 mact = OB_MOUSE_ACTION_CLICK;
502 } else if (obt_parse_attr_contains(nbut, "action","doubleclick")) {
503 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
504 } else if (obt_parse_attr_contains(nbut, "action", "drag")) {
505 mact = OB_MOUSE_ACTION_MOTION;
508 nact = obt_parse_find_node(nbut->children, "action");
510 ObActionsAct *action;
512 if ((action = actions_parse(nact)))
513 mouse_bind(buttonstr, contextstr, mact, action);
514 nact = obt_parse_find_node(nact->next, "action");
518 nbut = obt_parse_find_node(nbut->next, "mousebind");
522 n = obt_parse_find_node(n->next, "context");
526 static void parse_focus(xmlNodePtr node, gpointer d)
530 node = node->children;
532 if ((n = obt_parse_find_node(node, "focusNew")))
533 config_focus_new = obt_parse_node_bool(n);
534 if ((n = obt_parse_find_node(node, "followMouse")))
535 config_focus_follow = obt_parse_node_bool(n);
536 if ((n = obt_parse_find_node(node, "focusDelay")))
537 config_focus_delay = obt_parse_node_int(n);
538 if ((n = obt_parse_find_node(node, "raiseOnFocus")))
539 config_focus_raise = obt_parse_node_bool(n);
540 if ((n = obt_parse_find_node(node, "focusLast")))
541 config_focus_last = obt_parse_node_bool(n);
542 if ((n = obt_parse_find_node(node, "underMouse")))
543 config_focus_under_mouse = obt_parse_node_bool(n);
544 if ((n = obt_parse_find_node(node, "dontStop")))
545 config_focus_dontstop = obt_parse_node_bool(n);
548 static void parse_placement(xmlNodePtr node, gpointer d)
552 node = node->children;
554 if ((n = obt_parse_find_node(node, "policy")))
555 if (obt_parse_node_contains(n, "UnderMouse"))
556 config_place_policy = OB_PLACE_POLICY_MOUSE;
557 if ((n = obt_parse_find_node(node, "center")))
558 config_place_center = obt_parse_node_bool(n);
559 if ((n = obt_parse_find_node(node, "monitor"))) {
560 if (obt_parse_node_contains(n, "active"))
561 config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
562 else if (obt_parse_node_contains(n, "mouse"))
563 config_place_monitor = OB_PLACE_MONITOR_MOUSE;
567 static void parse_margins(xmlNodePtr node, gpointer d)
571 node = node->children;
573 if ((n = obt_parse_find_node(node, "top")))
574 config_margins.top = MAX(0, obt_parse_node_int(n));
575 if ((n = obt_parse_find_node(node, "left")))
576 config_margins.left = MAX(0, obt_parse_node_int(n));
577 if ((n = obt_parse_find_node(node, "right")))
578 config_margins.right = MAX(0, obt_parse_node_int(n));
579 if ((n = obt_parse_find_node(node, "bottom")))
580 config_margins.bottom = MAX(0, obt_parse_node_int(n));
583 static void parse_theme(xmlNodePtr node, gpointer d)
587 node = node->children;
589 if ((n = obt_parse_find_node(node, "name"))) {
592 g_free(config_theme);
593 c = obt_parse_node_string(n);
594 config_theme = obt_paths_expand_tilde(c);
597 if ((n = obt_parse_find_node(node, "titleLayout"))) {
600 g_free(config_title_layout);
601 config_title_layout = obt_parse_node_string(n);
603 /* replace duplicates with spaces */
604 for (c = config_title_layout; *c != '\0'; ++c)
605 for (d = c+1; *d != '\0'; ++d)
606 if (*c == *d) *d = ' ';
608 if ((n = obt_parse_find_node(node, "keepBorder")))
609 config_theme_keepborder = obt_parse_node_bool(n);
610 if ((n = obt_parse_find_node(node, "animateIconify")))
611 config_animate_iconify = obt_parse_node_bool(n);
612 if ((n = obt_parse_find_node(node, "windowListIconSize"))) {
613 config_theme_window_list_icon_size = obt_parse_node_int(n);
614 if (config_theme_window_list_icon_size < 16)
615 config_theme_window_list_icon_size = 16;
616 else if (config_theme_window_list_icon_size > 96)
617 config_theme_window_list_icon_size = 96;
620 n = obt_parse_find_node(node, "font");
624 gchar *name = g_strdup(RrDefaultFontFamily);
625 gint size = RrDefaultFontSize;
626 RrFontWeight weight = RrDefaultFontWeight;
627 RrFontSlant slant = RrDefaultFontSlant;
629 if (obt_parse_attr_contains(n, "place", "ActiveWindow"))
630 font = &config_font_activewindow;
631 else if (obt_parse_attr_contains(n, "place", "InactiveWindow"))
632 font = &config_font_inactivewindow;
633 else if (obt_parse_attr_contains(n, "place", "MenuHeader"))
634 font = &config_font_menutitle;
635 else if (obt_parse_attr_contains(n, "place", "MenuItem"))
636 font = &config_font_menuitem;
637 else if (obt_parse_attr_contains(n, "place", "OnScreenDisplay"))
638 font = &config_font_osd;
642 if ((fnode = obt_parse_find_node(n->children, "name"))) {
644 name = obt_parse_node_string(fnode);
646 if ((fnode = obt_parse_find_node(n->children, "size"))) {
647 int s = obt_parse_node_int(fnode);
650 if ((fnode = obt_parse_find_node(n->children, "weight"))) {
651 gchar *w = obt_parse_node_string(fnode);
652 if (!g_ascii_strcasecmp(w, "Bold"))
653 weight = RR_FONTWEIGHT_BOLD;
656 if ((fnode = obt_parse_find_node(n->children, "slant"))) {
657 gchar *s = obt_parse_node_string(fnode);
658 if (!g_ascii_strcasecmp(s, "Italic"))
659 slant = RR_FONTSLANT_ITALIC;
660 if (!g_ascii_strcasecmp(s, "Oblique"))
661 slant = RR_FONTSLANT_OBLIQUE;
665 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
668 n = obt_parse_find_node(n->next, "font");
672 static void parse_desktops(xmlNodePtr node, gpointer d)
676 node = node->children;
678 if ((n = obt_parse_find_node(node, "number"))) {
679 gint d = obt_parse_node_int(n);
681 config_desktops_num = (unsigned) d;
683 if ((n = obt_parse_find_node(node, "firstdesk"))) {
684 gint d = obt_parse_node_int(n);
686 config_screen_firstdesk = (unsigned) d;
688 if ((n = obt_parse_find_node(node, "names"))) {
692 for (it = config_desktops_names; it; it = it->next)
694 g_slist_free(config_desktops_names);
695 config_desktops_names = NULL;
697 nname = obt_parse_find_node(n->children, "name");
699 config_desktops_names =
700 g_slist_append(config_desktops_names,
701 obt_parse_node_string(nname));
702 nname = obt_parse_find_node(nname->next, "name");
705 if ((n = obt_parse_find_node(node, "popupTime")))
706 config_desktop_popup_time = obt_parse_node_int(n);
709 static void parse_resize(xmlNodePtr node, gpointer d)
713 node = node->children;
715 if ((n = obt_parse_find_node(node, "drawContents")))
716 config_resize_redraw = obt_parse_node_bool(n);
717 if ((n = obt_parse_find_node(node, "popupShow"))) {
718 config_resize_popup_show = obt_parse_node_int(n);
719 if (obt_parse_node_contains(n, "Always"))
720 config_resize_popup_show = 2;
721 else if (obt_parse_node_contains(n, "Never"))
722 config_resize_popup_show = 0;
723 else if (obt_parse_node_contains(n, "Nonpixel"))
724 config_resize_popup_show = 1;
726 if ((n = obt_parse_find_node(node, "popupPosition"))) {
727 if (obt_parse_node_contains(n, "Top"))
728 config_resize_popup_pos = OB_RESIZE_POS_TOP;
729 else if (obt_parse_node_contains(n, "Center"))
730 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
731 else if (obt_parse_node_contains(n, "Fixed")) {
732 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
734 if ((n = obt_parse_find_node(node, "popupFixedPosition"))) {
737 if ((n2 = obt_parse_find_node(n->children, "x")))
738 config_parse_gravity_coord(n2,
739 &config_resize_popup_fixed.x);
740 if ((n2 = obt_parse_find_node(n->children, "y")))
741 config_parse_gravity_coord(n2,
742 &config_resize_popup_fixed.y);
744 config_resize_popup_fixed.x.pos =
745 MAX(config_resize_popup_fixed.x.pos, 0);
746 config_resize_popup_fixed.y.pos =
747 MAX(config_resize_popup_fixed.y.pos, 0);
753 static void parse_dock(xmlNodePtr node, gpointer d)
757 node = node->children;
759 if ((n = obt_parse_find_node(node, "position"))) {
760 if (obt_parse_node_contains(n, "TopLeft"))
761 config_dock_floating = FALSE,
762 config_dock_pos = OB_DIRECTION_NORTHWEST;
763 else if (obt_parse_node_contains(n, "Top"))
764 config_dock_floating = FALSE,
765 config_dock_pos = OB_DIRECTION_NORTH;
766 else if (obt_parse_node_contains(n, "TopRight"))
767 config_dock_floating = FALSE,
768 config_dock_pos = OB_DIRECTION_NORTHEAST;
769 else if (obt_parse_node_contains(n, "Right"))
770 config_dock_floating = FALSE,
771 config_dock_pos = OB_DIRECTION_EAST;
772 else if (obt_parse_node_contains(n, "BottomRight"))
773 config_dock_floating = FALSE,
774 config_dock_pos = OB_DIRECTION_SOUTHEAST;
775 else if (obt_parse_node_contains(n, "Bottom"))
776 config_dock_floating = FALSE,
777 config_dock_pos = OB_DIRECTION_SOUTH;
778 else if (obt_parse_node_contains(n, "BottomLeft"))
779 config_dock_floating = FALSE,
780 config_dock_pos = OB_DIRECTION_SOUTHWEST;
781 else if (obt_parse_node_contains(n, "Left"))
782 config_dock_floating = FALSE,
783 config_dock_pos = OB_DIRECTION_WEST;
784 else if (obt_parse_node_contains(n, "Floating"))
785 config_dock_floating = TRUE;
787 if (config_dock_floating) {
788 if ((n = obt_parse_find_node(node, "floatingX")))
789 config_dock_x = obt_parse_node_int(n);
790 if ((n = obt_parse_find_node(node, "floatingY")))
791 config_dock_y = obt_parse_node_int(n);
793 if ((n = obt_parse_find_node(node, "noStrut")))
794 config_dock_nostrut = obt_parse_node_bool(n);
796 if ((n = obt_parse_find_node(node, "stacking"))) {
797 if (obt_parse_node_contains(n, "normal"))
798 config_dock_layer = OB_STACKING_LAYER_NORMAL;
799 else if (obt_parse_node_contains(n, "below"))
800 config_dock_layer = OB_STACKING_LAYER_BELOW;
801 else if (obt_parse_node_contains(n, "above"))
802 config_dock_layer = OB_STACKING_LAYER_ABOVE;
804 if ((n = obt_parse_find_node(node, "direction"))) {
805 if (obt_parse_node_contains(n, "horizontal"))
806 config_dock_orient = OB_ORIENTATION_HORZ;
807 else if (obt_parse_node_contains(n, "vertical"))
808 config_dock_orient = OB_ORIENTATION_VERT;
810 if ((n = obt_parse_find_node(node, "autoHide")))
811 config_dock_hide = obt_parse_node_bool(n);
812 if ((n = obt_parse_find_node(node, "hideDelay")))
813 config_dock_hide_delay = obt_parse_node_int(n);
814 if ((n = obt_parse_find_node(node, "showDelay")))
815 config_dock_show_delay = obt_parse_node_int(n);
816 if ((n = obt_parse_find_node(node, "moveButton"))) {
817 gchar *str = obt_parse_node_string(n);
819 if (translate_button(str, &s, &b)) {
820 config_dock_app_move_button = b;
821 config_dock_app_move_modifiers = s;
823 g_message(_("Invalid button \"%s\" specified in config file"), str);
829 static void parse_menu(xmlNodePtr node, gpointer d)
832 node = node->children;
834 if ((n = obt_parse_find_node(node, "hideDelay")))
835 config_menu_hide_delay = obt_parse_node_int(n);
836 if ((n = obt_parse_find_node(node, "middle")))
837 config_menu_middle = obt_parse_node_bool(n);
838 if ((n = obt_parse_find_node(node, "submenuShowDelay")))
839 config_submenu_show_delay = obt_parse_node_int(n);
840 if ((n = obt_parse_find_node(node, "applicationIcons")))
841 config_menu_client_list_icons = obt_parse_node_bool(n);
842 if ((n = obt_parse_find_node(node, "manageDesktops")))
843 config_menu_manage_desktops = obt_parse_node_bool(n);
845 if ((n = obt_parse_find_node(node, "showIcons"))) {
846 config_menu_user_show_icons = obt_parse_node_bool(n);
848 if (config_menu_user_show_icons)
849 g_message(_("Openbox was compiled without Imlib2."
850 " Icons in user-defined menus will NOT be loaded."));
854 while ((node = obt_parse_find_node(node, "file"))) {
855 gchar *c = obt_parse_node_string(node);
856 config_menu_files = g_slist_append(config_menu_files,
857 obt_paths_expand_tilde(c));
863 static void parse_resistance(xmlNodePtr node, gpointer d)
867 node = node->children;
868 if ((n = obt_parse_find_node(node, "strength")))
869 config_resist_win = obt_parse_node_int(n);
870 if ((n = obt_parse_find_node(node, "screen_edge_strength")))
871 config_resist_edge = obt_parse_node_int(n);
877 const gchar *actname;
880 static void bind_default_keyboard(void)
883 ObDefKeyBind binds[] = {
884 { "A-Tab", "NextWindow" },
885 { "S-A-Tab", "PreviousWindow" },
889 for (it = binds; it->key; ++it) {
890 GList *l = g_list_append(NULL, g_strdup(it->key));
891 keyboard_bind(l, actions_parse_string(it->actname), TRUE);
898 const gchar *context;
899 const ObMouseAction mact;
900 const gchar *actname;
903 static void bind_default_mouse(void)
906 ObDefMouseBind binds[] = {
907 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
908 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
909 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
910 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
911 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
912 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
913 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
914 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
915 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
916 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
917 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
918 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
919 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
920 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
921 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
922 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
923 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
924 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
925 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
926 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
927 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
928 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
929 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
930 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
931 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
932 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
933 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
934 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
935 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
936 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
937 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
938 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
939 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
940 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
941 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
942 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
943 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
944 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
945 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
946 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
947 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
948 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
949 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
950 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
951 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
952 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
953 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
954 { NULL, NULL, 0, NULL }
957 for (it = binds; it->button; ++it)
958 mouse_bind(it->button, it->context, it->mact,
959 actions_parse_string(it->actname));
962 void config_startup(ObtParseInst *i)
964 config_focus_new = TRUE;
965 config_focus_follow = FALSE;
966 config_focus_delay = 0;
967 config_focus_raise = FALSE;
968 config_focus_last = TRUE;
969 config_focus_under_mouse = FALSE;
970 config_focus_dontstop = FALSE;
972 obt_parse_register(i, "focus", parse_focus, NULL);
974 config_place_policy = OB_PLACE_POLICY_SMART;
975 config_place_center = TRUE;
976 config_place_monitor = OB_PLACE_MONITOR_ANY;
978 obt_parse_register(i, "placement", parse_placement, NULL);
980 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
982 obt_parse_register(i, "margins", parse_margins, NULL);
986 config_animate_iconify = TRUE;
987 config_title_layout = g_strdup("NLIMC");
988 config_theme_keepborder = TRUE;
989 config_theme_window_list_icon_size = 36;
991 config_font_activewindow = NULL;
992 config_font_inactivewindow = NULL;
993 config_font_menuitem = NULL;
994 config_font_menutitle = NULL;
996 obt_parse_register(i, "theme", parse_theme, NULL);
998 config_desktops_num = 4;
999 config_screen_firstdesk = 1;
1000 config_desktops_names = NULL;
1001 config_desktop_popup_time = 875;
1003 obt_parse_register(i, "desktops", parse_desktops, NULL);
1005 config_resize_redraw = TRUE;
1006 config_resize_popup_show = 1; /* nonpixel increments */
1007 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
1008 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
1009 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
1011 obt_parse_register(i, "resize", parse_resize, NULL);
1013 config_dock_layer = OB_STACKING_LAYER_ABOVE;
1014 config_dock_pos = OB_DIRECTION_NORTHEAST;
1015 config_dock_floating = FALSE;
1016 config_dock_nostrut = FALSE;
1019 config_dock_orient = OB_ORIENTATION_VERT;
1020 config_dock_hide = FALSE;
1021 config_dock_hide_delay = 300;
1022 config_dock_show_delay = 300;
1023 config_dock_app_move_button = 2; /* middle */
1024 config_dock_app_move_modifiers = 0;
1026 obt_parse_register(i, "dock", parse_dock, NULL);
1028 translate_key("C-g", &config_keyboard_reset_state,
1029 &config_keyboard_reset_keycode);
1031 bind_default_keyboard();
1033 obt_parse_register(i, "keyboard", parse_keyboard, NULL);
1035 config_mouse_threshold = 8;
1036 config_mouse_dclicktime = 200;
1037 config_mouse_screenedgetime = 400;
1039 bind_default_mouse();
1041 obt_parse_register(i, "mouse", parse_mouse, NULL);
1043 config_resist_win = 10;
1044 config_resist_edge = 20;
1046 obt_parse_register(i, "resistance", parse_resistance, NULL);
1048 config_menu_hide_delay = 250;
1049 config_menu_middle = FALSE;
1050 config_submenu_show_delay = 0;
1051 config_menu_client_list_icons = TRUE;
1052 config_menu_manage_desktops = TRUE;
1053 config_menu_files = NULL;
1054 config_menu_user_show_icons = TRUE;
1056 obt_parse_register(i, "menu", parse_menu, NULL);
1058 obt_parse_register(i, "hooks", parse_hooks, NULL);
1060 config_per_app_settings = NULL;
1062 obt_parse_register(i, "applications", parse_per_app_settings, NULL);
1065 void config_shutdown(void)
1069 g_free(config_theme);
1071 g_free(config_title_layout);
1073 RrFontClose(config_font_activewindow);
1074 RrFontClose(config_font_inactivewindow);
1075 RrFontClose(config_font_menuitem);
1076 RrFontClose(config_font_menutitle);
1077 RrFontClose(config_font_osd);
1079 for (it = config_desktops_names; it; it = g_slist_next(it))
1081 g_slist_free(config_desktops_names);
1083 for (it = config_menu_files; it; it = g_slist_next(it))
1085 g_slist_free(config_menu_files);
1087 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
1088 ObAppSettings *itd = (ObAppSettings *)it->data;
1089 if (itd->name) g_pattern_spec_free(itd->name);
1090 if (itd->role) g_pattern_spec_free(itd->role);
1091 if (itd->class) g_pattern_spec_free(itd->class);
1094 g_slist_free(config_per_app_settings);