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 #include "obt/paths.h"
32 gboolean config_focus_new
;
33 gboolean config_focus_follow
;
34 guint config_focus_delay
;
35 gboolean config_focus_raise
;
36 gboolean config_focus_last
;
37 gboolean config_focus_under_mouse
;
39 ObPlacePolicy config_place_policy
;
40 gboolean config_place_center
;
41 ObPlaceMonitor config_place_monitor
;
43 StrutPartial config_margins
;
46 gboolean config_theme_keepborder
;
47 guint config_theme_window_list_icon_size
;
49 gchar
*config_title_layout
;
51 gboolean config_animate_iconify
;
53 RrFont
*config_font_activewindow
;
54 RrFont
*config_font_inactivewindow
;
55 RrFont
*config_font_menuitem
;
56 RrFont
*config_font_menutitle
;
57 RrFont
*config_font_osd
;
59 guint config_desktops_num
;
60 GSList
*config_desktops_names
;
61 guint config_screen_firstdesk
;
62 guint config_desktop_popup_time
;
64 gboolean config_resize_redraw
;
65 gint config_resize_popup_show
;
66 ObResizePopupPos config_resize_popup_pos
;
67 GravityPoint config_resize_popup_fixed
;
69 ObStackingLayer config_dock_layer
;
70 gboolean config_dock_floating
;
71 gboolean config_dock_nostrut
;
72 ObDirection config_dock_pos
;
75 ObOrientation config_dock_orient
;
76 gboolean config_dock_hide
;
77 guint config_dock_hide_delay
;
78 guint config_dock_show_delay
;
79 guint config_dock_app_move_button
;
80 guint config_dock_app_move_modifiers
;
82 guint config_keyboard_reset_keycode
;
83 guint config_keyboard_reset_state
;
85 gint config_mouse_threshold
;
86 gint config_mouse_dclicktime
;
87 gint config_mouse_screenedgetime
;
89 guint config_menu_hide_delay
;
90 gboolean config_menu_middle
;
91 guint config_submenu_show_delay
;
92 gboolean config_menu_client_list_icons
;
93 gboolean config_menu_manage_desktops
;
95 GSList
*config_menu_files
;
97 gint config_resist_win
;
98 gint config_resist_edge
;
100 GSList
*config_per_app_settings
;
102 ObAppSettings
* config_create_app_settings(void)
104 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
106 settings
->decor
= -1;
107 settings
->shade
= -1;
108 settings
->monitor
= -1;
109 settings
->focus
= -1;
110 settings
->desktop
= 0;
111 settings
->layer
= -2;
112 settings
->iconic
= -1;
113 settings
->skip_pager
= -1;
114 settings
->skip_taskbar
= -1;
115 settings
->fullscreen
= -1;
116 settings
->max_horz
= -1;
117 settings
->max_vert
= -1;
121 #define copy_if(setting, default) \
122 if (src->setting != default) dst->setting = src->setting
123 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
126 g_assert(src
!= NULL
);
127 g_assert(dst
!= NULL
);
129 copy_if(type
, (ObClientType
)-1);
136 copy_if(skip_pager
, -1);
137 copy_if(skip_taskbar
, -1);
138 copy_if(fullscreen
, -1);
139 copy_if(max_horz
, -1);
140 copy_if(max_vert
, -1);
142 if (src
->pos_given
) {
143 dst
->pos_given
= TRUE
;
144 dst
->pos_force
= src
->pos_force
;
145 dst
->position
= src
->position
;
146 dst
->monitor
= src
->monitor
;
150 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
152 gchar
*s
= obt_parse_node_string(node
);
153 if (!g_ascii_strcasecmp(s
, "center"))
158 if (s
[0] == '-' || s
[0] == '+')
168 <application name="aterm">
171 <application name="Rhythmbox">
178 .. there is a lot more settings available
183 /* Manages settings for individual applications.
184 Some notes: monitor is the screen number in a multi monitor
185 (Xinerama) setup (starting from 0) or mouse, meaning the
186 monitor the pointer is on. Default: mouse.
187 Layer can be three values, above (Always on top), below
188 (Always on bottom) and everything else (normal behaviour).
189 Positions can be an integer value or center, which will
190 center the window in the specified axis. Position is within
191 the monitor, so <position><x>center</x></position><monitor>2</monitor>
192 will center the window on the second monitor.
194 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
196 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
197 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
198 gboolean name_set
, class_set
, type_set
;
199 gboolean x_pos_given
;
202 name_set
= class_set
= type_set
= x_pos_given
= FALSE
;
204 class_set
= obt_parse_attr_string(app
, "class", &class);
205 name_set
= obt_parse_attr_string(app
, "name", &name
);
206 type_set
= obt_parse_attr_string(app
, "type", &type
);
207 if (class_set
|| name_set
) {
209 ObAppSettings
*settings
= config_create_app_settings();;
212 settings
->name
= g_pattern_spec_new(name
);
215 settings
->class = g_pattern_spec_new(class);
218 if (!g_ascii_strcasecmp(type
, "normal"))
219 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
220 else if (!g_ascii_strcasecmp(type
, "dialog"))
221 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
222 else if (!g_ascii_strcasecmp(type
, "splash"))
223 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
224 else if (!g_ascii_strcasecmp(type
, "utility"))
225 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
226 else if (!g_ascii_strcasecmp(type
, "menu"))
227 settings
->type
= OB_CLIENT_TYPE_MENU
;
228 else if (!g_ascii_strcasecmp(type
, "toolbar"))
229 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
230 else if (!g_ascii_strcasecmp(type
, "dock"))
231 settings
->type
= OB_CLIENT_TYPE_DOCK
;
232 else if (!g_ascii_strcasecmp(type
, "desktop"))
233 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
236 if (obt_parse_attr_string(app
, "role", &role
))
237 settings
->role
= g_pattern_spec_new(role
);
239 if ((n
= obt_parse_find_node(app
->children
, "decor")))
240 if (!obt_parse_node_contains(n
, "default"))
241 settings
->decor
= obt_parse_node_bool(n
);
243 if ((n
= obt_parse_find_node(app
->children
, "shade")))
244 if (!obt_parse_node_contains(n
, "default"))
245 settings
->shade
= obt_parse_node_bool(n
);
247 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
248 if ((c
= obt_parse_find_node(n
->children
, "x")))
249 if (!obt_parse_node_contains(c
, "default")) {
250 config_parse_gravity_coord(c
, &settings
->position
.x
);
254 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
255 if (!obt_parse_node_contains(c
, "default")) {
256 config_parse_gravity_coord(c
, &settings
->position
.y
);
257 settings
->pos_given
= TRUE
;
260 if (settings
->pos_given
&&
261 (c
= obt_parse_find_node(n
->children
, "monitor")))
262 if (!obt_parse_node_contains(c
, "default")) {
263 gchar
*s
= obt_parse_node_string(c
);
264 if (!g_ascii_strcasecmp(s
, "mouse"))
265 settings
->monitor
= 0;
267 settings
->monitor
= obt_parse_node_int(c
) + 1;
271 obt_parse_attr_bool(n
, "force", &settings
->pos_force
);
274 if ((n
= obt_parse_find_node(app
->children
, "focus")))
275 if (!obt_parse_node_contains(n
, "default"))
276 settings
->focus
= obt_parse_node_bool(n
);
278 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
279 if (!obt_parse_node_contains(n
, "default")) {
280 gchar
*s
= obt_parse_node_string(n
);
281 if (!g_ascii_strcasecmp(s
, "all"))
282 settings
->desktop
= DESKTOP_ALL
;
284 gint i
= obt_parse_node_int(n
);
286 settings
->desktop
= i
;
292 if ((n
= obt_parse_find_node(app
->children
, "layer")))
293 if (!obt_parse_node_contains(n
, "default")) {
294 gchar
*s
= obt_parse_node_string(n
);
295 if (!g_ascii_strcasecmp(s
, "above"))
297 else if (!g_ascii_strcasecmp(s
, "below"))
298 settings
->layer
= -1;
304 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
305 if (!obt_parse_node_contains(n
, "default"))
306 settings
->iconic
= obt_parse_node_bool(n
);
308 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
309 if (!obt_parse_node_contains(n
, "default"))
310 settings
->skip_pager
= obt_parse_node_bool(n
);
312 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
313 if (!obt_parse_node_contains(n
, "default"))
314 settings
->skip_taskbar
= obt_parse_node_bool(n
);
316 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
317 if (!obt_parse_node_contains(n
, "default"))
318 settings
->fullscreen
= obt_parse_node_bool(n
);
320 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
321 if (!obt_parse_node_contains(n
, "default")) {
322 gchar
*s
= obt_parse_node_string(n
);
323 if (!g_ascii_strcasecmp(s
, "horizontal")) {
324 settings
->max_horz
= TRUE
;
325 settings
->max_vert
= FALSE
;
326 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
327 settings
->max_horz
= FALSE
;
328 settings
->max_vert
= TRUE
;
330 settings
->max_horz
= settings
->max_vert
=
331 obt_parse_node_bool(n
);
335 config_per_app_settings
= g_slist_append(config_per_app_settings
,
336 (gpointer
) settings
);
340 name
= class = role
= NULL
;
343 app
= obt_parse_find_node(app
->next
, "application");
347 static void parse_hook(xmlNodePtr node
, gpointer d
)
354 if (!obt_parse_attr_string(node
, "name", &name
)) {
355 g_message(_("Hook in config file is missing a name"));
359 hook
= hooks_hook_from_name(name
);
361 g_message(_("Unknown hook \"%s\" in config file"), name
);
363 if ((n
= obt_parse_find_node(node
->children
, "action")))
365 ObActionsAct
*action
;
367 action
= actions_parse(n
);
369 hooks_add(hook
, action
);
370 n
= obt_parse_find_node(n
->next
, "action");
377 static void parse_hooks(xmlNodePtr node
, gpointer d
)
381 if ((n
= obt_parse_find_node(node
->children
, "hook")))
384 n
= obt_parse_find_node(n
->next
, "hook");
391 <action name="ChangeDesktop">
398 static void parse_key(xmlNodePtr node
, GList
*keylist
)
402 gboolean is_chroot
= FALSE
;
404 if (!obt_parse_attr_string(node
, "key", &key
))
407 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
409 keylist
= g_list_append(keylist
, key
);
411 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
413 parse_key(n
, keylist
);
414 n
= obt_parse_find_node(n
->next
, "keybind");
417 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
419 ObActionsAct
*action
;
421 action
= actions_parse(n
);
423 keyboard_bind(keylist
, action
);
424 n
= obt_parse_find_node(n
->next
, "action");
429 keyboard_chroot(keylist
);
432 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
435 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
440 keyboard_unbind_all();
442 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
443 key
= obt_parse_node_string(n
);
444 translate_key(key
, &config_keyboard_reset_state
,
445 &config_keyboard_reset_keycode
);
449 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
452 n
= obt_parse_find_node(n
->next
, "keybind");
458 <context name="Titlebar">
459 <mousebind button="Left" action="Press">
460 <action name="Raise"></action>
466 static void parse_mouse(xmlNodePtr node
, gpointer d
)
468 xmlNodePtr n
, nbut
, nact
;
475 node
= node
->children
;
477 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
478 config_mouse_threshold
= obt_parse_node_int(n
);
479 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
480 config_mouse_dclicktime
= obt_parse_node_int(n
);
481 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime")))
482 config_mouse_screenedgetime
= obt_parse_node_int(n
);
484 n
= obt_parse_find_node(node
, "context");
486 if (!obt_parse_attr_string(n
, "name", &contextstr
))
488 nbut
= obt_parse_find_node(n
->children
, "mousebind");
490 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
492 if (obt_parse_attr_contains(nbut
, "action", "press")) {
493 mact
= OB_MOUSE_ACTION_PRESS
;
494 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
495 mact
= OB_MOUSE_ACTION_RELEASE
;
496 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
497 mact
= OB_MOUSE_ACTION_CLICK
;
498 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
499 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
500 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
501 mact
= OB_MOUSE_ACTION_MOTION
;
504 nact
= obt_parse_find_node(nbut
->children
, "action");
506 ObActionsAct
*action
;
508 if ((action
= actions_parse(nact
)))
509 mouse_bind(buttonstr
, contextstr
, mact
, action
);
510 nact
= obt_parse_find_node(nact
->next
, "action");
514 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
518 n
= obt_parse_find_node(n
->next
, "context");
522 static void parse_focus(xmlNodePtr node
, gpointer d
)
526 node
= node
->children
;
528 if ((n
= obt_parse_find_node(node
, "focusNew")))
529 config_focus_new
= obt_parse_node_bool(n
);
530 if ((n
= obt_parse_find_node(node
, "followMouse")))
531 config_focus_follow
= obt_parse_node_bool(n
);
532 if ((n
= obt_parse_find_node(node
, "focusDelay")))
533 config_focus_delay
= obt_parse_node_int(n
);
534 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
535 config_focus_raise
= obt_parse_node_bool(n
);
536 if ((n
= obt_parse_find_node(node
, "focusLast")))
537 config_focus_last
= obt_parse_node_bool(n
);
538 if ((n
= obt_parse_find_node(node
, "underMouse")))
539 config_focus_under_mouse
= obt_parse_node_bool(n
);
542 static void parse_placement(xmlNodePtr node
, gpointer d
)
546 node
= node
->children
;
548 if ((n
= obt_parse_find_node(node
, "policy")))
549 if (obt_parse_node_contains(n
, "UnderMouse"))
550 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
551 if ((n
= obt_parse_find_node(node
, "center")))
552 config_place_center
= obt_parse_node_bool(n
);
553 if ((n
= obt_parse_find_node(node
, "monitor"))) {
554 if (obt_parse_node_contains(n
, "active"))
555 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
556 else if (obt_parse_node_contains(n
, "mouse"))
557 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
561 static void parse_margins(xmlNodePtr node
, gpointer d
)
565 node
= node
->children
;
567 if ((n
= obt_parse_find_node(node
, "top")))
568 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
569 if ((n
= obt_parse_find_node(node
, "left")))
570 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
571 if ((n
= obt_parse_find_node(node
, "right")))
572 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
573 if ((n
= obt_parse_find_node(node
, "bottom")))
574 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
577 static void parse_theme(xmlNodePtr node
, gpointer d
)
581 node
= node
->children
;
583 if ((n
= obt_parse_find_node(node
, "name"))) {
586 g_free(config_theme
);
587 c
= obt_parse_node_string(n
);
588 config_theme
= obt_paths_expand_tilde(c
);
591 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
594 g_free(config_title_layout
);
595 config_title_layout
= obt_parse_node_string(n
);
597 /* replace duplicates with spaces */
598 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
599 for (d
= c
+1; *d
!= '\0'; ++d
)
600 if (*c
== *d
) *d
= ' ';
602 if ((n
= obt_parse_find_node(node
, "keepBorder")))
603 config_theme_keepborder
= obt_parse_node_bool(n
);
604 if ((n
= obt_parse_find_node(node
, "animateIconify")))
605 config_animate_iconify
= obt_parse_node_bool(n
);
606 if ((n
= obt_parse_find_node(node
, "windowListIconSize"))) {
607 config_theme_window_list_icon_size
= obt_parse_node_int(n
);
608 if (config_theme_window_list_icon_size
< 16)
609 config_theme_window_list_icon_size
= 16;
610 else if (config_theme_window_list_icon_size
> 96)
611 config_theme_window_list_icon_size
= 96;
614 n
= obt_parse_find_node(node
, "font");
618 gchar
*name
= g_strdup(RrDefaultFontFamily
);
619 gint size
= RrDefaultFontSize
;
620 RrFontWeight weight
= RrDefaultFontWeight
;
621 RrFontSlant slant
= RrDefaultFontSlant
;
623 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
624 font
= &config_font_activewindow
;
625 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
626 font
= &config_font_inactivewindow
;
627 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
628 font
= &config_font_menutitle
;
629 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
630 font
= &config_font_menuitem
;
631 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
632 font
= &config_font_osd
;
636 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
638 name
= obt_parse_node_string(fnode
);
640 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
641 int s
= obt_parse_node_int(fnode
);
644 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
645 gchar
*w
= obt_parse_node_string(fnode
);
646 if (!g_ascii_strcasecmp(w
, "Bold"))
647 weight
= RR_FONTWEIGHT_BOLD
;
650 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
651 gchar
*s
= obt_parse_node_string(fnode
);
652 if (!g_ascii_strcasecmp(s
, "Italic"))
653 slant
= RR_FONTSLANT_ITALIC
;
654 if (!g_ascii_strcasecmp(s
, "Oblique"))
655 slant
= RR_FONTSLANT_OBLIQUE
;
659 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
662 n
= obt_parse_find_node(n
->next
, "font");
666 static void parse_desktops(xmlNodePtr node
, gpointer d
)
670 node
= node
->children
;
672 if ((n
= obt_parse_find_node(node
, "number"))) {
673 gint d
= obt_parse_node_int(n
);
675 config_desktops_num
= (unsigned) d
;
677 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
678 gint d
= obt_parse_node_int(n
);
680 config_screen_firstdesk
= (unsigned) d
;
682 if ((n
= obt_parse_find_node(node
, "names"))) {
686 for (it
= config_desktops_names
; it
; it
= it
->next
)
688 g_slist_free(config_desktops_names
);
689 config_desktops_names
= NULL
;
691 nname
= obt_parse_find_node(n
->children
, "name");
693 config_desktops_names
=
694 g_slist_append(config_desktops_names
,
695 obt_parse_node_string(nname
));
696 nname
= obt_parse_find_node(nname
->next
, "name");
699 if ((n
= obt_parse_find_node(node
, "popupTime")))
700 config_desktop_popup_time
= obt_parse_node_int(n
);
703 static void parse_resize(xmlNodePtr node
, gpointer d
)
707 node
= node
->children
;
709 if ((n
= obt_parse_find_node(node
, "drawContents")))
710 config_resize_redraw
= obt_parse_node_bool(n
);
711 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
712 config_resize_popup_show
= obt_parse_node_int(n
);
713 if (obt_parse_node_contains(n
, "Always"))
714 config_resize_popup_show
= 2;
715 else if (obt_parse_node_contains(n
, "Never"))
716 config_resize_popup_show
= 0;
717 else if (obt_parse_node_contains(n
, "Nonpixel"))
718 config_resize_popup_show
= 1;
720 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
721 if (obt_parse_node_contains(n
, "Top"))
722 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
723 else if (obt_parse_node_contains(n
, "Center"))
724 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
725 else if (obt_parse_node_contains(n
, "Fixed")) {
726 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
728 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
731 if ((n2
= obt_parse_find_node(n
->children
, "x")))
732 config_parse_gravity_coord(n2
,
733 &config_resize_popup_fixed
.x
);
734 if ((n2
= obt_parse_find_node(n
->children
, "y")))
735 config_parse_gravity_coord(n2
,
736 &config_resize_popup_fixed
.y
);
738 config_resize_popup_fixed
.x
.pos
=
739 MAX(config_resize_popup_fixed
.x
.pos
, 0);
740 config_resize_popup_fixed
.y
.pos
=
741 MAX(config_resize_popup_fixed
.y
.pos
, 0);
747 static void parse_dock(xmlNodePtr node
, gpointer d
)
751 node
= node
->children
;
753 if ((n
= obt_parse_find_node(node
, "position"))) {
754 if (obt_parse_node_contains(n
, "TopLeft"))
755 config_dock_floating
= FALSE
,
756 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
757 else if (obt_parse_node_contains(n
, "Top"))
758 config_dock_floating
= FALSE
,
759 config_dock_pos
= OB_DIRECTION_NORTH
;
760 else if (obt_parse_node_contains(n
, "TopRight"))
761 config_dock_floating
= FALSE
,
762 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
763 else if (obt_parse_node_contains(n
, "Right"))
764 config_dock_floating
= FALSE
,
765 config_dock_pos
= OB_DIRECTION_EAST
;
766 else if (obt_parse_node_contains(n
, "BottomRight"))
767 config_dock_floating
= FALSE
,
768 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
769 else if (obt_parse_node_contains(n
, "Bottom"))
770 config_dock_floating
= FALSE
,
771 config_dock_pos
= OB_DIRECTION_SOUTH
;
772 else if (obt_parse_node_contains(n
, "BottomLeft"))
773 config_dock_floating
= FALSE
,
774 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
775 else if (obt_parse_node_contains(n
, "Left"))
776 config_dock_floating
= FALSE
,
777 config_dock_pos
= OB_DIRECTION_WEST
;
778 else if (obt_parse_node_contains(n
, "Floating"))
779 config_dock_floating
= TRUE
;
781 if (config_dock_floating
) {
782 if ((n
= obt_parse_find_node(node
, "floatingX")))
783 config_dock_x
= obt_parse_node_int(n
);
784 if ((n
= obt_parse_find_node(node
, "floatingY")))
785 config_dock_y
= obt_parse_node_int(n
);
787 if ((n
= obt_parse_find_node(node
, "noStrut")))
788 config_dock_nostrut
= obt_parse_node_bool(n
);
790 if ((n
= obt_parse_find_node(node
, "stacking"))) {
791 if (obt_parse_node_contains(n
, "normal"))
792 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
793 else if (obt_parse_node_contains(n
, "below"))
794 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
795 else if (obt_parse_node_contains(n
, "above"))
796 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
798 if ((n
= obt_parse_find_node(node
, "direction"))) {
799 if (obt_parse_node_contains(n
, "horizontal"))
800 config_dock_orient
= OB_ORIENTATION_HORZ
;
801 else if (obt_parse_node_contains(n
, "vertical"))
802 config_dock_orient
= OB_ORIENTATION_VERT
;
804 if ((n
= obt_parse_find_node(node
, "autoHide")))
805 config_dock_hide
= obt_parse_node_bool(n
);
806 if ((n
= obt_parse_find_node(node
, "hideDelay")))
807 config_dock_hide_delay
= obt_parse_node_int(n
);
808 if ((n
= obt_parse_find_node(node
, "showDelay")))
809 config_dock_show_delay
= obt_parse_node_int(n
);
810 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
811 gchar
*str
= obt_parse_node_string(n
);
813 if (translate_button(str
, &s
, &b
)) {
814 config_dock_app_move_button
= b
;
815 config_dock_app_move_modifiers
= s
;
817 g_message(_("Invalid button \"%s\" specified in config file"), str
);
823 static void parse_menu(xmlNodePtr node
, gpointer d
)
826 node
= node
->children
;
828 if ((n
= obt_parse_find_node(node
, "hideDelay")))
829 config_menu_hide_delay
= obt_parse_node_int(n
);
830 if ((n
= obt_parse_find_node(node
, "middle")))
831 config_menu_middle
= obt_parse_node_bool(n
);
832 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
833 config_submenu_show_delay
= obt_parse_node_int(n
);
834 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
835 config_menu_client_list_icons
= obt_parse_node_bool(n
);
836 if ((n
= obt_parse_find_node(node
, "manageDesktops")))
837 config_menu_manage_desktops
= obt_parse_node_bool(n
);
839 while ((node
= obt_parse_find_node(node
, "file"))) {
840 gchar
*c
= obt_parse_node_string(node
);
841 config_menu_files
= g_slist_append(config_menu_files
,
842 obt_paths_expand_tilde(c
));
848 static void parse_resistance(xmlNodePtr node
, gpointer d
)
852 node
= node
->children
;
853 if ((n
= obt_parse_find_node(node
, "strength")))
854 config_resist_win
= obt_parse_node_int(n
);
855 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
856 config_resist_edge
= obt_parse_node_int(n
);
862 const gchar
*actname
;
865 static void bind_default_keyboard(void)
868 ObDefKeyBind binds
[] = {
869 { "A-Tab", "NextWindow" },
870 { "S-A-Tab", "PreviousWindow" },
874 for (it
= binds
; it
->key
; ++it
) {
875 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
876 keyboard_bind(l
, actions_parse_string(it
->actname
));
883 const gchar
*context
;
884 const ObMouseAction mact
;
885 const gchar
*actname
;
888 static void bind_default_mouse(void)
891 ObDefMouseBind binds
[] = {
892 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
893 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
894 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
895 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
896 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
897 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
898 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
899 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
900 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
901 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
902 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
903 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
904 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
905 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
906 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
907 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
908 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
909 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
910 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
911 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
912 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
913 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
914 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
915 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
916 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
917 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
918 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
919 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
920 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
921 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
922 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
923 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
924 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
925 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
926 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
927 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
928 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
929 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
930 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
931 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
932 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
933 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
934 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
935 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
936 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
937 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
938 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
939 { NULL
, NULL
, 0, NULL
}
942 for (it
= binds
; it
->button
; ++it
)
943 mouse_bind(it
->button
, it
->context
, it
->mact
,
944 actions_parse_string(it
->actname
));
947 void config_startup(ObtParseInst
*i
)
949 config_focus_new
= TRUE
;
950 config_focus_follow
= FALSE
;
951 config_focus_delay
= 0;
952 config_focus_raise
= FALSE
;
953 config_focus_last
= TRUE
;
954 config_focus_under_mouse
= FALSE
;
956 obt_parse_register(i
, "focus", parse_focus
, NULL
);
958 config_place_policy
= OB_PLACE_POLICY_SMART
;
959 config_place_center
= TRUE
;
960 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
962 obt_parse_register(i
, "placement", parse_placement
, NULL
);
964 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
966 obt_parse_register(i
, "margins", parse_margins
, NULL
);
970 config_animate_iconify
= TRUE
;
971 config_title_layout
= g_strdup("NLIMC");
972 config_theme_keepborder
= TRUE
;
973 config_theme_window_list_icon_size
= 36;
975 config_font_activewindow
= NULL
;
976 config_font_inactivewindow
= NULL
;
977 config_font_menuitem
= NULL
;
978 config_font_menutitle
= NULL
;
980 obt_parse_register(i
, "theme", parse_theme
, NULL
);
982 config_desktops_num
= 4;
983 config_screen_firstdesk
= 1;
984 config_desktops_names
= NULL
;
985 config_desktop_popup_time
= 875;
987 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
989 config_resize_redraw
= TRUE
;
990 config_resize_popup_show
= 1; /* nonpixel increments */
991 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
992 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
993 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
995 obt_parse_register(i
, "resize", parse_resize
, NULL
);
997 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
998 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
999 config_dock_floating
= FALSE
;
1000 config_dock_nostrut
= FALSE
;
1003 config_dock_orient
= OB_ORIENTATION_VERT
;
1004 config_dock_hide
= FALSE
;
1005 config_dock_hide_delay
= 300;
1006 config_dock_show_delay
= 300;
1007 config_dock_app_move_button
= 2; /* middle */
1008 config_dock_app_move_modifiers
= 0;
1010 obt_parse_register(i
, "dock", parse_dock
, NULL
);
1012 translate_key("C-g", &config_keyboard_reset_state
,
1013 &config_keyboard_reset_keycode
);
1015 bind_default_keyboard();
1017 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
1019 config_mouse_threshold
= 8;
1020 config_mouse_dclicktime
= 200;
1021 config_mouse_screenedgetime
= 400;
1023 bind_default_mouse();
1025 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
1027 config_resist_win
= 10;
1028 config_resist_edge
= 20;
1030 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
1032 config_menu_hide_delay
= 250;
1033 config_menu_middle
= FALSE
;
1034 config_submenu_show_delay
= 0;
1035 config_menu_client_list_icons
= TRUE
;
1036 config_menu_manage_desktops
= TRUE
;
1037 config_menu_files
= NULL
;
1039 obt_parse_register(i
, "menu", parse_menu
, NULL
);
1041 obt_parse_register(i
, "hooks", parse_hooks
, NULL
);
1043 config_per_app_settings
= NULL
;
1045 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
1048 void config_shutdown(void)
1052 g_free(config_theme
);
1054 g_free(config_title_layout
);
1056 RrFontClose(config_font_activewindow
);
1057 RrFontClose(config_font_inactivewindow
);
1058 RrFontClose(config_font_menuitem
);
1059 RrFontClose(config_font_menutitle
);
1060 RrFontClose(config_font_osd
);
1062 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1064 g_slist_free(config_desktops_names
);
1066 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1068 g_slist_free(config_menu_files
);
1070 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1071 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1072 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1073 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1074 if (itd
->class) g_pattern_spec_free(itd
->class);
1077 g_slist_free(config_per_app_settings
);