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
;
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
, "monitor"))) {
485 if (obt_parse_node_contains(n
, "active"))
486 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
487 else if (obt_parse_node_contains(n
, "mouse"))
488 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
492 static void parse_margins(xmlNodePtr node
, gpointer d
)
496 node
= node
->children
;
498 if ((n
= obt_parse_find_node(node
, "top")))
499 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
500 if ((n
= obt_parse_find_node(node
, "left")))
501 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
502 if ((n
= obt_parse_find_node(node
, "right")))
503 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
504 if ((n
= obt_parse_find_node(node
, "bottom")))
505 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
508 static void parse_theme(xmlNodePtr node
, gpointer d
)
512 node
= node
->children
;
514 if ((n
= obt_parse_find_node(node
, "name"))) {
517 g_free(config_theme
);
518 c
= obt_parse_node_string(n
);
519 config_theme
= obt_paths_expand_tilde(c
);
522 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
525 g_free(config_title_layout
);
526 config_title_layout
= obt_parse_node_string(n
);
528 /* replace duplicates with spaces */
529 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
530 for (d
= c
+1; *d
!= '\0'; ++d
)
531 if (*c
== *d
) *d
= ' ';
533 if ((n
= obt_parse_find_node(node
, "keepBorder")))
534 config_theme_keepborder
= obt_parse_node_bool(n
);
535 if ((n
= obt_parse_find_node(node
, "animateIconify")))
536 config_animate_iconify
= obt_parse_node_bool(n
);
538 n
= obt_parse_find_node(node
, "font");
542 gchar
*name
= g_strdup(RrDefaultFontFamily
);
543 gint size
= RrDefaultFontSize
;
544 RrFontWeight weight
= RrDefaultFontWeight
;
545 RrFontSlant slant
= RrDefaultFontSlant
;
547 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
548 font
= &config_font_activewindow
;
549 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
550 font
= &config_font_inactivewindow
;
551 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
552 font
= &config_font_menutitle
;
553 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
554 font
= &config_font_menuitem
;
555 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
556 font
= &config_font_osd
;
560 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
562 name
= obt_parse_node_string(fnode
);
564 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
565 int s
= obt_parse_node_int(fnode
);
568 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
569 gchar
*w
= obt_parse_node_string(fnode
);
570 if (!g_ascii_strcasecmp(w
, "Bold"))
571 weight
= RR_FONTWEIGHT_BOLD
;
574 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
575 gchar
*s
= obt_parse_node_string(fnode
);
576 if (!g_ascii_strcasecmp(s
, "Italic"))
577 slant
= RR_FONTSLANT_ITALIC
;
578 if (!g_ascii_strcasecmp(s
, "Oblique"))
579 slant
= RR_FONTSLANT_OBLIQUE
;
583 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
586 n
= obt_parse_find_node(n
->next
, "font");
590 static void parse_desktops(xmlNodePtr node
, gpointer d
)
594 node
= node
->children
;
596 if ((n
= obt_parse_find_node(node
, "number"))) {
597 gint d
= obt_parse_node_int(n
);
599 config_desktops_num
= (unsigned) d
;
601 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
602 gint d
= obt_parse_node_int(n
);
604 config_screen_firstdesk
= (unsigned) d
;
606 if ((n
= obt_parse_find_node(node
, "names"))) {
610 for (it
= config_desktops_names
; it
; it
= it
->next
)
612 g_slist_free(config_desktops_names
);
613 config_desktops_names
= NULL
;
615 nname
= obt_parse_find_node(n
->children
, "name");
617 config_desktops_names
=
618 g_slist_append(config_desktops_names
,
619 obt_parse_node_string(nname
));
620 nname
= obt_parse_find_node(nname
->next
, "name");
623 if ((n
= obt_parse_find_node(node
, "popupTime")))
624 config_desktop_popup_time
= obt_parse_node_int(n
);
627 static void parse_resize(xmlNodePtr node
, gpointer d
)
631 node
= node
->children
;
633 if ((n
= obt_parse_find_node(node
, "drawContents")))
634 config_resize_redraw
= obt_parse_node_bool(n
);
635 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
636 config_resize_popup_show
= obt_parse_node_int(n
);
637 if (obt_parse_node_contains(n
, "Always"))
638 config_resize_popup_show
= 2;
639 else if (obt_parse_node_contains(n
, "Never"))
640 config_resize_popup_show
= 0;
641 else if (obt_parse_node_contains(n
, "Nonpixel"))
642 config_resize_popup_show
= 1;
644 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
645 if (obt_parse_node_contains(n
, "Top"))
646 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
647 else if (obt_parse_node_contains(n
, "Center"))
648 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
649 else if (obt_parse_node_contains(n
, "Fixed")) {
650 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
652 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
655 if ((n2
= obt_parse_find_node(n
->children
, "x")))
656 config_parse_gravity_coord(n2
,
657 &config_resize_popup_fixed
.x
);
658 if ((n2
= obt_parse_find_node(n
->children
, "y")))
659 config_parse_gravity_coord(n2
,
660 &config_resize_popup_fixed
.y
);
666 static void parse_dock(xmlNodePtr node
, gpointer d
)
670 node
= node
->children
;
672 if ((n
= obt_parse_find_node(node
, "position"))) {
673 if (obt_parse_node_contains(n
, "TopLeft"))
674 config_dock_floating
= FALSE
,
675 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
676 else if (obt_parse_node_contains(n
, "Top"))
677 config_dock_floating
= FALSE
,
678 config_dock_pos
= OB_DIRECTION_NORTH
;
679 else if (obt_parse_node_contains(n
, "TopRight"))
680 config_dock_floating
= FALSE
,
681 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
682 else if (obt_parse_node_contains(n
, "Right"))
683 config_dock_floating
= FALSE
,
684 config_dock_pos
= OB_DIRECTION_EAST
;
685 else if (obt_parse_node_contains(n
, "BottomRight"))
686 config_dock_floating
= FALSE
,
687 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
688 else if (obt_parse_node_contains(n
, "Bottom"))
689 config_dock_floating
= FALSE
,
690 config_dock_pos
= OB_DIRECTION_SOUTH
;
691 else if (obt_parse_node_contains(n
, "BottomLeft"))
692 config_dock_floating
= FALSE
,
693 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
694 else if (obt_parse_node_contains(n
, "Left"))
695 config_dock_floating
= FALSE
,
696 config_dock_pos
= OB_DIRECTION_WEST
;
697 else if (obt_parse_node_contains(n
, "Floating"))
698 config_dock_floating
= TRUE
;
700 if (config_dock_floating
) {
701 if ((n
= obt_parse_find_node(node
, "floatingX")))
702 config_dock_x
= obt_parse_node_int(n
);
703 if ((n
= obt_parse_find_node(node
, "floatingY")))
704 config_dock_y
= obt_parse_node_int(n
);
706 if ((n
= obt_parse_find_node(node
, "noStrut")))
707 config_dock_nostrut
= obt_parse_node_bool(n
);
709 if ((n
= obt_parse_find_node(node
, "stacking"))) {
710 if (obt_parse_node_contains(n
, "normal"))
711 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
712 else if (obt_parse_node_contains(n
, "below"))
713 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
714 else if (obt_parse_node_contains(n
, "above"))
715 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
717 if ((n
= obt_parse_find_node(node
, "direction"))) {
718 if (obt_parse_node_contains(n
, "horizontal"))
719 config_dock_orient
= OB_ORIENTATION_HORZ
;
720 else if (obt_parse_node_contains(n
, "vertical"))
721 config_dock_orient
= OB_ORIENTATION_VERT
;
723 if ((n
= obt_parse_find_node(node
, "autoHide")))
724 config_dock_hide
= obt_parse_node_bool(n
);
725 if ((n
= obt_parse_find_node(node
, "hideDelay")))
726 config_dock_hide_delay
= obt_parse_node_int(n
);
727 if ((n
= obt_parse_find_node(node
, "showDelay")))
728 config_dock_show_delay
= obt_parse_node_int(n
);
729 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
730 gchar
*str
= obt_parse_node_string(n
);
732 if (translate_button(str
, &s
, &b
)) {
733 config_dock_app_move_button
= b
;
734 config_dock_app_move_modifiers
= s
;
736 g_message(_("Invalid button '%s' specified in config file"), str
);
742 static void parse_menu(xmlNodePtr node
, gpointer d
)
745 for (node
= node
->children
; node
; node
= node
->next
) {
746 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
749 c
= obt_parse_node_string(node
);
750 config_menu_files
= g_slist_append(config_menu_files
,
751 obt_paths_expand_tilde(c
));
754 if ((n
= obt_parse_find_node(node
, "hideDelay")))
755 config_menu_hide_delay
= obt_parse_node_int(n
);
756 if ((n
= obt_parse_find_node(node
, "middle")))
757 config_menu_middle
= obt_parse_node_bool(n
);
758 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
759 config_submenu_show_delay
= obt_parse_node_int(n
);
760 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
761 config_menu_client_list_icons
= obt_parse_node_bool(n
);
765 static void parse_resistance(xmlNodePtr node
, gpointer d
)
769 node
= node
->children
;
770 if ((n
= obt_parse_find_node(node
, "strength")))
771 config_resist_win
= obt_parse_node_int(n
);
772 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
773 config_resist_edge
= obt_parse_node_int(n
);
779 const gchar
*actname
;
782 static void bind_default_keyboard(void)
785 ObDefKeyBind binds
[] = {
786 { "A-Tab", "NextWindow" },
787 { "S-A-Tab", "PreviousWindow" },
791 for (it
= binds
; it
->key
; ++it
) {
792 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
793 keyboard_bind(l
, actions_parse_string(it
->actname
));
800 const gchar
*context
;
801 const ObMouseAction mact
;
802 const gchar
*actname
;
805 static void bind_default_mouse(void)
808 ObDefMouseBind binds
[] = {
809 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
810 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
811 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
812 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
813 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
814 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
815 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
816 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
817 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
818 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
819 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
820 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
821 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
822 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
823 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
824 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
825 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
826 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
827 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
828 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
829 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
830 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
831 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
832 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
833 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
834 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
835 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
836 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
837 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
838 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
839 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
840 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
841 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
842 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
843 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
844 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
845 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
846 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
847 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
848 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
849 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
850 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
851 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
852 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
853 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
854 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
855 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
856 { NULL
, NULL
, 0, NULL
}
859 for (it
= binds
; it
->button
; ++it
)
860 mouse_bind(it
->button
, it
->context
, it
->mact
,
861 actions_parse_string(it
->actname
));
864 void config_startup(ObtParseInst
*i
)
866 config_focus_new
= TRUE
;
867 config_focus_follow
= FALSE
;
868 config_focus_delay
= 0;
869 config_focus_raise
= FALSE
;
870 config_focus_last
= TRUE
;
871 config_focus_under_mouse
= FALSE
;
873 obt_parse_register(i
, "focus", parse_focus
, NULL
);
875 config_place_policy
= OB_PLACE_POLICY_SMART
;
876 config_place_center
= TRUE
;
877 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
879 obt_parse_register(i
, "placement", parse_placement
, NULL
);
881 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
883 obt_parse_register(i
, "margins", parse_margins
, NULL
);
887 config_animate_iconify
= TRUE
;
888 config_title_layout
= g_strdup("NLIMC");
889 config_theme_keepborder
= TRUE
;
891 config_font_activewindow
= NULL
;
892 config_font_inactivewindow
= NULL
;
893 config_font_menuitem
= NULL
;
894 config_font_menutitle
= NULL
;
896 obt_parse_register(i
, "theme", parse_theme
, NULL
);
898 config_desktops_num
= 4;
899 config_screen_firstdesk
= 1;
900 config_desktops_names
= NULL
;
901 config_desktop_popup_time
= 875;
903 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
905 config_resize_redraw
= TRUE
;
906 config_resize_popup_show
= 1; /* nonpixel increments */
907 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
908 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
909 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
911 obt_parse_register(i
, "resize", parse_resize
, NULL
);
913 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
914 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
915 config_dock_floating
= FALSE
;
916 config_dock_nostrut
= FALSE
;
919 config_dock_orient
= OB_ORIENTATION_VERT
;
920 config_dock_hide
= FALSE
;
921 config_dock_hide_delay
= 300;
922 config_dock_show_delay
= 300;
923 config_dock_app_move_button
= 2; /* middle */
924 config_dock_app_move_modifiers
= 0;
926 obt_parse_register(i
, "dock", parse_dock
, NULL
);
928 translate_key("C-g", &config_keyboard_reset_state
,
929 &config_keyboard_reset_keycode
);
931 bind_default_keyboard();
933 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
935 config_mouse_threshold
= 8;
936 config_mouse_dclicktime
= 200;
937 config_mouse_screenedgetime
= 400;
939 bind_default_mouse();
941 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
943 config_resist_win
= 10;
944 config_resist_edge
= 20;
946 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
948 config_menu_hide_delay
= 250;
949 config_menu_middle
= FALSE
;
950 config_submenu_show_delay
= 0;
951 config_menu_client_list_icons
= TRUE
;
952 config_menu_files
= NULL
;
954 obt_parse_register(i
, "menu", parse_menu
, NULL
);
956 config_per_app_settings
= NULL
;
958 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
961 void config_shutdown(void)
965 g_free(config_theme
);
967 g_free(config_title_layout
);
969 RrFontClose(config_font_activewindow
);
970 RrFontClose(config_font_inactivewindow
);
971 RrFontClose(config_font_menuitem
);
972 RrFontClose(config_font_menutitle
);
973 RrFontClose(config_font_osd
);
975 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
977 g_slist_free(config_desktops_names
);
979 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
981 g_slist_free(config_menu_files
);
983 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
984 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
985 if (itd
->name
) g_pattern_spec_free(itd
->name
);
986 if (itd
->role
) g_pattern_spec_free(itd
->role
);
987 if (itd
->class) g_pattern_spec_free(itd
->class);
990 g_slist_free(config_per_app_settings
);