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
;
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 gint config_desktops_num
;
58 GSList
*config_desktops_names
;
59 guint config_screen_firstdesk
;
60 guint config_desktop_popup_time
;
62 gboolean config_resize_redraw
;
63 gboolean config_resize_four_corners
;
64 gint config_resize_popup_show
;
65 gint config_resize_popup_pos
;
67 ObStackingLayer config_dock_layer
;
68 gboolean config_dock_floating
;
69 gboolean config_dock_nostrut
;
70 ObDirection config_dock_pos
;
73 ObOrientation config_dock_orient
;
74 gboolean config_dock_hide
;
75 guint config_dock_hide_delay
;
76 guint config_dock_show_delay
;
77 guint config_dock_app_move_button
;
78 guint config_dock_app_move_modifiers
;
80 guint config_keyboard_reset_keycode
;
81 guint config_keyboard_reset_state
;
83 gint config_mouse_threshold
;
84 gint config_mouse_dclicktime
;
85 gint config_mouse_screenedgetime
;
87 guint config_menu_hide_delay
;
88 gboolean config_menu_middle
;
89 guint config_submenu_show_delay
;
90 gboolean config_menu_client_list_icons
;
92 GSList
*config_menu_files
;
94 gint config_resist_win
;
95 gint config_resist_edge
;
97 GSList
*config_per_app_settings
;
99 ObAppSettings
* config_create_app_settings()
101 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
102 settings
->decor
= -1;
103 settings
->shade
= -1;
104 settings
->monitor
= -1;
105 settings
->focus
= -1;
106 settings
->desktop
= 0;
107 settings
->layer
= -2;
108 settings
->iconic
= -1;
109 settings
->skip_pager
= -1;
110 settings
->skip_taskbar
= -1;
111 settings
->fullscreen
= -1;
112 settings
->max_horz
= -1;
113 settings
->max_vert
= -1;
117 #define copy_if(setting, default) \
118 if (src->setting != default) dst->setting = src->setting
119 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
122 g_assert(src
!= NULL
);
123 g_assert(dst
!= NULL
);
131 copy_if(skip_pager
, -1);
132 copy_if(skip_taskbar
, -1);
133 copy_if(fullscreen
, -1);
134 copy_if(max_horz
, -1);
135 copy_if(max_vert
, -1);
137 if (src
->pos_given
) {
138 dst
->pos_given
= TRUE
;
139 dst
->center_x
= src
->center_x
;
140 dst
->center_y
= src
->center_y
;
141 dst
->opposite_x
= src
->opposite_x
;
142 dst
->opposite_y
= src
->opposite_y
;
143 dst
->position
.x
= src
->position
.x
;
144 dst
->position
.y
= src
->position
.y
;
145 dst
->monitor
= src
->monitor
;
151 <application name="aterm">
154 <application name="Rhythmbox">
161 .. there is a lot more settings available
166 /* Manages settings for individual applications.
167 Some notes: monitor is the screen number in a multi monitor
168 (Xinerama) setup (starting from 0) or mouse, meaning the
169 monitor the pointer is on. Default: mouse.
170 Layer can be three values, above (Always on top), below
171 (Always on bottom) and everything else (normal behaviour).
172 Positions can be an integer value or center, which will
173 center the window in the specified axis. Position is within
174 the monitor, so <position><x>center</x></position><monitor>2</monitor>
175 will center the window on the second monitor.
177 static void parse_per_app_settings(ObParseInst
*i
, xmlDocPtr doc
,
178 xmlNodePtr node
, gpointer d
)
180 xmlNodePtr app
= parse_find_node("application", node
->children
);
181 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
182 gboolean name_set
, class_set
;
183 gboolean x_pos_given
;
186 name_set
= class_set
= x_pos_given
= FALSE
;
188 class_set
= parse_attr_string("class", app
, &class);
189 name_set
= parse_attr_string("name", app
, &name
);
190 if (class_set
|| name_set
) {
192 ObAppSettings
*settings
= config_create_app_settings();;
195 settings
->name
= g_pattern_spec_new(name
);
198 settings
->class = g_pattern_spec_new(class);
200 if (parse_attr_string("role", app
, &role
))
201 settings
->role
= g_pattern_spec_new(role
);
203 if ((n
= parse_find_node("decor", app
->children
)))
204 if (!parse_contains("default", doc
, n
))
205 settings
->decor
= parse_bool(doc
, n
);
207 if ((n
= parse_find_node("shade", app
->children
)))
208 if (!parse_contains("default", doc
, n
))
209 settings
->shade
= parse_bool(doc
, n
);
211 if ((n
= parse_find_node("position", app
->children
))) {
212 if ((c
= parse_find_node("x", n
->children
)))
213 if (!parse_contains("default", doc
, c
)) {
214 gchar
*s
= parse_string(doc
, c
);
215 if (!g_ascii_strcasecmp(s
, "center")) {
216 settings
->center_x
= TRUE
;
220 settings
->opposite_x
= TRUE
;
221 if (s
[0] == '-' || s
[0] == '+')
222 settings
->position
.x
= atoi(s
+1);
224 settings
->position
.x
= atoi(s
);
230 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
231 if (!parse_contains("default", doc
, c
)) {
232 gchar
*s
= parse_string(doc
, c
);
233 if (!g_ascii_strcasecmp(s
, "center")) {
234 settings
->center_y
= TRUE
;
235 settings
->pos_given
= TRUE
;
238 settings
->opposite_y
= TRUE
;
239 if (s
[0] == '-' || s
[0] == '+')
240 settings
->position
.y
= atoi(s
+1);
242 settings
->position
.y
= atoi(s
);
243 settings
->pos_given
= TRUE
;
248 if (settings
->pos_given
&&
249 (c
= parse_find_node("monitor", n
->children
)))
250 if (!parse_contains("default", doc
, c
)) {
251 gchar
*s
= parse_string(doc
, c
);
252 if (!g_ascii_strcasecmp(s
, "mouse"))
253 settings
->monitor
= 0;
255 settings
->monitor
= parse_int(doc
, c
) + 1;
260 if ((n
= parse_find_node("focus", app
->children
)))
261 if (!parse_contains("default", doc
, n
))
262 settings
->focus
= parse_bool(doc
, n
);
264 if ((n
= parse_find_node("desktop", app
->children
))) {
265 if (!parse_contains("default", doc
, n
)) {
266 gchar
*s
= parse_string(doc
, n
);
267 if (!g_ascii_strcasecmp(s
, "all"))
268 settings
->desktop
= DESKTOP_ALL
;
270 gint i
= parse_int(doc
, n
);
272 settings
->desktop
= i
;
278 if ((n
= parse_find_node("layer", app
->children
)))
279 if (!parse_contains("default", doc
, n
)) {
280 gchar
*s
= parse_string(doc
, n
);
281 if (!g_ascii_strcasecmp(s
, "above"))
283 else if (!g_ascii_strcasecmp(s
, "below"))
284 settings
->layer
= -1;
290 if ((n
= parse_find_node("iconic", app
->children
)))
291 if (!parse_contains("default", doc
, n
))
292 settings
->iconic
= parse_bool(doc
, n
);
294 if ((n
= parse_find_node("skip_pager", app
->children
)))
295 if (!parse_contains("default", doc
, n
))
296 settings
->skip_pager
= parse_bool(doc
, n
);
298 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
299 if (!parse_contains("default", doc
, n
))
300 settings
->skip_taskbar
= parse_bool(doc
, n
);
302 if ((n
= parse_find_node("fullscreen", app
->children
)))
303 if (!parse_contains("default", doc
, n
))
304 settings
->fullscreen
= parse_bool(doc
, n
);
306 if ((n
= parse_find_node("maximized", app
->children
)))
307 if (!parse_contains("default", doc
, n
)) {
308 gchar
*s
= parse_string(doc
, n
);
309 if (!g_ascii_strcasecmp(s
, "horizontal")) {
310 settings
->max_horz
= TRUE
;
311 settings
->max_vert
= FALSE
;
312 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
313 settings
->max_horz
= FALSE
;
314 settings
->max_vert
= TRUE
;
316 settings
->max_horz
= settings
->max_vert
=
321 config_per_app_settings
= g_slist_append(config_per_app_settings
,
322 (gpointer
) settings
);
326 name
= class = role
= NULL
;
329 app
= parse_find_node("application", app
->next
);
336 <action name="ChangeDesktop">
343 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
348 gboolean is_chroot
= FALSE
;
350 if (!parse_attr_string("key", node
, &key
))
353 parse_attr_bool("chroot", node
, &is_chroot
);
355 keylist
= g_list_append(keylist
, key
);
357 if ((n
= parse_find_node("keybind", node
->children
))) {
359 parse_key(i
, doc
, n
, keylist
);
360 n
= parse_find_node("keybind", n
->next
);
363 else if ((n
= parse_find_node("action", node
->children
))) {
365 ObActionsAct
*action
;
367 action
= actions_parse(i
, doc
, n
);
369 keyboard_bind(keylist
, action
);
370 n
= parse_find_node("action", n
->next
);
375 keyboard_chroot(keylist
);
378 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
381 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
387 keyboard_unbind_all();
389 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
390 key
= parse_string(doc
, n
);
391 translate_key(key
, &config_keyboard_reset_state
,
392 &config_keyboard_reset_keycode
);
396 if ((n
= parse_find_node("keybind", node
->children
)))
398 parse_key(i
, doc
, n
, NULL
);
399 n
= parse_find_node("keybind", n
->next
);
405 <context name="Titlebar">
406 <mousebind button="Left" action="Press">
407 <action name="Raise"></action>
413 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
416 xmlNodePtr n
, nbut
, nact
;
423 node
= node
->children
;
425 if ((n
= parse_find_node("dragThreshold", node
)))
426 config_mouse_threshold
= parse_int(doc
, n
);
427 if ((n
= parse_find_node("doubleClickTime", node
)))
428 config_mouse_dclicktime
= parse_int(doc
, n
);
429 if ((n
= parse_find_node("screenEdgeWarpTime", node
)))
430 config_mouse_screenedgetime
= parse_int(doc
, n
);
432 n
= parse_find_node("context", node
);
434 if (!parse_attr_string("name", n
, &contextstr
))
436 nbut
= parse_find_node("mousebind", n
->children
);
438 if (!parse_attr_string("button", nbut
, &buttonstr
))
440 if (parse_attr_contains("press", nbut
, "action")) {
441 mact
= OB_MOUSE_ACTION_PRESS
;
442 } else if (parse_attr_contains("release", nbut
, "action")) {
443 mact
= OB_MOUSE_ACTION_RELEASE
;
444 } else if (parse_attr_contains("click", nbut
, "action")) {
445 mact
= OB_MOUSE_ACTION_CLICK
;
446 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
447 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
448 } else if (parse_attr_contains("drag", nbut
, "action")) {
449 mact
= OB_MOUSE_ACTION_MOTION
;
452 nact
= parse_find_node("action", nbut
->children
);
454 ObActionsAct
*action
;
456 if ((action
= actions_parse(i
, doc
, nact
)))
457 mouse_bind(buttonstr
, contextstr
, mact
, action
);
458 nact
= parse_find_node("action", nact
->next
);
462 nbut
= parse_find_node("mousebind", nbut
->next
);
466 n
= parse_find_node("context", n
->next
);
470 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
475 node
= node
->children
;
477 if ((n
= parse_find_node("focusNew", node
)))
478 config_focus_new
= parse_bool(doc
, n
);
479 if ((n
= parse_find_node("followMouse", node
)))
480 config_focus_follow
= parse_bool(doc
, n
);
481 if ((n
= parse_find_node("focusDelay", node
)))
482 config_focus_delay
= parse_int(doc
, n
);
483 if ((n
= parse_find_node("raiseOnFocus", node
)))
484 config_focus_raise
= parse_bool(doc
, n
);
485 if ((n
= parse_find_node("focusLast", node
)))
486 config_focus_last
= parse_bool(doc
, n
);
487 if ((n
= parse_find_node("underMouse", node
)))
488 config_focus_under_mouse
= parse_bool(doc
, n
);
491 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
496 node
= node
->children
;
498 if ((n
= parse_find_node("policy", node
)))
499 if (parse_contains("UnderMouse", doc
, n
))
500 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
501 if ((n
= parse_find_node("center", node
)))
502 config_place_center
= parse_bool(doc
, n
);
505 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
510 node
= node
->children
;
512 if ((n
= parse_find_node("top", node
)))
513 config_margins
.top
= MAX(0, parse_int(doc
, n
));
514 if ((n
= parse_find_node("left", node
)))
515 config_margins
.left
= MAX(0, parse_int(doc
, n
));
516 if ((n
= parse_find_node("right", node
)))
517 config_margins
.right
= MAX(0, parse_int(doc
, n
));
518 if ((n
= parse_find_node("bottom", node
)))
519 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
522 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
527 node
= node
->children
;
529 if ((n
= parse_find_node("name", node
))) {
532 g_free(config_theme
);
533 c
= parse_string(doc
, n
);
534 config_theme
= parse_expand_tilde(c
);
537 if ((n
= parse_find_node("titleLayout", node
))) {
540 g_free(config_title_layout
);
541 config_title_layout
= parse_string(doc
, n
);
543 /* replace duplicates with spaces */
544 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
545 for (d
= c
+1; *d
!= '\0'; ++d
)
546 if (*c
== *d
) *d
= ' ';
548 if ((n
= parse_find_node("keepBorder", node
)))
549 config_theme_keepborder
= parse_bool(doc
, n
);
550 if ((n
= parse_find_node("animateIconify", node
)))
551 config_animate_iconify
= parse_bool(doc
, n
);
553 n
= parse_find_node("font", node
);
557 gchar
*name
= g_strdup(RrDefaultFontFamily
);
558 gint size
= RrDefaultFontSize
;
559 RrFontWeight weight
= RrDefaultFontWeight
;
560 RrFontSlant slant
= RrDefaultFontSlant
;
562 if (parse_attr_contains("ActiveWindow", n
, "place"))
563 font
= &config_font_activewindow
;
564 else if (parse_attr_contains("InactiveWindow", n
, "place"))
565 font
= &config_font_inactivewindow
;
566 else if (parse_attr_contains("MenuHeader", n
, "place"))
567 font
= &config_font_menutitle
;
568 else if (parse_attr_contains("MenuItem", n
, "place"))
569 font
= &config_font_menuitem
;
570 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
571 font
= &config_font_osd
;
575 if ((fnode
= parse_find_node("name", n
->children
))) {
577 name
= parse_string(doc
, fnode
);
579 if ((fnode
= parse_find_node("size", n
->children
))) {
580 int s
= parse_int(doc
, fnode
);
583 if ((fnode
= parse_find_node("weight", n
->children
))) {
584 gchar
*w
= parse_string(doc
, fnode
);
585 if (!g_ascii_strcasecmp(w
, "Bold"))
586 weight
= RR_FONTWEIGHT_BOLD
;
589 if ((fnode
= parse_find_node("slant", n
->children
))) {
590 gchar
*s
= parse_string(doc
, fnode
);
591 if (!g_ascii_strcasecmp(s
, "Italic"))
592 slant
= RR_FONTSLANT_ITALIC
;
593 if (!g_ascii_strcasecmp(s
, "Oblique"))
594 slant
= RR_FONTSLANT_OBLIQUE
;
598 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
601 n
= parse_find_node("font", n
->next
);
605 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
610 node
= node
->children
;
612 if ((n
= parse_find_node("number", node
))) {
613 gint d
= parse_int(doc
, n
);
615 config_desktops_num
= d
;
617 if ((n
= parse_find_node("firstdesk", node
))) {
618 gint d
= parse_int(doc
, n
);
620 config_screen_firstdesk
= (unsigned) d
;
622 if ((n
= parse_find_node("names", node
))) {
626 for (it
= config_desktops_names
; it
; it
= it
->next
)
628 g_slist_free(config_desktops_names
);
629 config_desktops_names
= NULL
;
631 nname
= parse_find_node("name", n
->children
);
633 config_desktops_names
= g_slist_append(config_desktops_names
,
634 parse_string(doc
, nname
));
635 nname
= parse_find_node("name", nname
->next
);
638 if ((n
= parse_find_node("popupTime", node
)))
639 config_desktop_popup_time
= parse_int(doc
, n
);
642 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
647 node
= node
->children
;
649 if ((n
= parse_find_node("drawContents", node
)))
650 config_resize_redraw
= parse_bool(doc
, n
);
651 if ((n
= parse_find_node("popupShow", node
))) {
652 config_resize_popup_show
= parse_int(doc
, n
);
653 if (parse_contains("Always", doc
, n
))
654 config_resize_popup_show
= 2;
655 else if (parse_contains("Never", doc
, n
))
656 config_resize_popup_show
= 0;
657 else if (parse_contains("Nonpixel", doc
, n
))
658 config_resize_popup_show
= 1;
660 if ((n
= parse_find_node("popupPosition", node
))) {
661 config_resize_popup_pos
= parse_int(doc
, n
);
662 if (parse_contains("Top", doc
, n
))
663 config_resize_popup_pos
= 1;
664 else if (parse_contains("Center", doc
, n
))
665 config_resize_popup_pos
= 0;
669 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
674 node
= node
->children
;
676 if ((n
= parse_find_node("position", node
))) {
677 if (parse_contains("TopLeft", doc
, n
))
678 config_dock_floating
= FALSE
,
679 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
680 else if (parse_contains("Top", doc
, n
))
681 config_dock_floating
= FALSE
,
682 config_dock_pos
= OB_DIRECTION_NORTH
;
683 else if (parse_contains("TopRight", doc
, n
))
684 config_dock_floating
= FALSE
,
685 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
686 else if (parse_contains("Right", doc
, n
))
687 config_dock_floating
= FALSE
,
688 config_dock_pos
= OB_DIRECTION_EAST
;
689 else if (parse_contains("BottomRight", doc
, n
))
690 config_dock_floating
= FALSE
,
691 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
692 else if (parse_contains("Bottom", doc
, n
))
693 config_dock_floating
= FALSE
,
694 config_dock_pos
= OB_DIRECTION_SOUTH
;
695 else if (parse_contains("BottomLeft", doc
, n
))
696 config_dock_floating
= FALSE
,
697 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
698 else if (parse_contains("Left", doc
, n
))
699 config_dock_floating
= FALSE
,
700 config_dock_pos
= OB_DIRECTION_WEST
;
701 else if (parse_contains("Floating", doc
, n
))
702 config_dock_floating
= TRUE
;
704 if (config_dock_floating
) {
705 if ((n
= parse_find_node("floatingX", node
)))
706 config_dock_x
= parse_int(doc
, n
);
707 if ((n
= parse_find_node("floatingY", node
)))
708 config_dock_y
= parse_int(doc
, n
);
710 if ((n
= parse_find_node("noStrut", node
)))
711 config_dock_nostrut
= parse_bool(doc
, n
);
713 if ((n
= parse_find_node("stacking", node
))) {
714 if (parse_contains("above", doc
, n
))
715 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
716 else if (parse_contains("normal", doc
, n
))
717 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
718 else if (parse_contains("below", doc
, n
))
719 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
721 if ((n
= parse_find_node("direction", node
))) {
722 if (parse_contains("horizontal", doc
, n
))
723 config_dock_orient
= OB_ORIENTATION_HORZ
;
724 else if (parse_contains("vertical", doc
, n
))
725 config_dock_orient
= OB_ORIENTATION_VERT
;
727 if ((n
= parse_find_node("autoHide", node
)))
728 config_dock_hide
= parse_bool(doc
, n
);
729 if ((n
= parse_find_node("hideDelay", node
)))
730 config_dock_hide_delay
= parse_int(doc
, n
);
731 if ((n
= parse_find_node("showDelay", node
)))
732 config_dock_show_delay
= parse_int(doc
, n
);
733 if ((n
= parse_find_node("moveButton", node
))) {
734 gchar
*str
= parse_string(doc
, n
);
736 if (translate_button(str
, &s
, &b
)) {
737 config_dock_app_move_button
= b
;
738 config_dock_app_move_modifiers
= s
;
740 g_message(_("Invalid button '%s' specified in config file"), str
);
746 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
750 for (node
= node
->children
; node
; node
= node
->next
) {
751 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
754 c
= parse_string(doc
, node
);
755 config_menu_files
= g_slist_append(config_menu_files
,
756 parse_expand_tilde(c
));
759 if ((n
= parse_find_node("hideDelay", node
)))
760 config_menu_hide_delay
= parse_int(doc
, n
);
761 if ((n
= parse_find_node("middle", node
)))
762 config_menu_middle
= parse_bool(doc
, n
);
763 if ((n
= parse_find_node("submenuShowDelay", node
)))
764 config_submenu_show_delay
= parse_int(doc
, n
);
765 if ((n
= parse_find_node("applicationIcons", node
)))
766 config_menu_client_list_icons
= parse_bool(doc
, n
);
770 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
775 node
= node
->children
;
776 if ((n
= parse_find_node("strength", node
)))
777 config_resist_win
= parse_int(doc
, n
);
778 if ((n
= parse_find_node("screen_edge_strength", node
)))
779 config_resist_edge
= parse_int(doc
, n
);
785 const gchar
*actname
;
788 static void bind_default_keyboard()
791 ObDefKeyBind binds
[] = {
792 { "A-Tab", "NextWindow" },
793 { "S-A-Tab", "PreviousWindow" },
797 for (it
= binds
; it
->key
; ++it
) {
798 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
799 keyboard_bind(l
, actions_parse_string(it
->actname
));
806 const gchar
*context
;
807 const ObMouseAction mact
;
808 const gchar
*actname
;
811 static void bind_default_mouse()
814 ObDefMouseBind binds
[] = {
815 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
816 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
817 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
818 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
819 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
820 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
821 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
822 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
823 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
824 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
825 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
826 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
827 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
828 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
829 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
830 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
831 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
832 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
833 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
834 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
835 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
836 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
837 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
838 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
839 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
840 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
841 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
842 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
843 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
844 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
845 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
846 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
847 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
848 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
849 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
850 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
851 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
852 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
853 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
854 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
855 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
856 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
857 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
858 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
859 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
860 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
861 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
862 { NULL
, NULL
, 0, NULL
}
865 for (it
= binds
; it
->button
; ++it
)
866 mouse_bind(it
->button
, it
->context
, it
->mact
,
867 actions_parse_string(it
->actname
));
870 void config_startup(ObParseInst
*i
)
872 config_focus_new
= TRUE
;
873 config_focus_follow
= FALSE
;
874 config_focus_delay
= 0;
875 config_focus_raise
= FALSE
;
876 config_focus_last
= TRUE
;
877 config_focus_under_mouse
= FALSE
;
879 parse_register(i
, "focus", parse_focus
, NULL
);
881 config_place_policy
= OB_PLACE_POLICY_SMART
;
882 config_place_center
= TRUE
;
884 parse_register(i
, "placement", parse_placement
, NULL
);
886 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
888 parse_register(i
, "margins", parse_margins
, NULL
);
892 config_animate_iconify
= TRUE
;
893 config_title_layout
= g_strdup("NLIMC");
894 config_theme_keepborder
= TRUE
;
896 config_font_activewindow
= NULL
;
897 config_font_inactivewindow
= NULL
;
898 config_font_menuitem
= NULL
;
899 config_font_menutitle
= NULL
;
901 parse_register(i
, "theme", parse_theme
, NULL
);
903 config_desktops_num
= 4;
904 config_screen_firstdesk
= 1;
905 config_desktops_names
= NULL
;
906 config_desktop_popup_time
= 875;
908 parse_register(i
, "desktops", parse_desktops
, NULL
);
910 config_resize_redraw
= TRUE
;
911 config_resize_four_corners
= FALSE
;
912 config_resize_popup_show
= 1; /* nonpixel increments */
913 config_resize_popup_pos
= 0; /* center of client */
915 parse_register(i
, "resize", parse_resize
, NULL
);
917 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
918 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
919 config_dock_floating
= FALSE
;
920 config_dock_nostrut
= FALSE
;
923 config_dock_orient
= OB_ORIENTATION_VERT
;
924 config_dock_hide
= FALSE
;
925 config_dock_hide_delay
= 300;
926 config_dock_show_delay
= 300;
927 config_dock_app_move_button
= 2; /* middle */
928 config_dock_app_move_modifiers
= 0;
930 parse_register(i
, "dock", parse_dock
, NULL
);
932 translate_key("C-g", &config_keyboard_reset_state
,
933 &config_keyboard_reset_keycode
);
935 bind_default_keyboard();
937 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
939 config_mouse_threshold
= 8;
940 config_mouse_dclicktime
= 200;
941 config_mouse_screenedgetime
= 400;
943 bind_default_mouse();
945 parse_register(i
, "mouse", parse_mouse
, NULL
);
947 config_resist_win
= 10;
948 config_resist_edge
= 20;
950 parse_register(i
, "resistance", parse_resistance
, NULL
);
952 config_menu_hide_delay
= 250;
953 config_menu_middle
= FALSE
;
954 config_submenu_show_delay
= 0;
955 config_menu_client_list_icons
= TRUE
;
956 config_menu_files
= NULL
;
958 parse_register(i
, "menu", parse_menu
, NULL
);
960 config_per_app_settings
= NULL
;
962 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
965 void config_shutdown()
969 g_free(config_theme
);
971 g_free(config_title_layout
);
973 RrFontClose(config_font_activewindow
);
974 RrFontClose(config_font_inactivewindow
);
975 RrFontClose(config_font_menuitem
);
976 RrFontClose(config_font_menutitle
);
978 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
980 g_slist_free(config_desktops_names
);
982 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
984 g_slist_free(config_menu_files
);
986 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
987 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
988 if (itd
->name
) g_pattern_spec_free(itd
->name
);
989 if (itd
->role
) g_pattern_spec_free(itd
->role
);
990 if (itd
->class) g_pattern_spec_free(itd
->class);
993 g_slist_free(config_per_app_settings
);