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"
30 gboolean config_focus_new
;
31 gboolean config_focus_follow
;
32 guint config_focus_delay
;
33 gboolean config_focus_raise
;
34 gboolean config_focus_last
;
35 gboolean config_focus_under_mouse
;
37 ObPlacePolicy config_place_policy
;
38 gboolean config_place_center
;
39 gboolean config_place_active
;
41 StrutPartial config_margins
;
44 gboolean config_theme_keepborder
;
46 gchar
*config_title_layout
;
48 gboolean config_animate_iconify
;
50 RrFont
*config_font_activewindow
;
51 RrFont
*config_font_inactivewindow
;
52 RrFont
*config_font_menuitem
;
53 RrFont
*config_font_menutitle
;
54 RrFont
*config_font_osd
;
56 gint config_desktops_num
;
57 GSList
*config_desktops_names
;
58 guint config_screen_firstdesk
;
59 guint config_desktop_popup_time
;
61 gboolean config_resize_redraw
;
62 gint config_resize_popup_show
;
63 ObResizePopupPos config_resize_popup_pos
;
64 GravityPoint config_resize_popup_fixed
;
66 ObStackingLayer config_dock_layer
;
67 gboolean config_dock_floating
;
68 gboolean config_dock_nostrut
;
69 ObDirection config_dock_pos
;
72 ObOrientation config_dock_orient
;
73 gboolean config_dock_hide
;
74 guint config_dock_hide_delay
;
75 guint config_dock_show_delay
;
76 guint config_dock_app_move_button
;
77 guint config_dock_app_move_modifiers
;
79 guint config_keyboard_reset_keycode
;
80 guint config_keyboard_reset_state
;
82 gint config_mouse_threshold
;
83 gint config_mouse_dclicktime
;
84 gint config_mouse_screenedgetime
;
86 guint config_menu_hide_delay
;
87 gboolean config_menu_middle
;
88 guint config_submenu_show_delay
;
89 gboolean config_menu_client_list_icons
;
91 GSList
*config_menu_files
;
93 gint config_resist_win
;
94 gint config_resist_edge
;
96 GSList
*config_per_app_settings
;
98 ObAppSettings
* config_create_app_settings(void)
100 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
101 settings
->decor
= -1;
102 settings
->shade
= -1;
103 settings
->monitor
= -1;
104 settings
->focus
= -1;
105 settings
->desktop
= 0;
106 settings
->layer
= -2;
107 settings
->iconic
= -1;
108 settings
->skip_pager
= -1;
109 settings
->skip_taskbar
= -1;
110 settings
->fullscreen
= -1;
111 settings
->max_horz
= -1;
112 settings
->max_vert
= -1;
116 #define copy_if(setting, default) \
117 if (src->setting != default) dst->setting = src->setting
118 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
121 g_assert(src
!= NULL
);
122 g_assert(dst
!= NULL
);
130 copy_if(skip_pager
, -1);
131 copy_if(skip_taskbar
, -1);
132 copy_if(fullscreen
, -1);
133 copy_if(max_horz
, -1);
134 copy_if(max_vert
, -1);
136 if (src
->pos_given
) {
137 dst
->pos_given
= TRUE
;
138 dst
->position
= src
->position
;
139 dst
->monitor
= src
->monitor
;
143 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
145 gchar
*s
= obt_parse_node_string(node
);
146 if (!g_ascii_strcasecmp(s
, "center"))
151 if (s
[0] == '-' || s
[0] == '+')
161 <application name="aterm">
164 <application name="Rhythmbox">
171 .. there is a lot more settings available
176 /* Manages settings for individual applications.
177 Some notes: monitor is the screen number in a multi monitor
178 (Xinerama) setup (starting from 0) or mouse, meaning the
179 monitor the pointer is on. Default: mouse.
180 Layer can be three values, above (Always on top), below
181 (Always on bottom) and everything else (normal behaviour).
182 Positions can be an integer value or center, which will
183 center the window in the specified axis. Position is within
184 the monitor, so <position><x>center</x></position><monitor>2</monitor>
185 will center the window on the second monitor.
187 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
189 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
190 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
;
191 gboolean name_set
, class_set
;
192 gboolean x_pos_given
;
195 name_set
= class_set
= x_pos_given
= FALSE
;
197 class_set
= obt_parse_attr_string(app
, "class", &class);
198 name_set
= obt_parse_attr_string(app
, "name", &name
);
199 if (class_set
|| name_set
) {
201 ObAppSettings
*settings
= config_create_app_settings();;
204 settings
->name
= g_pattern_spec_new(name
);
207 settings
->class = g_pattern_spec_new(class);
209 if (obt_parse_attr_string(app
, "role", &role
))
210 settings
->role
= g_pattern_spec_new(role
);
212 if ((n
= obt_parse_find_node(app
->children
, "decor")))
213 if (!obt_parse_node_contains(n
, "default"))
214 settings
->decor
= obt_parse_node_bool(n
);
216 if ((n
= obt_parse_find_node(app
->children
, "shade")))
217 if (!obt_parse_node_contains(n
, "default"))
218 settings
->shade
= obt_parse_node_bool(n
);
220 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
221 if ((c
= obt_parse_find_node(n
->children
, "x")))
222 if (!obt_parse_node_contains(c
, "default")) {
223 config_parse_gravity_coord(c
, &settings
->position
.x
);
227 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
228 if (!obt_parse_node_contains("default", doc
, c
)) {
229 config_parse_gravity_coord(c
, &settings
->position
.y
);
230 settings
->pos_given
= TRUE
;
233 if (settings
->pos_given
&&
234 (c
= obt_parse_find_node(n
->children
, "monitor")))
235 if (!obt_parse_node_contains(c
, "default")) {
236 gchar
*s
= obt_parse_node_string(c
);
237 if (!g_ascii_strcasecmp(s
, "mouse"))
238 settings
->monitor
= 0;
240 settings
->monitor
= obt_parse_node_int(c
) + 1;
245 if ((n
= obt_parse_find_node(app
->children
, "focus")))
246 if (!obt_parse_node_contains(n
, "default"))
247 settings
->focus
= obt_parse_node_bool(n
);
249 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
250 if (!obt_parse_node_contains(n
, "default")) {
251 gchar
*s
= obt_parse_node_string(n
);
252 if (!g_ascii_strcasecmp(s
, "all"))
253 settings
->desktop
= DESKTOP_ALL
;
255 gint i
= obt_parse_node_int(n
);
257 settings
->desktop
= i
;
263 if ((n
= obt_parse_find_node(app
->children
, "layer")))
264 if (!obt_parse_node_contains(n
, "default")) {
265 gchar
*s
= obt_parse_node_string(n
);
266 if (!g_ascii_strcasecmp(s
, "above"))
268 else if (!g_ascii_strcasecmp(s
, "below"))
269 settings
->layer
= -1;
275 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
276 if (!obt_parse_node_contains(n
, "default"))
277 settings
->iconic
= obt_parse_node_bool(n
);
279 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
280 if (!obt_parse_node_contains(n
, "default"))
281 settings
->skip_pager
= obt_parse_node_bool(n
);
283 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
284 if (!obt_parse_node_contains(n
, "default"))
285 settings
->skip_taskbar
= obt_parse_node_bool(n
);
287 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
288 if (!obt_parse_node_contains(n
, "default"))
289 settings
->fullscreen
= obt_parse_node_bool(n
);
291 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
292 if (!obt_parse_node_contains(n
, "default")) {
293 gchar
*s
= obt_parse_node_string(n
);
294 if (!g_ascii_strcasecmp(s
, "horizontal")) {
295 settings
->max_horz
= TRUE
;
296 settings
->max_vert
= FALSE
;
297 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
298 settings
->max_horz
= FALSE
;
299 settings
->max_vert
= TRUE
;
301 settings
->max_horz
= settings
->max_vert
=
302 obt_parse_node_bool(n
);
306 config_per_app_settings
= g_slist_append(config_per_app_settings
,
307 (gpointer
) settings
);
311 name
= class = role
= NULL
;
314 app
= obt_parse_find_node(app
->next
, "application");
321 <action name="ChangeDesktop">
328 static void parse_key(xmlNodePtr node
, GList
*keylist
)
332 gboolean is_chroot
= FALSE
;
334 if (!obt_parse_attr_string(node
, "key", &key
))
337 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
339 keylist
= g_list_append(keylist
, key
);
341 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
343 parse_key(n
, keylist
);
344 n
= obt_parse_find_node(n
->next
, "keybind");
347 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
349 ObActionsAct
*action
;
351 action
= actions_parse(n
);
353 keyboard_bind(keylist
, action
);
354 n
= obt_parse_find_node(n
->next
, "action");
359 keyboard_chroot(keylist
);
362 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
365 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
370 keyboard_unbind_all();
372 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
373 key
= obt_parse_node_string(n
);
374 translate_key(key
, &config_keyboard_reset_state
,
375 &config_keyboard_reset_keycode
);
379 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
382 n
= obt_parse_find_node(n
->next
, "keybind");
388 <context name="Titlebar">
389 <mousebind button="Left" action="Press">
390 <action name="Raise"></action>
396 static void parse_mouse(xmlNodePtr node
, gpointer d
)
398 xmlNodePtr n
, nbut
, nact
;
405 node
= node
->children
;
407 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
408 config_mouse_threshold
= obt_parse_node_int(n
);
409 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
410 config_mouse_dclicktime
= obt_parse_node_int(n
);
411 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime")))
412 config_mouse_screenedgetime
= obt_parse_node_int(n
);
414 n
= obt_parse_find_node(node
, "context");
416 if (!obt_parse_attr_string(n
, "name", &contextstr
))
418 nbut
= obt_parse_find_node(n
->children
, "mousebind");
420 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
422 if (obt_parse_attr_contains(nbut
, "action", "press")) {
423 mact
= OB_MOUSE_ACTION_PRESS
;
424 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
425 mact
= OB_MOUSE_ACTION_RELEASE
;
426 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
427 mact
= OB_MOUSE_ACTION_CLICK
;
428 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
429 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
430 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
431 mact
= OB_MOUSE_ACTION_MOTION
;
434 nact
= obt_parse_find_node(nbut
->children
, "action");
436 ObActionsAct
*action
;
438 if ((action
= actions_parse(nact
)))
439 mouse_bind(buttonstr
, contextstr
, mact
, action
);
440 nact
= obt_parse_find_node(nact
->next
, "action");
444 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
448 n
= obt_parse_find_node(n
->next
, "context");
452 static void parse_focus(xmlNodePtr node
, gpointer d
)
456 node
= node
->children
;
458 if ((n
= obt_parse_find_node(node
, "focusNew")))
459 config_focus_new
= obt_parse_node_bool(n
);
460 if ((n
= obt_parse_find_node(node
, "followMouse")))
461 config_focus_follow
= obt_parse_node_bool(n
);
462 if ((n
= obt_parse_find_node(node
, "focusDelay")))
463 config_focus_delay
= obt_parse_node_int(n
);
464 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
465 config_focus_raise
= obt_parse_node_bool(n
);
466 if ((n
= obt_parse_find_node(node
, "focusLast")))
467 config_focus_last
= obt_parse_node_bool(n
);
468 if ((n
= obt_parse_find_node(node
, "underMouse")))
469 config_focus_under_mouse
= obt_parse_node_bool(n
);
472 static void parse_placement(xmlNodePtr node
, gpointer d
)
476 node
= node
->children
;
478 if ((n
= obt_parse_find_node(node
, "policy")))
479 if (obt_parse_node_contains(n
, "UnderMouse"))
480 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
481 if ((n
= obt_parse_find_node(node
, "center")))
482 config_place_center
= obt_parse_node_bool(n
);
483 if ((n
= obt_parse_find_node(node
, "active")))
484 config_place_active
= obt_parse_node_bool(n
);
487 static void parse_margins(xmlNodePtr node
, gpointer d
)
491 node
= node
->children
;
493 if ((n
= obt_parse_find_node(node
, "top")))
494 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
495 if ((n
= obt_parse_find_node(node
, "left")))
496 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
497 if ((n
= obt_parse_find_node(node
, "right")))
498 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
499 if ((n
= obt_parse_find_node(node
, "bottom")))
500 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
503 static void parse_theme(xmlNodePtr node
, gpointer d
)
507 node
= node
->children
;
509 if ((n
= obt_parse_find_node(node
, "name"))) {
512 g_free(config_theme
);
513 c
= obt_parse_node_string(n
);
514 config_theme
= parse_expand_tilde(c
);
517 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
520 g_free(config_title_layout
);
521 config_title_layout
= obt_parse_node_string(n
);
523 /* replace duplicates with spaces */
524 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
525 for (d
= c
+1; *d
!= '\0'; ++d
)
526 if (*c
== *d
) *d
= ' ';
528 if ((n
= obt_parse_find_node(node
, "keepBorder")))
529 config_theme_keepborder
= obt_parse_node_bool(n
);
530 if ((n
= obt_parse_find_node(node
, "animateIconify")))
531 config_animate_iconify
= obt_parse_node_bool(n
);
533 n
= obt_parse_find_node(node
, "font");
537 gchar
*name
= g_strdup(RrDefaultFontFamily
);
538 gint size
= RrDefaultFontSize
;
539 RrFontWeight weight
= RrDefaultFontWeight
;
540 RrFontSlant slant
= RrDefaultFontSlant
;
542 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
543 font
= &config_font_activewindow
;
544 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
545 font
= &config_font_inactivewindow
;
546 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
547 font
= &config_font_menutitle
;
548 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
549 font
= &config_font_menuitem
;
550 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
551 font
= &config_font_osd
;
555 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
557 name
= obt_parse_node_string(fnode
);
559 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
560 int s
= obt_parse_node_int(fnode
);
563 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
564 gchar
*w
= obt_parse_node_string(fnode
);
565 if (!g_ascii_strcasecmp(w
, "Bold"))
566 weight
= RR_FONTWEIGHT_BOLD
;
569 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
570 gchar
*s
= obt_parse_node_string(fnode
);
571 if (!g_ascii_strcasecmp(s
, "Italic"))
572 slant
= RR_FONTSLANT_ITALIC
;
573 if (!g_ascii_strcasecmp(s
, "Oblique"))
574 slant
= RR_FONTSLANT_OBLIQUE
;
578 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
581 n
= obt_parse_find_node(n
->next
, "font");
585 static void parse_desktops(xmlNodePtr node
, gpointer d
)
589 node
= node
->children
;
591 if ((n
= obt_parse_find_node(node
, "number"))) {
592 gint d
= obt_parse_node_int(n
);
594 config_desktops_num
= d
;
596 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
597 gint d
= obt_parse_node_int(n
);
599 config_screen_firstdesk
= (unsigned) d
;
601 if ((n
= obt_parse_find_node(node
, "names"))) {
605 for (it
= config_desktops_names
; it
; it
= it
->next
)
607 g_slist_free(config_desktops_names
);
608 config_desktops_names
= NULL
;
610 nname
= obt_parse_find_node(n
->children
, "name");
612 config_desktops_names
=
613 g_slist_append(config_desktops_names
,
614 obt_parse_node_string(nname
));
615 nname
= obt_parse_find_node(nname
->next
, "name");
618 if ((n
= obt_parse_find_node(node
, "popupTime")))
619 config_desktop_popup_time
= obt_parse_node_int(n
);
622 static void parse_resize(xmlNodePtr node
, gpointer d
)
626 node
= node
->children
;
628 if ((n
= obt_parse_find_node(node
, "drawContents")))
629 config_resize_redraw
= obt_parse_node_bool(n
);
630 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
631 config_resize_popup_show
= obt_parse_node_int(n
);
632 if (obt_parse_node_contains(n
, "Always"))
633 config_resize_popup_show
= 2;
634 else if (obt_parse_node_contains(n
, "Never"))
635 config_resize_popup_show
= 0;
636 else if (obt_parse_node_contains(n
, "Nonpixel"))
637 config_resize_popup_show
= 1;
639 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
640 if (obt_parse_node_contains(n
, "Top"))
641 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
642 else if (obt_parse_node_contains(n
, "Center"))
643 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
644 else if (obt_parse_node_contains(n
, "Fixed")) {
645 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
647 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
650 if ((n2
= obt_parse_find_node(n
->children
, "x")))
651 config_parse_gravity_coord(n2
,
652 &config_resize_popup_fixed
.x
);
653 if ((n2
= obt_parse_find_node(n
->children
, "y")))
654 config_parse_gravity_coord(n2
,
655 &config_resize_popup_fixed
.y
);
661 static void parse_dock(xmlNodePtr node
, gpointer d
)
665 node
= node
->children
;
667 if ((n
= obt_parse_find_node(node
, "position"))) {
668 if (obt_parse_node_contains(n
, "TopLeft"))
669 config_dock_floating
= FALSE
,
670 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
671 else if (obt_parse_node_contains(n
, "Top"))
672 config_dock_floating
= FALSE
,
673 config_dock_pos
= OB_DIRECTION_NORTH
;
674 else if (obt_parse_node_contains(n
, "TopRight"))
675 config_dock_floating
= FALSE
,
676 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
677 else if (obt_parse_node_contains(n
, "Right"))
678 config_dock_floating
= FALSE
,
679 config_dock_pos
= OB_DIRECTION_EAST
;
680 else if (obt_parse_node_contains(n
, "BottomRight"))
681 config_dock_floating
= FALSE
,
682 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
683 else if (obt_parse_node_contains(n
, "Bottom"))
684 config_dock_floating
= FALSE
,
685 config_dock_pos
= OB_DIRECTION_SOUTH
;
686 else if (obt_parse_node_contains(n
, "BottomLeft"))
687 config_dock_floating
= FALSE
,
688 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
689 else if (obt_parse_node_contains(n
, "Left"))
690 config_dock_floating
= FALSE
,
691 config_dock_pos
= OB_DIRECTION_WEST
;
692 else if (obt_parse_node_contains(n
, "Floating"))
693 config_dock_floating
= TRUE
;
695 if (config_dock_floating
) {
696 if ((n
= obt_parse_find_node(node
, "floatingX")))
697 config_dock_x
= obt_parse_node_int(n
);
698 if ((n
= obt_parse_find_node(node
, "floatingY")))
699 config_dock_y
= obt_parse_node_int(n
);
701 if ((n
= obt_parse_find_node(node
, "noStrut")))
702 config_dock_nostrut
= obt_parse_node_bool(n
);
704 if ((n
= obt_parse_find_node(node
, "stacking"))) {
705 if (obt_parse_node_contains(n
, "normal"))
706 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
707 else if (obt_parse_node_contains(n
, "below"))
708 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
709 else if (obt_parse_node_contains(n
, "above"))
710 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
712 if ((n
= obt_parse_find_node(node
, "direction"))) {
713 if (obt_parse_node_contains(n
, "horizontal"))
714 config_dock_orient
= OB_ORIENTATION_HORZ
;
715 else if (obt_parse_node_contains(n
, "vertical"))
716 config_dock_orient
= OB_ORIENTATION_VERT
;
718 if ((n
= obt_parse_find_node(node
, "autoHide")))
719 config_dock_hide
= obt_parse_node_bool(n
);
720 if ((n
= obt_parse_find_node(node
, "hideDelay")))
721 config_dock_hide_delay
= obt_parse_node_int(n
);
722 if ((n
= obt_parse_find_node(node
, "showDelay")))
723 config_dock_show_delay
= obt_parse_node_int(n
);
724 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
725 gchar
*str
= obt_parse_node_string(n
);
727 if (translate_button(str
, &s
, &b
)) {
728 config_dock_app_move_button
= b
;
729 config_dock_app_move_modifiers
= s
;
731 g_message(_("Invalid button '%s' specified in config file"), str
);
737 static void parse_menu(xmlNodePtr node
, gpointer d
)
740 for (node
= node
->children
; node
; node
= node
->next
) {
741 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
744 c
= obt_parse_node_string(node
);
745 config_menu_files
= g_slist_append(config_menu_files
,
746 parse_expand_tilde(c
));
749 if ((n
= obt_parse_find_node(node
, "hideDelay")))
750 config_menu_hide_delay
= obt_parse_node_int(n
);
751 if ((n
= obt_parse_find_node(node
, "middle")))
752 config_menu_middle
= obt_parse_node_bool(n
);
753 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
754 config_submenu_show_delay
= obt_parse_node_int(n
);
755 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
756 config_menu_client_list_icons
= obt_parse_node_bool(n
);
760 static void parse_resistance(xmlNodePtr node
, gpointer d
)
764 node
= node
->children
;
765 if ((n
= obt_parse_find_node(node
, "strength")))
766 config_resist_win
= obt_parse_node_int(n
);
767 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
768 config_resist_edge
= obt_parse_node_int(n
);
774 const gchar
*actname
;
777 static void bind_default_keyboard(void)
780 ObDefKeyBind binds
[] = {
781 { "A-Tab", "NextWindow" },
782 { "S-A-Tab", "PreviousWindow" },
786 for (it
= binds
; it
->key
; ++it
) {
787 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
788 keyboard_bind(l
, actions_parse_string(it
->actname
));
795 const gchar
*context
;
796 const ObMouseAction mact
;
797 const gchar
*actname
;
800 static void bind_default_mouse(void)
803 ObDefMouseBind binds
[] = {
804 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
805 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
806 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
807 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
808 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
809 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
810 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
811 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
812 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
813 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
814 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
815 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
816 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
817 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
818 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
819 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
820 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
821 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
822 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
823 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
824 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
825 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
826 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
827 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
828 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
829 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
830 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
831 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
832 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
833 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
834 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
835 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
836 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
837 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
838 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
839 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
840 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
841 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
842 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
843 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
844 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
845 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
846 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
847 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
848 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
849 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
850 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
851 { NULL
, NULL
, 0, NULL
}
854 for (it
= binds
; it
->button
; ++it
)
855 mouse_bind(it
->button
, it
->context
, it
->mact
,
856 actions_parse_string(it
->actname
));
859 void config_startup(ObtParseInst
*i
)
861 config_focus_new
= TRUE
;
862 config_focus_follow
= FALSE
;
863 config_focus_delay
= 0;
864 config_focus_raise
= FALSE
;
865 config_focus_last
= TRUE
;
866 config_focus_under_mouse
= FALSE
;
868 obt_parse_register(i
, "focus", parse_focus
, NULL
);
870 config_place_policy
= OB_PLACE_POLICY_SMART
;
871 config_place_center
= TRUE
;
872 config_place_active
= FALSE
;
874 obt_parse_register(i
, "placement", parse_placement
, NULL
);
876 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
878 obt_parse_register(i
, "margins", parse_margins
, NULL
);
882 config_animate_iconify
= TRUE
;
883 config_title_layout
= g_strdup("NLIMC");
884 config_theme_keepborder
= TRUE
;
886 config_font_activewindow
= NULL
;
887 config_font_inactivewindow
= NULL
;
888 config_font_menuitem
= NULL
;
889 config_font_menutitle
= NULL
;
891 obt_parse_register(i
, "theme", parse_theme
, NULL
);
893 config_desktops_num
= 4;
894 config_screen_firstdesk
= 1;
895 config_desktops_names
= NULL
;
896 config_desktop_popup_time
= 875;
898 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
900 config_resize_redraw
= TRUE
;
901 config_resize_popup_show
= 1; /* nonpixel increments */
902 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
903 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
904 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
906 obt_parse_register(i
, "resize", parse_resize
, NULL
);
908 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
909 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
910 config_dock_floating
= FALSE
;
911 config_dock_nostrut
= FALSE
;
914 config_dock_orient
= OB_ORIENTATION_VERT
;
915 config_dock_hide
= FALSE
;
916 config_dock_hide_delay
= 300;
917 config_dock_show_delay
= 300;
918 config_dock_app_move_button
= 2; /* middle */
919 config_dock_app_move_modifiers
= 0;
921 obt_parse_register(i
, "dock", parse_dock
, NULL
);
923 translate_key("C-g", &config_keyboard_reset_state
,
924 &config_keyboard_reset_keycode
);
926 bind_default_keyboard();
928 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
930 config_mouse_threshold
= 8;
931 config_mouse_dclicktime
= 200;
932 config_mouse_screenedgetime
= 400;
934 bind_default_mouse();
936 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
938 config_resist_win
= 10;
939 config_resist_edge
= 20;
941 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
943 config_menu_hide_delay
= 250;
944 config_menu_middle
= FALSE
;
945 config_submenu_show_delay
= 0;
946 config_menu_client_list_icons
= TRUE
;
947 config_menu_files
= NULL
;
949 obt_parse_register(i
, "menu", parse_menu
, NULL
);
951 config_per_app_settings
= NULL
;
953 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
956 void config_shutdown(void)
960 g_free(config_theme
);
962 g_free(config_title_layout
);
964 RrFontClose(config_font_activewindow
);
965 RrFontClose(config_font_inactivewindow
);
966 RrFontClose(config_font_menuitem
);
967 RrFontClose(config_font_menutitle
);
969 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
971 g_slist_free(config_desktops_names
);
973 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
975 g_slist_free(config_menu_files
);
977 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
978 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
979 if (itd
->name
) g_pattern_spec_free(itd
->name
);
980 if (itd
->role
) g_pattern_spec_free(itd
->role
);
981 if (itd
->class) g_pattern_spec_free(itd
->class);
984 g_slist_free(config_per_app_settings
);