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
;
91 gboolean config_menu_manage_desktops
;
93 GSList
*config_menu_files
;
95 gint config_resist_win
;
96 gint config_resist_edge
;
98 GSList
*config_per_app_settings
;
100 ObAppSettings
* config_create_app_settings(void)
102 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
104 settings
->decor
= -1;
105 settings
->shade
= -1;
106 settings
->monitor
= -1;
107 settings
->focus
= -1;
108 settings
->desktop
= 0;
109 settings
->layer
= -2;
110 settings
->iconic
= -1;
111 settings
->skip_pager
= -1;
112 settings
->skip_taskbar
= -1;
113 settings
->fullscreen
= -1;
114 settings
->max_horz
= -1;
115 settings
->max_vert
= -1;
119 #define copy_if(setting, default) \
120 if (src->setting != default) dst->setting = src->setting
121 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
124 g_assert(src
!= NULL
);
125 g_assert(dst
!= NULL
);
127 copy_if(type
, (ObClientType
)-1);
134 copy_if(skip_pager
, -1);
135 copy_if(skip_taskbar
, -1);
136 copy_if(fullscreen
, -1);
137 copy_if(max_horz
, -1);
138 copy_if(max_vert
, -1);
140 if (src
->pos_given
) {
141 dst
->pos_given
= TRUE
;
142 dst
->pos_force
= src
->pos_force
;
143 dst
->position
= src
->position
;
144 dst
->monitor
= src
->monitor
;
148 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
150 gchar
*s
= obt_parse_node_string(node
);
151 if (!g_ascii_strcasecmp(s
, "center"))
156 if (s
[0] == '-' || s
[0] == '+')
166 <application name="aterm">
169 <application name="Rhythmbox">
176 .. there is a lot more settings available
181 /* Manages settings for individual applications.
182 Some notes: monitor is the screen number in a multi monitor
183 (Xinerama) setup (starting from 0) or mouse, meaning the
184 monitor the pointer is on. Default: mouse.
185 Layer can be three values, above (Always on top), below
186 (Always on bottom) and everything else (normal behaviour).
187 Positions can be an integer value or center, which will
188 center the window in the specified axis. Position is within
189 the monitor, so <position><x>center</x></position><monitor>2</monitor>
190 will center the window on the second monitor.
192 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
194 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
195 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
196 gboolean name_set
, class_set
, type_set
;
197 gboolean x_pos_given
;
200 name_set
= class_set
= type_set
= x_pos_given
= FALSE
;
202 class_set
= obt_parse_attr_string(app
, "class", &class);
203 name_set
= obt_parse_attr_string(app
, "name", &name
);
204 type_set
= obt_parse_attr_string(app
, "type", &type
);
205 if (class_set
|| name_set
) {
207 ObAppSettings
*settings
= config_create_app_settings();;
210 settings
->name
= g_pattern_spec_new(name
);
213 settings
->class = g_pattern_spec_new(class);
216 if (!g_ascii_strcasecmp(type
, "normal"))
217 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
218 else if (!g_ascii_strcasecmp(type
, "dialog"))
219 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
220 else if (!g_ascii_strcasecmp(type
, "splash"))
221 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
222 else if (!g_ascii_strcasecmp(type
, "utility"))
223 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
224 else if (!g_ascii_strcasecmp(type
, "menu"))
225 settings
->type
= OB_CLIENT_TYPE_MENU
;
226 else if (!g_ascii_strcasecmp(type
, "toolbar"))
227 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
228 else if (!g_ascii_strcasecmp(type
, "dock"))
229 settings
->type
= OB_CLIENT_TYPE_DOCK
;
230 else if (!g_ascii_strcasecmp(type
, "desktop"))
231 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
234 if (obt_parse_attr_string(app
, "role", &role
))
235 settings
->role
= g_pattern_spec_new(role
);
237 if ((n
= obt_parse_find_node(app
->children
, "decor")))
238 if (!obt_parse_node_contains(n
, "default"))
239 settings
->decor
= obt_parse_node_bool(n
);
241 if ((n
= obt_parse_find_node(app
->children
, "shade")))
242 if (!obt_parse_node_contains(n
, "default"))
243 settings
->shade
= obt_parse_node_bool(n
);
245 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
246 if ((c
= obt_parse_find_node(n
->children
, "x")))
247 if (!obt_parse_node_contains(c
, "default")) {
248 config_parse_gravity_coord(c
, &settings
->position
.x
);
252 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
253 if (!obt_parse_node_contains(c
, "default")) {
254 config_parse_gravity_coord(c
, &settings
->position
.y
);
255 settings
->pos_given
= TRUE
;
258 if (settings
->pos_given
&&
259 (c
= obt_parse_find_node(n
->children
, "monitor")))
260 if (!obt_parse_node_contains(c
, "default")) {
261 gchar
*s
= obt_parse_node_string(c
);
262 if (!g_ascii_strcasecmp(s
, "mouse"))
263 settings
->monitor
= 0;
265 settings
->monitor
= obt_parse_node_int(c
) + 1;
269 obt_parse_attr_bool(n
, "force", &settings
->pos_force
);
272 if ((n
= obt_parse_find_node(app
->children
, "focus")))
273 if (!obt_parse_node_contains(n
, "default"))
274 settings
->focus
= obt_parse_node_bool(n
);
276 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
277 if (!obt_parse_node_contains(n
, "default")) {
278 gchar
*s
= obt_parse_node_string(n
);
279 if (!g_ascii_strcasecmp(s
, "all"))
280 settings
->desktop
= DESKTOP_ALL
;
282 gint i
= obt_parse_node_int(n
);
284 settings
->desktop
= i
;
290 if ((n
= obt_parse_find_node(app
->children
, "layer")))
291 if (!obt_parse_node_contains(n
, "default")) {
292 gchar
*s
= obt_parse_node_string(n
);
293 if (!g_ascii_strcasecmp(s
, "above"))
295 else if (!g_ascii_strcasecmp(s
, "below"))
296 settings
->layer
= -1;
302 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
303 if (!obt_parse_node_contains(n
, "default"))
304 settings
->iconic
= obt_parse_node_bool(n
);
306 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
307 if (!obt_parse_node_contains(n
, "default"))
308 settings
->skip_pager
= obt_parse_node_bool(n
);
310 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
311 if (!obt_parse_node_contains(n
, "default"))
312 settings
->skip_taskbar
= obt_parse_node_bool(n
);
314 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
315 if (!obt_parse_node_contains(n
, "default"))
316 settings
->fullscreen
= obt_parse_node_bool(n
);
318 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
319 if (!obt_parse_node_contains(n
, "default")) {
320 gchar
*s
= obt_parse_node_string(n
);
321 if (!g_ascii_strcasecmp(s
, "horizontal")) {
322 settings
->max_horz
= TRUE
;
323 settings
->max_vert
= FALSE
;
324 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
325 settings
->max_horz
= FALSE
;
326 settings
->max_vert
= TRUE
;
328 settings
->max_horz
= settings
->max_vert
=
329 obt_parse_node_bool(n
);
333 config_per_app_settings
= g_slist_append(config_per_app_settings
,
334 (gpointer
) settings
);
338 name
= class = role
= NULL
;
341 app
= obt_parse_find_node(app
->next
, "application");
348 <action name="ChangeDesktop">
355 static void parse_key(xmlNodePtr node
, GList
*keylist
)
359 gboolean is_chroot
= FALSE
;
361 if (!obt_parse_attr_string(node
, "key", &key
))
364 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
366 keylist
= g_list_append(keylist
, key
);
368 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
370 parse_key(n
, keylist
);
371 n
= obt_parse_find_node(n
->next
, "keybind");
374 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
376 ObActionsAct
*action
;
378 action
= actions_parse(n
);
380 keyboard_bind(keylist
, action
);
381 n
= obt_parse_find_node(n
->next
, "action");
386 keyboard_chroot(keylist
);
389 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
392 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
397 keyboard_unbind_all();
399 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
400 key
= obt_parse_node_string(n
);
401 translate_key(key
, &config_keyboard_reset_state
,
402 &config_keyboard_reset_keycode
);
406 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
409 n
= obt_parse_find_node(n
->next
, "keybind");
415 <context name="Titlebar">
416 <mousebind button="Left" action="Press">
417 <action name="Raise"></action>
423 static void parse_mouse(xmlNodePtr node
, gpointer d
)
425 xmlNodePtr n
, nbut
, nact
;
432 node
= node
->children
;
434 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
435 config_mouse_threshold
= obt_parse_node_int(n
);
436 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
437 config_mouse_dclicktime
= obt_parse_node_int(n
);
438 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime")))
439 config_mouse_screenedgetime
= obt_parse_node_int(n
);
441 n
= obt_parse_find_node(node
, "context");
443 if (!obt_parse_attr_string(n
, "name", &contextstr
))
445 nbut
= obt_parse_find_node(n
->children
, "mousebind");
447 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
449 if (obt_parse_attr_contains(nbut
, "action", "press")) {
450 mact
= OB_MOUSE_ACTION_PRESS
;
451 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
452 mact
= OB_MOUSE_ACTION_RELEASE
;
453 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
454 mact
= OB_MOUSE_ACTION_CLICK
;
455 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
456 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
457 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
458 mact
= OB_MOUSE_ACTION_MOTION
;
461 nact
= obt_parse_find_node(nbut
->children
, "action");
463 ObActionsAct
*action
;
465 if ((action
= actions_parse(nact
)))
466 mouse_bind(buttonstr
, contextstr
, mact
, action
);
467 nact
= obt_parse_find_node(nact
->next
, "action");
471 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
475 n
= obt_parse_find_node(n
->next
, "context");
479 static void parse_focus(xmlNodePtr node
, gpointer d
)
483 node
= node
->children
;
485 if ((n
= obt_parse_find_node(node
, "focusNew")))
486 config_focus_new
= obt_parse_node_bool(n
);
487 if ((n
= obt_parse_find_node(node
, "followMouse")))
488 config_focus_follow
= obt_parse_node_bool(n
);
489 if ((n
= obt_parse_find_node(node
, "focusDelay")))
490 config_focus_delay
= obt_parse_node_int(n
);
491 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
492 config_focus_raise
= obt_parse_node_bool(n
);
493 if ((n
= obt_parse_find_node(node
, "focusLast")))
494 config_focus_last
= obt_parse_node_bool(n
);
495 if ((n
= obt_parse_find_node(node
, "underMouse")))
496 config_focus_under_mouse
= obt_parse_node_bool(n
);
499 static void parse_placement(xmlNodePtr node
, gpointer d
)
503 node
= node
->children
;
505 if ((n
= obt_parse_find_node(node
, "policy")))
506 if (obt_parse_node_contains(n
, "UnderMouse"))
507 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
508 if ((n
= obt_parse_find_node(node
, "center")))
509 config_place_center
= obt_parse_node_bool(n
);
510 if ((n
= obt_parse_find_node(node
, "monitor"))) {
511 if (obt_parse_node_contains(n
, "active"))
512 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
513 else if (obt_parse_node_contains(n
, "mouse"))
514 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
518 static void parse_margins(xmlNodePtr node
, gpointer d
)
522 node
= node
->children
;
524 if ((n
= obt_parse_find_node(node
, "top")))
525 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
526 if ((n
= obt_parse_find_node(node
, "left")))
527 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
528 if ((n
= obt_parse_find_node(node
, "right")))
529 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
530 if ((n
= obt_parse_find_node(node
, "bottom")))
531 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
534 static void parse_theme(xmlNodePtr node
, gpointer d
)
538 node
= node
->children
;
540 if ((n
= obt_parse_find_node(node
, "name"))) {
543 g_free(config_theme
);
544 c
= obt_parse_node_string(n
);
545 config_theme
= obt_paths_expand_tilde(c
);
548 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
551 g_free(config_title_layout
);
552 config_title_layout
= obt_parse_node_string(n
);
554 /* replace duplicates with spaces */
555 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
556 for (d
= c
+1; *d
!= '\0'; ++d
)
557 if (*c
== *d
) *d
= ' ';
559 if ((n
= obt_parse_find_node(node
, "keepBorder")))
560 config_theme_keepborder
= obt_parse_node_bool(n
);
561 if ((n
= obt_parse_find_node(node
, "animateIconify")))
562 config_animate_iconify
= obt_parse_node_bool(n
);
564 n
= obt_parse_find_node(node
, "font");
568 gchar
*name
= g_strdup(RrDefaultFontFamily
);
569 gint size
= RrDefaultFontSize
;
570 RrFontWeight weight
= RrDefaultFontWeight
;
571 RrFontSlant slant
= RrDefaultFontSlant
;
573 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
574 font
= &config_font_activewindow
;
575 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
576 font
= &config_font_inactivewindow
;
577 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
578 font
= &config_font_menutitle
;
579 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
580 font
= &config_font_menuitem
;
581 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
582 font
= &config_font_osd
;
586 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
588 name
= obt_parse_node_string(fnode
);
590 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
591 int s
= obt_parse_node_int(fnode
);
594 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
595 gchar
*w
= obt_parse_node_string(fnode
);
596 if (!g_ascii_strcasecmp(w
, "Bold"))
597 weight
= RR_FONTWEIGHT_BOLD
;
600 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
601 gchar
*s
= obt_parse_node_string(fnode
);
602 if (!g_ascii_strcasecmp(s
, "Italic"))
603 slant
= RR_FONTSLANT_ITALIC
;
604 if (!g_ascii_strcasecmp(s
, "Oblique"))
605 slant
= RR_FONTSLANT_OBLIQUE
;
609 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
612 n
= obt_parse_find_node(n
->next
, "font");
616 static void parse_desktops(xmlNodePtr node
, gpointer d
)
620 node
= node
->children
;
622 if ((n
= obt_parse_find_node(node
, "number"))) {
623 gint d
= obt_parse_node_int(n
);
625 config_desktops_num
= (unsigned) d
;
627 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
628 gint d
= obt_parse_node_int(n
);
630 config_screen_firstdesk
= (unsigned) d
;
632 if ((n
= obt_parse_find_node(node
, "names"))) {
636 for (it
= config_desktops_names
; it
; it
= it
->next
)
638 g_slist_free(config_desktops_names
);
639 config_desktops_names
= NULL
;
641 nname
= obt_parse_find_node(n
->children
, "name");
643 config_desktops_names
=
644 g_slist_append(config_desktops_names
,
645 obt_parse_node_string(nname
));
646 nname
= obt_parse_find_node(nname
->next
, "name");
649 if ((n
= obt_parse_find_node(node
, "popupTime")))
650 config_desktop_popup_time
= obt_parse_node_int(n
);
653 static void parse_resize(xmlNodePtr node
, gpointer d
)
657 node
= node
->children
;
659 if ((n
= obt_parse_find_node(node
, "drawContents")))
660 config_resize_redraw
= obt_parse_node_bool(n
);
661 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
662 config_resize_popup_show
= obt_parse_node_int(n
);
663 if (obt_parse_node_contains(n
, "Always"))
664 config_resize_popup_show
= 2;
665 else if (obt_parse_node_contains(n
, "Never"))
666 config_resize_popup_show
= 0;
667 else if (obt_parse_node_contains(n
, "Nonpixel"))
668 config_resize_popup_show
= 1;
670 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
671 if (obt_parse_node_contains(n
, "Top"))
672 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
673 else if (obt_parse_node_contains(n
, "Center"))
674 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
675 else if (obt_parse_node_contains(n
, "Fixed")) {
676 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
678 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
681 if ((n2
= obt_parse_find_node(n
->children
, "x")))
682 config_parse_gravity_coord(n2
,
683 &config_resize_popup_fixed
.x
);
684 if ((n2
= obt_parse_find_node(n
->children
, "y")))
685 config_parse_gravity_coord(n2
,
686 &config_resize_popup_fixed
.y
);
688 config_resize_popup_fixed
.x
.pos
=
689 MAX(config_resize_popup_fixed
.x
.pos
, 0);
690 config_resize_popup_fixed
.y
.pos
=
691 MAX(config_resize_popup_fixed
.y
.pos
, 0);
697 static void parse_dock(xmlNodePtr node
, gpointer d
)
701 node
= node
->children
;
703 if ((n
= obt_parse_find_node(node
, "position"))) {
704 if (obt_parse_node_contains(n
, "TopLeft"))
705 config_dock_floating
= FALSE
,
706 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
707 else if (obt_parse_node_contains(n
, "Top"))
708 config_dock_floating
= FALSE
,
709 config_dock_pos
= OB_DIRECTION_NORTH
;
710 else if (obt_parse_node_contains(n
, "TopRight"))
711 config_dock_floating
= FALSE
,
712 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
713 else if (obt_parse_node_contains(n
, "Right"))
714 config_dock_floating
= FALSE
,
715 config_dock_pos
= OB_DIRECTION_EAST
;
716 else if (obt_parse_node_contains(n
, "BottomRight"))
717 config_dock_floating
= FALSE
,
718 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
719 else if (obt_parse_node_contains(n
, "Bottom"))
720 config_dock_floating
= FALSE
,
721 config_dock_pos
= OB_DIRECTION_SOUTH
;
722 else if (obt_parse_node_contains(n
, "BottomLeft"))
723 config_dock_floating
= FALSE
,
724 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
725 else if (obt_parse_node_contains(n
, "Left"))
726 config_dock_floating
= FALSE
,
727 config_dock_pos
= OB_DIRECTION_WEST
;
728 else if (obt_parse_node_contains(n
, "Floating"))
729 config_dock_floating
= TRUE
;
731 if (config_dock_floating
) {
732 if ((n
= obt_parse_find_node(node
, "floatingX")))
733 config_dock_x
= obt_parse_node_int(n
);
734 if ((n
= obt_parse_find_node(node
, "floatingY")))
735 config_dock_y
= obt_parse_node_int(n
);
737 if ((n
= obt_parse_find_node(node
, "noStrut")))
738 config_dock_nostrut
= obt_parse_node_bool(n
);
740 if ((n
= obt_parse_find_node(node
, "stacking"))) {
741 if (obt_parse_node_contains(n
, "normal"))
742 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
743 else if (obt_parse_node_contains(n
, "below"))
744 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
745 else if (obt_parse_node_contains(n
, "above"))
746 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
748 if ((n
= obt_parse_find_node(node
, "direction"))) {
749 if (obt_parse_node_contains(n
, "horizontal"))
750 config_dock_orient
= OB_ORIENTATION_HORZ
;
751 else if (obt_parse_node_contains(n
, "vertical"))
752 config_dock_orient
= OB_ORIENTATION_VERT
;
754 if ((n
= obt_parse_find_node(node
, "autoHide")))
755 config_dock_hide
= obt_parse_node_bool(n
);
756 if ((n
= obt_parse_find_node(node
, "hideDelay")))
757 config_dock_hide_delay
= obt_parse_node_int(n
);
758 if ((n
= obt_parse_find_node(node
, "showDelay")))
759 config_dock_show_delay
= obt_parse_node_int(n
);
760 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
761 gchar
*str
= obt_parse_node_string(n
);
763 if (translate_button(str
, &s
, &b
)) {
764 config_dock_app_move_button
= b
;
765 config_dock_app_move_modifiers
= s
;
767 g_message(_("Invalid button \"%s\" specified in config file"), str
);
773 static void parse_menu(xmlNodePtr node
, gpointer d
)
776 for (node
= node
->children
; node
; node
= node
->next
) {
777 if (!xmlStrcasecmp(node
->name
, (const xmlChar
*) "file")) {
780 c
= obt_parse_node_string(node
);
781 config_menu_files
= g_slist_append(config_menu_files
,
782 obt_paths_expand_tilde(c
));
785 if ((n
= obt_parse_find_node(node
, "hideDelay")))
786 config_menu_hide_delay
= obt_parse_node_int(n
);
787 if ((n
= obt_parse_find_node(node
, "middle")))
788 config_menu_middle
= obt_parse_node_bool(n
);
789 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
790 config_submenu_show_delay
= obt_parse_node_int(n
);
791 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
792 config_menu_client_list_icons
= obt_parse_node_bool(n
);
793 if ((n
= obt_parse_find_node(node
, "manageDesktops")))
794 config_menu_manage_desktops
= obt_parse_node_bool(n
);
798 static void parse_resistance(xmlNodePtr node
, gpointer d
)
802 node
= node
->children
;
803 if ((n
= obt_parse_find_node(node
, "strength")))
804 config_resist_win
= obt_parse_node_int(n
);
805 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
806 config_resist_edge
= obt_parse_node_int(n
);
812 const gchar
*actname
;
815 static void bind_default_keyboard(void)
818 ObDefKeyBind binds
[] = {
819 { "A-Tab", "NextWindow" },
820 { "S-A-Tab", "PreviousWindow" },
824 for (it
= binds
; it
->key
; ++it
) {
825 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
826 keyboard_bind(l
, actions_parse_string(it
->actname
));
833 const gchar
*context
;
834 const ObMouseAction mact
;
835 const gchar
*actname
;
838 static void bind_default_mouse(void)
841 ObDefMouseBind binds
[] = {
842 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
843 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
844 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
845 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
846 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
847 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
848 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
849 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
850 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
851 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
852 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
853 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
854 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
855 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
856 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
857 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
858 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
859 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
860 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
861 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
862 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
863 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
864 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
865 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
866 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
867 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
868 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
869 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
870 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
871 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
872 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
873 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
874 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
875 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
876 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
877 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
878 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
879 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
880 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
881 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
882 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
883 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
884 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
885 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
886 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
887 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
888 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
889 { NULL
, NULL
, 0, NULL
}
892 for (it
= binds
; it
->button
; ++it
)
893 mouse_bind(it
->button
, it
->context
, it
->mact
,
894 actions_parse_string(it
->actname
));
897 void config_startup(ObtParseInst
*i
)
899 config_focus_new
= TRUE
;
900 config_focus_follow
= FALSE
;
901 config_focus_delay
= 0;
902 config_focus_raise
= FALSE
;
903 config_focus_last
= TRUE
;
904 config_focus_under_mouse
= FALSE
;
906 obt_parse_register(i
, "focus", parse_focus
, NULL
);
908 config_place_policy
= OB_PLACE_POLICY_SMART
;
909 config_place_center
= TRUE
;
910 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
912 obt_parse_register(i
, "placement", parse_placement
, NULL
);
914 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
916 obt_parse_register(i
, "margins", parse_margins
, NULL
);
920 config_animate_iconify
= TRUE
;
921 config_title_layout
= g_strdup("NLIMC");
922 config_theme_keepborder
= TRUE
;
924 config_font_activewindow
= NULL
;
925 config_font_inactivewindow
= NULL
;
926 config_font_menuitem
= NULL
;
927 config_font_menutitle
= NULL
;
929 obt_parse_register(i
, "theme", parse_theme
, NULL
);
931 config_desktops_num
= 4;
932 config_screen_firstdesk
= 1;
933 config_desktops_names
= NULL
;
934 config_desktop_popup_time
= 875;
936 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
938 config_resize_redraw
= TRUE
;
939 config_resize_popup_show
= 1; /* nonpixel increments */
940 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
941 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
942 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
944 obt_parse_register(i
, "resize", parse_resize
, NULL
);
946 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
947 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
948 config_dock_floating
= FALSE
;
949 config_dock_nostrut
= FALSE
;
952 config_dock_orient
= OB_ORIENTATION_VERT
;
953 config_dock_hide
= FALSE
;
954 config_dock_hide_delay
= 300;
955 config_dock_show_delay
= 300;
956 config_dock_app_move_button
= 2; /* middle */
957 config_dock_app_move_modifiers
= 0;
959 obt_parse_register(i
, "dock", parse_dock
, NULL
);
961 translate_key("C-g", &config_keyboard_reset_state
,
962 &config_keyboard_reset_keycode
);
964 bind_default_keyboard();
966 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
968 config_mouse_threshold
= 8;
969 config_mouse_dclicktime
= 200;
970 config_mouse_screenedgetime
= 400;
972 bind_default_mouse();
974 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
976 config_resist_win
= 10;
977 config_resist_edge
= 20;
979 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
981 config_menu_hide_delay
= 250;
982 config_menu_middle
= FALSE
;
983 config_submenu_show_delay
= 0;
984 config_menu_client_list_icons
= TRUE
;
985 config_menu_manage_desktops
= TRUE
;
986 config_menu_files
= NULL
;
988 obt_parse_register(i
, "menu", parse_menu
, NULL
);
990 config_per_app_settings
= NULL
;
992 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
995 void config_shutdown(void)
999 g_free(config_theme
);
1001 g_free(config_title_layout
);
1003 RrFontClose(config_font_activewindow
);
1004 RrFontClose(config_font_inactivewindow
);
1005 RrFontClose(config_font_menuitem
);
1006 RrFontClose(config_font_menutitle
);
1007 RrFontClose(config_font_osd
);
1009 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1011 g_slist_free(config_desktops_names
);
1013 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1015 g_slist_free(config_menu_files
);
1017 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1018 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1019 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1020 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1021 if (itd
->class) g_pattern_spec_free(itd
->class);
1024 g_slist_free(config_per_app_settings
);