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.
24 #include "translate.h"
29 #include "obt/paths.h"
31 gboolean config_focus_new
;
32 gboolean config_focus_follow
;
33 guint config_focus_delay
;
34 gboolean config_focus_raise
;
35 gboolean config_focus_last
;
36 gboolean config_focus_under_mouse
;
38 ObPlacePolicy config_place_policy
;
39 gboolean config_place_center
;
40 ObPlaceMonitor config_place_monitor
;
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 guint 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 gint config_resize_popup_show
;
64 ObResizePopupPos config_resize_popup_pos
;
65 GravityPoint config_resize_popup_fixed
;
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
;
91 gboolean config_menu_manage_desktops
;
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
->pos_force
= src
->pos_force
;
141 dst
->position
= src
->position
;
142 dst
->monitor
= src
->monitor
;
146 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
148 gchar
*s
= obt_parse_node_string(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(xmlNodePtr node
, gpointer d
)
192 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
193 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
194 gboolean name_set
, class_set
;
195 gboolean x_pos_given
;
198 name_set
= class_set
= x_pos_given
= FALSE
;
200 class_set
= obt_parse_attr_string(app
, "class", &class);
201 name_set
= obt_parse_attr_string(app
, "name", &name
);
202 if (class_set
|| name_set
) {
204 ObAppSettings
*settings
= config_create_app_settings();;
207 settings
->name
= g_pattern_spec_new(name
);
210 settings
->class = g_pattern_spec_new(class);
212 if (obt_parse_attr_string(app
, "role", &role
))
213 settings
->role
= g_pattern_spec_new(role
);
215 if ((n
= obt_parse_find_node(app
->children
, "decor")))
216 if (!obt_parse_node_contains(n
, "default"))
217 settings
->decor
= obt_parse_node_bool(n
);
219 if ((n
= obt_parse_find_node(app
->children
, "shade")))
220 if (!obt_parse_node_contains(n
, "default"))
221 settings
->shade
= obt_parse_node_bool(n
);
223 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
224 if ((c
= obt_parse_find_node(n
->children
, "x")))
225 if (!obt_parse_node_contains(c
, "default")) {
226 config_parse_gravity_coord(c
, &settings
->position
.x
);
230 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
231 if (!obt_parse_node_contains(c
, "default")) {
232 config_parse_gravity_coord(c
, &settings
->position
.y
);
233 settings
->pos_given
= TRUE
;
236 if (settings
->pos_given
&&
237 (c
= obt_parse_find_node(n
->children
, "monitor")))
238 if (!obt_parse_node_contains(c
, "default")) {
239 gchar
*s
= obt_parse_node_string(c
);
240 if (!g_ascii_strcasecmp(s
, "mouse"))
241 settings
->monitor
= 0;
243 settings
->monitor
= obt_parse_node_int(c
) + 1;
247 obt_parse_attr_bool(n
, "force", &settings
->pos_force
);
250 if ((n
= obt_parse_find_node(app
->children
, "focus")))
251 if (!obt_parse_node_contains(n
, "default"))
252 settings
->focus
= obt_parse_node_bool(n
);
254 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
255 if (!obt_parse_node_contains(n
, "default")) {
256 gchar
*s
= obt_parse_node_string(n
);
257 if (!g_ascii_strcasecmp(s
, "all"))
258 settings
->desktop
= DESKTOP_ALL
;
260 gint i
= obt_parse_node_int(n
);
262 settings
->desktop
= i
;
268 if ((n
= obt_parse_find_node(app
->children
, "layer")))
269 if (!obt_parse_node_contains(n
, "default")) {
270 gchar
*s
= obt_parse_node_string(n
);
271 if (!g_ascii_strcasecmp(s
, "above"))
273 else if (!g_ascii_strcasecmp(s
, "below"))
274 settings
->layer
= -1;
280 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
281 if (!obt_parse_node_contains(n
, "default"))
282 settings
->iconic
= obt_parse_node_bool(n
);
284 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
285 if (!obt_parse_node_contains(n
, "default"))
286 settings
->skip_pager
= obt_parse_node_bool(n
);
288 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
289 if (!obt_parse_node_contains(n
, "default"))
290 settings
->skip_taskbar
= obt_parse_node_bool(n
);
292 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
293 if (!obt_parse_node_contains(n
, "default"))
294 settings
->fullscreen
= obt_parse_node_bool(n
);
296 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
297 if (!obt_parse_node_contains(n
, "default")) {
298 gchar
*s
= obt_parse_node_string(n
);
299 if (!g_ascii_strcasecmp(s
, "horizontal")) {
300 settings
->max_horz
= TRUE
;
301 settings
->max_vert
= FALSE
;
302 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
303 settings
->max_horz
= FALSE
;
304 settings
->max_vert
= TRUE
;
306 settings
->max_horz
= settings
->max_vert
=
307 obt_parse_node_bool(n
);
311 config_per_app_settings
= g_slist_append(config_per_app_settings
,
312 (gpointer
) settings
);
316 name
= class = role
= NULL
;
319 app
= obt_parse_find_node(app
->next
, "application");
326 <action name="ChangeDesktop">
333 static void parse_key(xmlNodePtr node
, GList
*keylist
)
337 gboolean is_chroot
= FALSE
;
339 if (!obt_parse_attr_string(node
, "key", &key
))
342 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
344 keylist
= g_list_append(keylist
, key
);
346 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
348 parse_key(n
, keylist
);
349 n
= obt_parse_find_node(n
->next
, "keybind");
352 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
354 ObActionsAct
*action
;
356 action
= actions_parse(n
);
358 keyboard_bind(keylist
, action
);
359 n
= obt_parse_find_node(n
->next
, "action");
364 keyboard_chroot(keylist
);
367 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
370 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
375 keyboard_unbind_all();
377 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
378 key
= obt_parse_node_string(n
);
379 translate_key(key
, &config_keyboard_reset_state
,
380 &config_keyboard_reset_keycode
);
384 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
387 n
= obt_parse_find_node(n
->next
, "keybind");
393 <context name="Titlebar">
394 <mousebind button="Left" action="Press">
395 <action name="Raise"></action>
401 static void parse_mouse(xmlNodePtr node
, gpointer d
)
403 xmlNodePtr n
, nbut
, nact
;
410 node
= node
->children
;
412 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
413 config_mouse_threshold
= obt_parse_node_int(n
);
414 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
415 config_mouse_dclicktime
= obt_parse_node_int(n
);
416 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime")))
417 config_mouse_screenedgetime
= obt_parse_node_int(n
);
419 n
= obt_parse_find_node(node
, "context");
421 if (!obt_parse_attr_string(n
, "name", &contextstr
))
423 nbut
= obt_parse_find_node(n
->children
, "mousebind");
425 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
427 if (obt_parse_attr_contains(nbut
, "action", "press")) {
428 mact
= OB_MOUSE_ACTION_PRESS
;
429 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
430 mact
= OB_MOUSE_ACTION_RELEASE
;
431 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
432 mact
= OB_MOUSE_ACTION_CLICK
;
433 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
434 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
435 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
436 mact
= OB_MOUSE_ACTION_MOTION
;
439 nact
= obt_parse_find_node(nbut
->children
, "action");
441 ObActionsAct
*action
;
443 if ((action
= actions_parse(nact
)))
444 mouse_bind(buttonstr
, contextstr
, mact
, action
);
445 nact
= obt_parse_find_node(nact
->next
, "action");
449 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
453 n
= obt_parse_find_node(n
->next
, "context");
457 static void parse_focus(xmlNodePtr node
, gpointer d
)
461 node
= node
->children
;
463 if ((n
= obt_parse_find_node(node
, "focusNew")))
464 config_focus_new
= obt_parse_node_bool(n
);
465 if ((n
= obt_parse_find_node(node
, "followMouse")))
466 config_focus_follow
= obt_parse_node_bool(n
);
467 if ((n
= obt_parse_find_node(node
, "focusDelay")))
468 config_focus_delay
= obt_parse_node_int(n
);
469 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
470 config_focus_raise
= obt_parse_node_bool(n
);
471 if ((n
= obt_parse_find_node(node
, "focusLast")))
472 config_focus_last
= obt_parse_node_bool(n
);
473 if ((n
= obt_parse_find_node(node
, "underMouse")))
474 config_focus_under_mouse
= obt_parse_node_bool(n
);
477 static void parse_placement(xmlNodePtr node
, gpointer d
)
481 node
= node
->children
;
483 if ((n
= obt_parse_find_node(node
, "policy")))
484 if (obt_parse_node_contains(n
, "UnderMouse"))
485 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
486 if ((n
= obt_parse_find_node(node
, "center")))
487 config_place_center
= obt_parse_node_bool(n
);
488 if ((n
= obt_parse_find_node(node
, "monitor"))) {
489 if (obt_parse_node_contains(n
, "active"))
490 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
491 else if (obt_parse_node_contains(n
, "mouse"))
492 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
496 static void parse_margins(xmlNodePtr node
, gpointer d
)
500 node
= node
->children
;
502 if ((n
= obt_parse_find_node(node
, "top")))
503 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
504 if ((n
= obt_parse_find_node(node
, "left")))
505 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
506 if ((n
= obt_parse_find_node(node
, "right")))
507 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
508 if ((n
= obt_parse_find_node(node
, "bottom")))
509 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
512 static void parse_theme(xmlNodePtr node
, gpointer d
)
516 node
= node
->children
;
518 if ((n
= obt_parse_find_node(node
, "name"))) {
521 g_free(config_theme
);
522 c
= obt_parse_node_string(n
);
523 config_theme
= obt_paths_expand_tilde(c
);
526 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
529 g_free(config_title_layout
);
530 config_title_layout
= obt_parse_node_string(n
);
532 /* replace duplicates with spaces */
533 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
534 for (d
= c
+1; *d
!= '\0'; ++d
)
535 if (*c
== *d
) *d
= ' ';
537 if ((n
= obt_parse_find_node(node
, "keepBorder")))
538 config_theme_keepborder
= obt_parse_node_bool(n
);
539 if ((n
= obt_parse_find_node(node
, "animateIconify")))
540 config_animate_iconify
= obt_parse_node_bool(n
);
542 n
= obt_parse_find_node(node
, "font");
546 gchar
*name
= g_strdup(RrDefaultFontFamily
);
547 gint size
= RrDefaultFontSize
;
548 RrFontWeight weight
= RrDefaultFontWeight
;
549 RrFontSlant slant
= RrDefaultFontSlant
;
551 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
552 font
= &config_font_activewindow
;
553 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
554 font
= &config_font_inactivewindow
;
555 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
556 font
= &config_font_menutitle
;
557 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
558 font
= &config_font_menuitem
;
559 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
560 font
= &config_font_osd
;
564 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
566 name
= obt_parse_node_string(fnode
);
568 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
569 int s
= obt_parse_node_int(fnode
);
572 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
573 gchar
*w
= obt_parse_node_string(fnode
);
574 if (!g_ascii_strcasecmp(w
, "Bold"))
575 weight
= RR_FONTWEIGHT_BOLD
;
578 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
579 gchar
*s
= obt_parse_node_string(fnode
);
580 if (!g_ascii_strcasecmp(s
, "Italic"))
581 slant
= RR_FONTSLANT_ITALIC
;
582 if (!g_ascii_strcasecmp(s
, "Oblique"))
583 slant
= RR_FONTSLANT_OBLIQUE
;
587 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
590 n
= obt_parse_find_node(n
->next
, "font");
594 static void parse_desktops(xmlNodePtr node
, gpointer d
)
598 node
= node
->children
;
600 if ((n
= obt_parse_find_node(node
, "number"))) {
601 gint d
= obt_parse_node_int(n
);
603 config_desktops_num
= (unsigned) d
;
605 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
606 gint d
= obt_parse_node_int(n
);
608 config_screen_firstdesk
= (unsigned) d
;
610 if ((n
= obt_parse_find_node(node
, "names"))) {
614 for (it
= config_desktops_names
; it
; it
= it
->next
)
616 g_slist_free(config_desktops_names
);
617 config_desktops_names
= NULL
;
619 nname
= obt_parse_find_node(n
->children
, "name");
621 config_desktops_names
=
622 g_slist_append(config_desktops_names
,
623 obt_parse_node_string(nname
));
624 nname
= obt_parse_find_node(nname
->next
, "name");
627 if ((n
= obt_parse_find_node(node
, "popupTime")))
628 config_desktop_popup_time
= obt_parse_node_int(n
);
631 static void parse_resize(xmlNodePtr node
, gpointer d
)
635 node
= node
->children
;
637 if ((n
= obt_parse_find_node(node
, "drawContents")))
638 config_resize_redraw
= obt_parse_node_bool(n
);
639 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
640 config_resize_popup_show
= obt_parse_node_int(n
);
641 if (obt_parse_node_contains(n
, "Always"))
642 config_resize_popup_show
= 2;
643 else if (obt_parse_node_contains(n
, "Never"))
644 config_resize_popup_show
= 0;
645 else if (obt_parse_node_contains(n
, "Nonpixel"))
646 config_resize_popup_show
= 1;
648 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
649 if (obt_parse_node_contains(n
, "Top"))
650 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
651 else if (obt_parse_node_contains(n
, "Center"))
652 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
653 else if (obt_parse_node_contains(n
, "Fixed")) {
654 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
656 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
659 if ((n2
= obt_parse_find_node(n
->children
, "x")))
660 config_parse_gravity_coord(n2
,
661 &config_resize_popup_fixed
.x
);
662 if ((n2
= obt_parse_find_node(n
->children
, "y")))
663 config_parse_gravity_coord(n2
,
664 &config_resize_popup_fixed
.y
);
670 static void parse_dock(xmlNodePtr node
, gpointer d
)
674 node
= node
->children
;
676 if ((n
= obt_parse_find_node(node
, "position"))) {
677 if (obt_parse_node_contains(n
, "TopLeft"))
678 config_dock_floating
= FALSE
,
679 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
680 else if (obt_parse_node_contains(n
, "Top"))
681 config_dock_floating
= FALSE
,
682 config_dock_pos
= OB_DIRECTION_NORTH
;
683 else if (obt_parse_node_contains(n
, "TopRight"))
684 config_dock_floating
= FALSE
,
685 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
686 else if (obt_parse_node_contains(n
, "Right"))
687 config_dock_floating
= FALSE
,
688 config_dock_pos
= OB_DIRECTION_EAST
;
689 else if (obt_parse_node_contains(n
, "BottomRight"))
690 config_dock_floating
= FALSE
,
691 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
692 else if (obt_parse_node_contains(n
, "Bottom"))
693 config_dock_floating
= FALSE
,
694 config_dock_pos
= OB_DIRECTION_SOUTH
;
695 else if (obt_parse_node_contains(n
, "BottomLeft"))
696 config_dock_floating
= FALSE
,
697 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
698 else if (obt_parse_node_contains(n
, "Left"))
699 config_dock_floating
= FALSE
,
700 config_dock_pos
= OB_DIRECTION_WEST
;
701 else if (obt_parse_node_contains(n
, "Floating"))
702 config_dock_floating
= TRUE
;
704 if (config_dock_floating
) {
705 if ((n
= obt_parse_find_node(node
, "floatingX")))
706 config_dock_x
= obt_parse_node_int(n
);
707 if ((n
= obt_parse_find_node(node
, "floatingY")))
708 config_dock_y
= obt_parse_node_int(n
);
710 if ((n
= obt_parse_find_node(node
, "noStrut")))
711 config_dock_nostrut
= obt_parse_node_bool(n
);
713 if ((n
= obt_parse_find_node(node
, "stacking"))) {
714 if (obt_parse_node_contains(n
, "normal"))
715 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
716 else if (obt_parse_node_contains(n
, "below"))
717 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
718 else if (obt_parse_node_contains(n
, "above"))
719 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
721 if ((n
= obt_parse_find_node(node
, "direction"))) {
722 if (obt_parse_node_contains(n
, "horizontal"))
723 config_dock_orient
= OB_ORIENTATION_HORZ
;
724 else if (obt_parse_node_contains(n
, "vertical"))
725 config_dock_orient
= OB_ORIENTATION_VERT
;
727 if ((n
= obt_parse_find_node(node
, "autoHide")))
728 config_dock_hide
= obt_parse_node_bool(n
);
729 if ((n
= obt_parse_find_node(node
, "hideDelay")))
730 config_dock_hide_delay
= obt_parse_node_int(n
);
731 if ((n
= obt_parse_find_node(node
, "showDelay")))
732 config_dock_show_delay
= obt_parse_node_int(n
);
733 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
734 gchar
*str
= obt_parse_node_string(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(xmlNodePtr node
, gpointer d
)
749 for (node
= node
->children
; node
; node
= node
->next
) {
750 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
753 c
= obt_parse_node_string(node
);
754 config_menu_files
= g_slist_append(config_menu_files
,
755 obt_paths_expand_tilde(c
));
758 if ((n
= obt_parse_find_node(node
, "hideDelay")))
759 config_menu_hide_delay
= obt_parse_node_int(n
);
760 if ((n
= obt_parse_find_node(node
, "middle")))
761 config_menu_middle
= obt_parse_node_bool(n
);
762 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
763 config_submenu_show_delay
= obt_parse_node_int(n
);
764 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
765 config_menu_client_list_icons
= obt_parse_node_bool(n
);
766 if ((n
= obt_parse_find_node(node
, "manageDesktops")))
767 config_menu_manage_desktops
= obt_parse_node_bool(n
);
771 static void parse_resistance(xmlNodePtr node
, gpointer d
)
775 node
= node
->children
;
776 if ((n
= obt_parse_find_node(node
, "strength")))
777 config_resist_win
= obt_parse_node_int(n
);
778 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
779 config_resist_edge
= obt_parse_node_int(n
);
785 const gchar
*actname
;
788 static void bind_default_keyboard(void)
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(void)
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(ObtParseInst
*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 obt_parse_register(i
, "focus", parse_focus
, NULL
);
881 config_place_policy
= OB_PLACE_POLICY_SMART
;
882 config_place_center
= TRUE
;
883 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
885 obt_parse_register(i
, "placement", parse_placement
, NULL
);
887 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
889 obt_parse_register(i
, "margins", parse_margins
, NULL
);
893 config_animate_iconify
= TRUE
;
894 config_title_layout
= g_strdup("NLIMC");
895 config_theme_keepborder
= TRUE
;
897 config_font_activewindow
= NULL
;
898 config_font_inactivewindow
= NULL
;
899 config_font_menuitem
= NULL
;
900 config_font_menutitle
= NULL
;
902 obt_parse_register(i
, "theme", parse_theme
, NULL
);
904 config_desktops_num
= 4;
905 config_screen_firstdesk
= 1;
906 config_desktops_names
= NULL
;
907 config_desktop_popup_time
= 875;
909 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
911 config_resize_redraw
= TRUE
;
912 config_resize_popup_show
= 1; /* nonpixel increments */
913 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
914 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
915 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
917 obt_parse_register(i
, "resize", parse_resize
, NULL
);
919 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
920 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
921 config_dock_floating
= FALSE
;
922 config_dock_nostrut
= FALSE
;
925 config_dock_orient
= OB_ORIENTATION_VERT
;
926 config_dock_hide
= FALSE
;
927 config_dock_hide_delay
= 300;
928 config_dock_show_delay
= 300;
929 config_dock_app_move_button
= 2; /* middle */
930 config_dock_app_move_modifiers
= 0;
932 obt_parse_register(i
, "dock", parse_dock
, NULL
);
934 translate_key("C-g", &config_keyboard_reset_state
,
935 &config_keyboard_reset_keycode
);
937 bind_default_keyboard();
939 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
941 config_mouse_threshold
= 8;
942 config_mouse_dclicktime
= 200;
943 config_mouse_screenedgetime
= 400;
945 bind_default_mouse();
947 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
949 config_resist_win
= 10;
950 config_resist_edge
= 20;
952 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
954 config_menu_hide_delay
= 250;
955 config_menu_middle
= FALSE
;
956 config_submenu_show_delay
= 0;
957 config_menu_client_list_icons
= TRUE
;
958 config_menu_manage_desktops
= TRUE
;
959 config_menu_files
= NULL
;
961 obt_parse_register(i
, "menu", parse_menu
, NULL
);
963 config_per_app_settings
= NULL
;
965 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
968 void config_shutdown(void)
972 g_free(config_theme
);
974 g_free(config_title_layout
);
976 RrFontClose(config_font_activewindow
);
977 RrFontClose(config_font_inactivewindow
);
978 RrFontClose(config_font_menuitem
);
979 RrFontClose(config_font_menutitle
);
980 RrFontClose(config_font_osd
);
982 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
984 g_slist_free(config_desktops_names
);
986 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
988 g_slist_free(config_menu_files
);
990 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
991 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
992 if (itd
->name
) g_pattern_spec_free(itd
->name
);
993 if (itd
->role
) g_pattern_spec_free(itd
->role
);
994 if (itd
->class) g_pattern_spec_free(itd
->class);
997 g_slist_free(config_per_app_settings
);