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 gboolean config_resize_popup_x_center
;
68 gboolean config_resize_popup_y_center
;
69 gboolean config_resize_popup_x_opposite
;
70 gboolean config_resize_popup_y_opposite
;
71 gint config_resize_popup_x
;
72 gint config_resize_popup_y
;
74 ObStackingLayer config_dock_layer
;
75 gboolean config_dock_floating
;
76 gboolean config_dock_nostrut
;
77 ObDirection config_dock_pos
;
80 ObOrientation config_dock_orient
;
81 gboolean config_dock_hide
;
82 guint config_dock_hide_delay
;
83 guint config_dock_show_delay
;
84 guint config_dock_app_move_button
;
85 guint config_dock_app_move_modifiers
;
87 guint config_keyboard_reset_keycode
;
88 guint config_keyboard_reset_state
;
90 gint config_mouse_threshold
;
91 gint config_mouse_dclicktime
;
92 gint config_mouse_screenedgetime
;
94 guint config_menu_hide_delay
;
95 gboolean config_menu_middle
;
96 guint config_submenu_show_delay
;
97 gboolean config_menu_client_list_icons
;
99 GSList
*config_menu_files
;
101 gint config_resist_win
;
102 gint config_resist_edge
;
104 GSList
*config_per_app_settings
;
106 ObAppSettings
* config_create_app_settings(void)
108 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
109 settings
->decor
= -1;
110 settings
->shade
= -1;
111 settings
->monitor
= -1;
112 settings
->focus
= -1;
113 settings
->desktop
= 0;
114 settings
->layer
= -2;
115 settings
->iconic
= -1;
116 settings
->skip_pager
= -1;
117 settings
->skip_taskbar
= -1;
118 settings
->fullscreen
= -1;
119 settings
->max_horz
= -1;
120 settings
->max_vert
= -1;
124 #define copy_if(setting, default) \
125 if (src->setting != default) dst->setting = src->setting
126 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
129 g_assert(src
!= NULL
);
130 g_assert(dst
!= NULL
);
138 copy_if(skip_pager
, -1);
139 copy_if(skip_taskbar
, -1);
140 copy_if(fullscreen
, -1);
141 copy_if(max_horz
, -1);
142 copy_if(max_vert
, -1);
144 if (src
->pos_given
) {
145 dst
->pos_given
= TRUE
;
146 dst
->center_x
= src
->center_x
;
147 dst
->center_y
= src
->center_y
;
148 dst
->opposite_x
= src
->opposite_x
;
149 dst
->opposite_y
= src
->opposite_y
;
150 dst
->position
.x
= src
->position
.x
;
151 dst
->position
.y
= src
->position
.y
;
152 dst
->monitor
= src
->monitor
;
158 <application name="aterm">
161 <application name="Rhythmbox">
168 .. there is a lot more settings available
173 /* Manages settings for individual applications.
174 Some notes: monitor is the screen number in a multi monitor
175 (Xinerama) setup (starting from 0) or mouse, meaning the
176 monitor the pointer is on. Default: mouse.
177 Layer can be three values, above (Always on top), below
178 (Always on bottom) and everything else (normal behaviour).
179 Positions can be an integer value or center, which will
180 center the window in the specified axis. Position is within
181 the monitor, so <position><x>center</x></position><monitor>2</monitor>
182 will center the window on the second monitor.
184 static void parse_per_app_settings(ObParseInst
*inst
, xmlDocPtr doc
,
185 xmlNodePtr node
, gpointer data
)
187 xmlNodePtr app
= parse_find_node("application", node
->children
);
188 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
189 gboolean name_set
, class_set
;
190 gboolean x_pos_given
;
193 name_set
= class_set
= x_pos_given
= FALSE
;
195 class_set
= parse_attr_string("class", app
, &class);
196 name_set
= parse_attr_string("name", app
, &name
);
197 if (class_set
|| name_set
) {
199 ObAppSettings
*settings
= config_create_app_settings();;
202 settings
->name
= g_pattern_spec_new(name
);
205 settings
->class = g_pattern_spec_new(class);
207 if (parse_attr_string("role", app
, &role
))
208 settings
->role
= g_pattern_spec_new(role
);
210 if ((n
= parse_find_node("decor", app
->children
)))
211 if (!parse_contains("default", doc
, n
))
212 settings
->decor
= parse_bool(doc
, n
);
214 if ((n
= parse_find_node("shade", app
->children
)))
215 if (!parse_contains("default", doc
, n
))
216 settings
->shade
= parse_bool(doc
, n
);
218 if ((n
= parse_find_node("position", app
->children
))) {
219 if ((c
= parse_find_node("x", n
->children
)))
220 if (!parse_contains("default", doc
, c
)) {
221 gchar
*s
= parse_string(doc
, c
);
222 if (!g_ascii_strcasecmp(s
, "center")) {
223 settings
->center_x
= TRUE
;
227 settings
->opposite_x
= TRUE
;
228 if (s
[0] == '-' || s
[0] == '+')
229 settings
->position
.x
= atoi(s
+1);
231 settings
->position
.x
= atoi(s
);
237 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
238 if (!parse_contains("default", doc
, c
)) {
239 gchar
*s
= parse_string(doc
, c
);
240 if (!g_ascii_strcasecmp(s
, "center")) {
241 settings
->center_y
= TRUE
;
242 settings
->pos_given
= TRUE
;
245 settings
->opposite_y
= TRUE
;
246 if (s
[0] == '-' || s
[0] == '+')
247 settings
->position
.y
= atoi(s
+1);
249 settings
->position
.y
= atoi(s
);
250 settings
->pos_given
= TRUE
;
255 if (settings
->pos_given
&&
256 (c
= parse_find_node("monitor", n
->children
)))
257 if (!parse_contains("default", doc
, c
)) {
258 gchar
*s
= parse_string(doc
, c
);
259 if (!g_ascii_strcasecmp(s
, "mouse"))
260 settings
->monitor
= 0;
262 settings
->monitor
= parse_int(doc
, c
) + 1;
267 if ((n
= parse_find_node("focus", app
->children
)))
268 if (!parse_contains("default", doc
, n
))
269 settings
->focus
= parse_bool(doc
, n
);
271 if ((n
= parse_find_node("desktop", app
->children
))) {
272 if (!parse_contains("default", doc
, n
)) {
273 gchar
*s
= parse_string(doc
, n
);
274 if (!g_ascii_strcasecmp(s
, "all"))
275 settings
->desktop
= DESKTOP_ALL
;
277 gint i
= parse_int(doc
, n
);
279 settings
->desktop
= i
;
285 if ((n
= parse_find_node("layer", app
->children
)))
286 if (!parse_contains("default", doc
, n
)) {
287 gchar
*s
= parse_string(doc
, n
);
288 if (!g_ascii_strcasecmp(s
, "above"))
290 else if (!g_ascii_strcasecmp(s
, "below"))
291 settings
->layer
= -1;
297 if ((n
= parse_find_node("iconic", app
->children
)))
298 if (!parse_contains("default", doc
, n
))
299 settings
->iconic
= parse_bool(doc
, n
);
301 if ((n
= parse_find_node("skip_pager", app
->children
)))
302 if (!parse_contains("default", doc
, n
))
303 settings
->skip_pager
= parse_bool(doc
, n
);
305 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
306 if (!parse_contains("default", doc
, n
))
307 settings
->skip_taskbar
= parse_bool(doc
, n
);
309 if ((n
= parse_find_node("fullscreen", app
->children
)))
310 if (!parse_contains("default", doc
, n
))
311 settings
->fullscreen
= parse_bool(doc
, n
);
313 if ((n
= parse_find_node("maximized", app
->children
)))
314 if (!parse_contains("default", doc
, n
)) {
315 gchar
*s
= parse_string(doc
, n
);
316 if (!g_ascii_strcasecmp(s
, "horizontal")) {
317 settings
->max_horz
= TRUE
;
318 settings
->max_vert
= FALSE
;
319 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
320 settings
->max_horz
= FALSE
;
321 settings
->max_vert
= TRUE
;
323 settings
->max_horz
= settings
->max_vert
=
328 config_per_app_settings
= g_slist_append(config_per_app_settings
,
329 (gpointer
) settings
);
333 name
= class = role
= NULL
;
336 app
= parse_find_node("application", app
->next
);
343 <action name="ChangeDesktop">
350 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
355 gboolean is_chroot
= FALSE
;
357 if (!parse_attr_string("key", node
, &key
))
360 parse_attr_bool("chroot", node
, &is_chroot
);
362 keylist
= g_list_append(keylist
, key
);
364 if ((n
= parse_find_node("keybind", node
->children
))) {
366 parse_key(i
, doc
, n
, keylist
);
367 n
= parse_find_node("keybind", n
->next
);
370 else if ((n
= parse_find_node("action", node
->children
))) {
372 ObActionsAct
*action
;
374 action
= actions_parse(i
, doc
, n
);
376 keyboard_bind(keylist
, action
);
377 n
= parse_find_node("action", n
->next
);
382 keyboard_chroot(keylist
);
385 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
388 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
394 keyboard_unbind_all();
396 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
397 key
= parse_string(doc
, n
);
398 translate_key(key
, &config_keyboard_reset_state
,
399 &config_keyboard_reset_keycode
);
403 if ((n
= parse_find_node("keybind", node
->children
)))
405 parse_key(i
, doc
, n
, NULL
);
406 n
= parse_find_node("keybind", n
->next
);
412 <context name="Titlebar">
413 <mousebind button="Left" action="Press">
414 <action name="Raise"></action>
420 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
423 xmlNodePtr n
, nbut
, nact
;
430 node
= node
->children
;
432 if ((n
= parse_find_node("dragThreshold", node
)))
433 config_mouse_threshold
= parse_int(doc
, n
);
434 if ((n
= parse_find_node("doubleClickTime", node
)))
435 config_mouse_dclicktime
= parse_int(doc
, n
);
436 if ((n
= parse_find_node("screenEdgeWarpTime", node
)))
437 config_mouse_screenedgetime
= parse_int(doc
, n
);
439 n
= parse_find_node("context", node
);
441 if (!parse_attr_string("name", n
, &contextstr
))
443 nbut
= parse_find_node("mousebind", n
->children
);
445 if (!parse_attr_string("button", nbut
, &buttonstr
))
447 if (parse_attr_contains("press", nbut
, "action")) {
448 mact
= OB_MOUSE_ACTION_PRESS
;
449 } else if (parse_attr_contains("release", nbut
, "action")) {
450 mact
= OB_MOUSE_ACTION_RELEASE
;
451 } else if (parse_attr_contains("click", nbut
, "action")) {
452 mact
= OB_MOUSE_ACTION_CLICK
;
453 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
454 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
455 } else if (parse_attr_contains("drag", nbut
, "action")) {
456 mact
= OB_MOUSE_ACTION_MOTION
;
459 nact
= parse_find_node("action", nbut
->children
);
461 ObActionsAct
*action
;
463 if ((action
= actions_parse(i
, doc
, nact
)))
464 mouse_bind(buttonstr
, contextstr
, mact
, action
);
465 nact
= parse_find_node("action", nact
->next
);
469 nbut
= parse_find_node("mousebind", nbut
->next
);
473 n
= parse_find_node("context", n
->next
);
477 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
482 node
= node
->children
;
484 if ((n
= parse_find_node("focusNew", node
)))
485 config_focus_new
= parse_bool(doc
, n
);
486 if ((n
= parse_find_node("followMouse", node
)))
487 config_focus_follow
= parse_bool(doc
, n
);
488 if ((n
= parse_find_node("focusDelay", node
)))
489 config_focus_delay
= parse_int(doc
, n
);
490 if ((n
= parse_find_node("raiseOnFocus", node
)))
491 config_focus_raise
= parse_bool(doc
, n
);
492 if ((n
= parse_find_node("focusLast", node
)))
493 config_focus_last
= parse_bool(doc
, n
);
494 if ((n
= parse_find_node("underMouse", node
)))
495 config_focus_under_mouse
= parse_bool(doc
, n
);
498 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
503 node
= node
->children
;
505 if ((n
= parse_find_node("policy", node
)))
506 if (parse_contains("UnderMouse", doc
, n
))
507 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
508 if ((n
= parse_find_node("center", node
)))
509 config_place_center
= parse_bool(doc
, n
);
510 if ((n
= parse_find_node("active", node
)))
511 config_place_active
= parse_bool(doc
, n
);
514 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
519 node
= node
->children
;
521 if ((n
= parse_find_node("top", node
)))
522 config_margins
.top
= MAX(0, parse_int(doc
, n
));
523 if ((n
= parse_find_node("left", node
)))
524 config_margins
.left
= MAX(0, parse_int(doc
, n
));
525 if ((n
= parse_find_node("right", node
)))
526 config_margins
.right
= MAX(0, parse_int(doc
, n
));
527 if ((n
= parse_find_node("bottom", node
)))
528 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
531 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
536 node
= node
->children
;
538 if ((n
= parse_find_node("name", node
))) {
541 g_free(config_theme
);
542 c
= parse_string(doc
, n
);
543 config_theme
= parse_expand_tilde(c
);
546 if ((n
= parse_find_node("titleLayout", node
))) {
549 g_free(config_title_layout
);
550 config_title_layout
= parse_string(doc
, n
);
552 /* replace duplicates with spaces */
553 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
554 for (d
= c
+1; *d
!= '\0'; ++d
)
555 if (*c
== *d
) *d
= ' ';
557 if ((n
= parse_find_node("keepBorder", node
)))
558 config_theme_keepborder
= parse_bool(doc
, n
);
559 if ((n
= parse_find_node("animateIconify", node
)))
560 config_animate_iconify
= parse_bool(doc
, n
);
562 n
= parse_find_node("font", node
);
566 gchar
*name
= g_strdup(RrDefaultFontFamily
);
567 gint size
= RrDefaultFontSize
;
568 RrFontWeight weight
= RrDefaultFontWeight
;
569 RrFontSlant slant
= RrDefaultFontSlant
;
571 if (parse_attr_contains("ActiveWindow", n
, "place"))
572 font
= &config_font_activewindow
;
573 else if (parse_attr_contains("InactiveWindow", n
, "place"))
574 font
= &config_font_inactivewindow
;
575 else if (parse_attr_contains("MenuHeader", n
, "place"))
576 font
= &config_font_menutitle
;
577 else if (parse_attr_contains("MenuItem", n
, "place"))
578 font
= &config_font_menuitem
;
579 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
580 font
= &config_font_osd
;
584 if ((fnode
= parse_find_node("name", n
->children
))) {
586 name
= parse_string(doc
, fnode
);
588 if ((fnode
= parse_find_node("size", n
->children
))) {
589 int s
= parse_int(doc
, fnode
);
592 if ((fnode
= parse_find_node("weight", n
->children
))) {
593 gchar
*w
= parse_string(doc
, fnode
);
594 if (!g_ascii_strcasecmp(w
, "Bold"))
595 weight
= RR_FONTWEIGHT_BOLD
;
598 if ((fnode
= parse_find_node("slant", n
->children
))) {
599 gchar
*s
= parse_string(doc
, fnode
);
600 if (!g_ascii_strcasecmp(s
, "Italic"))
601 slant
= RR_FONTSLANT_ITALIC
;
602 if (!g_ascii_strcasecmp(s
, "Oblique"))
603 slant
= RR_FONTSLANT_OBLIQUE
;
607 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
610 n
= parse_find_node("font", n
->next
);
614 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
619 node
= node
->children
;
621 if ((n
= parse_find_node("number", node
))) {
622 gint d
= parse_int(doc
, n
);
624 config_desktops_num
= d
;
626 if ((n
= parse_find_node("firstdesk", node
))) {
627 gint d
= parse_int(doc
, n
);
629 config_screen_firstdesk
= (unsigned) d
;
631 if ((n
= parse_find_node("names", node
))) {
635 for (it
= config_desktops_names
; it
; it
= it
->next
)
637 g_slist_free(config_desktops_names
);
638 config_desktops_names
= NULL
;
640 nname
= parse_find_node("name", n
->children
);
642 config_desktops_names
= g_slist_append(config_desktops_names
,
643 parse_string(doc
, nname
));
644 nname
= parse_find_node("name", nname
->next
);
647 if ((n
= parse_find_node("popupTime", node
)))
648 config_desktop_popup_time
= parse_int(doc
, n
);
651 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
656 node
= node
->children
;
658 if ((n
= parse_find_node("drawContents", node
)))
659 config_resize_redraw
= parse_bool(doc
, n
);
660 if ((n
= parse_find_node("popupShow", node
))) {
661 config_resize_popup_show
= parse_int(doc
, n
);
662 if (parse_contains("Always", doc
, n
))
663 config_resize_popup_show
= 2;
664 else if (parse_contains("Never", doc
, n
))
665 config_resize_popup_show
= 0;
666 else if (parse_contains("Nonpixel", doc
, n
))
667 config_resize_popup_show
= 1;
669 if ((n
= parse_find_node("popupPosition", node
))) {
670 if (parse_contains("Top", doc
, n
))
671 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
672 else if (parse_contains("Center", doc
, n
))
673 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
674 else if (parse_contains("Fixed", doc
, n
)) {
675 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
677 if ((n
= parse_find_node("popupFixedPosition", node
))) {
680 if ((n2
= parse_find_node("x", n
->children
))) {
681 gchar
*s
= parse_string(doc
, n2
);
682 if (!g_ascii_strcasecmp(s
, "center"))
683 config_resize_popup_x_center
= TRUE
;
686 config_resize_popup_x_opposite
= TRUE
;
687 if (s
[0] == '-' || s
[0] == '+')
688 config_resize_popup_x
= atoi(s
+1);
690 config_resize_popup_x
= atoi(s
);
693 if ((n2
= parse_find_node("y", n
->children
))) {
694 gchar
*s
= parse_string(doc
, n2
);
695 if (!g_ascii_strcasecmp(s
, "center"))
696 config_resize_popup_y_center
= TRUE
;
699 config_resize_popup_y_opposite
= TRUE
;
700 if (s
[0] == '-' || s
[0] == '+')
701 config_resize_popup_y
= atoi(s
+1);
703 config_resize_popup_y
= atoi(s
);
706 g_print("X %d %d %d\n", config_resize_popup_x_center
, config_resize_popup_x_opposite
, config_resize_popup_x
);
707 g_print("Y %d %d %d\n", config_resize_popup_y_center
, config_resize_popup_y_opposite
, config_resize_popup_y
);
713 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
718 node
= node
->children
;
720 if ((n
= parse_find_node("position", node
))) {
721 if (parse_contains("TopLeft", doc
, n
))
722 config_dock_floating
= FALSE
,
723 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
724 else if (parse_contains("Top", doc
, n
))
725 config_dock_floating
= FALSE
,
726 config_dock_pos
= OB_DIRECTION_NORTH
;
727 else if (parse_contains("TopRight", doc
, n
))
728 config_dock_floating
= FALSE
,
729 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
730 else if (parse_contains("Right", doc
, n
))
731 config_dock_floating
= FALSE
,
732 config_dock_pos
= OB_DIRECTION_EAST
;
733 else if (parse_contains("BottomRight", doc
, n
))
734 config_dock_floating
= FALSE
,
735 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
736 else if (parse_contains("Bottom", doc
, n
))
737 config_dock_floating
= FALSE
,
738 config_dock_pos
= OB_DIRECTION_SOUTH
;
739 else if (parse_contains("BottomLeft", doc
, n
))
740 config_dock_floating
= FALSE
,
741 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
742 else if (parse_contains("Left", doc
, n
))
743 config_dock_floating
= FALSE
,
744 config_dock_pos
= OB_DIRECTION_WEST
;
745 else if (parse_contains("Floating", doc
, n
))
746 config_dock_floating
= TRUE
;
748 if (config_dock_floating
) {
749 if ((n
= parse_find_node("floatingX", node
)))
750 config_dock_x
= parse_int(doc
, n
);
751 if ((n
= parse_find_node("floatingY", node
)))
752 config_dock_y
= parse_int(doc
, n
);
754 if ((n
= parse_find_node("noStrut", node
)))
755 config_dock_nostrut
= parse_bool(doc
, n
);
757 if ((n
= parse_find_node("stacking", node
))) {
758 if (parse_contains("above", doc
, n
))
759 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
760 else if (parse_contains("normal", doc
, n
))
761 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
762 else if (parse_contains("below", doc
, n
))
763 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
765 if ((n
= parse_find_node("direction", node
))) {
766 if (parse_contains("horizontal", doc
, n
))
767 config_dock_orient
= OB_ORIENTATION_HORZ
;
768 else if (parse_contains("vertical", doc
, n
))
769 config_dock_orient
= OB_ORIENTATION_VERT
;
771 if ((n
= parse_find_node("autoHide", node
)))
772 config_dock_hide
= parse_bool(doc
, n
);
773 if ((n
= parse_find_node("hideDelay", node
)))
774 config_dock_hide_delay
= parse_int(doc
, n
);
775 if ((n
= parse_find_node("showDelay", node
)))
776 config_dock_show_delay
= parse_int(doc
, n
);
777 if ((n
= parse_find_node("moveButton", node
))) {
778 gchar
*str
= parse_string(doc
, n
);
780 if (translate_button(str
, &s
, &b
)) {
781 config_dock_app_move_button
= b
;
782 config_dock_app_move_modifiers
= s
;
784 g_message(_("Invalid button '%s' specified in config file"), str
);
790 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
794 for (node
= node
->children
; node
; node
= node
->next
) {
795 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
798 c
= parse_string(doc
, node
);
799 config_menu_files
= g_slist_append(config_menu_files
,
800 parse_expand_tilde(c
));
803 if ((n
= parse_find_node("hideDelay", node
)))
804 config_menu_hide_delay
= parse_int(doc
, n
);
805 if ((n
= parse_find_node("middle", node
)))
806 config_menu_middle
= parse_bool(doc
, n
);
807 if ((n
= parse_find_node("submenuShowDelay", node
)))
808 config_submenu_show_delay
= parse_int(doc
, n
);
809 if ((n
= parse_find_node("applicationIcons", node
)))
810 config_menu_client_list_icons
= parse_bool(doc
, n
);
814 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
819 node
= node
->children
;
820 if ((n
= parse_find_node("strength", node
)))
821 config_resist_win
= parse_int(doc
, n
);
822 if ((n
= parse_find_node("screen_edge_strength", node
)))
823 config_resist_edge
= parse_int(doc
, n
);
829 const gchar
*actname
;
832 static void bind_default_keyboard(void)
835 ObDefKeyBind binds
[] = {
836 { "A-Tab", "NextWindow" },
837 { "S-A-Tab", "PreviousWindow" },
841 for (it
= binds
; it
->key
; ++it
) {
842 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
843 keyboard_bind(l
, actions_parse_string(it
->actname
));
850 const gchar
*context
;
851 const ObMouseAction mact
;
852 const gchar
*actname
;
855 static void bind_default_mouse(void)
858 ObDefMouseBind binds
[] = {
859 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
860 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
861 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
862 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
863 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
864 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
865 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
866 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
867 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
868 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
869 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
870 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
871 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
872 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
873 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
874 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
875 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
876 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
877 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
878 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
879 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
880 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
881 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
882 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
883 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
884 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
885 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
886 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
887 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
888 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
889 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
890 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
891 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
892 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
893 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
894 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
895 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
896 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
897 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
898 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
899 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
900 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
901 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
902 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
903 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
904 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
905 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
906 { NULL
, NULL
, 0, NULL
}
909 for (it
= binds
; it
->button
; ++it
)
910 mouse_bind(it
->button
, it
->context
, it
->mact
,
911 actions_parse_string(it
->actname
));
914 void config_startup(ObParseInst
*i
)
916 config_focus_new
= TRUE
;
917 config_focus_follow
= FALSE
;
918 config_focus_delay
= 0;
919 config_focus_raise
= FALSE
;
920 config_focus_last
= TRUE
;
921 config_focus_under_mouse
= FALSE
;
923 parse_register(i
, "focus", parse_focus
, NULL
);
925 config_place_policy
= OB_PLACE_POLICY_SMART
;
926 config_place_center
= TRUE
;
927 config_place_active
= FALSE
;
929 parse_register(i
, "placement", parse_placement
, NULL
);
931 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
933 parse_register(i
, "margins", parse_margins
, NULL
);
937 config_animate_iconify
= TRUE
;
938 config_title_layout
= g_strdup("NLIMC");
939 config_theme_keepborder
= TRUE
;
941 config_font_activewindow
= NULL
;
942 config_font_inactivewindow
= NULL
;
943 config_font_menuitem
= NULL
;
944 config_font_menutitle
= NULL
;
946 parse_register(i
, "theme", parse_theme
, NULL
);
948 config_desktops_num
= 4;
949 config_screen_firstdesk
= 1;
950 config_desktops_names
= NULL
;
951 config_desktop_popup_time
= 875;
953 parse_register(i
, "desktops", parse_desktops
, NULL
);
955 config_resize_redraw
= TRUE
;
956 config_resize_four_corners
= FALSE
;
957 config_resize_popup_show
= 1; /* nonpixel increments */
958 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
959 config_resize_popup_x_center
= FALSE
;
960 config_resize_popup_x_opposite
= FALSE
;
961 config_resize_popup_x
= 0;
962 config_resize_popup_y_center
= FALSE
;
963 config_resize_popup_y_opposite
= FALSE
;
964 config_resize_popup_y
= 0;
966 parse_register(i
, "resize", parse_resize
, NULL
);
968 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
969 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
970 config_dock_floating
= FALSE
;
971 config_dock_nostrut
= FALSE
;
974 config_dock_orient
= OB_ORIENTATION_VERT
;
975 config_dock_hide
= FALSE
;
976 config_dock_hide_delay
= 300;
977 config_dock_show_delay
= 300;
978 config_dock_app_move_button
= 2; /* middle */
979 config_dock_app_move_modifiers
= 0;
981 parse_register(i
, "dock", parse_dock
, NULL
);
983 translate_key("C-g", &config_keyboard_reset_state
,
984 &config_keyboard_reset_keycode
);
986 bind_default_keyboard();
988 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
990 config_mouse_threshold
= 8;
991 config_mouse_dclicktime
= 200;
992 config_mouse_screenedgetime
= 400;
994 bind_default_mouse();
996 parse_register(i
, "mouse", parse_mouse
, NULL
);
998 config_resist_win
= 10;
999 config_resist_edge
= 20;
1001 parse_register(i
, "resistance", parse_resistance
, NULL
);
1003 config_menu_hide_delay
= 250;
1004 config_menu_middle
= FALSE
;
1005 config_submenu_show_delay
= 0;
1006 config_menu_client_list_icons
= TRUE
;
1007 config_menu_files
= NULL
;
1009 parse_register(i
, "menu", parse_menu
, NULL
);
1011 config_per_app_settings
= NULL
;
1013 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
1016 void config_shutdown(void)
1020 g_free(config_theme
);
1022 g_free(config_title_layout
);
1024 RrFontClose(config_font_activewindow
);
1025 RrFontClose(config_font_inactivewindow
);
1026 RrFontClose(config_font_menuitem
);
1027 RrFontClose(config_font_menutitle
);
1029 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1031 g_slist_free(config_desktops_names
);
1033 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1035 g_slist_free(config_menu_files
);
1037 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1038 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1039 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1040 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1041 if (itd
->class) g_pattern_spec_free(itd
->class);
1044 g_slist_free(config_per_app_settings
);