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 ObPlaceMonitor config_place_monitor
;
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
;
92 gboolean config_menu_manage_desktops
;
94 GSList
*config_menu_files
;
96 gint config_resist_win
;
97 gint config_resist_edge
;
99 GSList
*config_per_app_settings
;
101 ObAppSettings
* config_create_app_settings(void)
103 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
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
->pos_force
= src
->pos_force
;
142 dst
->position
= src
->position
;
143 dst
->monitor
= src
->monitor
;
147 static void config_parse_gravity_coord(xmlDocPtr doc
, xmlNodePtr node
,
150 gchar
*s
= parse_string(doc
, node
);
151 if (!g_ascii_strcasecmp(s
, "center"))
156 if (s
[0] == '-' || s
[0] == '+')
166 <application name="aterm">
169 <application name="Rhythmbox">
176 .. there is a lot more settings available
181 /* Manages settings for individual applications.
182 Some notes: monitor is the screen number in a multi monitor
183 (Xinerama) setup (starting from 0) or mouse, meaning the
184 monitor the pointer is on. Default: mouse.
185 Layer can be three values, above (Always on top), below
186 (Always on bottom) and everything else (normal behaviour).
187 Positions can be an integer value or center, which will
188 center the window in the specified axis. Position is within
189 the monitor, so <position><x>center</x></position><monitor>2</monitor>
190 will center the window on the second monitor.
192 static void parse_per_app_settings(ObParseInst
*inst
, xmlDocPtr doc
,
193 xmlNodePtr node
, gpointer data
)
195 xmlNodePtr app
= parse_find_node("application", node
->children
);
196 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
197 gboolean name_set
, class_set
;
198 gboolean x_pos_given
;
201 name_set
= class_set
= x_pos_given
= FALSE
;
203 class_set
= parse_attr_string("class", app
, &class);
204 name_set
= parse_attr_string("name", app
, &name
);
205 if (class_set
|| name_set
) {
207 ObAppSettings
*settings
= config_create_app_settings();;
210 settings
->name
= g_pattern_spec_new(name
);
213 settings
->class = g_pattern_spec_new(class);
215 if (parse_attr_string("role", app
, &role
))
216 settings
->role
= g_pattern_spec_new(role
);
218 if ((n
= parse_find_node("decor", app
->children
)))
219 if (!parse_contains("default", doc
, n
))
220 settings
->decor
= parse_bool(doc
, n
);
222 if ((n
= parse_find_node("shade", app
->children
)))
223 if (!parse_contains("default", doc
, n
))
224 settings
->shade
= parse_bool(doc
, n
);
226 if ((n
= parse_find_node("position", app
->children
))) {
227 if ((c
= parse_find_node("x", n
->children
)))
228 if (!parse_contains("default", doc
, c
)) {
229 config_parse_gravity_coord(doc
, c
,
230 &settings
->position
.x
);
234 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
235 if (!parse_contains("default", doc
, c
)) {
236 config_parse_gravity_coord(doc
, c
,
237 &settings
->position
.y
);
238 settings
->pos_given
= TRUE
;
241 if (settings
->pos_given
&&
242 (c
= parse_find_node("monitor", n
->children
)))
243 if (!parse_contains("default", doc
, c
)) {
244 gchar
*s
= parse_string(doc
, c
);
245 if (!g_ascii_strcasecmp(s
, "mouse"))
246 settings
->monitor
= 0;
248 settings
->monitor
= parse_int(doc
, c
) + 1;
252 parse_attr_bool("force", n
, &settings
->pos_force
);
255 if ((n
= parse_find_node("focus", app
->children
)))
256 if (!parse_contains("default", doc
, n
))
257 settings
->focus
= parse_bool(doc
, n
);
259 if ((n
= parse_find_node("desktop", app
->children
))) {
260 if (!parse_contains("default", doc
, n
)) {
261 gchar
*s
= parse_string(doc
, n
);
262 if (!g_ascii_strcasecmp(s
, "all"))
263 settings
->desktop
= DESKTOP_ALL
;
265 gint i
= parse_int(doc
, n
);
267 settings
->desktop
= i
;
273 if ((n
= parse_find_node("layer", app
->children
)))
274 if (!parse_contains("default", doc
, n
)) {
275 gchar
*s
= parse_string(doc
, n
);
276 if (!g_ascii_strcasecmp(s
, "above"))
278 else if (!g_ascii_strcasecmp(s
, "below"))
279 settings
->layer
= -1;
285 if ((n
= parse_find_node("iconic", app
->children
)))
286 if (!parse_contains("default", doc
, n
))
287 settings
->iconic
= parse_bool(doc
, n
);
289 if ((n
= parse_find_node("skip_pager", app
->children
)))
290 if (!parse_contains("default", doc
, n
))
291 settings
->skip_pager
= parse_bool(doc
, n
);
293 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
294 if (!parse_contains("default", doc
, n
))
295 settings
->skip_taskbar
= parse_bool(doc
, n
);
297 if ((n
= parse_find_node("fullscreen", app
->children
)))
298 if (!parse_contains("default", doc
, n
))
299 settings
->fullscreen
= parse_bool(doc
, n
);
301 if ((n
= parse_find_node("maximized", app
->children
)))
302 if (!parse_contains("default", doc
, n
)) {
303 gchar
*s
= parse_string(doc
, n
);
304 if (!g_ascii_strcasecmp(s
, "horizontal")) {
305 settings
->max_horz
= TRUE
;
306 settings
->max_vert
= FALSE
;
307 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
308 settings
->max_horz
= FALSE
;
309 settings
->max_vert
= TRUE
;
311 settings
->max_horz
= settings
->max_vert
=
316 config_per_app_settings
= g_slist_append(config_per_app_settings
,
317 (gpointer
) settings
);
321 name
= class = role
= NULL
;
324 app
= parse_find_node("application", app
->next
);
331 <action name="ChangeDesktop">
338 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
343 gboolean is_chroot
= FALSE
;
345 if (!parse_attr_string("key", node
, &key
))
348 parse_attr_bool("chroot", node
, &is_chroot
);
350 keylist
= g_list_append(keylist
, key
);
352 if ((n
= parse_find_node("keybind", node
->children
))) {
354 parse_key(i
, doc
, n
, keylist
);
355 n
= parse_find_node("keybind", n
->next
);
358 else if ((n
= parse_find_node("action", node
->children
))) {
360 ObActionsAct
*action
;
362 action
= actions_parse(i
, doc
, n
);
364 keyboard_bind(keylist
, action
);
365 n
= parse_find_node("action", n
->next
);
370 keyboard_chroot(keylist
);
373 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
376 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
382 keyboard_unbind_all();
384 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
385 key
= parse_string(doc
, n
);
386 translate_key(key
, &config_keyboard_reset_state
,
387 &config_keyboard_reset_keycode
);
391 if ((n
= parse_find_node("keybind", node
->children
)))
393 parse_key(i
, doc
, n
, NULL
);
394 n
= parse_find_node("keybind", n
->next
);
400 <context name="Titlebar">
401 <mousebind button="Left" action="Press">
402 <action name="Raise"></action>
408 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
411 xmlNodePtr n
, nbut
, nact
;
418 node
= node
->children
;
420 if ((n
= parse_find_node("dragThreshold", node
)))
421 config_mouse_threshold
= parse_int(doc
, n
);
422 if ((n
= parse_find_node("doubleClickTime", node
)))
423 config_mouse_dclicktime
= parse_int(doc
, n
);
424 if ((n
= parse_find_node("screenEdgeWarpTime", node
)))
425 config_mouse_screenedgetime
= parse_int(doc
, n
);
427 n
= parse_find_node("context", node
);
429 if (!parse_attr_string("name", n
, &contextstr
))
431 nbut
= parse_find_node("mousebind", n
->children
);
433 if (!parse_attr_string("button", nbut
, &buttonstr
))
435 if (parse_attr_contains("press", nbut
, "action")) {
436 mact
= OB_MOUSE_ACTION_PRESS
;
437 } else if (parse_attr_contains("release", nbut
, "action")) {
438 mact
= OB_MOUSE_ACTION_RELEASE
;
439 } else if (parse_attr_contains("click", nbut
, "action")) {
440 mact
= OB_MOUSE_ACTION_CLICK
;
441 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
442 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
443 } else if (parse_attr_contains("drag", nbut
, "action")) {
444 mact
= OB_MOUSE_ACTION_MOTION
;
447 nact
= parse_find_node("action", nbut
->children
);
449 ObActionsAct
*action
;
451 if ((action
= actions_parse(i
, doc
, nact
)))
452 mouse_bind(buttonstr
, contextstr
, mact
, action
);
453 nact
= parse_find_node("action", nact
->next
);
457 nbut
= parse_find_node("mousebind", nbut
->next
);
461 n
= parse_find_node("context", n
->next
);
465 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
470 node
= node
->children
;
472 if ((n
= parse_find_node("focusNew", node
)))
473 config_focus_new
= parse_bool(doc
, n
);
474 if ((n
= parse_find_node("followMouse", node
)))
475 config_focus_follow
= parse_bool(doc
, n
);
476 if ((n
= parse_find_node("focusDelay", node
)))
477 config_focus_delay
= parse_int(doc
, n
);
478 if ((n
= parse_find_node("raiseOnFocus", node
)))
479 config_focus_raise
= parse_bool(doc
, n
);
480 if ((n
= parse_find_node("focusLast", node
)))
481 config_focus_last
= parse_bool(doc
, n
);
482 if ((n
= parse_find_node("underMouse", node
)))
483 config_focus_under_mouse
= parse_bool(doc
, n
);
486 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
491 node
= node
->children
;
493 if ((n
= parse_find_node("policy", node
)))
494 if (parse_contains("UnderMouse", doc
, n
))
495 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
496 if ((n
= parse_find_node("center", node
)))
497 config_place_center
= parse_bool(doc
, n
);
498 if ((n
= parse_find_node("monitor", node
))) {
499 if (parse_contains("active", doc
, n
))
500 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
501 else if (parse_contains("mouse", doc
, n
))
502 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
506 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
511 node
= node
->children
;
513 if ((n
= parse_find_node("top", node
)))
514 config_margins
.top
= MAX(0, parse_int(doc
, n
));
515 if ((n
= parse_find_node("left", node
)))
516 config_margins
.left
= MAX(0, parse_int(doc
, n
));
517 if ((n
= parse_find_node("right", node
)))
518 config_margins
.right
= MAX(0, parse_int(doc
, n
));
519 if ((n
= parse_find_node("bottom", node
)))
520 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
523 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
528 node
= node
->children
;
530 if ((n
= parse_find_node("name", node
))) {
533 g_free(config_theme
);
534 c
= parse_string(doc
, n
);
535 config_theme
= parse_expand_tilde(c
);
538 if ((n
= parse_find_node("titleLayout", node
))) {
541 g_free(config_title_layout
);
542 config_title_layout
= parse_string(doc
, n
);
544 /* replace duplicates with spaces */
545 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
546 for (d
= c
+1; *d
!= '\0'; ++d
)
547 if (*c
== *d
) *d
= ' ';
549 if ((n
= parse_find_node("keepBorder", node
)))
550 config_theme_keepborder
= parse_bool(doc
, n
);
551 if ((n
= parse_find_node("animateIconify", node
)))
552 config_animate_iconify
= parse_bool(doc
, n
);
554 n
= parse_find_node("font", node
);
558 gchar
*name
= g_strdup(RrDefaultFontFamily
);
559 gint size
= RrDefaultFontSize
;
560 RrFontWeight weight
= RrDefaultFontWeight
;
561 RrFontSlant slant
= RrDefaultFontSlant
;
563 if (parse_attr_contains("ActiveWindow", n
, "place"))
564 font
= &config_font_activewindow
;
565 else if (parse_attr_contains("InactiveWindow", n
, "place"))
566 font
= &config_font_inactivewindow
;
567 else if (parse_attr_contains("MenuHeader", n
, "place"))
568 font
= &config_font_menutitle
;
569 else if (parse_attr_contains("MenuItem", n
, "place"))
570 font
= &config_font_menuitem
;
571 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
572 font
= &config_font_osd
;
576 if ((fnode
= parse_find_node("name", n
->children
))) {
578 name
= parse_string(doc
, fnode
);
580 if ((fnode
= parse_find_node("size", n
->children
))) {
581 int s
= parse_int(doc
, fnode
);
584 if ((fnode
= parse_find_node("weight", n
->children
))) {
585 gchar
*w
= parse_string(doc
, fnode
);
586 if (!g_ascii_strcasecmp(w
, "Bold"))
587 weight
= RR_FONTWEIGHT_BOLD
;
590 if ((fnode
= parse_find_node("slant", n
->children
))) {
591 gchar
*s
= parse_string(doc
, fnode
);
592 if (!g_ascii_strcasecmp(s
, "Italic"))
593 slant
= RR_FONTSLANT_ITALIC
;
594 if (!g_ascii_strcasecmp(s
, "Oblique"))
595 slant
= RR_FONTSLANT_OBLIQUE
;
599 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
602 n
= parse_find_node("font", n
->next
);
606 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
611 node
= node
->children
;
613 if ((n
= parse_find_node("number", node
))) {
614 gint d
= parse_int(doc
, n
);
616 config_desktops_num
= (unsigned) d
;
618 if ((n
= parse_find_node("firstdesk", node
))) {
619 gint d
= parse_int(doc
, n
);
621 config_screen_firstdesk
= (unsigned) d
;
623 if ((n
= parse_find_node("names", node
))) {
627 for (it
= config_desktops_names
; it
; it
= it
->next
)
629 g_slist_free(config_desktops_names
);
630 config_desktops_names
= NULL
;
632 nname
= parse_find_node("name", n
->children
);
634 config_desktops_names
= g_slist_append(config_desktops_names
,
635 parse_string(doc
, nname
));
636 nname
= parse_find_node("name", nname
->next
);
639 if ((n
= parse_find_node("popupTime", node
)))
640 config_desktop_popup_time
= parse_int(doc
, n
);
643 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
648 node
= node
->children
;
650 if ((n
= parse_find_node("drawContents", node
)))
651 config_resize_redraw
= parse_bool(doc
, n
);
652 if ((n
= parse_find_node("popupShow", node
))) {
653 config_resize_popup_show
= parse_int(doc
, n
);
654 if (parse_contains("Always", doc
, n
))
655 config_resize_popup_show
= 2;
656 else if (parse_contains("Never", doc
, n
))
657 config_resize_popup_show
= 0;
658 else if (parse_contains("Nonpixel", doc
, n
))
659 config_resize_popup_show
= 1;
661 if ((n
= parse_find_node("popupPosition", node
))) {
662 if (parse_contains("Top", doc
, n
))
663 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
664 else if (parse_contains("Center", doc
, n
))
665 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
666 else if (parse_contains("Fixed", doc
, n
)) {
667 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
669 if ((n
= parse_find_node("popupFixedPosition", node
))) {
672 if ((n2
= parse_find_node("x", n
->children
)))
673 config_parse_gravity_coord(doc
, n2
,
674 &config_resize_popup_fixed
.x
);
675 if ((n2
= parse_find_node("y", n
->children
)))
676 config_parse_gravity_coord(doc
, n2
,
677 &config_resize_popup_fixed
.y
);
679 config_resize_popup_fixed
.x
.pos
=
680 MAX(config_resize_popup_fixed
.x
.pos
, 0);
681 config_resize_popup_fixed
.y
.pos
=
682 MAX(config_resize_popup_fixed
.y
.pos
, 0);
688 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
693 node
= node
->children
;
695 if ((n
= parse_find_node("position", node
))) {
696 if (parse_contains("TopLeft", doc
, n
))
697 config_dock_floating
= FALSE
,
698 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
699 else if (parse_contains("Top", doc
, n
))
700 config_dock_floating
= FALSE
,
701 config_dock_pos
= OB_DIRECTION_NORTH
;
702 else if (parse_contains("TopRight", doc
, n
))
703 config_dock_floating
= FALSE
,
704 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
705 else if (parse_contains("Right", doc
, n
))
706 config_dock_floating
= FALSE
,
707 config_dock_pos
= OB_DIRECTION_EAST
;
708 else if (parse_contains("BottomRight", doc
, n
))
709 config_dock_floating
= FALSE
,
710 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
711 else if (parse_contains("Bottom", doc
, n
))
712 config_dock_floating
= FALSE
,
713 config_dock_pos
= OB_DIRECTION_SOUTH
;
714 else if (parse_contains("BottomLeft", doc
, n
))
715 config_dock_floating
= FALSE
,
716 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
717 else if (parse_contains("Left", doc
, n
))
718 config_dock_floating
= FALSE
,
719 config_dock_pos
= OB_DIRECTION_WEST
;
720 else if (parse_contains("Floating", doc
, n
))
721 config_dock_floating
= TRUE
;
723 if (config_dock_floating
) {
724 if ((n
= parse_find_node("floatingX", node
)))
725 config_dock_x
= parse_int(doc
, n
);
726 if ((n
= parse_find_node("floatingY", node
)))
727 config_dock_y
= parse_int(doc
, n
);
729 if ((n
= parse_find_node("noStrut", node
)))
730 config_dock_nostrut
= parse_bool(doc
, n
);
732 if ((n
= parse_find_node("stacking", node
))) {
733 if (parse_contains("above", doc
, n
))
734 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
735 else if (parse_contains("normal", doc
, n
))
736 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
737 else if (parse_contains("below", doc
, n
))
738 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
740 if ((n
= parse_find_node("direction", node
))) {
741 if (parse_contains("horizontal", doc
, n
))
742 config_dock_orient
= OB_ORIENTATION_HORZ
;
743 else if (parse_contains("vertical", doc
, n
))
744 config_dock_orient
= OB_ORIENTATION_VERT
;
746 if ((n
= parse_find_node("autoHide", node
)))
747 config_dock_hide
= parse_bool(doc
, n
);
748 if ((n
= parse_find_node("hideDelay", node
)))
749 config_dock_hide_delay
= parse_int(doc
, n
);
750 if ((n
= parse_find_node("showDelay", node
)))
751 config_dock_show_delay
= parse_int(doc
, n
);
752 if ((n
= parse_find_node("moveButton", node
))) {
753 gchar
*str
= parse_string(doc
, n
);
755 if (translate_button(str
, &s
, &b
)) {
756 config_dock_app_move_button
= b
;
757 config_dock_app_move_modifiers
= s
;
759 g_message(_("Invalid button '%s' specified in config file"), str
);
765 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
769 for (node
= node
->children
; node
; node
= node
->next
) {
770 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
773 c
= parse_string(doc
, node
);
774 config_menu_files
= g_slist_append(config_menu_files
,
775 parse_expand_tilde(c
));
778 if ((n
= parse_find_node("hideDelay", node
)))
779 config_menu_hide_delay
= parse_int(doc
, n
);
780 if ((n
= parse_find_node("middle", node
)))
781 config_menu_middle
= parse_bool(doc
, n
);
782 if ((n
= parse_find_node("submenuShowDelay", node
)))
783 config_submenu_show_delay
= parse_int(doc
, n
);
784 if ((n
= parse_find_node("applicationIcons", node
)))
785 config_menu_client_list_icons
= parse_bool(doc
, n
);
786 if ((n
= parse_find_node("manageDesktops", node
)))
787 config_menu_manage_desktops
= parse_bool(doc
, n
);
791 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
796 node
= node
->children
;
797 if ((n
= parse_find_node("strength", node
)))
798 config_resist_win
= parse_int(doc
, n
);
799 if ((n
= parse_find_node("screen_edge_strength", node
)))
800 config_resist_edge
= parse_int(doc
, n
);
806 const gchar
*actname
;
809 static void bind_default_keyboard(void)
812 ObDefKeyBind binds
[] = {
813 { "A-Tab", "NextWindow" },
814 { "S-A-Tab", "PreviousWindow" },
818 for (it
= binds
; it
->key
; ++it
) {
819 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
820 keyboard_bind(l
, actions_parse_string(it
->actname
));
827 const gchar
*context
;
828 const ObMouseAction mact
;
829 const gchar
*actname
;
832 static void bind_default_mouse(void)
835 ObDefMouseBind binds
[] = {
836 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
837 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
838 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
839 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
840 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
841 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
842 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
843 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
844 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
845 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
846 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
847 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
848 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
849 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
850 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
851 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
852 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
853 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
854 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
855 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
856 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
857 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
858 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
859 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
860 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
861 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
862 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
863 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
864 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
865 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
866 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
867 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
868 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
869 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
870 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
871 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
872 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
873 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
874 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
875 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
876 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
877 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
878 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
879 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
880 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
881 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
882 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
883 { NULL
, NULL
, 0, NULL
}
886 for (it
= binds
; it
->button
; ++it
)
887 mouse_bind(it
->button
, it
->context
, it
->mact
,
888 actions_parse_string(it
->actname
));
891 void config_startup(ObParseInst
*i
)
893 config_focus_new
= TRUE
;
894 config_focus_follow
= FALSE
;
895 config_focus_delay
= 0;
896 config_focus_raise
= FALSE
;
897 config_focus_last
= TRUE
;
898 config_focus_under_mouse
= FALSE
;
900 parse_register(i
, "focus", parse_focus
, NULL
);
902 config_place_policy
= OB_PLACE_POLICY_SMART
;
903 config_place_center
= TRUE
;
904 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
906 parse_register(i
, "placement", parse_placement
, NULL
);
908 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
910 parse_register(i
, "margins", parse_margins
, NULL
);
914 config_animate_iconify
= TRUE
;
915 config_title_layout
= g_strdup("NLIMC");
916 config_theme_keepborder
= TRUE
;
918 config_font_activewindow
= NULL
;
919 config_font_inactivewindow
= NULL
;
920 config_font_menuitem
= NULL
;
921 config_font_menutitle
= NULL
;
923 parse_register(i
, "theme", parse_theme
, NULL
);
925 config_desktops_num
= 4;
926 config_screen_firstdesk
= 1;
927 config_desktops_names
= NULL
;
928 config_desktop_popup_time
= 875;
930 parse_register(i
, "desktops", parse_desktops
, NULL
);
932 config_resize_redraw
= TRUE
;
933 config_resize_popup_show
= 1; /* nonpixel increments */
934 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
935 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
936 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
938 parse_register(i
, "resize", parse_resize
, NULL
);
940 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
941 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
942 config_dock_floating
= FALSE
;
943 config_dock_nostrut
= FALSE
;
946 config_dock_orient
= OB_ORIENTATION_VERT
;
947 config_dock_hide
= FALSE
;
948 config_dock_hide_delay
= 300;
949 config_dock_show_delay
= 300;
950 config_dock_app_move_button
= 2; /* middle */
951 config_dock_app_move_modifiers
= 0;
953 parse_register(i
, "dock", parse_dock
, NULL
);
955 translate_key("C-g", &config_keyboard_reset_state
,
956 &config_keyboard_reset_keycode
);
958 bind_default_keyboard();
960 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
962 config_mouse_threshold
= 8;
963 config_mouse_dclicktime
= 200;
964 config_mouse_screenedgetime
= 400;
966 bind_default_mouse();
968 parse_register(i
, "mouse", parse_mouse
, NULL
);
970 config_resist_win
= 10;
971 config_resist_edge
= 20;
973 parse_register(i
, "resistance", parse_resistance
, NULL
);
975 config_menu_hide_delay
= 250;
976 config_menu_middle
= FALSE
;
977 config_submenu_show_delay
= 0;
978 config_menu_client_list_icons
= TRUE
;
979 config_menu_manage_desktops
= TRUE
;
980 config_menu_files
= NULL
;
982 parse_register(i
, "menu", parse_menu
, NULL
);
984 config_per_app_settings
= NULL
;
986 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
989 void config_shutdown(void)
993 g_free(config_theme
);
995 g_free(config_title_layout
);
997 RrFontClose(config_font_activewindow
);
998 RrFontClose(config_font_inactivewindow
);
999 RrFontClose(config_font_menuitem
);
1000 RrFontClose(config_font_menutitle
);
1001 RrFontClose(config_font_osd
);
1003 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1005 g_slist_free(config_desktops_names
);
1007 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1009 g_slist_free(config_menu_files
);
1011 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1012 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1013 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1014 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1015 if (itd
->class) g_pattern_spec_free(itd
->class);
1018 g_slist_free(config_per_app_settings
);