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 gboolean config_place_active
;
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 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
;
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(void)
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
->position
= src
->position
;
140 dst
->monitor
= src
->monitor
;
144 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
146 gchar
*s
= obt_parse_node_string(node
);
147 if (!g_ascii_strcasecmp(s
, "center"))
152 if (s
[0] == '-' || s
[0] == '+')
162 <application name="aterm">
165 <application name="Rhythmbox">
172 .. there is a lot more settings available
177 /* Manages settings for individual applications.
178 Some notes: monitor is the screen number in a multi monitor
179 (Xinerama) setup (starting from 0) or mouse, meaning the
180 monitor the pointer is on. Default: mouse.
181 Layer can be three values, above (Always on top), below
182 (Always on bottom) and everything else (normal behaviour).
183 Positions can be an integer value or center, which will
184 center the window in the specified axis. Position is within
185 the monitor, so <position><x>center</x></position><monitor>2</monitor>
186 will center the window on the second monitor.
188 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
190 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
191 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
192 gboolean name_set
, class_set
;
193 gboolean x_pos_given
;
196 name_set
= class_set
= x_pos_given
= FALSE
;
198 class_set
= obt_parse_attr_string(app
, "class", &class);
199 name_set
= obt_parse_attr_string(app
, "name", &name
);
200 if (class_set
|| name_set
) {
202 ObAppSettings
*settings
= config_create_app_settings();;
205 settings
->name
= g_pattern_spec_new(name
);
208 settings
->class = g_pattern_spec_new(class);
210 if (obt_parse_attr_string(app
, "role", &role
))
211 settings
->role
= g_pattern_spec_new(role
);
213 if ((n
= obt_parse_find_node(app
->children
, "decor")))
214 if (!obt_parse_node_contains(n
, "default"))
215 settings
->decor
= obt_parse_node_bool(n
);
217 if ((n
= obt_parse_find_node(app
->children
, "shade")))
218 if (!obt_parse_node_contains(n
, "default"))
219 settings
->shade
= obt_parse_node_bool(n
);
221 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
222 if ((c
= obt_parse_find_node(n
->children
, "x")))
223 if (!obt_parse_node_contains(c
, "default")) {
224 config_parse_gravity_coord(c
, &settings
->position
.x
);
228 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
229 if (!obt_parse_node_contains(c
, "default")) {
230 config_parse_gravity_coord(c
, &settings
->position
.y
);
231 settings
->pos_given
= TRUE
;
234 if (settings
->pos_given
&&
235 (c
= obt_parse_find_node(n
->children
, "monitor")))
236 if (!obt_parse_node_contains(c
, "default")) {
237 gchar
*s
= obt_parse_node_string(c
);
238 if (!g_ascii_strcasecmp(s
, "mouse"))
239 settings
->monitor
= 0;
241 settings
->monitor
= obt_parse_node_int(c
) + 1;
246 if ((n
= obt_parse_find_node(app
->children
, "focus")))
247 if (!obt_parse_node_contains(n
, "default"))
248 settings
->focus
= obt_parse_node_bool(n
);
250 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
251 if (!obt_parse_node_contains(n
, "default")) {
252 gchar
*s
= obt_parse_node_string(n
);
253 if (!g_ascii_strcasecmp(s
, "all"))
254 settings
->desktop
= DESKTOP_ALL
;
256 gint i
= obt_parse_node_int(n
);
258 settings
->desktop
= i
;
264 if ((n
= obt_parse_find_node(app
->children
, "layer")))
265 if (!obt_parse_node_contains(n
, "default")) {
266 gchar
*s
= obt_parse_node_string(n
);
267 if (!g_ascii_strcasecmp(s
, "above"))
269 else if (!g_ascii_strcasecmp(s
, "below"))
270 settings
->layer
= -1;
276 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
277 if (!obt_parse_node_contains(n
, "default"))
278 settings
->iconic
= obt_parse_node_bool(n
);
280 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
281 if (!obt_parse_node_contains(n
, "default"))
282 settings
->skip_pager
= obt_parse_node_bool(n
);
284 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
285 if (!obt_parse_node_contains(n
, "default"))
286 settings
->skip_taskbar
= obt_parse_node_bool(n
);
288 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
289 if (!obt_parse_node_contains(n
, "default"))
290 settings
->fullscreen
= obt_parse_node_bool(n
);
292 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
293 if (!obt_parse_node_contains(n
, "default")) {
294 gchar
*s
= obt_parse_node_string(n
);
295 if (!g_ascii_strcasecmp(s
, "horizontal")) {
296 settings
->max_horz
= TRUE
;
297 settings
->max_vert
= FALSE
;
298 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
299 settings
->max_horz
= FALSE
;
300 settings
->max_vert
= TRUE
;
302 settings
->max_horz
= settings
->max_vert
=
303 obt_parse_node_bool(n
);
307 config_per_app_settings
= g_slist_append(config_per_app_settings
,
308 (gpointer
) settings
);
312 name
= class = role
= NULL
;
315 app
= obt_parse_find_node(app
->next
, "application");
322 <action name="ChangeDesktop">
329 static void parse_key(xmlNodePtr node
, GList
*keylist
)
333 gboolean is_chroot
= FALSE
;
335 if (!obt_parse_attr_string(node
, "key", &key
))
338 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
340 keylist
= g_list_append(keylist
, key
);
342 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
344 parse_key(n
, keylist
);
345 n
= obt_parse_find_node(n
->next
, "keybind");
348 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
350 ObActionsAct
*action
;
352 action
= actions_parse(n
);
354 keyboard_bind(keylist
, action
);
355 n
= obt_parse_find_node(n
->next
, "action");
360 keyboard_chroot(keylist
);
363 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
366 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
371 keyboard_unbind_all();
373 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
374 key
= obt_parse_node_string(n
);
375 translate_key(key
, &config_keyboard_reset_state
,
376 &config_keyboard_reset_keycode
);
380 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
383 n
= obt_parse_find_node(n
->next
, "keybind");
389 <context name="Titlebar">
390 <mousebind button="Left" action="Press">
391 <action name="Raise"></action>
397 static void parse_mouse(xmlNodePtr node
, gpointer d
)
399 xmlNodePtr n
, nbut
, nact
;
406 node
= node
->children
;
408 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
409 config_mouse_threshold
= obt_parse_node_int(n
);
410 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
411 config_mouse_dclicktime
= obt_parse_node_int(n
);
412 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime")))
413 config_mouse_screenedgetime
= obt_parse_node_int(n
);
415 n
= obt_parse_find_node(node
, "context");
417 if (!obt_parse_attr_string(n
, "name", &contextstr
))
419 nbut
= obt_parse_find_node(n
->children
, "mousebind");
421 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
423 if (obt_parse_attr_contains(nbut
, "action", "press")) {
424 mact
= OB_MOUSE_ACTION_PRESS
;
425 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
426 mact
= OB_MOUSE_ACTION_RELEASE
;
427 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
428 mact
= OB_MOUSE_ACTION_CLICK
;
429 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
430 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
431 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
432 mact
= OB_MOUSE_ACTION_MOTION
;
435 nact
= obt_parse_find_node(nbut
->children
, "action");
437 ObActionsAct
*action
;
439 if ((action
= actions_parse(nact
)))
440 mouse_bind(buttonstr
, contextstr
, mact
, action
);
441 nact
= obt_parse_find_node(nact
->next
, "action");
445 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
449 n
= obt_parse_find_node(n
->next
, "context");
453 static void parse_focus(xmlNodePtr node
, gpointer d
)
457 node
= node
->children
;
459 if ((n
= obt_parse_find_node(node
, "focusNew")))
460 config_focus_new
= obt_parse_node_bool(n
);
461 if ((n
= obt_parse_find_node(node
, "followMouse")))
462 config_focus_follow
= obt_parse_node_bool(n
);
463 if ((n
= obt_parse_find_node(node
, "focusDelay")))
464 config_focus_delay
= obt_parse_node_int(n
);
465 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
466 config_focus_raise
= obt_parse_node_bool(n
);
467 if ((n
= obt_parse_find_node(node
, "focusLast")))
468 config_focus_last
= obt_parse_node_bool(n
);
469 if ((n
= obt_parse_find_node(node
, "underMouse")))
470 config_focus_under_mouse
= obt_parse_node_bool(n
);
473 static void parse_placement(xmlNodePtr node
, gpointer d
)
477 node
= node
->children
;
479 if ((n
= obt_parse_find_node(node
, "policy")))
480 if (obt_parse_node_contains(n
, "UnderMouse"))
481 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
482 if ((n
= obt_parse_find_node(node
, "center")))
483 config_place_center
= obt_parse_node_bool(n
);
484 if ((n
= obt_parse_find_node(node
, "active")))
485 config_place_active
= obt_parse_node_bool(n
);
488 static void parse_margins(xmlNodePtr node
, gpointer d
)
492 node
= node
->children
;
494 if ((n
= obt_parse_find_node(node
, "top")))
495 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
496 if ((n
= obt_parse_find_node(node
, "left")))
497 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
498 if ((n
= obt_parse_find_node(node
, "right")))
499 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
500 if ((n
= obt_parse_find_node(node
, "bottom")))
501 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
504 static void parse_theme(xmlNodePtr node
, gpointer d
)
508 node
= node
->children
;
510 if ((n
= obt_parse_find_node(node
, "name"))) {
513 g_free(config_theme
);
514 c
= obt_parse_node_string(n
);
515 config_theme
= obt_paths_expand_tilde(c
);
518 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
521 g_free(config_title_layout
);
522 config_title_layout
= obt_parse_node_string(n
);
524 /* replace duplicates with spaces */
525 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
526 for (d
= c
+1; *d
!= '\0'; ++d
)
527 if (*c
== *d
) *d
= ' ';
529 if ((n
= obt_parse_find_node(node
, "keepBorder")))
530 config_theme_keepborder
= obt_parse_node_bool(n
);
531 if ((n
= obt_parse_find_node(node
, "animateIconify")))
532 config_animate_iconify
= obt_parse_node_bool(n
);
534 n
= obt_parse_find_node(node
, "font");
538 gchar
*name
= g_strdup(RrDefaultFontFamily
);
539 gint size
= RrDefaultFontSize
;
540 RrFontWeight weight
= RrDefaultFontWeight
;
541 RrFontSlant slant
= RrDefaultFontSlant
;
543 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
544 font
= &config_font_activewindow
;
545 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
546 font
= &config_font_inactivewindow
;
547 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
548 font
= &config_font_menutitle
;
549 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
550 font
= &config_font_menuitem
;
551 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
552 font
= &config_font_osd
;
556 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
558 name
= obt_parse_node_string(fnode
);
560 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
561 int s
= obt_parse_node_int(fnode
);
564 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
565 gchar
*w
= obt_parse_node_string(fnode
);
566 if (!g_ascii_strcasecmp(w
, "Bold"))
567 weight
= RR_FONTWEIGHT_BOLD
;
570 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
571 gchar
*s
= obt_parse_node_string(fnode
);
572 if (!g_ascii_strcasecmp(s
, "Italic"))
573 slant
= RR_FONTSLANT_ITALIC
;
574 if (!g_ascii_strcasecmp(s
, "Oblique"))
575 slant
= RR_FONTSLANT_OBLIQUE
;
579 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
582 n
= obt_parse_find_node(n
->next
, "font");
586 static void parse_desktops(xmlNodePtr node
, gpointer d
)
590 node
= node
->children
;
592 if ((n
= obt_parse_find_node(node
, "number"))) {
593 gint d
= obt_parse_node_int(n
);
595 config_desktops_num
= d
;
597 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
598 gint d
= obt_parse_node_int(n
);
600 config_screen_firstdesk
= (unsigned) d
;
602 if ((n
= obt_parse_find_node(node
, "names"))) {
606 for (it
= config_desktops_names
; it
; it
= it
->next
)
608 g_slist_free(config_desktops_names
);
609 config_desktops_names
= NULL
;
611 nname
= obt_parse_find_node(n
->children
, "name");
613 config_desktops_names
=
614 g_slist_append(config_desktops_names
,
615 obt_parse_node_string(nname
));
616 nname
= obt_parse_find_node(nname
->next
, "name");
619 if ((n
= obt_parse_find_node(node
, "popupTime")))
620 config_desktop_popup_time
= obt_parse_node_int(n
);
623 static void parse_resize(xmlNodePtr node
, gpointer d
)
627 node
= node
->children
;
629 if ((n
= obt_parse_find_node(node
, "drawContents")))
630 config_resize_redraw
= obt_parse_node_bool(n
);
631 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
632 config_resize_popup_show
= obt_parse_node_int(n
);
633 if (obt_parse_node_contains(n
, "Always"))
634 config_resize_popup_show
= 2;
635 else if (obt_parse_node_contains(n
, "Never"))
636 config_resize_popup_show
= 0;
637 else if (obt_parse_node_contains(n
, "Nonpixel"))
638 config_resize_popup_show
= 1;
640 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
641 if (obt_parse_node_contains(n
, "Top"))
642 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
643 else if (obt_parse_node_contains(n
, "Center"))
644 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
645 else if (obt_parse_node_contains(n
, "Fixed")) {
646 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
648 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
651 if ((n2
= obt_parse_find_node(n
->children
, "x")))
652 config_parse_gravity_coord(n2
,
653 &config_resize_popup_fixed
.x
);
654 if ((n2
= obt_parse_find_node(n
->children
, "y")))
655 config_parse_gravity_coord(n2
,
656 &config_resize_popup_fixed
.y
);
662 static void parse_dock(xmlNodePtr node
, gpointer d
)
666 node
= node
->children
;
668 if ((n
= obt_parse_find_node(node
, "position"))) {
669 if (obt_parse_node_contains(n
, "TopLeft"))
670 config_dock_floating
= FALSE
,
671 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
672 else if (obt_parse_node_contains(n
, "Top"))
673 config_dock_floating
= FALSE
,
674 config_dock_pos
= OB_DIRECTION_NORTH
;
675 else if (obt_parse_node_contains(n
, "TopRight"))
676 config_dock_floating
= FALSE
,
677 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
678 else if (obt_parse_node_contains(n
, "Right"))
679 config_dock_floating
= FALSE
,
680 config_dock_pos
= OB_DIRECTION_EAST
;
681 else if (obt_parse_node_contains(n
, "BottomRight"))
682 config_dock_floating
= FALSE
,
683 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
684 else if (obt_parse_node_contains(n
, "Bottom"))
685 config_dock_floating
= FALSE
,
686 config_dock_pos
= OB_DIRECTION_SOUTH
;
687 else if (obt_parse_node_contains(n
, "BottomLeft"))
688 config_dock_floating
= FALSE
,
689 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
690 else if (obt_parse_node_contains(n
, "Left"))
691 config_dock_floating
= FALSE
,
692 config_dock_pos
= OB_DIRECTION_WEST
;
693 else if (obt_parse_node_contains(n
, "Floating"))
694 config_dock_floating
= TRUE
;
696 if (config_dock_floating
) {
697 if ((n
= obt_parse_find_node(node
, "floatingX")))
698 config_dock_x
= obt_parse_node_int(n
);
699 if ((n
= obt_parse_find_node(node
, "floatingY")))
700 config_dock_y
= obt_parse_node_int(n
);
702 if ((n
= obt_parse_find_node(node
, "noStrut")))
703 config_dock_nostrut
= obt_parse_node_bool(n
);
705 if ((n
= obt_parse_find_node(node
, "stacking"))) {
706 if (obt_parse_node_contains(n
, "normal"))
707 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
708 else if (obt_parse_node_contains(n
, "below"))
709 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
710 else if (obt_parse_node_contains(n
, "above"))
711 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
713 if ((n
= obt_parse_find_node(node
, "direction"))) {
714 if (obt_parse_node_contains(n
, "horizontal"))
715 config_dock_orient
= OB_ORIENTATION_HORZ
;
716 else if (obt_parse_node_contains(n
, "vertical"))
717 config_dock_orient
= OB_ORIENTATION_VERT
;
719 if ((n
= obt_parse_find_node(node
, "autoHide")))
720 config_dock_hide
= obt_parse_node_bool(n
);
721 if ((n
= obt_parse_find_node(node
, "hideDelay")))
722 config_dock_hide_delay
= obt_parse_node_int(n
);
723 if ((n
= obt_parse_find_node(node
, "showDelay")))
724 config_dock_show_delay
= obt_parse_node_int(n
);
725 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
726 gchar
*str
= obt_parse_node_string(n
);
728 if (translate_button(str
, &s
, &b
)) {
729 config_dock_app_move_button
= b
;
730 config_dock_app_move_modifiers
= s
;
732 g_message(_("Invalid button '%s' specified in config file"), str
);
738 static void parse_menu(xmlNodePtr node
, gpointer d
)
741 for (node
= node
->children
; node
; node
= node
->next
) {
742 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
745 c
= obt_parse_node_string(node
);
746 config_menu_files
= g_slist_append(config_menu_files
,
747 obt_paths_expand_tilde(c
));
750 if ((n
= obt_parse_find_node(node
, "hideDelay")))
751 config_menu_hide_delay
= obt_parse_node_int(n
);
752 if ((n
= obt_parse_find_node(node
, "middle")))
753 config_menu_middle
= obt_parse_node_bool(n
);
754 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
755 config_submenu_show_delay
= obt_parse_node_int(n
);
756 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
757 config_menu_client_list_icons
= obt_parse_node_bool(n
);
761 static void parse_resistance(xmlNodePtr node
, gpointer d
)
765 node
= node
->children
;
766 if ((n
= obt_parse_find_node(node
, "strength")))
767 config_resist_win
= obt_parse_node_int(n
);
768 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
769 config_resist_edge
= obt_parse_node_int(n
);
775 const gchar
*actname
;
778 static void bind_default_keyboard(void)
781 ObDefKeyBind binds
[] = {
782 { "A-Tab", "NextWindow" },
783 { "S-A-Tab", "PreviousWindow" },
787 for (it
= binds
; it
->key
; ++it
) {
788 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
789 keyboard_bind(l
, actions_parse_string(it
->actname
));
796 const gchar
*context
;
797 const ObMouseAction mact
;
798 const gchar
*actname
;
801 static void bind_default_mouse(void)
804 ObDefMouseBind binds
[] = {
805 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
806 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
807 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
808 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
809 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
810 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
811 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
812 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
813 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
814 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
815 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
816 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
817 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
818 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
819 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
820 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
821 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
822 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
823 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
824 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
825 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
826 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
827 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
828 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
829 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
830 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
831 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
832 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
833 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
834 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
835 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
836 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
837 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
838 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
839 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
840 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
841 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
842 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
843 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
844 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
845 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
846 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
847 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
848 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
849 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
850 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
851 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
852 { NULL
, NULL
, 0, NULL
}
855 for (it
= binds
; it
->button
; ++it
)
856 mouse_bind(it
->button
, it
->context
, it
->mact
,
857 actions_parse_string(it
->actname
));
860 void config_startup(ObtParseInst
*i
)
862 config_focus_new
= TRUE
;
863 config_focus_follow
= FALSE
;
864 config_focus_delay
= 0;
865 config_focus_raise
= FALSE
;
866 config_focus_last
= TRUE
;
867 config_focus_under_mouse
= FALSE
;
869 obt_parse_register(i
, "focus", parse_focus
, NULL
);
871 config_place_policy
= OB_PLACE_POLICY_SMART
;
872 config_place_center
= TRUE
;
873 config_place_active
= FALSE
;
875 obt_parse_register(i
, "placement", parse_placement
, NULL
);
877 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
879 obt_parse_register(i
, "margins", parse_margins
, NULL
);
883 config_animate_iconify
= TRUE
;
884 config_title_layout
= g_strdup("NLIMC");
885 config_theme_keepborder
= TRUE
;
887 config_font_activewindow
= NULL
;
888 config_font_inactivewindow
= NULL
;
889 config_font_menuitem
= NULL
;
890 config_font_menutitle
= NULL
;
892 obt_parse_register(i
, "theme", parse_theme
, NULL
);
894 config_desktops_num
= 4;
895 config_screen_firstdesk
= 1;
896 config_desktops_names
= NULL
;
897 config_desktop_popup_time
= 875;
899 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
901 config_resize_redraw
= TRUE
;
902 config_resize_popup_show
= 1; /* nonpixel increments */
903 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
904 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
905 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
907 obt_parse_register(i
, "resize", parse_resize
, NULL
);
909 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
910 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
911 config_dock_floating
= FALSE
;
912 config_dock_nostrut
= FALSE
;
915 config_dock_orient
= OB_ORIENTATION_VERT
;
916 config_dock_hide
= FALSE
;
917 config_dock_hide_delay
= 300;
918 config_dock_show_delay
= 300;
919 config_dock_app_move_button
= 2; /* middle */
920 config_dock_app_move_modifiers
= 0;
922 obt_parse_register(i
, "dock", parse_dock
, NULL
);
924 translate_key("C-g", &config_keyboard_reset_state
,
925 &config_keyboard_reset_keycode
);
927 bind_default_keyboard();
929 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
931 config_mouse_threshold
= 8;
932 config_mouse_dclicktime
= 200;
933 config_mouse_screenedgetime
= 400;
935 bind_default_mouse();
937 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
939 config_resist_win
= 10;
940 config_resist_edge
= 20;
942 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
944 config_menu_hide_delay
= 250;
945 config_menu_middle
= FALSE
;
946 config_submenu_show_delay
= 0;
947 config_menu_client_list_icons
= TRUE
;
948 config_menu_files
= NULL
;
950 obt_parse_register(i
, "menu", parse_menu
, NULL
);
952 config_per_app_settings
= NULL
;
954 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
957 void config_shutdown(void)
961 g_free(config_theme
);
963 g_free(config_title_layout
);
965 RrFontClose(config_font_activewindow
);
966 RrFontClose(config_font_inactivewindow
);
967 RrFontClose(config_font_menuitem
);
968 RrFontClose(config_font_menutitle
);
970 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
972 g_slist_free(config_desktops_names
);
974 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
976 g_slist_free(config_menu_files
);
978 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
979 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
980 if (itd
->name
) g_pattern_spec_free(itd
->name
);
981 if (itd
->role
) g_pattern_spec_free(itd
->role
);
982 if (itd
->class) g_pattern_spec_free(itd
->class);
985 g_slist_free(config_per_app_settings
);