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 guint 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 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
;
93 GSList
*config_menu_files
;
95 gint config_resist_win
;
96 gint config_resist_edge
;
98 GSList
*config_per_app_settings
;
100 ObAppSettings
* config_create_app_settings(void)
102 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
103 settings
->decor
= -1;
104 settings
->shade
= -1;
105 settings
->monitor
= -1;
106 settings
->focus
= -1;
107 settings
->desktop
= 0;
108 settings
->layer
= -2;
109 settings
->iconic
= -1;
110 settings
->skip_pager
= -1;
111 settings
->skip_taskbar
= -1;
112 settings
->fullscreen
= -1;
113 settings
->max_horz
= -1;
114 settings
->max_vert
= -1;
118 #define copy_if(setting, default) \
119 if (src->setting != default) dst->setting = src->setting
120 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
123 g_assert(src
!= NULL
);
124 g_assert(dst
!= NULL
);
132 copy_if(skip_pager
, -1);
133 copy_if(skip_taskbar
, -1);
134 copy_if(fullscreen
, -1);
135 copy_if(max_horz
, -1);
136 copy_if(max_vert
, -1);
138 if (src
->pos_given
) {
139 dst
->pos_given
= TRUE
;
140 dst
->position
= src
->position
;
141 dst
->monitor
= src
->monitor
;
145 static void config_parse_gravity_coord(xmlDocPtr doc
, xmlNodePtr node
,
148 gchar
*s
= parse_string(doc
, node
);
149 if (!g_ascii_strcasecmp(s
, "center"))
154 if (s
[0] == '-' || s
[0] == '+')
164 <application name="aterm">
167 <application name="Rhythmbox">
174 .. there is a lot more settings available
179 /* Manages settings for individual applications.
180 Some notes: monitor is the screen number in a multi monitor
181 (Xinerama) setup (starting from 0) or mouse, meaning the
182 monitor the pointer is on. Default: mouse.
183 Layer can be three values, above (Always on top), below
184 (Always on bottom) and everything else (normal behaviour).
185 Positions can be an integer value or center, which will
186 center the window in the specified axis. Position is within
187 the monitor, so <position><x>center</x></position><monitor>2</monitor>
188 will center the window on the second monitor.
190 static void parse_per_app_settings(ObParseInst
*inst
, xmlDocPtr doc
,
191 xmlNodePtr node
, gpointer data
)
193 xmlNodePtr app
= parse_find_node("application", node
->children
);
194 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
195 gboolean name_set
, class_set
;
196 gboolean x_pos_given
;
199 name_set
= class_set
= x_pos_given
= FALSE
;
201 class_set
= parse_attr_string("class", app
, &class);
202 name_set
= parse_attr_string("name", app
, &name
);
203 if (class_set
|| name_set
) {
205 ObAppSettings
*settings
= config_create_app_settings();;
208 settings
->name
= g_pattern_spec_new(name
);
211 settings
->class = g_pattern_spec_new(class);
213 if (parse_attr_string("role", app
, &role
))
214 settings
->role
= g_pattern_spec_new(role
);
216 if ((n
= parse_find_node("decor", app
->children
)))
217 if (!parse_contains("default", doc
, n
))
218 settings
->decor
= parse_bool(doc
, n
);
220 if ((n
= parse_find_node("shade", app
->children
)))
221 if (!parse_contains("default", doc
, n
))
222 settings
->shade
= parse_bool(doc
, n
);
224 if ((n
= parse_find_node("position", app
->children
))) {
225 if ((c
= parse_find_node("x", n
->children
)))
226 if (!parse_contains("default", doc
, c
)) {
227 config_parse_gravity_coord(doc
, c
,
228 &settings
->position
.x
);
232 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
233 if (!parse_contains("default", doc
, c
)) {
234 config_parse_gravity_coord(doc
, c
,
235 &settings
->position
.y
);
236 settings
->pos_given
= TRUE
;
239 if (settings
->pos_given
&&
240 (c
= parse_find_node("monitor", n
->children
)))
241 if (!parse_contains("default", doc
, c
)) {
242 gchar
*s
= parse_string(doc
, c
);
243 if (!g_ascii_strcasecmp(s
, "mouse"))
244 settings
->monitor
= 0;
246 settings
->monitor
= parse_int(doc
, c
) + 1;
251 if ((n
= parse_find_node("focus", app
->children
)))
252 if (!parse_contains("default", doc
, n
))
253 settings
->focus
= parse_bool(doc
, n
);
255 if ((n
= parse_find_node("desktop", app
->children
))) {
256 if (!parse_contains("default", doc
, n
)) {
257 gchar
*s
= parse_string(doc
, n
);
258 if (!g_ascii_strcasecmp(s
, "all"))
259 settings
->desktop
= DESKTOP_ALL
;
261 gint i
= parse_int(doc
, n
);
263 settings
->desktop
= i
;
269 if ((n
= parse_find_node("layer", app
->children
)))
270 if (!parse_contains("default", doc
, n
)) {
271 gchar
*s
= parse_string(doc
, n
);
272 if (!g_ascii_strcasecmp(s
, "above"))
274 else if (!g_ascii_strcasecmp(s
, "below"))
275 settings
->layer
= -1;
281 if ((n
= parse_find_node("iconic", app
->children
)))
282 if (!parse_contains("default", doc
, n
))
283 settings
->iconic
= parse_bool(doc
, n
);
285 if ((n
= parse_find_node("skip_pager", app
->children
)))
286 if (!parse_contains("default", doc
, n
))
287 settings
->skip_pager
= parse_bool(doc
, n
);
289 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
290 if (!parse_contains("default", doc
, n
))
291 settings
->skip_taskbar
= parse_bool(doc
, n
);
293 if ((n
= parse_find_node("fullscreen", app
->children
)))
294 if (!parse_contains("default", doc
, n
))
295 settings
->fullscreen
= parse_bool(doc
, n
);
297 if ((n
= parse_find_node("maximized", app
->children
)))
298 if (!parse_contains("default", doc
, n
)) {
299 gchar
*s
= parse_string(doc
, n
);
300 if (!g_ascii_strcasecmp(s
, "horizontal")) {
301 settings
->max_horz
= TRUE
;
302 settings
->max_vert
= FALSE
;
303 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
304 settings
->max_horz
= FALSE
;
305 settings
->max_vert
= TRUE
;
307 settings
->max_horz
= settings
->max_vert
=
312 config_per_app_settings
= g_slist_append(config_per_app_settings
,
313 (gpointer
) settings
);
317 name
= class = role
= NULL
;
320 app
= parse_find_node("application", app
->next
);
327 <action name="ChangeDesktop">
334 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
339 gboolean is_chroot
= FALSE
;
341 if (!parse_attr_string("key", node
, &key
))
344 parse_attr_bool("chroot", node
, &is_chroot
);
346 keylist
= g_list_append(keylist
, key
);
348 if ((n
= parse_find_node("keybind", node
->children
))) {
350 parse_key(i
, doc
, n
, keylist
);
351 n
= parse_find_node("keybind", n
->next
);
354 else if ((n
= parse_find_node("action", node
->children
))) {
356 ObActionsAct
*action
;
358 action
= actions_parse(i
, doc
, n
);
360 keyboard_bind(keylist
, action
);
361 n
= parse_find_node("action", n
->next
);
366 keyboard_chroot(keylist
);
369 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
372 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
378 keyboard_unbind_all();
380 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
381 key
= parse_string(doc
, n
);
382 translate_key(key
, &config_keyboard_reset_state
,
383 &config_keyboard_reset_keycode
);
387 if ((n
= parse_find_node("keybind", node
->children
)))
389 parse_key(i
, doc
, n
, NULL
);
390 n
= parse_find_node("keybind", n
->next
);
396 <context name="Titlebar">
397 <mousebind button="Left" action="Press">
398 <action name="Raise"></action>
404 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
407 xmlNodePtr n
, nbut
, nact
;
414 node
= node
->children
;
416 if ((n
= parse_find_node("dragThreshold", node
)))
417 config_mouse_threshold
= parse_int(doc
, n
);
418 if ((n
= parse_find_node("doubleClickTime", node
)))
419 config_mouse_dclicktime
= parse_int(doc
, n
);
420 if ((n
= parse_find_node("screenEdgeWarpTime", node
)))
421 config_mouse_screenedgetime
= parse_int(doc
, n
);
423 n
= parse_find_node("context", node
);
425 if (!parse_attr_string("name", n
, &contextstr
))
427 nbut
= parse_find_node("mousebind", n
->children
);
429 if (!parse_attr_string("button", nbut
, &buttonstr
))
431 if (parse_attr_contains("press", nbut
, "action")) {
432 mact
= OB_MOUSE_ACTION_PRESS
;
433 } else if (parse_attr_contains("release", nbut
, "action")) {
434 mact
= OB_MOUSE_ACTION_RELEASE
;
435 } else if (parse_attr_contains("click", nbut
, "action")) {
436 mact
= OB_MOUSE_ACTION_CLICK
;
437 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
438 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
439 } else if (parse_attr_contains("drag", nbut
, "action")) {
440 mact
= OB_MOUSE_ACTION_MOTION
;
443 nact
= parse_find_node("action", nbut
->children
);
445 ObActionsAct
*action
;
447 if ((action
= actions_parse(i
, doc
, nact
)))
448 mouse_bind(buttonstr
, contextstr
, mact
, action
);
449 nact
= parse_find_node("action", nact
->next
);
453 nbut
= parse_find_node("mousebind", nbut
->next
);
457 n
= parse_find_node("context", n
->next
);
461 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
466 node
= node
->children
;
468 if ((n
= parse_find_node("focusNew", node
)))
469 config_focus_new
= parse_bool(doc
, n
);
470 if ((n
= parse_find_node("followMouse", node
)))
471 config_focus_follow
= parse_bool(doc
, n
);
472 if ((n
= parse_find_node("focusDelay", node
)))
473 config_focus_delay
= parse_int(doc
, n
);
474 if ((n
= parse_find_node("raiseOnFocus", node
)))
475 config_focus_raise
= parse_bool(doc
, n
);
476 if ((n
= parse_find_node("focusLast", node
)))
477 config_focus_last
= parse_bool(doc
, n
);
478 if ((n
= parse_find_node("underMouse", node
)))
479 config_focus_under_mouse
= parse_bool(doc
, n
);
482 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
487 node
= node
->children
;
489 if ((n
= parse_find_node("policy", node
)))
490 if (parse_contains("UnderMouse", doc
, n
))
491 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
492 if ((n
= parse_find_node("center", node
)))
493 config_place_center
= parse_bool(doc
, n
);
494 if ((n
= parse_find_node("active", node
)))
495 config_place_active
= parse_bool(doc
, n
);
498 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
503 node
= node
->children
;
505 if ((n
= parse_find_node("top", node
)))
506 config_margins
.top
= MAX(0, parse_int(doc
, n
));
507 if ((n
= parse_find_node("left", node
)))
508 config_margins
.left
= MAX(0, parse_int(doc
, n
));
509 if ((n
= parse_find_node("right", node
)))
510 config_margins
.right
= MAX(0, parse_int(doc
, n
));
511 if ((n
= parse_find_node("bottom", node
)))
512 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
515 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
520 node
= node
->children
;
522 if ((n
= parse_find_node("name", node
))) {
525 g_free(config_theme
);
526 c
= parse_string(doc
, n
);
527 config_theme
= parse_expand_tilde(c
);
530 if ((n
= parse_find_node("titleLayout", node
))) {
533 g_free(config_title_layout
);
534 config_title_layout
= parse_string(doc
, n
);
536 /* replace duplicates with spaces */
537 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
538 for (d
= c
+1; *d
!= '\0'; ++d
)
539 if (*c
== *d
) *d
= ' ';
541 if ((n
= parse_find_node("keepBorder", node
)))
542 config_theme_keepborder
= parse_bool(doc
, n
);
543 if ((n
= parse_find_node("animateIconify", node
)))
544 config_animate_iconify
= parse_bool(doc
, n
);
546 n
= parse_find_node("font", node
);
550 gchar
*name
= g_strdup(RrDefaultFontFamily
);
551 gint size
= RrDefaultFontSize
;
552 RrFontWeight weight
= RrDefaultFontWeight
;
553 RrFontSlant slant
= RrDefaultFontSlant
;
555 if (parse_attr_contains("ActiveWindow", n
, "place"))
556 font
= &config_font_activewindow
;
557 else if (parse_attr_contains("InactiveWindow", n
, "place"))
558 font
= &config_font_inactivewindow
;
559 else if (parse_attr_contains("MenuHeader", n
, "place"))
560 font
= &config_font_menutitle
;
561 else if (parse_attr_contains("MenuItem", n
, "place"))
562 font
= &config_font_menuitem
;
563 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
564 font
= &config_font_osd
;
568 if ((fnode
= parse_find_node("name", n
->children
))) {
570 name
= parse_string(doc
, fnode
);
572 if ((fnode
= parse_find_node("size", n
->children
))) {
573 int s
= parse_int(doc
, fnode
);
576 if ((fnode
= parse_find_node("weight", n
->children
))) {
577 gchar
*w
= parse_string(doc
, fnode
);
578 if (!g_ascii_strcasecmp(w
, "Bold"))
579 weight
= RR_FONTWEIGHT_BOLD
;
582 if ((fnode
= parse_find_node("slant", n
->children
))) {
583 gchar
*s
= parse_string(doc
, fnode
);
584 if (!g_ascii_strcasecmp(s
, "Italic"))
585 slant
= RR_FONTSLANT_ITALIC
;
586 if (!g_ascii_strcasecmp(s
, "Oblique"))
587 slant
= RR_FONTSLANT_OBLIQUE
;
591 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
594 n
= parse_find_node("font", n
->next
);
598 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
603 node
= node
->children
;
605 if ((n
= parse_find_node("number", node
))) {
606 gint d
= parse_int(doc
, n
);
608 config_desktops_num
= (unsigned) d
;
610 if ((n
= parse_find_node("firstdesk", node
))) {
611 gint d
= parse_int(doc
, n
);
613 config_screen_firstdesk
= (unsigned) d
;
615 if ((n
= parse_find_node("names", node
))) {
619 for (it
= config_desktops_names
; it
; it
= it
->next
)
621 g_slist_free(config_desktops_names
);
622 config_desktops_names
= NULL
;
624 nname
= parse_find_node("name", n
->children
);
626 config_desktops_names
= g_slist_append(config_desktops_names
,
627 parse_string(doc
, nname
));
628 nname
= parse_find_node("name", nname
->next
);
631 if ((n
= parse_find_node("popupTime", node
)))
632 config_desktop_popup_time
= parse_int(doc
, n
);
635 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
640 node
= node
->children
;
642 if ((n
= parse_find_node("drawContents", node
)))
643 config_resize_redraw
= parse_bool(doc
, n
);
644 if ((n
= parse_find_node("popupShow", node
))) {
645 config_resize_popup_show
= parse_int(doc
, n
);
646 if (parse_contains("Always", doc
, n
))
647 config_resize_popup_show
= 2;
648 else if (parse_contains("Never", doc
, n
))
649 config_resize_popup_show
= 0;
650 else if (parse_contains("Nonpixel", doc
, n
))
651 config_resize_popup_show
= 1;
653 if ((n
= parse_find_node("popupPosition", node
))) {
654 if (parse_contains("Top", doc
, n
))
655 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
656 else if (parse_contains("Center", doc
, n
))
657 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
658 else if (parse_contains("Fixed", doc
, n
)) {
659 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
661 if ((n
= parse_find_node("popupFixedPosition", node
))) {
664 if ((n2
= parse_find_node("x", n
->children
)))
665 config_parse_gravity_coord(doc
, n2
,
666 &config_resize_popup_fixed
.x
);
667 if ((n2
= parse_find_node("y", n
->children
)))
668 config_parse_gravity_coord(doc
, n2
,
669 &config_resize_popup_fixed
.y
);
675 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
680 node
= node
->children
;
682 if ((n
= parse_find_node("position", node
))) {
683 if (parse_contains("TopLeft", doc
, n
))
684 config_dock_floating
= FALSE
,
685 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
686 else if (parse_contains("Top", doc
, n
))
687 config_dock_floating
= FALSE
,
688 config_dock_pos
= OB_DIRECTION_NORTH
;
689 else if (parse_contains("TopRight", doc
, n
))
690 config_dock_floating
= FALSE
,
691 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
692 else if (parse_contains("Right", doc
, n
))
693 config_dock_floating
= FALSE
,
694 config_dock_pos
= OB_DIRECTION_EAST
;
695 else if (parse_contains("BottomRight", doc
, n
))
696 config_dock_floating
= FALSE
,
697 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
698 else if (parse_contains("Bottom", doc
, n
))
699 config_dock_floating
= FALSE
,
700 config_dock_pos
= OB_DIRECTION_SOUTH
;
701 else if (parse_contains("BottomLeft", doc
, n
))
702 config_dock_floating
= FALSE
,
703 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
704 else if (parse_contains("Left", doc
, n
))
705 config_dock_floating
= FALSE
,
706 config_dock_pos
= OB_DIRECTION_WEST
;
707 else if (parse_contains("Floating", doc
, n
))
708 config_dock_floating
= TRUE
;
710 if (config_dock_floating
) {
711 if ((n
= parse_find_node("floatingX", node
)))
712 config_dock_x
= parse_int(doc
, n
);
713 if ((n
= parse_find_node("floatingY", node
)))
714 config_dock_y
= parse_int(doc
, n
);
716 if ((n
= parse_find_node("noStrut", node
)))
717 config_dock_nostrut
= parse_bool(doc
, n
);
719 if ((n
= parse_find_node("stacking", node
))) {
720 if (parse_contains("above", doc
, n
))
721 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
722 else if (parse_contains("normal", doc
, n
))
723 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
724 else if (parse_contains("below", doc
, n
))
725 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
727 if ((n
= parse_find_node("direction", node
))) {
728 if (parse_contains("horizontal", doc
, n
))
729 config_dock_orient
= OB_ORIENTATION_HORZ
;
730 else if (parse_contains("vertical", doc
, n
))
731 config_dock_orient
= OB_ORIENTATION_VERT
;
733 if ((n
= parse_find_node("autoHide", node
)))
734 config_dock_hide
= parse_bool(doc
, n
);
735 if ((n
= parse_find_node("hideDelay", node
)))
736 config_dock_hide_delay
= parse_int(doc
, n
);
737 if ((n
= parse_find_node("showDelay", node
)))
738 config_dock_show_delay
= parse_int(doc
, n
);
739 if ((n
= parse_find_node("moveButton", node
))) {
740 gchar
*str
= parse_string(doc
, n
);
742 if (translate_button(str
, &s
, &b
)) {
743 config_dock_app_move_button
= b
;
744 config_dock_app_move_modifiers
= s
;
746 g_message(_("Invalid button '%s' specified in config file"), str
);
752 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
756 for (node
= node
->children
; node
; node
= node
->next
) {
757 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
760 c
= parse_string(doc
, node
);
761 config_menu_files
= g_slist_append(config_menu_files
,
762 parse_expand_tilde(c
));
765 if ((n
= parse_find_node("hideDelay", node
)))
766 config_menu_hide_delay
= parse_int(doc
, n
);
767 if ((n
= parse_find_node("middle", node
)))
768 config_menu_middle
= parse_bool(doc
, n
);
769 if ((n
= parse_find_node("submenuShowDelay", node
)))
770 config_submenu_show_delay
= parse_int(doc
, n
);
771 if ((n
= parse_find_node("applicationIcons", node
)))
772 config_menu_client_list_icons
= parse_bool(doc
, n
);
776 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
781 node
= node
->children
;
782 if ((n
= parse_find_node("strength", node
)))
783 config_resist_win
= parse_int(doc
, n
);
784 if ((n
= parse_find_node("screen_edge_strength", node
)))
785 config_resist_edge
= parse_int(doc
, n
);
791 const gchar
*actname
;
794 static void bind_default_keyboard(void)
797 ObDefKeyBind binds
[] = {
798 { "A-Tab", "NextWindow" },
799 { "S-A-Tab", "PreviousWindow" },
803 for (it
= binds
; it
->key
; ++it
) {
804 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
805 keyboard_bind(l
, actions_parse_string(it
->actname
));
812 const gchar
*context
;
813 const ObMouseAction mact
;
814 const gchar
*actname
;
817 static void bind_default_mouse(void)
820 ObDefMouseBind binds
[] = {
821 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
822 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
823 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
824 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
825 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
826 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
827 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
828 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
829 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
830 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
831 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
832 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
833 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
834 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
835 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
836 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
837 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
838 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
839 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
840 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
841 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
842 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
843 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
844 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
845 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
846 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
847 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
848 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
849 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
850 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
851 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
852 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
853 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
854 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
855 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
856 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
857 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
858 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
859 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
860 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
861 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
862 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
863 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
864 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
865 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
866 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
867 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
868 { NULL
, NULL
, 0, NULL
}
871 for (it
= binds
; it
->button
; ++it
)
872 mouse_bind(it
->button
, it
->context
, it
->mact
,
873 actions_parse_string(it
->actname
));
876 void config_startup(ObParseInst
*i
)
878 config_focus_new
= TRUE
;
879 config_focus_follow
= FALSE
;
880 config_focus_delay
= 0;
881 config_focus_raise
= FALSE
;
882 config_focus_last
= TRUE
;
883 config_focus_under_mouse
= FALSE
;
885 parse_register(i
, "focus", parse_focus
, NULL
);
887 config_place_policy
= OB_PLACE_POLICY_SMART
;
888 config_place_center
= TRUE
;
889 config_place_active
= FALSE
;
891 parse_register(i
, "placement", parse_placement
, NULL
);
893 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
895 parse_register(i
, "margins", parse_margins
, NULL
);
899 config_animate_iconify
= TRUE
;
900 config_title_layout
= g_strdup("NLIMC");
901 config_theme_keepborder
= TRUE
;
903 config_font_activewindow
= NULL
;
904 config_font_inactivewindow
= NULL
;
905 config_font_menuitem
= NULL
;
906 config_font_menutitle
= NULL
;
908 parse_register(i
, "theme", parse_theme
, NULL
);
910 config_desktops_num
= 4;
911 config_screen_firstdesk
= 1;
912 config_desktops_names
= NULL
;
913 config_desktop_popup_time
= 875;
915 parse_register(i
, "desktops", parse_desktops
, NULL
);
917 config_resize_redraw
= TRUE
;
918 config_resize_popup_show
= 1; /* nonpixel increments */
919 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
920 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
921 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
923 parse_register(i
, "resize", parse_resize
, NULL
);
925 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
926 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
927 config_dock_floating
= FALSE
;
928 config_dock_nostrut
= FALSE
;
931 config_dock_orient
= OB_ORIENTATION_VERT
;
932 config_dock_hide
= FALSE
;
933 config_dock_hide_delay
= 300;
934 config_dock_show_delay
= 300;
935 config_dock_app_move_button
= 2; /* middle */
936 config_dock_app_move_modifiers
= 0;
938 parse_register(i
, "dock", parse_dock
, NULL
);
940 translate_key("C-g", &config_keyboard_reset_state
,
941 &config_keyboard_reset_keycode
);
943 bind_default_keyboard();
945 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
947 config_mouse_threshold
= 8;
948 config_mouse_dclicktime
= 200;
949 config_mouse_screenedgetime
= 400;
951 bind_default_mouse();
953 parse_register(i
, "mouse", parse_mouse
, NULL
);
955 config_resist_win
= 10;
956 config_resist_edge
= 20;
958 parse_register(i
, "resistance", parse_resistance
, NULL
);
960 config_menu_hide_delay
= 250;
961 config_menu_middle
= FALSE
;
962 config_submenu_show_delay
= 0;
963 config_menu_client_list_icons
= TRUE
;
964 config_menu_files
= NULL
;
966 parse_register(i
, "menu", parse_menu
, NULL
);
968 config_per_app_settings
= NULL
;
970 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
973 void config_shutdown(void)
977 g_free(config_theme
);
979 g_free(config_title_layout
);
981 RrFontClose(config_font_activewindow
);
982 RrFontClose(config_font_inactivewindow
);
983 RrFontClose(config_font_menuitem
);
984 RrFontClose(config_font_menutitle
);
985 RrFontClose(config_font_osd
);
987 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
989 g_slist_free(config_desktops_names
);
991 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
993 g_slist_free(config_menu_files
);
995 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
996 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
997 if (itd
->name
) g_pattern_spec_free(itd
->name
);
998 if (itd
->role
) g_pattern_spec_free(itd
->role
);
999 if (itd
->class) g_pattern_spec_free(itd
->class);
1002 g_slist_free(config_per_app_settings
);