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
;
37 gboolean config_unfocus_leave
;
39 ObPlacePolicy config_place_policy
;
40 gboolean config_place_center
;
41 ObPlaceMonitor config_place_monitor
;
43 guint config_primary_monitor_index
;
44 ObPlaceMonitor config_primary_monitor
;
46 StrutPartial config_margins
;
49 gboolean config_theme_keepborder
;
50 guint config_theme_window_list_icon_size
;
52 gchar
*config_title_layout
;
54 gboolean config_animate_iconify
;
56 RrFont
*config_font_activewindow
;
57 RrFont
*config_font_inactivewindow
;
58 RrFont
*config_font_menuitem
;
59 RrFont
*config_font_menutitle
;
60 RrFont
*config_font_activeosd
;
61 RrFont
*config_font_inactiveosd
;
63 guint config_desktops_num
;
64 GSList
*config_desktops_names
;
65 guint config_screen_firstdesk
;
66 guint config_desktop_popup_time
;
68 gboolean config_resize_redraw
;
69 gint config_resize_popup_show
;
70 ObResizePopupPos config_resize_popup_pos
;
71 GravityPoint config_resize_popup_fixed
;
73 ObStackingLayer config_dock_layer
;
74 gboolean config_dock_floating
;
75 gboolean config_dock_nostrut
;
76 ObDirection config_dock_pos
;
79 ObOrientation config_dock_orient
;
80 gboolean config_dock_hide
;
81 guint config_dock_hide_delay
;
82 guint config_dock_show_delay
;
83 guint config_dock_app_move_button
;
84 guint config_dock_app_move_modifiers
;
86 guint config_keyboard_reset_keycode
;
87 guint config_keyboard_reset_state
;
89 gint config_mouse_threshold
;
90 gint config_mouse_dclicktime
;
91 gint config_mouse_screenedgetime
;
93 guint config_menu_hide_delay
;
94 gboolean config_menu_middle
;
95 guint config_submenu_show_delay
;
96 guint config_submenu_hide_delay
;
97 gboolean config_menu_client_list_icons
;
98 gboolean config_menu_manage_desktops
;
99 gboolean config_menu_user_show_icons
;
101 GSList
*config_menu_files
;
103 gint config_resist_win
;
104 gint config_resist_edge
;
106 GSList
*config_per_app_settings
;
108 ObAppSettings
* config_create_app_settings(void)
110 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
112 settings
->decor
= -1;
113 settings
->shade
= -1;
114 settings
->monitor
= -1;
115 settings
->focus
= -1;
116 settings
->desktop
= 0;
117 settings
->layer
= -2;
118 settings
->iconic
= -1;
119 settings
->skip_pager
= -1;
120 settings
->skip_taskbar
= -1;
121 settings
->fullscreen
= -1;
122 settings
->max_horz
= -1;
123 settings
->max_vert
= -1;
127 #define copy_if(setting, default) \
128 if (src->setting != default) dst->setting = src->setting
129 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
132 g_assert(src
!= NULL
);
133 g_assert(dst
!= NULL
);
135 copy_if(type
, (ObClientType
)-1);
138 copy_if(monitor
, -1);
143 copy_if(skip_pager
, -1);
144 copy_if(skip_taskbar
, -1);
145 copy_if(fullscreen
, -1);
146 copy_if(max_horz
, -1);
147 copy_if(max_vert
, -1);
149 if (src
->pos_given
) {
150 dst
->pos_given
= TRUE
;
151 dst
->pos_force
= src
->pos_force
;
152 dst
->position
= src
->position
;
153 dst
->monitor
= src
->monitor
;
157 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
159 gchar
*s
= obt_xml_node_string(node
);
160 if (!g_ascii_strcasecmp(s
, "center"))
165 if (s
[0] == '-' || s
[0] == '+')
175 <application name="aterm">
178 <application name="Rhythmbox">
185 .. there is a lot more settings available
190 /* Manages settings for individual applications.
191 Some notes: monitor is the screen number in a multi monitor
192 (Xinerama) setup (starting from 0) or mouse, meaning the
193 monitor the pointer is on. Default: mouse.
194 Layer can be three values, above (Always on top), below
195 (Always on bottom) and everything else (normal behaviour).
196 Positions can be an integer value or center, which will
197 center the window in the specified axis. Position is within
198 the monitor, so <position><x>center</x></position><monitor>2</monitor>
199 will center the window on the second monitor.
201 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
203 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
204 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
205 gboolean name_set
, class_set
, type_set
;
206 gboolean x_pos_given
;
211 class_set
= obt_xml_attr_string(app
, "class", &class);
212 name_set
= obt_xml_attr_string(app
, "name", &name
);
213 type_set
= obt_xml_attr_string(app
, "type", &type
);
214 if (class_set
|| name_set
) {
216 ObAppSettings
*settings
= config_create_app_settings();;
219 settings
->name
= g_pattern_spec_new(name
);
222 settings
->class = g_pattern_spec_new(class);
225 if (!g_ascii_strcasecmp(type
, "normal"))
226 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
227 else if (!g_ascii_strcasecmp(type
, "dialog"))
228 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
229 else if (!g_ascii_strcasecmp(type
, "splash"))
230 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
231 else if (!g_ascii_strcasecmp(type
, "utility"))
232 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
233 else if (!g_ascii_strcasecmp(type
, "menu"))
234 settings
->type
= OB_CLIENT_TYPE_MENU
;
235 else if (!g_ascii_strcasecmp(type
, "toolbar"))
236 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
237 else if (!g_ascii_strcasecmp(type
, "dock"))
238 settings
->type
= OB_CLIENT_TYPE_DOCK
;
239 else if (!g_ascii_strcasecmp(type
, "desktop"))
240 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
243 if (obt_xml_attr_string(app
, "role", &role
))
244 settings
->role
= g_pattern_spec_new(role
);
246 if ((n
= obt_xml_find_node(app
->children
, "decor")))
247 if (!obt_xml_node_contains(n
, "default"))
248 settings
->decor
= obt_xml_node_bool(n
);
250 if ((n
= obt_xml_find_node(app
->children
, "shade")))
251 if (!obt_xml_node_contains(n
, "default"))
252 settings
->shade
= obt_xml_node_bool(n
);
254 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
255 if ((c
= obt_xml_find_node(n
->children
, "x")))
256 if (!obt_xml_node_contains(c
, "default")) {
257 config_parse_gravity_coord(c
, &settings
->position
.x
);
261 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
262 if (!obt_xml_node_contains(c
, "default")) {
263 config_parse_gravity_coord(c
, &settings
->position
.y
);
264 settings
->pos_given
= TRUE
;
267 if (settings
->pos_given
&&
268 (c
= obt_xml_find_node(n
->children
, "monitor")))
269 if (!obt_xml_node_contains(c
, "default")) {
270 gchar
*s
= obt_xml_node_string(c
);
271 if (!g_ascii_strcasecmp(s
, "mouse"))
272 settings
->monitor
= 0;
274 settings
->monitor
= obt_xml_node_int(c
);
278 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
281 if ((n
= obt_xml_find_node(app
->children
, "focus")))
282 if (!obt_xml_node_contains(n
, "default"))
283 settings
->focus
= obt_xml_node_bool(n
);
285 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
286 if (!obt_xml_node_contains(n
, "default")) {
287 gchar
*s
= obt_xml_node_string(n
);
288 if (!g_ascii_strcasecmp(s
, "all"))
289 settings
->desktop
= DESKTOP_ALL
;
291 gint i
= obt_xml_node_int(n
);
293 settings
->desktop
= i
;
299 if ((n
= obt_xml_find_node(app
->children
, "layer")))
300 if (!obt_xml_node_contains(n
, "default")) {
301 gchar
*s
= obt_xml_node_string(n
);
302 if (!g_ascii_strcasecmp(s
, "above"))
304 else if (!g_ascii_strcasecmp(s
, "below"))
305 settings
->layer
= -1;
311 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
312 if (!obt_xml_node_contains(n
, "default"))
313 settings
->iconic
= obt_xml_node_bool(n
);
315 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
316 if (!obt_xml_node_contains(n
, "default"))
317 settings
->skip_pager
= obt_xml_node_bool(n
);
319 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
320 if (!obt_xml_node_contains(n
, "default"))
321 settings
->skip_taskbar
= obt_xml_node_bool(n
);
323 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
324 if (!obt_xml_node_contains(n
, "default"))
325 settings
->fullscreen
= obt_xml_node_bool(n
);
327 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
328 if (!obt_xml_node_contains(n
, "default")) {
329 gchar
*s
= obt_xml_node_string(n
);
330 if (!g_ascii_strcasecmp(s
, "horizontal")) {
331 settings
->max_horz
= TRUE
;
332 settings
->max_vert
= FALSE
;
333 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
334 settings
->max_horz
= FALSE
;
335 settings
->max_vert
= TRUE
;
337 settings
->max_horz
= settings
->max_vert
=
338 obt_xml_node_bool(n
);
342 config_per_app_settings
= g_slist_append(config_per_app_settings
,
343 (gpointer
) settings
);
347 name
= class = role
= NULL
;
350 app
= obt_xml_find_node(app
->next
, "application");
357 <action name="ChangeDesktop">
364 static void parse_key(xmlNodePtr node
, GList
*keylist
)
368 gboolean is_chroot
= FALSE
;
370 if (!obt_xml_attr_string(node
, "key", &key
))
373 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
375 keylist
= g_list_append(keylist
, key
);
377 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
379 parse_key(n
, keylist
);
380 n
= obt_xml_find_node(n
->next
, "keybind");
383 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
385 ObActionsAct
*action
;
387 action
= actions_parse(n
);
389 keyboard_bind(keylist
, action
);
390 n
= obt_xml_find_node(n
->next
, "action");
395 keyboard_chroot(keylist
);
398 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
401 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
406 keyboard_unbind_all();
408 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
409 key
= obt_xml_node_string(n
);
410 translate_key(key
, &config_keyboard_reset_state
,
411 &config_keyboard_reset_keycode
);
415 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
418 n
= obt_xml_find_node(n
->next
, "keybind");
424 <context name="Titlebar">
425 <mousebind button="Left" action="Press">
426 <action name="Raise"></action>
432 static void parse_mouse(xmlNodePtr node
, gpointer d
)
434 xmlNodePtr n
, nbut
, nact
;
441 node
= node
->children
;
443 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
444 config_mouse_threshold
= obt_xml_node_int(n
);
445 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
446 config_mouse_dclicktime
= obt_xml_node_int(n
);
447 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
448 config_mouse_screenedgetime
= obt_xml_node_int(n
);
449 /* minimum value of 25 for this property, when it is 1 and you hit the
450 edge it basically never stops */
451 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
452 config_mouse_screenedgetime
= 25;
455 n
= obt_xml_find_node(node
, "context");
457 if (!obt_xml_attr_string(n
, "name", &contextstr
))
459 nbut
= obt_xml_find_node(n
->children
, "mousebind");
461 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
463 if (obt_xml_attr_contains(nbut
, "action", "press")) {
464 mact
= OB_MOUSE_ACTION_PRESS
;
465 } else if (obt_xml_attr_contains(nbut
, "action", "release")) {
466 mact
= OB_MOUSE_ACTION_RELEASE
;
467 } else if (obt_xml_attr_contains(nbut
, "action", "click")) {
468 mact
= OB_MOUSE_ACTION_CLICK
;
469 } else if (obt_xml_attr_contains(nbut
, "action","doubleclick")) {
470 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
471 } else if (obt_xml_attr_contains(nbut
, "action", "drag")) {
472 mact
= OB_MOUSE_ACTION_MOTION
;
475 nact
= obt_xml_find_node(nbut
->children
, "action");
477 ObActionsAct
*action
;
479 if ((action
= actions_parse(nact
)))
480 mouse_bind(buttonstr
, contextstr
, mact
, action
);
481 nact
= obt_xml_find_node(nact
->next
, "action");
485 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
489 n
= obt_xml_find_node(n
->next
, "context");
493 static void parse_focus(xmlNodePtr node
, gpointer d
)
497 node
= node
->children
;
499 if ((n
= obt_xml_find_node(node
, "focusNew")))
500 config_focus_new
= obt_xml_node_bool(n
);
501 if ((n
= obt_xml_find_node(node
, "followMouse")))
502 config_focus_follow
= obt_xml_node_bool(n
);
503 if ((n
= obt_xml_find_node(node
, "focusDelay")))
504 config_focus_delay
= obt_xml_node_int(n
);
505 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
506 config_focus_raise
= obt_xml_node_bool(n
);
507 if ((n
= obt_xml_find_node(node
, "focusLast")))
508 config_focus_last
= obt_xml_node_bool(n
);
509 if ((n
= obt_xml_find_node(node
, "underMouse")))
510 config_focus_under_mouse
= obt_xml_node_bool(n
);
511 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
512 config_unfocus_leave
= obt_xml_node_bool(n
);
515 static void parse_placement(xmlNodePtr node
, gpointer d
)
519 node
= node
->children
;
521 if ((n
= obt_xml_find_node(node
, "policy")))
522 if (obt_xml_node_contains(n
, "UnderMouse"))
523 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
524 if ((n
= obt_xml_find_node(node
, "center")))
525 config_place_center
= obt_xml_node_bool(n
);
526 if ((n
= obt_xml_find_node(node
, "monitor"))) {
527 if (obt_xml_node_contains(n
, "active"))
528 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
529 else if (obt_xml_node_contains(n
, "mouse"))
530 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
532 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
533 config_primary_monitor_index
= obt_xml_node_int(n
);
534 if (!config_primary_monitor_index
) {
535 if (obt_xml_node_contains(n
, "mouse"))
536 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
541 static void parse_margins(xmlNodePtr node
, gpointer d
)
545 node
= node
->children
;
547 if ((n
= obt_xml_find_node(node
, "top")))
548 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
549 if ((n
= obt_xml_find_node(node
, "left")))
550 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
551 if ((n
= obt_xml_find_node(node
, "right")))
552 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
553 if ((n
= obt_xml_find_node(node
, "bottom")))
554 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
557 static void parse_theme(xmlNodePtr node
, gpointer d
)
561 node
= node
->children
;
563 if ((n
= obt_xml_find_node(node
, "name"))) {
566 g_free(config_theme
);
567 c
= obt_xml_node_string(n
);
568 config_theme
= obt_paths_expand_tilde(c
);
571 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
574 g_free(config_title_layout
);
575 config_title_layout
= obt_xml_node_string(n
);
577 /* replace duplicates with spaces */
578 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
579 for (d
= c
+1; *d
!= '\0'; ++d
)
580 if (*c
== *d
) *d
= ' ';
582 if ((n
= obt_xml_find_node(node
, "keepBorder")))
583 config_theme_keepborder
= obt_xml_node_bool(n
);
584 if ((n
= obt_xml_find_node(node
, "animateIconify")))
585 config_animate_iconify
= obt_xml_node_bool(n
);
586 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
587 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
588 if (config_theme_window_list_icon_size
< 16)
589 config_theme_window_list_icon_size
= 16;
590 else if (config_theme_window_list_icon_size
> 96)
591 config_theme_window_list_icon_size
= 96;
594 n
= obt_xml_find_node(node
, "font");
598 gchar
*name
= g_strdup(RrDefaultFontFamily
);
599 gint size
= RrDefaultFontSize
;
600 RrFontWeight weight
= RrDefaultFontWeight
;
601 RrFontSlant slant
= RrDefaultFontSlant
;
603 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
604 font
= &config_font_activewindow
;
605 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
606 font
= &config_font_inactivewindow
;
607 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
608 font
= &config_font_menutitle
;
609 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
610 font
= &config_font_menuitem
;
611 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
612 font
= &config_font_activeosd
;
613 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
614 font
= &config_font_activeosd
;
615 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
616 font
= &config_font_inactiveosd
;
620 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
622 name
= obt_xml_node_string(fnode
);
624 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
625 int s
= obt_xml_node_int(fnode
);
628 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
629 gchar
*w
= obt_xml_node_string(fnode
);
630 if (!g_ascii_strcasecmp(w
, "Bold"))
631 weight
= RR_FONTWEIGHT_BOLD
;
634 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
635 gchar
*s
= obt_xml_node_string(fnode
);
636 if (!g_ascii_strcasecmp(s
, "Italic"))
637 slant
= RR_FONTSLANT_ITALIC
;
638 if (!g_ascii_strcasecmp(s
, "Oblique"))
639 slant
= RR_FONTSLANT_OBLIQUE
;
643 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
646 n
= obt_xml_find_node(n
->next
, "font");
650 static void parse_desktops(xmlNodePtr node
, gpointer d
)
654 node
= node
->children
;
656 if ((n
= obt_xml_find_node(node
, "number"))) {
657 gint d
= obt_xml_node_int(n
);
659 config_desktops_num
= (unsigned) d
;
661 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
662 gint d
= obt_xml_node_int(n
);
664 config_screen_firstdesk
= (unsigned) d
;
666 if ((n
= obt_xml_find_node(node
, "names"))) {
670 for (it
= config_desktops_names
; it
; it
= it
->next
)
672 g_slist_free(config_desktops_names
);
673 config_desktops_names
= NULL
;
675 nname
= obt_xml_find_node(n
->children
, "name");
677 config_desktops_names
=
678 g_slist_append(config_desktops_names
,
679 obt_xml_node_string(nname
));
680 nname
= obt_xml_find_node(nname
->next
, "name");
683 if ((n
= obt_xml_find_node(node
, "popupTime")))
684 config_desktop_popup_time
= obt_xml_node_int(n
);
687 static void parse_resize(xmlNodePtr node
, gpointer d
)
691 node
= node
->children
;
693 if ((n
= obt_xml_find_node(node
, "drawContents")))
694 config_resize_redraw
= obt_xml_node_bool(n
);
695 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
696 config_resize_popup_show
= obt_xml_node_int(n
);
697 if (obt_xml_node_contains(n
, "Always"))
698 config_resize_popup_show
= 2;
699 else if (obt_xml_node_contains(n
, "Never"))
700 config_resize_popup_show
= 0;
701 else if (obt_xml_node_contains(n
, "Nonpixel"))
702 config_resize_popup_show
= 1;
704 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
705 if (obt_xml_node_contains(n
, "Top"))
706 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
707 else if (obt_xml_node_contains(n
, "Center"))
708 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
709 else if (obt_xml_node_contains(n
, "Fixed")) {
710 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
712 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
715 if ((n2
= obt_xml_find_node(n
->children
, "x")))
716 config_parse_gravity_coord(n2
,
717 &config_resize_popup_fixed
.x
);
718 if ((n2
= obt_xml_find_node(n
->children
, "y")))
719 config_parse_gravity_coord(n2
,
720 &config_resize_popup_fixed
.y
);
722 config_resize_popup_fixed
.x
.pos
=
723 MAX(config_resize_popup_fixed
.x
.pos
, 0);
724 config_resize_popup_fixed
.y
.pos
=
725 MAX(config_resize_popup_fixed
.y
.pos
, 0);
731 static void parse_dock(xmlNodePtr node
, gpointer d
)
735 node
= node
->children
;
737 if ((n
= obt_xml_find_node(node
, "position"))) {
738 if (obt_xml_node_contains(n
, "TopLeft"))
739 config_dock_floating
= FALSE
,
740 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
741 else if (obt_xml_node_contains(n
, "Top"))
742 config_dock_floating
= FALSE
,
743 config_dock_pos
= OB_DIRECTION_NORTH
;
744 else if (obt_xml_node_contains(n
, "TopRight"))
745 config_dock_floating
= FALSE
,
746 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
747 else if (obt_xml_node_contains(n
, "Right"))
748 config_dock_floating
= FALSE
,
749 config_dock_pos
= OB_DIRECTION_EAST
;
750 else if (obt_xml_node_contains(n
, "BottomRight"))
751 config_dock_floating
= FALSE
,
752 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
753 else if (obt_xml_node_contains(n
, "Bottom"))
754 config_dock_floating
= FALSE
,
755 config_dock_pos
= OB_DIRECTION_SOUTH
;
756 else if (obt_xml_node_contains(n
, "BottomLeft"))
757 config_dock_floating
= FALSE
,
758 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
759 else if (obt_xml_node_contains(n
, "Left"))
760 config_dock_floating
= FALSE
,
761 config_dock_pos
= OB_DIRECTION_WEST
;
762 else if (obt_xml_node_contains(n
, "Floating"))
763 config_dock_floating
= TRUE
;
765 if (config_dock_floating
) {
766 if ((n
= obt_xml_find_node(node
, "floatingX")))
767 config_dock_x
= obt_xml_node_int(n
);
768 if ((n
= obt_xml_find_node(node
, "floatingY")))
769 config_dock_y
= obt_xml_node_int(n
);
771 if ((n
= obt_xml_find_node(node
, "noStrut")))
772 config_dock_nostrut
= obt_xml_node_bool(n
);
774 if ((n
= obt_xml_find_node(node
, "stacking"))) {
775 if (obt_xml_node_contains(n
, "normal"))
776 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
777 else if (obt_xml_node_contains(n
, "below"))
778 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
779 else if (obt_xml_node_contains(n
, "above"))
780 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
782 if ((n
= obt_xml_find_node(node
, "direction"))) {
783 if (obt_xml_node_contains(n
, "horizontal"))
784 config_dock_orient
= OB_ORIENTATION_HORZ
;
785 else if (obt_xml_node_contains(n
, "vertical"))
786 config_dock_orient
= OB_ORIENTATION_VERT
;
788 if ((n
= obt_xml_find_node(node
, "autoHide")))
789 config_dock_hide
= obt_xml_node_bool(n
);
790 if ((n
= obt_xml_find_node(node
, "hideDelay")))
791 config_dock_hide_delay
= obt_xml_node_int(n
);
792 if ((n
= obt_xml_find_node(node
, "showDelay")))
793 config_dock_show_delay
= obt_xml_node_int(n
);
794 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
795 gchar
*str
= obt_xml_node_string(n
);
797 if (translate_button(str
, &s
, &b
)) {
798 config_dock_app_move_button
= b
;
799 config_dock_app_move_modifiers
= s
;
801 g_message(_("Invalid button \"%s\" specified in config file"), str
);
807 static void parse_menu(xmlNodePtr node
, gpointer d
)
810 node
= node
->children
;
812 if ((n
= obt_xml_find_node(node
, "hideDelay")))
813 config_menu_hide_delay
= obt_xml_node_int(n
);
814 if ((n
= obt_xml_find_node(node
, "middle")))
815 config_menu_middle
= obt_xml_node_bool(n
);
816 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
817 config_submenu_show_delay
= obt_xml_node_int(n
);
818 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
819 config_submenu_hide_delay
= obt_xml_node_int(n
);
820 if ((n
= obt_xml_find_node(node
, "applicationIcons")))
821 config_menu_client_list_icons
= obt_xml_node_bool(n
);
822 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
823 config_menu_manage_desktops
= obt_xml_node_bool(n
);
824 if ((n
= obt_xml_find_node(node
, "showIcons"))) {
825 config_menu_user_show_icons
= obt_xml_node_bool(n
);
827 if (config_menu_user_show_icons
)
828 g_message(_("Openbox was compiled without Imlib2."
829 " Icons in user-defined menus will NOT be loaded."));
833 while ((node
= obt_xml_find_node(node
, "file"))) {
834 gchar
*c
= obt_xml_node_string(node
);
835 config_menu_files
= g_slist_append(config_menu_files
,
836 obt_paths_expand_tilde(c
));
842 static void parse_resistance(xmlNodePtr node
, gpointer d
)
846 node
= node
->children
;
847 if ((n
= obt_xml_find_node(node
, "strength")))
848 config_resist_win
= obt_xml_node_int(n
);
849 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
850 config_resist_edge
= obt_xml_node_int(n
);
856 const gchar
*actname
;
859 static void bind_default_keyboard(void)
862 ObDefKeyBind binds
[] = {
863 { "A-Tab", "NextWindow" },
864 { "S-A-Tab", "PreviousWindow" },
868 for (it
= binds
; it
->key
; ++it
) {
869 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
870 keyboard_bind(l
, actions_parse_string(it
->actname
));
877 const gchar
*context
;
878 const ObMouseAction mact
;
879 const gchar
*actname
;
882 static void bind_default_mouse(void)
885 ObDefMouseBind binds
[] = {
886 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
887 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
888 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
889 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
890 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
891 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
892 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
893 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
894 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
895 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
896 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
897 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
898 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
899 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
900 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
901 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
902 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
903 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
904 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
905 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
906 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
907 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
908 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
909 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
910 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
911 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
912 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
913 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
914 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
915 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
916 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
917 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
918 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
919 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
920 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
921 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
922 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
923 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
924 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
925 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
926 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
927 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
928 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
929 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
930 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
931 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
932 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
933 { NULL
, NULL
, 0, NULL
}
936 for (it
= binds
; it
->button
; ++it
)
937 mouse_bind(it
->button
, it
->context
, it
->mact
,
938 actions_parse_string(it
->actname
));
941 void config_startup(ObtXmlInst
*i
)
943 config_focus_new
= TRUE
;
944 config_focus_follow
= FALSE
;
945 config_focus_delay
= 0;
946 config_focus_raise
= FALSE
;
947 config_focus_last
= TRUE
;
948 config_focus_under_mouse
= FALSE
;
949 config_unfocus_leave
= FALSE
;
951 obt_xml_register(i
, "focus", parse_focus
, NULL
);
953 config_place_policy
= OB_PLACE_POLICY_SMART
;
954 config_place_center
= TRUE
;
955 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
957 config_primary_monitor_index
= 1;
958 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
960 obt_xml_register(i
, "placement", parse_placement
, NULL
);
962 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
964 obt_xml_register(i
, "margins", parse_margins
, NULL
);
968 config_animate_iconify
= TRUE
;
969 config_title_layout
= g_strdup("NLIMC");
970 config_theme_keepborder
= TRUE
;
971 config_theme_window_list_icon_size
= 36;
973 config_font_activewindow
= NULL
;
974 config_font_inactivewindow
= NULL
;
975 config_font_menuitem
= NULL
;
976 config_font_menutitle
= NULL
;
978 obt_xml_register(i
, "theme", parse_theme
, NULL
);
980 config_desktops_num
= 4;
981 config_screen_firstdesk
= 1;
982 config_desktops_names
= NULL
;
983 config_desktop_popup_time
= 875;
985 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
987 config_resize_redraw
= TRUE
;
988 config_resize_popup_show
= 1; /* nonpixel increments */
989 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
990 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
991 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
993 obt_xml_register(i
, "resize", parse_resize
, NULL
);
995 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
996 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
997 config_dock_floating
= FALSE
;
998 config_dock_nostrut
= FALSE
;
1001 config_dock_orient
= OB_ORIENTATION_VERT
;
1002 config_dock_hide
= FALSE
;
1003 config_dock_hide_delay
= 300;
1004 config_dock_show_delay
= 300;
1005 config_dock_app_move_button
= 2; /* middle */
1006 config_dock_app_move_modifiers
= 0;
1008 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1010 translate_key("C-g", &config_keyboard_reset_state
,
1011 &config_keyboard_reset_keycode
);
1013 bind_default_keyboard();
1015 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1017 config_mouse_threshold
= 8;
1018 config_mouse_dclicktime
= 200;
1019 config_mouse_screenedgetime
= 400;
1021 bind_default_mouse();
1023 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1025 config_resist_win
= 10;
1026 config_resist_edge
= 20;
1028 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1030 config_menu_hide_delay
= 250;
1031 config_menu_middle
= FALSE
;
1032 config_submenu_show_delay
= 200;
1033 config_submenu_hide_delay
= 400;
1034 config_menu_client_list_icons
= TRUE
;
1035 config_menu_manage_desktops
= TRUE
;
1036 config_menu_files
= NULL
;
1037 config_menu_user_show_icons
= TRUE
;
1039 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1041 config_per_app_settings
= NULL
;
1043 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1046 void config_shutdown(void)
1050 g_free(config_theme
);
1052 g_free(config_title_layout
);
1054 RrFontClose(config_font_activewindow
);
1055 RrFontClose(config_font_inactivewindow
);
1056 RrFontClose(config_font_menuitem
);
1057 RrFontClose(config_font_menutitle
);
1058 RrFontClose(config_font_activeosd
);
1059 RrFontClose(config_font_inactiveosd
);
1061 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1063 g_slist_free(config_desktops_names
);
1065 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1067 g_slist_free(config_menu_files
);
1069 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1070 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1071 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1072 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1073 if (itd
->class) g_pattern_spec_free(itd
->class);
1076 g_slist_free(config_per_app_settings
);