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"
29 #include "obt/paths.h"
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;
38 ObPlacePolicy config_place_policy;
39 gboolean config_place_center;
40 ObPlaceMonitor config_place_monitor;
42 StrutPartial config_margins;
45 gboolean config_theme_keepborder;
47 gchar *config_title_layout;
49 gboolean config_animate_iconify;
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;
57 guint config_desktops_num;
58 GSList *config_desktops_names;
59 guint config_screen_firstdesk;
60 guint config_desktop_popup_time;
61 gint config_emulate_xinerama;
63 gboolean config_resize_redraw;
64 gint config_resize_popup_show;
65 ObResizePopupPos config_resize_popup_pos;
66 GravityPoint config_resize_popup_fixed;
68 ObStackingLayer config_dock_layer;
69 gboolean config_dock_floating;
70 gboolean config_dock_nostrut;
71 ObDirection config_dock_pos;
74 ObOrientation config_dock_orient;
75 gboolean config_dock_hide;
76 guint config_dock_hide_delay;
77 guint config_dock_show_delay;
78 guint config_dock_app_move_button;
79 guint config_dock_app_move_modifiers;
81 guint config_keyboard_reset_keycode;
82 guint config_keyboard_reset_state;
84 gint config_mouse_threshold;
85 gint config_mouse_dclicktime;
86 gint config_mouse_screenedgetime;
88 guint config_menu_hide_delay;
89 gboolean config_menu_middle;
90 guint config_submenu_show_delay;
91 gboolean config_menu_client_list_icons;
92 gboolean config_menu_manage_desktops;
94 GSList *config_menu_files;
96 gint config_resist_win;
97 gint config_resist_edge;
99 GSList *config_per_app_settings;
101 ObAppSettings* config_create_app_settings(void)
103 ObAppSettings *settings = g_new0(ObAppSettings, 1);
105 settings->decor = -1;
106 settings->shade = -1;
107 settings->monitor = -1;
108 settings->focus = -1;
109 settings->desktop = 0;
110 settings->layer = -2;
111 settings->iconic = -1;
112 settings->skip_pager = -1;
113 settings->skip_taskbar = -1;
114 settings->fullscreen = -1;
115 settings->max_horz = -1;
116 settings->max_vert = -1;
120 #define copy_if(setting, default) \
121 if (src->setting != default) dst->setting = src->setting
122 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
125 g_assert(src != NULL);
126 g_assert(dst != NULL);
128 copy_if(type, (ObClientType)-1);
135 copy_if(skip_pager, -1);
136 copy_if(skip_taskbar, -1);
137 copy_if(fullscreen, -1);
138 copy_if(max_horz, -1);
139 copy_if(max_vert, -1);
141 if (src->pos_given) {
142 dst->pos_given = TRUE;
143 dst->pos_force = src->pos_force;
144 dst->position = src->position;
145 dst->monitor = src->monitor;
149 static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
151 gchar *s = obt_parse_node_string(node);
152 if (!g_ascii_strcasecmp(s, "center"))
157 if (s[0] == '-' || s[0] == '+')
167 <application name="aterm">
170 <application name="Rhythmbox">
177 .. there is a lot more settings available
182 /* Manages settings for individual applications.
183 Some notes: monitor is the screen number in a multi monitor
184 (Xinerama) setup (starting from 0) or mouse, meaning the
185 monitor the pointer is on. Default: mouse.
186 Layer can be three values, above (Always on top), below
187 (Always on bottom) and everything else (normal behaviour).
188 Positions can be an integer value or center, which will
189 center the window in the specified axis. Position is within
190 the monitor, so <position><x>center</x></position><monitor>2</monitor>
191 will center the window on the second monitor.
193 static void parse_per_app_settings(xmlNodePtr node, gpointer d)
195 xmlNodePtr app = obt_parse_find_node(node->children, "application");
196 gchar *name = NULL, *class = NULL, *role = NULL, *type = NULL;
197 gboolean name_set, class_set, type_set;
198 gboolean x_pos_given;
201 name_set = class_set = type_set = x_pos_given = FALSE;
203 class_set = obt_parse_attr_string(app, "class", &class);
204 name_set = obt_parse_attr_string(app, "name", &name);
205 type_set = obt_parse_attr_string(app, "type", &type);
206 if (class_set || name_set) {
208 ObAppSettings *settings = config_create_app_settings();;
211 settings->name = g_pattern_spec_new(name);
214 settings->class = g_pattern_spec_new(class);
217 if (!g_ascii_strcasecmp(type, "normal"))
218 settings->type = OB_CLIENT_TYPE_NORMAL;
219 else if (!g_ascii_strcasecmp(type, "dialog"))
220 settings->type = OB_CLIENT_TYPE_DIALOG;
221 else if (!g_ascii_strcasecmp(type, "splash"))
222 settings->type = OB_CLIENT_TYPE_SPLASH;
223 else if (!g_ascii_strcasecmp(type, "utility"))
224 settings->type = OB_CLIENT_TYPE_UTILITY;
225 else if (!g_ascii_strcasecmp(type, "menu"))
226 settings->type = OB_CLIENT_TYPE_MENU;
227 else if (!g_ascii_strcasecmp(type, "toolbar"))
228 settings->type = OB_CLIENT_TYPE_TOOLBAR;
229 else if (!g_ascii_strcasecmp(type, "dock"))
230 settings->type = OB_CLIENT_TYPE_DOCK;
231 else if (!g_ascii_strcasecmp(type, "desktop"))
232 settings->type = OB_CLIENT_TYPE_DESKTOP;
235 if (obt_parse_attr_string(app, "role", &role))
236 settings->role = g_pattern_spec_new(role);
238 if ((n = obt_parse_find_node(app->children, "decor")))
239 if (!obt_parse_node_contains(n, "default"))
240 settings->decor = obt_parse_node_bool(n);
242 if ((n = obt_parse_find_node(app->children, "shade")))
243 if (!obt_parse_node_contains(n, "default"))
244 settings->shade = obt_parse_node_bool(n);
246 if ((n = obt_parse_find_node(app->children, "position"))) {
247 if ((c = obt_parse_find_node(n->children, "x")))
248 if (!obt_parse_node_contains(c, "default")) {
249 config_parse_gravity_coord(c, &settings->position.x);
253 if (x_pos_given && (c = obt_parse_find_node(n->children, "y")))
254 if (!obt_parse_node_contains(c, "default")) {
255 config_parse_gravity_coord(c, &settings->position.y);
256 settings->pos_given = TRUE;
259 if (settings->pos_given &&
260 (c = obt_parse_find_node(n->children, "monitor")))
261 if (!obt_parse_node_contains(c, "default")) {
262 gchar *s = obt_parse_node_string(c);
263 if (!g_ascii_strcasecmp(s, "mouse"))
264 settings->monitor = 0;
266 settings->monitor = obt_parse_node_int(c) + 1;
270 obt_parse_attr_bool(n, "force", &settings->pos_force);
273 if ((n = obt_parse_find_node(app->children, "focus")))
274 if (!obt_parse_node_contains(n, "default"))
275 settings->focus = obt_parse_node_bool(n);
277 if ((n = obt_parse_find_node(app->children, "desktop"))) {
278 if (!obt_parse_node_contains(n, "default")) {
279 gchar *s = obt_parse_node_string(n);
280 if (!g_ascii_strcasecmp(s, "all"))
281 settings->desktop = DESKTOP_ALL;
283 gint i = obt_parse_node_int(n);
285 settings->desktop = i;
291 if ((n = obt_parse_find_node(app->children, "layer")))
292 if (!obt_parse_node_contains(n, "default")) {
293 gchar *s = obt_parse_node_string(n);
294 if (!g_ascii_strcasecmp(s, "above"))
296 else if (!g_ascii_strcasecmp(s, "below"))
297 settings->layer = -1;
303 if ((n = obt_parse_find_node(app->children, "iconic")))
304 if (!obt_parse_node_contains(n, "default"))
305 settings->iconic = obt_parse_node_bool(n);
307 if ((n = obt_parse_find_node(app->children, "skip_pager")))
308 if (!obt_parse_node_contains(n, "default"))
309 settings->skip_pager = obt_parse_node_bool(n);
311 if ((n = obt_parse_find_node(app->children, "skip_taskbar")))
312 if (!obt_parse_node_contains(n, "default"))
313 settings->skip_taskbar = obt_parse_node_bool(n);
315 if ((n = obt_parse_find_node(app->children, "fullscreen")))
316 if (!obt_parse_node_contains(n, "default"))
317 settings->fullscreen = obt_parse_node_bool(n);
319 if ((n = obt_parse_find_node(app->children, "maximized")))
320 if (!obt_parse_node_contains(n, "default")) {
321 gchar *s = obt_parse_node_string(n);
322 if (!g_ascii_strcasecmp(s, "horizontal")) {
323 settings->max_horz = TRUE;
324 settings->max_vert = FALSE;
325 } else if (!g_ascii_strcasecmp(s, "vertical")) {
326 settings->max_horz = FALSE;
327 settings->max_vert = TRUE;
329 settings->max_horz = settings->max_vert =
330 obt_parse_node_bool(n);
334 config_per_app_settings = g_slist_append(config_per_app_settings,
335 (gpointer) settings);
339 name = class = role = NULL;
342 app = obt_parse_find_node(app->next, "application");
349 <action name="ChangeDesktop">
356 static void parse_key(xmlNodePtr node, GList *keylist)
360 gboolean is_chroot = FALSE;
362 if (!obt_parse_attr_string(node, "key", &key))
365 obt_parse_attr_bool(node, "chroot", &is_chroot);
367 keylist = g_list_append(keylist, key);
369 if ((n = obt_parse_find_node(node->children, "keybind"))) {
371 parse_key(n, keylist);
372 n = obt_parse_find_node(n->next, "keybind");
375 else if ((n = obt_parse_find_node(node->children, "action"))) {
377 ObActionsAct *action;
379 action = actions_parse(n);
381 keyboard_bind(keylist, action);
382 n = obt_parse_find_node(n->next, "action");
387 keyboard_chroot(keylist);
390 keylist = g_list_delete_link(keylist, g_list_last(keylist));
393 static void parse_keyboard(xmlNodePtr node, gpointer d)
398 keyboard_unbind_all();
400 if ((n = obt_parse_find_node(node->children, "chainQuitKey"))) {
401 key = obt_parse_node_string(n);
402 translate_key(key, &config_keyboard_reset_state,
403 &config_keyboard_reset_keycode);
407 if ((n = obt_parse_find_node(node->children, "keybind")))
410 n = obt_parse_find_node(n->next, "keybind");
416 <context name="Titlebar">
417 <mousebind button="Left" action="Press">
418 <action name="Raise"></action>
424 static void parse_mouse(xmlNodePtr node, gpointer d)
426 xmlNodePtr n, nbut, nact;
433 node = node->children;
435 if ((n = obt_parse_find_node(node, "dragThreshold")))
436 config_mouse_threshold = obt_parse_node_int(n);
437 if ((n = obt_parse_find_node(node, "doubleClickTime")))
438 config_mouse_dclicktime = obt_parse_node_int(n);
439 if ((n = obt_parse_find_node(node, "screenEdgeWarpTime")))
440 config_mouse_screenedgetime = obt_parse_node_int(n);
442 n = obt_parse_find_node(node, "context");
444 if (!obt_parse_attr_string(n, "name", &contextstr))
446 nbut = obt_parse_find_node(n->children, "mousebind");
448 if (!obt_parse_attr_string(nbut, "button", &buttonstr))
450 if (obt_parse_attr_contains(nbut, "action", "press")) {
451 mact = OB_MOUSE_ACTION_PRESS;
452 } else if (obt_parse_attr_contains(nbut, "action", "release")) {
453 mact = OB_MOUSE_ACTION_RELEASE;
454 } else if (obt_parse_attr_contains(nbut, "action", "click")) {
455 mact = OB_MOUSE_ACTION_CLICK;
456 } else if (obt_parse_attr_contains(nbut, "action","doubleclick")) {
457 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
458 } else if (obt_parse_attr_contains(nbut, "action", "drag")) {
459 mact = OB_MOUSE_ACTION_MOTION;
462 nact = obt_parse_find_node(nbut->children, "action");
464 ObActionsAct *action;
466 if ((action = actions_parse(nact)))
467 mouse_bind(buttonstr, contextstr, mact, action);
468 nact = obt_parse_find_node(nact->next, "action");
472 nbut = obt_parse_find_node(nbut->next, "mousebind");
476 n = obt_parse_find_node(n->next, "context");
480 static void parse_focus(xmlNodePtr node, gpointer d)
484 node = node->children;
486 if ((n = obt_parse_find_node(node, "focusNew")))
487 config_focus_new = obt_parse_node_bool(n);
488 if ((n = obt_parse_find_node(node, "followMouse")))
489 config_focus_follow = obt_parse_node_bool(n);
490 if ((n = obt_parse_find_node(node, "focusDelay")))
491 config_focus_delay = obt_parse_node_int(n);
492 if ((n = obt_parse_find_node(node, "raiseOnFocus")))
493 config_focus_raise = obt_parse_node_bool(n);
494 if ((n = obt_parse_find_node(node, "focusLast")))
495 config_focus_last = obt_parse_node_bool(n);
496 if ((n = obt_parse_find_node(node, "underMouse")))
497 config_focus_under_mouse = obt_parse_node_bool(n);
500 static void parse_placement(xmlNodePtr node, gpointer d)
504 node = node->children;
506 if ((n = obt_parse_find_node(node, "policy"))) {
507 if (obt_parse_node_contains(n, "UnderMouse"))
508 config_place_policy = OB_PLACE_POLICY_MOUSE;
509 if (obt_parse_node_contains(n, "Random"))
510 config_place_policy = OB_PLACE_POLICY_RANDOM;
512 if ((n = obt_parse_find_node(node, "center")))
513 config_place_center = obt_parse_node_bool(n);
514 if ((n = obt_parse_find_node(node, "monitor"))) {
515 if (obt_parse_node_contains(n, "active"))
516 config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
517 else if (obt_parse_node_contains(n, "mouse"))
518 config_place_monitor = OB_PLACE_MONITOR_MOUSE;
522 static void parse_margins(xmlNodePtr node, gpointer d)
526 node = node->children;
528 if ((n = obt_parse_find_node(node, "top")))
529 config_margins.top = MAX(0, obt_parse_node_int(n));
530 if ((n = obt_parse_find_node(node, "left")))
531 config_margins.left = MAX(0, obt_parse_node_int(n));
532 if ((n = obt_parse_find_node(node, "right")))
533 config_margins.right = MAX(0, obt_parse_node_int(n));
534 if ((n = obt_parse_find_node(node, "bottom")))
535 config_margins.bottom = MAX(0, obt_parse_node_int(n));
538 static void parse_theme(xmlNodePtr node, gpointer d)
542 node = node->children;
544 if ((n = obt_parse_find_node(node, "name"))) {
547 g_free(config_theme);
548 c = obt_parse_node_string(n);
549 config_theme = obt_paths_expand_tilde(c);
552 if ((n = obt_parse_find_node(node, "titleLayout"))) {
555 g_free(config_title_layout);
556 config_title_layout = obt_parse_node_string(n);
558 /* replace duplicates with spaces */
559 for (c = config_title_layout; *c != '\0'; ++c)
560 for (d = c+1; *d != '\0'; ++d)
561 if (*c == *d) *d = ' ';
563 if ((n = obt_parse_find_node(node, "keepBorder")))
564 config_theme_keepborder = obt_parse_node_bool(n);
565 if ((n = obt_parse_find_node(node, "animateIconify")))
566 config_animate_iconify = obt_parse_node_bool(n);
568 n = obt_parse_find_node(node, "font");
572 gchar *name = g_strdup(RrDefaultFontFamily);
573 gint size = RrDefaultFontSize;
574 RrFontWeight weight = RrDefaultFontWeight;
575 RrFontSlant slant = RrDefaultFontSlant;
577 if (obt_parse_attr_contains(n, "place", "ActiveWindow"))
578 font = &config_font_activewindow;
579 else if (obt_parse_attr_contains(n, "place", "InactiveWindow"))
580 font = &config_font_inactivewindow;
581 else if (obt_parse_attr_contains(n, "place", "MenuHeader"))
582 font = &config_font_menutitle;
583 else if (obt_parse_attr_contains(n, "place", "MenuItem"))
584 font = &config_font_menuitem;
585 else if (obt_parse_attr_contains(n, "place", "OnScreenDisplay"))
586 font = &config_font_osd;
590 if ((fnode = obt_parse_find_node(n->children, "name"))) {
592 name = obt_parse_node_string(fnode);
594 if ((fnode = obt_parse_find_node(n->children, "size"))) {
595 int s = obt_parse_node_int(fnode);
598 if ((fnode = obt_parse_find_node(n->children, "weight"))) {
599 gchar *w = obt_parse_node_string(fnode);
600 if (!g_ascii_strcasecmp(w, "Bold"))
601 weight = RR_FONTWEIGHT_BOLD;
604 if ((fnode = obt_parse_find_node(n->children, "slant"))) {
605 gchar *s = obt_parse_node_string(fnode);
606 if (!g_ascii_strcasecmp(s, "Italic"))
607 slant = RR_FONTSLANT_ITALIC;
608 if (!g_ascii_strcasecmp(s, "Oblique"))
609 slant = RR_FONTSLANT_OBLIQUE;
613 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
616 n = obt_parse_find_node(n->next, "font");
620 static void parse_desktops(xmlNodePtr node, gpointer d)
624 node = node->children;
626 if ((n = obt_parse_find_node(node, "number"))) {
627 gint d = obt_parse_node_int(n);
629 config_desktops_num = (unsigned) d;
631 if ((n = obt_parse_find_node(node, "firstdesk"))) {
632 gint d = obt_parse_node_int(n);
634 config_screen_firstdesk = (unsigned) d;
636 if ((n = obt_parse_find_node(node, "emulatexinerama")))
637 config_emulate_xinerama = obt_parse_node_bool(n);
638 if ((n = obt_parse_find_node(node, "names"))) {
642 for (it = config_desktops_names; it; it = it->next)
644 g_slist_free(config_desktops_names);
645 config_desktops_names = NULL;
647 nname = obt_parse_find_node(n->children, "name");
649 config_desktops_names =
650 g_slist_append(config_desktops_names,
651 obt_parse_node_string(nname));
652 nname = obt_parse_find_node(nname->next, "name");
655 if ((n = obt_parse_find_node(node, "popupTime")))
656 config_desktop_popup_time = obt_parse_node_int(n);
659 static void parse_resize(xmlNodePtr node, gpointer d)
663 node = node->children;
665 if ((n = obt_parse_find_node(node, "drawContents")))
666 config_resize_redraw = obt_parse_node_bool(n);
667 if ((n = obt_parse_find_node(node, "popupShow"))) {
668 config_resize_popup_show = obt_parse_node_int(n);
669 if (obt_parse_node_contains(n, "Always"))
670 config_resize_popup_show = 2;
671 else if (obt_parse_node_contains(n, "Never"))
672 config_resize_popup_show = 0;
673 else if (obt_parse_node_contains(n, "Nonpixel"))
674 config_resize_popup_show = 1;
676 if ((n = obt_parse_find_node(node, "popupPosition"))) {
677 if (obt_parse_node_contains(n, "Top"))
678 config_resize_popup_pos = OB_RESIZE_POS_TOP;
679 else if (obt_parse_node_contains(n, "Center"))
680 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
681 else if (obt_parse_node_contains(n, "Fixed")) {
682 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
684 if ((n = obt_parse_find_node(node, "popupFixedPosition"))) {
687 if ((n2 = obt_parse_find_node(n->children, "x")))
688 config_parse_gravity_coord(n2,
689 &config_resize_popup_fixed.x);
690 if ((n2 = obt_parse_find_node(n->children, "y")))
691 config_parse_gravity_coord(n2,
692 &config_resize_popup_fixed.y);
694 config_resize_popup_fixed.x.pos =
695 MAX(config_resize_popup_fixed.x.pos, 0);
696 config_resize_popup_fixed.y.pos =
697 MAX(config_resize_popup_fixed.y.pos, 0);
703 static void parse_dock(xmlNodePtr node, gpointer d)
707 node = node->children;
709 if ((n = obt_parse_find_node(node, "position"))) {
710 if (obt_parse_node_contains(n, "TopLeft"))
711 config_dock_floating = FALSE,
712 config_dock_pos = OB_DIRECTION_NORTHWEST;
713 else if (obt_parse_node_contains(n, "Top"))
714 config_dock_floating = FALSE,
715 config_dock_pos = OB_DIRECTION_NORTH;
716 else if (obt_parse_node_contains(n, "TopRight"))
717 config_dock_floating = FALSE,
718 config_dock_pos = OB_DIRECTION_NORTHEAST;
719 else if (obt_parse_node_contains(n, "Right"))
720 config_dock_floating = FALSE,
721 config_dock_pos = OB_DIRECTION_EAST;
722 else if (obt_parse_node_contains(n, "BottomRight"))
723 config_dock_floating = FALSE,
724 config_dock_pos = OB_DIRECTION_SOUTHEAST;
725 else if (obt_parse_node_contains(n, "Bottom"))
726 config_dock_floating = FALSE,
727 config_dock_pos = OB_DIRECTION_SOUTH;
728 else if (obt_parse_node_contains(n, "BottomLeft"))
729 config_dock_floating = FALSE,
730 config_dock_pos = OB_DIRECTION_SOUTHWEST;
731 else if (obt_parse_node_contains(n, "Left"))
732 config_dock_floating = FALSE,
733 config_dock_pos = OB_DIRECTION_WEST;
734 else if (obt_parse_node_contains(n, "Floating"))
735 config_dock_floating = TRUE;
737 if (config_dock_floating) {
738 if ((n = obt_parse_find_node(node, "floatingX")))
739 config_dock_x = obt_parse_node_int(n);
740 if ((n = obt_parse_find_node(node, "floatingY")))
741 config_dock_y = obt_parse_node_int(n);
743 if ((n = obt_parse_find_node(node, "noStrut")))
744 config_dock_nostrut = obt_parse_node_bool(n);
746 if ((n = obt_parse_find_node(node, "stacking"))) {
747 if (obt_parse_node_contains(n, "normal"))
748 config_dock_layer = OB_STACKING_LAYER_NORMAL;
749 else if (obt_parse_node_contains(n, "below"))
750 config_dock_layer = OB_STACKING_LAYER_BELOW;
751 else if (obt_parse_node_contains(n, "above"))
752 config_dock_layer = OB_STACKING_LAYER_ABOVE;
754 if ((n = obt_parse_find_node(node, "direction"))) {
755 if (obt_parse_node_contains(n, "horizontal"))
756 config_dock_orient = OB_ORIENTATION_HORZ;
757 else if (obt_parse_node_contains(n, "vertical"))
758 config_dock_orient = OB_ORIENTATION_VERT;
760 if ((n = obt_parse_find_node(node, "autoHide")))
761 config_dock_hide = obt_parse_node_bool(n);
762 if ((n = obt_parse_find_node(node, "hideDelay")))
763 config_dock_hide_delay = obt_parse_node_int(n);
764 if ((n = obt_parse_find_node(node, "showDelay")))
765 config_dock_show_delay = obt_parse_node_int(n);
766 if ((n = obt_parse_find_node(node, "moveButton"))) {
767 gchar *str = obt_parse_node_string(n);
769 if (translate_button(str, &s, &b)) {
770 config_dock_app_move_button = b;
771 config_dock_app_move_modifiers = s;
773 g_message(_("Invalid button \"%s\" specified in config file"), str);
779 static void parse_menu(xmlNodePtr node, gpointer d)
782 for (node = node->children; node; node = node->next) {
783 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
786 c = obt_parse_node_string(node);
787 config_menu_files = g_slist_append(config_menu_files,
788 obt_paths_expand_tilde(c));
791 if ((n = obt_parse_find_node(node, "hideDelay")))
792 config_menu_hide_delay = obt_parse_node_int(n);
793 if ((n = obt_parse_find_node(node, "middle")))
794 config_menu_middle = obt_parse_node_bool(n);
795 if ((n = obt_parse_find_node(node, "submenuShowDelay")))
796 config_submenu_show_delay = obt_parse_node_int(n);
797 if ((n = obt_parse_find_node(node, "applicationIcons")))
798 config_menu_client_list_icons = obt_parse_node_bool(n);
799 if ((n = obt_parse_find_node(node, "manageDesktops")))
800 config_menu_manage_desktops = obt_parse_node_bool(n);
804 static void parse_resistance(xmlNodePtr node, gpointer d)
808 node = node->children;
809 if ((n = obt_parse_find_node(node, "strength")))
810 config_resist_win = obt_parse_node_int(n);
811 if ((n = obt_parse_find_node(node, "screen_edge_strength")))
812 config_resist_edge = obt_parse_node_int(n);
818 const gchar *actname;
821 static void bind_default_keyboard(void)
824 ObDefKeyBind binds[] = {
825 { "A-Tab", "NextWindow" },
826 { "S-A-Tab", "PreviousWindow" },
830 for (it = binds; it->key; ++it) {
831 GList *l = g_list_append(NULL, g_strdup(it->key));
832 keyboard_bind(l, actions_parse_string(it->actname));
839 const gchar *context;
840 const ObMouseAction mact;
841 const gchar *actname;
844 static void bind_default_mouse(void)
847 ObDefMouseBind binds[] = {
848 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
849 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
850 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
851 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
852 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
853 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
854 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
855 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
856 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
857 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
858 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
859 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
860 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
861 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
862 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
863 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
864 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
865 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
866 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
867 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
868 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
869 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
870 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
871 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
872 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
873 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
874 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
875 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
876 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
877 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
878 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
879 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
880 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
881 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
882 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
883 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
884 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
885 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
886 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
887 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
888 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
889 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
890 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
891 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
892 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
893 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
894 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
895 { NULL, NULL, 0, NULL }
898 for (it = binds; it->button; ++it)
899 mouse_bind(it->button, it->context, it->mact,
900 actions_parse_string(it->actname));
903 void config_startup(ObtParseInst *i)
905 config_focus_new = TRUE;
906 config_focus_follow = FALSE;
907 config_focus_delay = 0;
908 config_focus_raise = FALSE;
909 config_focus_last = TRUE;
910 config_focus_under_mouse = FALSE;
912 obt_parse_register(i, "focus", parse_focus, NULL);
914 config_place_policy = OB_PLACE_POLICY_SMART;
915 config_place_center = TRUE;
916 config_place_monitor = OB_PLACE_MONITOR_ANY;
918 obt_parse_register(i, "placement", parse_placement, NULL);
920 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
922 obt_parse_register(i, "margins", parse_margins, NULL);
926 config_animate_iconify = TRUE;
927 config_title_layout = g_strdup("NLIMC");
928 config_theme_keepborder = TRUE;
930 config_font_activewindow = NULL;
931 config_font_inactivewindow = NULL;
932 config_font_menuitem = NULL;
933 config_font_menutitle = NULL;
935 obt_parse_register(i, "theme", parse_theme, NULL);
937 config_desktops_num = 4;
938 config_screen_firstdesk = 1;
939 config_emulate_xinerama = FALSE;
940 config_desktops_names = NULL;
941 config_desktop_popup_time = 875;
943 obt_parse_register(i, "desktops", parse_desktops, NULL);
945 config_resize_redraw = TRUE;
946 config_resize_popup_show = 1; /* nonpixel increments */
947 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
948 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
949 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
951 obt_parse_register(i, "resize", parse_resize, NULL);
953 config_dock_layer = OB_STACKING_LAYER_ABOVE;
954 config_dock_pos = OB_DIRECTION_NORTHEAST;
955 config_dock_floating = FALSE;
956 config_dock_nostrut = FALSE;
959 config_dock_orient = OB_ORIENTATION_VERT;
960 config_dock_hide = FALSE;
961 config_dock_hide_delay = 300;
962 config_dock_show_delay = 300;
963 config_dock_app_move_button = 2; /* middle */
964 config_dock_app_move_modifiers = 0;
966 obt_parse_register(i, "dock", parse_dock, NULL);
968 translate_key("C-g", &config_keyboard_reset_state,
969 &config_keyboard_reset_keycode);
971 bind_default_keyboard();
973 obt_parse_register(i, "keyboard", parse_keyboard, NULL);
975 config_mouse_threshold = 8;
976 config_mouse_dclicktime = 200;
977 config_mouse_screenedgetime = 400;
979 bind_default_mouse();
981 obt_parse_register(i, "mouse", parse_mouse, NULL);
983 config_resist_win = 10;
984 config_resist_edge = 20;
986 obt_parse_register(i, "resistance", parse_resistance, NULL);
988 config_menu_hide_delay = 250;
989 config_menu_middle = FALSE;
990 config_submenu_show_delay = 0;
991 config_menu_client_list_icons = TRUE;
992 config_menu_manage_desktops = TRUE;
993 config_menu_files = NULL;
995 obt_parse_register(i, "menu", parse_menu, NULL);
997 config_per_app_settings = NULL;
999 obt_parse_register(i, "applications", parse_per_app_settings, NULL);
1002 void config_shutdown(void)
1006 g_free(config_theme);
1008 g_free(config_title_layout);
1010 RrFontClose(config_font_activewindow);
1011 RrFontClose(config_font_inactivewindow);
1012 RrFontClose(config_font_menuitem);
1013 RrFontClose(config_font_menutitle);
1014 RrFontClose(config_font_osd);
1016 for (it = config_desktops_names; it; it = g_slist_next(it))
1018 g_slist_free(config_desktops_names);
1020 for (it = config_menu_files; it; it = g_slist_next(it))
1022 g_slist_free(config_menu_files);
1024 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
1025 ObAppSettings *itd = (ObAppSettings *)it->data;
1026 if (itd->name) g_pattern_spec_free(itd->name);
1027 if (itd->role) g_pattern_spec_free(itd->role);
1028 if (itd->class) g_pattern_spec_free(itd->class);
1031 g_slist_free(config_per_app_settings);