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.
25 #include "translate.h"
28 #include "parser/parse.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
;
39 ObPlacePolicy config_place_policy
;
40 gboolean config_place_center
;
41 gboolean config_place_active
;
43 StrutPartial config_margins
;
46 gboolean config_theme_keepborder
;
48 gchar
*config_title_layout
;
50 gboolean config_animate_iconify
;
52 RrFont
*config_font_activewindow
;
53 RrFont
*config_font_inactivewindow
;
54 RrFont
*config_font_menuitem
;
55 RrFont
*config_font_menutitle
;
56 RrFont
*config_font_osd
;
58 gint config_desktops_num
;
59 GSList
*config_desktops_names
;
60 guint config_screen_firstdesk
;
61 guint config_desktop_popup_time
;
63 gboolean config_resize_redraw
;
64 gboolean config_resize_four_corners
;
65 gint config_resize_popup_show
;
66 ObResizePopupPos config_resize_popup_pos
;
67 GravityPoint config_resize_popup_fixed
;
69 ObStackingLayer config_dock_layer
;
70 gboolean config_dock_floating
;
71 gboolean config_dock_nostrut
;
72 ObDirection config_dock_pos
;
75 ObOrientation config_dock_orient
;
76 gboolean config_dock_hide
;
77 guint config_dock_hide_delay
;
78 guint config_dock_show_delay
;
79 guint config_dock_app_move_button
;
80 guint config_dock_app_move_modifiers
;
82 guint config_keyboard_reset_keycode
;
83 guint config_keyboard_reset_state
;
85 gint config_mouse_threshold
;
86 gint config_mouse_dclicktime
;
87 gint config_mouse_screenedgetime
;
89 guint config_menu_hide_delay
;
90 gboolean config_menu_middle
;
91 guint config_submenu_show_delay
;
92 gboolean config_menu_client_list_icons
;
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);
104 settings
->decor
= -1;
105 settings
->shade
= -1;
106 settings
->monitor
= -1;
107 settings
->focus
= -1;
108 settings
->desktop
= 0;
109 settings
->layer
= -2;
110 settings
->iconic
= -1;
111 settings
->skip_pager
= -1;
112 settings
->skip_taskbar
= -1;
113 settings
->fullscreen
= -1;
114 settings
->max_horz
= -1;
115 settings
->max_vert
= -1;
119 #define copy_if(setting, default) \
120 if (src->setting != default) dst->setting = src->setting
121 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
124 g_assert(src
!= NULL
);
125 g_assert(dst
!= NULL
);
133 copy_if(skip_pager
, -1);
134 copy_if(skip_taskbar
, -1);
135 copy_if(fullscreen
, -1);
136 copy_if(max_horz
, -1);
137 copy_if(max_vert
, -1);
139 if (src
->pos_given
) {
140 dst
->pos_given
= TRUE
;
141 dst
->position
= src
->position
;
142 dst
->monitor
= src
->monitor
;
146 static void config_parse_gravity_coord(xmlDocPtr doc
, xmlNodePtr node
,
149 gchar
*s
= parse_string(doc
, node
);
150 if (!g_ascii_strcasecmp(s
, "center"))
155 if (s
[0] == '-' || s
[0] == '+')
165 <application name="aterm">
168 <application name="Rhythmbox">
175 .. there is a lot more settings available
180 /* Manages settings for individual applications.
181 Some notes: monitor is the screen number in a multi monitor
182 (Xinerama) setup (starting from 0) or mouse, meaning the
183 monitor the pointer is on. Default: mouse.
184 Layer can be three values, above (Always on top), below
185 (Always on bottom) and everything else (normal behaviour).
186 Positions can be an integer value or center, which will
187 center the window in the specified axis. Position is within
188 the monitor, so <position><x>center</x></position><monitor>2</monitor>
189 will center the window on the second monitor.
191 static void parse_per_app_settings(ObParseInst
*inst
, xmlDocPtr doc
,
192 xmlNodePtr node
, gpointer data
)
194 xmlNodePtr app
= parse_find_node("application", node
->children
);
195 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
196 gboolean name_set
, class_set
;
197 gboolean x_pos_given
;
200 name_set
= class_set
= x_pos_given
= FALSE
;
202 class_set
= parse_attr_string("class", app
, &class);
203 name_set
= parse_attr_string("name", app
, &name
);
204 if (class_set
|| name_set
) {
206 ObAppSettings
*settings
= config_create_app_settings();;
209 settings
->name
= g_pattern_spec_new(name
);
212 settings
->class = g_pattern_spec_new(class);
214 if (parse_attr_string("role", app
, &role
))
215 settings
->role
= g_pattern_spec_new(role
);
217 if ((n
= parse_find_node("decor", app
->children
)))
218 if (!parse_contains("default", doc
, n
))
219 settings
->decor
= parse_bool(doc
, n
);
221 if ((n
= parse_find_node("shade", app
->children
)))
222 if (!parse_contains("default", doc
, n
))
223 settings
->shade
= parse_bool(doc
, n
);
225 if ((n
= parse_find_node("position", app
->children
))) {
226 if ((c
= parse_find_node("x", n
->children
)))
227 if (!parse_contains("default", doc
, c
)) {
228 config_parse_gravity_coord(doc
, c
,
229 &settings
->position
.x
);
233 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
234 if (!parse_contains("default", doc
, c
)) {
235 config_parse_gravity_coord(doc
, c
,
236 &settings
->position
.y
);
237 settings
->pos_given
= TRUE
;
240 if (settings
->pos_given
&&
241 (c
= parse_find_node("monitor", n
->children
)))
242 if (!parse_contains("default", doc
, c
)) {
243 gchar
*s
= parse_string(doc
, c
);
244 if (!g_ascii_strcasecmp(s
, "mouse"))
245 settings
->monitor
= 0;
247 settings
->monitor
= parse_int(doc
, c
) + 1;
252 if ((n
= parse_find_node("focus", app
->children
)))
253 if (!parse_contains("default", doc
, n
))
254 settings
->focus
= parse_bool(doc
, n
);
256 if ((n
= parse_find_node("desktop", app
->children
))) {
257 if (!parse_contains("default", doc
, n
)) {
258 gchar
*s
= parse_string(doc
, n
);
259 if (!g_ascii_strcasecmp(s
, "all"))
260 settings
->desktop
= DESKTOP_ALL
;
262 gint i
= parse_int(doc
, n
);
264 settings
->desktop
= i
;
270 if ((n
= parse_find_node("layer", app
->children
)))
271 if (!parse_contains("default", doc
, n
)) {
272 gchar
*s
= parse_string(doc
, n
);
273 if (!g_ascii_strcasecmp(s
, "above"))
275 else if (!g_ascii_strcasecmp(s
, "below"))
276 settings
->layer
= -1;
282 if ((n
= parse_find_node("iconic", app
->children
)))
283 if (!parse_contains("default", doc
, n
))
284 settings
->iconic
= parse_bool(doc
, n
);
286 if ((n
= parse_find_node("skip_pager", app
->children
)))
287 if (!parse_contains("default", doc
, n
))
288 settings
->skip_pager
= parse_bool(doc
, n
);
290 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
291 if (!parse_contains("default", doc
, n
))
292 settings
->skip_taskbar
= parse_bool(doc
, n
);
294 if ((n
= parse_find_node("fullscreen", app
->children
)))
295 if (!parse_contains("default", doc
, n
))
296 settings
->fullscreen
= parse_bool(doc
, n
);
298 if ((n
= parse_find_node("maximized", app
->children
)))
299 if (!parse_contains("default", doc
, n
)) {
300 gchar
*s
= parse_string(doc
, n
);
301 if (!g_ascii_strcasecmp(s
, "horizontal")) {
302 settings
->max_horz
= TRUE
;
303 settings
->max_vert
= FALSE
;
304 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
305 settings
->max_horz
= FALSE
;
306 settings
->max_vert
= TRUE
;
308 settings
->max_horz
= settings
->max_vert
=
313 config_per_app_settings
= g_slist_append(config_per_app_settings
,
314 (gpointer
) settings
);
318 name
= class = role
= NULL
;
321 app
= parse_find_node("application", app
->next
);
328 <action name="ChangeDesktop">
335 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
340 gboolean is_chroot
= FALSE
;
342 if (!parse_attr_string("key", node
, &key
))
345 parse_attr_bool("chroot", node
, &is_chroot
);
347 keylist
= g_list_append(keylist
, key
);
349 if ((n
= parse_find_node("keybind", node
->children
))) {
351 parse_key(i
, doc
, n
, keylist
);
352 n
= parse_find_node("keybind", n
->next
);
355 else if ((n
= parse_find_node("action", node
->children
))) {
357 ObActionsAct
*action
;
359 action
= actions_parse(i
, doc
, n
);
361 keyboard_bind(keylist
, action
);
362 n
= parse_find_node("action", n
->next
);
367 keyboard_chroot(keylist
);
370 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
373 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
379 keyboard_unbind_all();
381 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
382 key
= parse_string(doc
, n
);
383 translate_key(key
, &config_keyboard_reset_state
,
384 &config_keyboard_reset_keycode
);
388 if ((n
= parse_find_node("keybind", node
->children
)))
390 parse_key(i
, doc
, n
, NULL
);
391 n
= parse_find_node("keybind", n
->next
);
397 <context name="Titlebar">
398 <mousebind button="Left" action="Press">
399 <action name="Raise"></action>
405 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
408 xmlNodePtr n
, nbut
, nact
;
415 node
= node
->children
;
417 if ((n
= parse_find_node("dragThreshold", node
)))
418 config_mouse_threshold
= parse_int(doc
, n
);
419 if ((n
= parse_find_node("doubleClickTime", node
)))
420 config_mouse_dclicktime
= parse_int(doc
, n
);
421 if ((n
= parse_find_node("screenEdgeWarpTime", node
)))
422 config_mouse_screenedgetime
= parse_int(doc
, n
);
424 n
= parse_find_node("context", node
);
426 if (!parse_attr_string("name", n
, &contextstr
))
428 nbut
= parse_find_node("mousebind", n
->children
);
430 if (!parse_attr_string("button", nbut
, &buttonstr
))
432 if (parse_attr_contains("press", nbut
, "action")) {
433 mact
= OB_MOUSE_ACTION_PRESS
;
434 } else if (parse_attr_contains("release", nbut
, "action")) {
435 mact
= OB_MOUSE_ACTION_RELEASE
;
436 } else if (parse_attr_contains("click", nbut
, "action")) {
437 mact
= OB_MOUSE_ACTION_CLICK
;
438 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
439 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
440 } else if (parse_attr_contains("drag", nbut
, "action")) {
441 mact
= OB_MOUSE_ACTION_MOTION
;
444 nact
= parse_find_node("action", nbut
->children
);
446 ObActionsAct
*action
;
448 if ((action
= actions_parse(i
, doc
, nact
)))
449 mouse_bind(buttonstr
, contextstr
, mact
, action
);
450 nact
= parse_find_node("action", nact
->next
);
454 nbut
= parse_find_node("mousebind", nbut
->next
);
458 n
= parse_find_node("context", n
->next
);
462 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
467 node
= node
->children
;
469 if ((n
= parse_find_node("focusNew", node
)))
470 config_focus_new
= parse_bool(doc
, n
);
471 if ((n
= parse_find_node("followMouse", node
)))
472 config_focus_follow
= parse_bool(doc
, n
);
473 if ((n
= parse_find_node("focusDelay", node
)))
474 config_focus_delay
= parse_int(doc
, n
);
475 if ((n
= parse_find_node("raiseOnFocus", node
)))
476 config_focus_raise
= parse_bool(doc
, n
);
477 if ((n
= parse_find_node("focusLast", node
)))
478 config_focus_last
= parse_bool(doc
, n
);
479 if ((n
= parse_find_node("underMouse", node
)))
480 config_focus_under_mouse
= parse_bool(doc
, n
);
483 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
488 node
= node
->children
;
490 if ((n
= parse_find_node("policy", node
)))
491 if (parse_contains("UnderMouse", doc
, n
))
492 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
493 if ((n
= parse_find_node("center", node
)))
494 config_place_center
= parse_bool(doc
, n
);
495 if ((n
= parse_find_node("active", node
)))
496 config_place_active
= parse_bool(doc
, n
);
499 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
504 node
= node
->children
;
506 if ((n
= parse_find_node("top", node
)))
507 config_margins
.top
= MAX(0, parse_int(doc
, n
));
508 if ((n
= parse_find_node("left", node
)))
509 config_margins
.left
= MAX(0, parse_int(doc
, n
));
510 if ((n
= parse_find_node("right", node
)))
511 config_margins
.right
= MAX(0, parse_int(doc
, n
));
512 if ((n
= parse_find_node("bottom", node
)))
513 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
516 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
521 node
= node
->children
;
523 if ((n
= parse_find_node("name", node
))) {
526 g_free(config_theme
);
527 c
= parse_string(doc
, n
);
528 config_theme
= parse_expand_tilde(c
);
531 if ((n
= parse_find_node("titleLayout", node
))) {
534 g_free(config_title_layout
);
535 config_title_layout
= parse_string(doc
, n
);
537 /* replace duplicates with spaces */
538 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
539 for (d
= c
+1; *d
!= '\0'; ++d
)
540 if (*c
== *d
) *d
= ' ';
542 if ((n
= parse_find_node("keepBorder", node
)))
543 config_theme_keepborder
= parse_bool(doc
, n
);
544 if ((n
= parse_find_node("animateIconify", node
)))
545 config_animate_iconify
= parse_bool(doc
, n
);
547 n
= parse_find_node("font", node
);
551 gchar
*name
= g_strdup(RrDefaultFontFamily
);
552 gint size
= RrDefaultFontSize
;
553 RrFontWeight weight
= RrDefaultFontWeight
;
554 RrFontSlant slant
= RrDefaultFontSlant
;
556 if (parse_attr_contains("ActiveWindow", n
, "place"))
557 font
= &config_font_activewindow
;
558 else if (parse_attr_contains("InactiveWindow", n
, "place"))
559 font
= &config_font_inactivewindow
;
560 else if (parse_attr_contains("MenuHeader", n
, "place"))
561 font
= &config_font_menutitle
;
562 else if (parse_attr_contains("MenuItem", n
, "place"))
563 font
= &config_font_menuitem
;
564 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
565 font
= &config_font_osd
;
569 if ((fnode
= parse_find_node("name", n
->children
))) {
571 name
= parse_string(doc
, fnode
);
573 if ((fnode
= parse_find_node("size", n
->children
))) {
574 int s
= parse_int(doc
, fnode
);
577 if ((fnode
= parse_find_node("weight", n
->children
))) {
578 gchar
*w
= parse_string(doc
, fnode
);
579 if (!g_ascii_strcasecmp(w
, "Bold"))
580 weight
= RR_FONTWEIGHT_BOLD
;
583 if ((fnode
= parse_find_node("slant", n
->children
))) {
584 gchar
*s
= parse_string(doc
, fnode
);
585 if (!g_ascii_strcasecmp(s
, "Italic"))
586 slant
= RR_FONTSLANT_ITALIC
;
587 if (!g_ascii_strcasecmp(s
, "Oblique"))
588 slant
= RR_FONTSLANT_OBLIQUE
;
592 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
595 n
= parse_find_node("font", n
->next
);
599 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
604 node
= node
->children
;
606 if ((n
= parse_find_node("number", node
))) {
607 gint d
= parse_int(doc
, n
);
609 config_desktops_num
= d
;
611 if ((n
= parse_find_node("firstdesk", node
))) {
612 gint d
= parse_int(doc
, n
);
614 config_screen_firstdesk
= (unsigned) d
;
616 if ((n
= parse_find_node("names", node
))) {
620 for (it
= config_desktops_names
; it
; it
= it
->next
)
622 g_slist_free(config_desktops_names
);
623 config_desktops_names
= NULL
;
625 nname
= parse_find_node("name", n
->children
);
627 config_desktops_names
= g_slist_append(config_desktops_names
,
628 parse_string(doc
, nname
));
629 nname
= parse_find_node("name", nname
->next
);
632 if ((n
= parse_find_node("popupTime", node
)))
633 config_desktop_popup_time
= parse_int(doc
, n
);
636 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
641 node
= node
->children
;
643 if ((n
= parse_find_node("drawContents", node
)))
644 config_resize_redraw
= parse_bool(doc
, n
);
645 if ((n
= parse_find_node("popupShow", node
))) {
646 config_resize_popup_show
= parse_int(doc
, n
);
647 if (parse_contains("Always", doc
, n
))
648 config_resize_popup_show
= 2;
649 else if (parse_contains("Never", doc
, n
))
650 config_resize_popup_show
= 0;
651 else if (parse_contains("Nonpixel", doc
, n
))
652 config_resize_popup_show
= 1;
654 if ((n
= parse_find_node("popupPosition", node
))) {
655 if (parse_contains("Top", doc
, n
))
656 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
657 else if (parse_contains("Center", doc
, n
))
658 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
659 else if (parse_contains("Fixed", doc
, n
)) {
660 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
662 if ((n
= parse_find_node("popupFixedPosition", node
))) {
665 if ((n2
= parse_find_node("x", n
->children
)))
666 config_parse_gravity_coord(doc
, n2
,
667 &config_resize_popup_fixed
.x
);
668 if ((n2
= parse_find_node("y", n
->children
)))
669 config_parse_gravity_coord(doc
, n2
,
670 &config_resize_popup_fixed
.y
);
676 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
681 node
= node
->children
;
683 if ((n
= parse_find_node("position", node
))) {
684 if (parse_contains("TopLeft", doc
, n
))
685 config_dock_floating
= FALSE
,
686 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
687 else if (parse_contains("Top", doc
, n
))
688 config_dock_floating
= FALSE
,
689 config_dock_pos
= OB_DIRECTION_NORTH
;
690 else if (parse_contains("TopRight", doc
, n
))
691 config_dock_floating
= FALSE
,
692 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
693 else if (parse_contains("Right", doc
, n
))
694 config_dock_floating
= FALSE
,
695 config_dock_pos
= OB_DIRECTION_EAST
;
696 else if (parse_contains("BottomRight", doc
, n
))
697 config_dock_floating
= FALSE
,
698 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
699 else if (parse_contains("Bottom", doc
, n
))
700 config_dock_floating
= FALSE
,
701 config_dock_pos
= OB_DIRECTION_SOUTH
;
702 else if (parse_contains("BottomLeft", doc
, n
))
703 config_dock_floating
= FALSE
,
704 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
705 else if (parse_contains("Left", doc
, n
))
706 config_dock_floating
= FALSE
,
707 config_dock_pos
= OB_DIRECTION_WEST
;
708 else if (parse_contains("Floating", doc
, n
))
709 config_dock_floating
= TRUE
;
711 if (config_dock_floating
) {
712 if ((n
= parse_find_node("floatingX", node
)))
713 config_dock_x
= parse_int(doc
, n
);
714 if ((n
= parse_find_node("floatingY", node
)))
715 config_dock_y
= parse_int(doc
, n
);
717 if ((n
= parse_find_node("noStrut", node
)))
718 config_dock_nostrut
= parse_bool(doc
, n
);
720 if ((n
= parse_find_node("stacking", node
))) {
721 if (parse_contains("above", doc
, n
))
722 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
723 else if (parse_contains("normal", doc
, n
))
724 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
725 else if (parse_contains("below", doc
, n
))
726 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
728 if ((n
= parse_find_node("direction", node
))) {
729 if (parse_contains("horizontal", doc
, n
))
730 config_dock_orient
= OB_ORIENTATION_HORZ
;
731 else if (parse_contains("vertical", doc
, n
))
732 config_dock_orient
= OB_ORIENTATION_VERT
;
734 if ((n
= parse_find_node("autoHide", node
)))
735 config_dock_hide
= parse_bool(doc
, n
);
736 if ((n
= parse_find_node("hideDelay", node
)))
737 config_dock_hide_delay
= parse_int(doc
, n
);
738 if ((n
= parse_find_node("showDelay", node
)))
739 config_dock_show_delay
= parse_int(doc
, n
);
740 if ((n
= parse_find_node("moveButton", node
))) {
741 gchar
*str
= parse_string(doc
, n
);
743 if (translate_button(str
, &s
, &b
)) {
744 config_dock_app_move_button
= b
;
745 config_dock_app_move_modifiers
= s
;
747 g_message(_("Invalid button '%s' specified in config file"), str
);
753 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
757 for (node
= node
->children
; node
; node
= node
->next
) {
758 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
761 c
= parse_string(doc
, node
);
762 config_menu_files
= g_slist_append(config_menu_files
,
763 parse_expand_tilde(c
));
766 if ((n
= parse_find_node("hideDelay", node
)))
767 config_menu_hide_delay
= parse_int(doc
, n
);
768 if ((n
= parse_find_node("middle", node
)))
769 config_menu_middle
= parse_bool(doc
, n
);
770 if ((n
= parse_find_node("submenuShowDelay", node
)))
771 config_submenu_show_delay
= parse_int(doc
, n
);
772 if ((n
= parse_find_node("applicationIcons", node
)))
773 config_menu_client_list_icons
= parse_bool(doc
, n
);
777 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
782 node
= node
->children
;
783 if ((n
= parse_find_node("strength", node
)))
784 config_resist_win
= parse_int(doc
, n
);
785 if ((n
= parse_find_node("screen_edge_strength", node
)))
786 config_resist_edge
= parse_int(doc
, n
);
792 const gchar
*actname
;
795 static void bind_default_keyboard(void)
798 ObDefKeyBind binds
[] = {
799 { "A-Tab", "NextWindow" },
800 { "S-A-Tab", "PreviousWindow" },
804 for (it
= binds
; it
->key
; ++it
) {
805 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
806 keyboard_bind(l
, actions_parse_string(it
->actname
));
813 const gchar
*context
;
814 const ObMouseAction mact
;
815 const gchar
*actname
;
818 static void bind_default_mouse(void)
821 ObDefMouseBind binds
[] = {
822 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
823 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
824 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
825 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
826 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
827 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
828 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
829 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
830 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
831 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
832 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
833 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
834 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
835 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
836 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
837 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
838 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
839 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
840 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
841 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
842 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
843 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
844 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
845 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
846 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
847 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
848 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
849 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
850 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
851 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
852 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
853 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
854 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
855 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
856 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
857 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
858 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
859 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
860 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
861 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
862 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
863 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
864 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
865 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
866 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
867 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
868 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
869 { NULL
, NULL
, 0, NULL
}
872 for (it
= binds
; it
->button
; ++it
)
873 mouse_bind(it
->button
, it
->context
, it
->mact
,
874 actions_parse_string(it
->actname
));
877 void config_startup(ObParseInst
*i
)
879 config_focus_new
= TRUE
;
880 config_focus_follow
= FALSE
;
881 config_focus_delay
= 0;
882 config_focus_raise
= FALSE
;
883 config_focus_last
= TRUE
;
884 config_focus_under_mouse
= FALSE
;
886 parse_register(i
, "focus", parse_focus
, NULL
);
888 config_place_policy
= OB_PLACE_POLICY_SMART
;
889 config_place_center
= TRUE
;
890 config_place_active
= FALSE
;
892 parse_register(i
, "placement", parse_placement
, NULL
);
894 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
896 parse_register(i
, "margins", parse_margins
, NULL
);
900 config_animate_iconify
= TRUE
;
901 config_title_layout
= g_strdup("NLIMC");
902 config_theme_keepborder
= TRUE
;
904 config_font_activewindow
= NULL
;
905 config_font_inactivewindow
= NULL
;
906 config_font_menuitem
= NULL
;
907 config_font_menutitle
= NULL
;
909 parse_register(i
, "theme", parse_theme
, NULL
);
911 config_desktops_num
= 4;
912 config_screen_firstdesk
= 1;
913 config_desktops_names
= NULL
;
914 config_desktop_popup_time
= 875;
916 parse_register(i
, "desktops", parse_desktops
, NULL
);
918 config_resize_redraw
= TRUE
;
919 config_resize_four_corners
= FALSE
;
920 config_resize_popup_show
= 1; /* nonpixel increments */
921 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
922 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
923 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
925 parse_register(i
, "resize", parse_resize
, NULL
);
927 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
928 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
929 config_dock_floating
= FALSE
;
930 config_dock_nostrut
= FALSE
;
933 config_dock_orient
= OB_ORIENTATION_VERT
;
934 config_dock_hide
= FALSE
;
935 config_dock_hide_delay
= 300;
936 config_dock_show_delay
= 300;
937 config_dock_app_move_button
= 2; /* middle */
938 config_dock_app_move_modifiers
= 0;
940 parse_register(i
, "dock", parse_dock
, NULL
);
942 translate_key("C-g", &config_keyboard_reset_state
,
943 &config_keyboard_reset_keycode
);
945 bind_default_keyboard();
947 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
949 config_mouse_threshold
= 8;
950 config_mouse_dclicktime
= 200;
951 config_mouse_screenedgetime
= 400;
953 bind_default_mouse();
955 parse_register(i
, "mouse", parse_mouse
, NULL
);
957 config_resist_win
= 10;
958 config_resist_edge
= 20;
960 parse_register(i
, "resistance", parse_resistance
, NULL
);
962 config_menu_hide_delay
= 250;
963 config_menu_middle
= FALSE
;
964 config_submenu_show_delay
= 0;
965 config_menu_client_list_icons
= TRUE
;
966 config_menu_files
= NULL
;
968 parse_register(i
, "menu", parse_menu
, NULL
);
970 config_per_app_settings
= NULL
;
972 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
975 void config_shutdown(void)
979 g_free(config_theme
);
981 g_free(config_title_layout
);
983 RrFontClose(config_font_activewindow
);
984 RrFontClose(config_font_inactivewindow
);
985 RrFontClose(config_font_menuitem
);
986 RrFontClose(config_font_menutitle
);
988 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
990 g_slist_free(config_desktops_names
);
992 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
994 g_slist_free(config_menu_files
);
996 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
997 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
998 if (itd
->name
) g_pattern_spec_free(itd
->name
);
999 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1000 if (itd
->class) g_pattern_spec_free(itd
->class);
1003 g_slist_free(config_per_app_settings
);