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
;
100 GSList
*config_menu_files
;
102 gint config_resist_win
;
103 gint config_resist_edge
;
105 GSList
*config_per_app_settings
;
107 ObAppSettings
* config_create_app_settings(void)
109 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
111 settings
->decor
= -1;
112 settings
->shade
= -1;
113 settings
->monitor
= -1;
114 settings
->focus
= -1;
115 settings
->desktop
= 0;
116 settings
->layer
= -2;
117 settings
->iconic
= -1;
118 settings
->skip_pager
= -1;
119 settings
->skip_taskbar
= -1;
120 settings
->fullscreen
= -1;
121 settings
->max_horz
= -1;
122 settings
->max_vert
= -1;
126 #define copy_if(setting, default) \
127 if (src->setting != default) dst->setting = src->setting
128 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
131 g_assert(src
!= NULL
);
132 g_assert(dst
!= NULL
);
134 copy_if(type
, (ObClientType
)-1);
137 copy_if(monitor
, -1);
142 copy_if(skip_pager
, -1);
143 copy_if(skip_taskbar
, -1);
144 copy_if(fullscreen
, -1);
145 copy_if(max_horz
, -1);
146 copy_if(max_vert
, -1);
148 if (src
->pos_given
) {
149 dst
->pos_given
= TRUE
;
150 dst
->pos_force
= src
->pos_force
;
151 dst
->position
= src
->position
;
152 dst
->monitor
= src
->monitor
;
156 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
158 gchar
*s
= obt_xml_node_string(node
);
159 if (!g_ascii_strcasecmp(s
, "center"))
164 if (s
[0] == '-' || s
[0] == '+')
174 <application name="aterm">
177 <application name="Rhythmbox">
184 .. there is a lot more settings available
189 /* Manages settings for individual applications.
190 Some notes: monitor is the screen number in a multi monitor
191 (Xinerama) setup (starting from 0) or mouse, meaning the
192 monitor the pointer is on. Default: mouse.
193 Layer can be three values, above (Always on top), below
194 (Always on bottom) and everything else (normal behaviour).
195 Positions can be an integer value or center, which will
196 center the window in the specified axis. Position is within
197 the monitor, so <position><x>center</x></position><monitor>2</monitor>
198 will center the window on the second monitor.
200 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
202 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
203 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
204 gboolean name_set
, class_set
, type_set
;
205 gboolean x_pos_given
;
210 class_set
= obt_xml_attr_string(app
, "class", &class);
211 name_set
= obt_xml_attr_string(app
, "name", &name
);
212 type_set
= obt_xml_attr_string(app
, "type", &type
);
213 if (class_set
|| name_set
) {
215 ObAppSettings
*settings
= config_create_app_settings();;
218 settings
->name
= g_pattern_spec_new(name
);
221 settings
->class = g_pattern_spec_new(class);
224 if (!g_ascii_strcasecmp(type
, "normal"))
225 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
226 else if (!g_ascii_strcasecmp(type
, "dialog"))
227 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
228 else if (!g_ascii_strcasecmp(type
, "splash"))
229 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
230 else if (!g_ascii_strcasecmp(type
, "utility"))
231 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
232 else if (!g_ascii_strcasecmp(type
, "menu"))
233 settings
->type
= OB_CLIENT_TYPE_MENU
;
234 else if (!g_ascii_strcasecmp(type
, "toolbar"))
235 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
236 else if (!g_ascii_strcasecmp(type
, "dock"))
237 settings
->type
= OB_CLIENT_TYPE_DOCK
;
238 else if (!g_ascii_strcasecmp(type
, "desktop"))
239 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
242 if (obt_xml_attr_string(app
, "role", &role
))
243 settings
->role
= g_pattern_spec_new(role
);
245 if ((n
= obt_xml_find_node(app
->children
, "decor")))
246 if (!obt_xml_node_contains(n
, "default"))
247 settings
->decor
= obt_xml_node_bool(n
);
249 if ((n
= obt_xml_find_node(app
->children
, "shade")))
250 if (!obt_xml_node_contains(n
, "default"))
251 settings
->shade
= obt_xml_node_bool(n
);
253 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
254 if ((c
= obt_xml_find_node(n
->children
, "x")))
255 if (!obt_xml_node_contains(c
, "default")) {
256 config_parse_gravity_coord(c
, &settings
->position
.x
);
260 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
261 if (!obt_xml_node_contains(c
, "default")) {
262 config_parse_gravity_coord(c
, &settings
->position
.y
);
263 settings
->pos_given
= TRUE
;
266 if (settings
->pos_given
&&
267 (c
= obt_xml_find_node(n
->children
, "monitor")))
268 if (!obt_xml_node_contains(c
, "default")) {
269 gchar
*s
= obt_xml_node_string(c
);
270 if (!g_ascii_strcasecmp(s
, "mouse"))
271 settings
->monitor
= 0;
273 settings
->monitor
= obt_xml_node_int(c
);
277 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
280 if ((n
= obt_xml_find_node(app
->children
, "focus")))
281 if (!obt_xml_node_contains(n
, "default"))
282 settings
->focus
= obt_xml_node_bool(n
);
284 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
285 if (!obt_xml_node_contains(n
, "default")) {
286 gchar
*s
= obt_xml_node_string(n
);
287 if (!g_ascii_strcasecmp(s
, "all"))
288 settings
->desktop
= DESKTOP_ALL
;
290 gint i
= obt_xml_node_int(n
);
292 settings
->desktop
= i
;
298 if ((n
= obt_xml_find_node(app
->children
, "layer")))
299 if (!obt_xml_node_contains(n
, "default")) {
300 gchar
*s
= obt_xml_node_string(n
);
301 if (!g_ascii_strcasecmp(s
, "above"))
303 else if (!g_ascii_strcasecmp(s
, "below"))
304 settings
->layer
= -1;
310 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
311 if (!obt_xml_node_contains(n
, "default"))
312 settings
->iconic
= obt_xml_node_bool(n
);
314 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
315 if (!obt_xml_node_contains(n
, "default"))
316 settings
->skip_pager
= obt_xml_node_bool(n
);
318 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
319 if (!obt_xml_node_contains(n
, "default"))
320 settings
->skip_taskbar
= obt_xml_node_bool(n
);
322 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
323 if (!obt_xml_node_contains(n
, "default"))
324 settings
->fullscreen
= obt_xml_node_bool(n
);
326 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
327 if (!obt_xml_node_contains(n
, "default")) {
328 gchar
*s
= obt_xml_node_string(n
);
329 if (!g_ascii_strcasecmp(s
, "horizontal")) {
330 settings
->max_horz
= TRUE
;
331 settings
->max_vert
= FALSE
;
332 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
333 settings
->max_horz
= FALSE
;
334 settings
->max_vert
= TRUE
;
336 settings
->max_horz
= settings
->max_vert
=
337 obt_xml_node_bool(n
);
341 config_per_app_settings
= g_slist_append(config_per_app_settings
,
342 (gpointer
) settings
);
346 name
= class = role
= NULL
;
349 app
= obt_xml_find_node(app
->next
, "application");
356 <action name="ChangeDesktop">
363 static void parse_key(xmlNodePtr node
, GList
*keylist
)
367 gboolean is_chroot
= FALSE
;
369 if (!obt_xml_attr_string(node
, "key", &key
))
372 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
374 keylist
= g_list_append(keylist
, key
);
376 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
378 parse_key(n
, keylist
);
379 n
= obt_xml_find_node(n
->next
, "keybind");
382 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
384 ObActionsAct
*action
;
386 action
= actions_parse(n
);
388 keyboard_bind(keylist
, action
);
389 n
= obt_xml_find_node(n
->next
, "action");
394 keyboard_chroot(keylist
);
397 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
400 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
405 keyboard_unbind_all();
407 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
408 key
= obt_xml_node_string(n
);
409 translate_key(key
, &config_keyboard_reset_state
,
410 &config_keyboard_reset_keycode
);
414 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
417 n
= obt_xml_find_node(n
->next
, "keybind");
423 <context name="Titlebar">
424 <mousebind button="Left" action="Press">
425 <action name="Raise"></action>
431 static void parse_mouse(xmlNodePtr node
, gpointer d
)
433 xmlNodePtr n
, nbut
, nact
;
440 node
= node
->children
;
442 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
443 config_mouse_threshold
= obt_xml_node_int(n
);
444 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
445 config_mouse_dclicktime
= obt_xml_node_int(n
);
446 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
447 config_mouse_screenedgetime
= obt_xml_node_int(n
);
448 /* minimum value of 25 for this property, when it is 1 and you hit the
449 edge it basically never stops */
450 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
451 config_mouse_screenedgetime
= 25;
454 n
= obt_xml_find_node(node
, "context");
456 if (!obt_xml_attr_string(n
, "name", &contextstr
))
458 nbut
= obt_xml_find_node(n
->children
, "mousebind");
460 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
462 if (obt_xml_attr_contains(nbut
, "action", "press")) {
463 mact
= OB_MOUSE_ACTION_PRESS
;
464 } else if (obt_xml_attr_contains(nbut
, "action", "release")) {
465 mact
= OB_MOUSE_ACTION_RELEASE
;
466 } else if (obt_xml_attr_contains(nbut
, "action", "click")) {
467 mact
= OB_MOUSE_ACTION_CLICK
;
468 } else if (obt_xml_attr_contains(nbut
, "action","doubleclick")) {
469 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
470 } else if (obt_xml_attr_contains(nbut
, "action", "drag")) {
471 mact
= OB_MOUSE_ACTION_MOTION
;
474 nact
= obt_xml_find_node(nbut
->children
, "action");
476 ObActionsAct
*action
;
478 if ((action
= actions_parse(nact
)))
479 mouse_bind(buttonstr
, contextstr
, mact
, action
);
480 nact
= obt_xml_find_node(nact
->next
, "action");
484 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
488 n
= obt_xml_find_node(n
->next
, "context");
492 static void parse_focus(xmlNodePtr node
, gpointer d
)
496 node
= node
->children
;
498 if ((n
= obt_xml_find_node(node
, "focusNew")))
499 config_focus_new
= obt_xml_node_bool(n
);
500 if ((n
= obt_xml_find_node(node
, "followMouse")))
501 config_focus_follow
= obt_xml_node_bool(n
);
502 if ((n
= obt_xml_find_node(node
, "focusDelay")))
503 config_focus_delay
= obt_xml_node_int(n
);
504 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
505 config_focus_raise
= obt_xml_node_bool(n
);
506 if ((n
= obt_xml_find_node(node
, "focusLast")))
507 config_focus_last
= obt_xml_node_bool(n
);
508 if ((n
= obt_xml_find_node(node
, "underMouse")))
509 config_focus_under_mouse
= obt_xml_node_bool(n
);
510 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
511 config_unfocus_leave
= obt_xml_node_bool(n
);
514 static void parse_placement(xmlNodePtr node
, gpointer d
)
518 node
= node
->children
;
520 if ((n
= obt_xml_find_node(node
, "policy")))
521 if (obt_xml_node_contains(n
, "UnderMouse"))
522 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
523 if ((n
= obt_xml_find_node(node
, "center")))
524 config_place_center
= obt_xml_node_bool(n
);
525 if ((n
= obt_xml_find_node(node
, "monitor"))) {
526 if (obt_xml_node_contains(n
, "active"))
527 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
528 else if (obt_xml_node_contains(n
, "mouse"))
529 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
531 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
532 config_primary_monitor_index
= obt_xml_node_int(n
);
533 if (!config_primary_monitor_index
) {
534 if (obt_xml_node_contains(n
, "mouse"))
535 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
540 static void parse_margins(xmlNodePtr node
, gpointer d
)
544 node
= node
->children
;
546 if ((n
= obt_xml_find_node(node
, "top")))
547 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
548 if ((n
= obt_xml_find_node(node
, "left")))
549 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
550 if ((n
= obt_xml_find_node(node
, "right")))
551 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
552 if ((n
= obt_xml_find_node(node
, "bottom")))
553 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
556 static void parse_theme(xmlNodePtr node
, gpointer d
)
560 node
= node
->children
;
562 if ((n
= obt_xml_find_node(node
, "name"))) {
565 g_free(config_theme
);
566 c
= obt_xml_node_string(n
);
567 config_theme
= obt_paths_expand_tilde(c
);
570 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
573 g_free(config_title_layout
);
574 config_title_layout
= obt_xml_node_string(n
);
576 /* replace duplicates with spaces */
577 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
578 for (d
= c
+1; *d
!= '\0'; ++d
)
579 if (*c
== *d
) *d
= ' ';
581 if ((n
= obt_xml_find_node(node
, "keepBorder")))
582 config_theme_keepborder
= obt_xml_node_bool(n
);
583 if ((n
= obt_xml_find_node(node
, "animateIconify")))
584 config_animate_iconify
= obt_xml_node_bool(n
);
585 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
586 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
587 if (config_theme_window_list_icon_size
< 16)
588 config_theme_window_list_icon_size
= 16;
589 else if (config_theme_window_list_icon_size
> 96)
590 config_theme_window_list_icon_size
= 96;
593 n
= obt_xml_find_node(node
, "font");
597 gchar
*name
= g_strdup(RrDefaultFontFamily
);
598 gint size
= RrDefaultFontSize
;
599 RrFontWeight weight
= RrDefaultFontWeight
;
600 RrFontSlant slant
= RrDefaultFontSlant
;
602 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
603 font
= &config_font_activewindow
;
604 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
605 font
= &config_font_inactivewindow
;
606 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
607 font
= &config_font_menutitle
;
608 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
609 font
= &config_font_menuitem
;
610 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
611 font
= &config_font_activeosd
;
612 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
613 font
= &config_font_activeosd
;
614 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
615 font
= &config_font_inactiveosd
;
619 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
621 name
= obt_xml_node_string(fnode
);
623 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
624 int s
= obt_xml_node_int(fnode
);
627 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
628 gchar
*w
= obt_xml_node_string(fnode
);
629 if (!g_ascii_strcasecmp(w
, "Bold"))
630 weight
= RR_FONTWEIGHT_BOLD
;
633 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
634 gchar
*s
= obt_xml_node_string(fnode
);
635 if (!g_ascii_strcasecmp(s
, "Italic"))
636 slant
= RR_FONTSLANT_ITALIC
;
637 if (!g_ascii_strcasecmp(s
, "Oblique"))
638 slant
= RR_FONTSLANT_OBLIQUE
;
642 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
645 n
= obt_xml_find_node(n
->next
, "font");
649 static void parse_desktops(xmlNodePtr node
, gpointer d
)
653 node
= node
->children
;
655 if ((n
= obt_xml_find_node(node
, "number"))) {
656 gint d
= obt_xml_node_int(n
);
658 config_desktops_num
= (unsigned) d
;
660 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
661 gint d
= obt_xml_node_int(n
);
663 config_screen_firstdesk
= (unsigned) d
;
665 if ((n
= obt_xml_find_node(node
, "names"))) {
669 for (it
= config_desktops_names
; it
; it
= it
->next
)
671 g_slist_free(config_desktops_names
);
672 config_desktops_names
= NULL
;
674 nname
= obt_xml_find_node(n
->children
, "name");
676 config_desktops_names
=
677 g_slist_append(config_desktops_names
,
678 obt_xml_node_string(nname
));
679 nname
= obt_xml_find_node(nname
->next
, "name");
682 if ((n
= obt_xml_find_node(node
, "popupTime")))
683 config_desktop_popup_time
= obt_xml_node_int(n
);
686 static void parse_resize(xmlNodePtr node
, gpointer d
)
690 node
= node
->children
;
692 if ((n
= obt_xml_find_node(node
, "drawContents")))
693 config_resize_redraw
= obt_xml_node_bool(n
);
694 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
695 config_resize_popup_show
= obt_xml_node_int(n
);
696 if (obt_xml_node_contains(n
, "Always"))
697 config_resize_popup_show
= 2;
698 else if (obt_xml_node_contains(n
, "Never"))
699 config_resize_popup_show
= 0;
700 else if (obt_xml_node_contains(n
, "Nonpixel"))
701 config_resize_popup_show
= 1;
703 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
704 if (obt_xml_node_contains(n
, "Top"))
705 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
706 else if (obt_xml_node_contains(n
, "Center"))
707 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
708 else if (obt_xml_node_contains(n
, "Fixed")) {
709 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
711 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
714 if ((n2
= obt_xml_find_node(n
->children
, "x")))
715 config_parse_gravity_coord(n2
,
716 &config_resize_popup_fixed
.x
);
717 if ((n2
= obt_xml_find_node(n
->children
, "y")))
718 config_parse_gravity_coord(n2
,
719 &config_resize_popup_fixed
.y
);
721 config_resize_popup_fixed
.x
.pos
=
722 MAX(config_resize_popup_fixed
.x
.pos
, 0);
723 config_resize_popup_fixed
.y
.pos
=
724 MAX(config_resize_popup_fixed
.y
.pos
, 0);
730 static void parse_dock(xmlNodePtr node
, gpointer d
)
734 node
= node
->children
;
736 if ((n
= obt_xml_find_node(node
, "position"))) {
737 if (obt_xml_node_contains(n
, "TopLeft"))
738 config_dock_floating
= FALSE
,
739 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
740 else if (obt_xml_node_contains(n
, "Top"))
741 config_dock_floating
= FALSE
,
742 config_dock_pos
= OB_DIRECTION_NORTH
;
743 else if (obt_xml_node_contains(n
, "TopRight"))
744 config_dock_floating
= FALSE
,
745 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
746 else if (obt_xml_node_contains(n
, "Right"))
747 config_dock_floating
= FALSE
,
748 config_dock_pos
= OB_DIRECTION_EAST
;
749 else if (obt_xml_node_contains(n
, "BottomRight"))
750 config_dock_floating
= FALSE
,
751 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
752 else if (obt_xml_node_contains(n
, "Bottom"))
753 config_dock_floating
= FALSE
,
754 config_dock_pos
= OB_DIRECTION_SOUTH
;
755 else if (obt_xml_node_contains(n
, "BottomLeft"))
756 config_dock_floating
= FALSE
,
757 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
758 else if (obt_xml_node_contains(n
, "Left"))
759 config_dock_floating
= FALSE
,
760 config_dock_pos
= OB_DIRECTION_WEST
;
761 else if (obt_xml_node_contains(n
, "Floating"))
762 config_dock_floating
= TRUE
;
764 if (config_dock_floating
) {
765 if ((n
= obt_xml_find_node(node
, "floatingX")))
766 config_dock_x
= obt_xml_node_int(n
);
767 if ((n
= obt_xml_find_node(node
, "floatingY")))
768 config_dock_y
= obt_xml_node_int(n
);
770 if ((n
= obt_xml_find_node(node
, "noStrut")))
771 config_dock_nostrut
= obt_xml_node_bool(n
);
773 if ((n
= obt_xml_find_node(node
, "stacking"))) {
774 if (obt_xml_node_contains(n
, "normal"))
775 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
776 else if (obt_xml_node_contains(n
, "below"))
777 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
778 else if (obt_xml_node_contains(n
, "above"))
779 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
781 if ((n
= obt_xml_find_node(node
, "direction"))) {
782 if (obt_xml_node_contains(n
, "horizontal"))
783 config_dock_orient
= OB_ORIENTATION_HORZ
;
784 else if (obt_xml_node_contains(n
, "vertical"))
785 config_dock_orient
= OB_ORIENTATION_VERT
;
787 if ((n
= obt_xml_find_node(node
, "autoHide")))
788 config_dock_hide
= obt_xml_node_bool(n
);
789 if ((n
= obt_xml_find_node(node
, "hideDelay")))
790 config_dock_hide_delay
= obt_xml_node_int(n
);
791 if ((n
= obt_xml_find_node(node
, "showDelay")))
792 config_dock_show_delay
= obt_xml_node_int(n
);
793 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
794 gchar
*str
= obt_xml_node_string(n
);
796 if (translate_button(str
, &s
, &b
)) {
797 config_dock_app_move_button
= b
;
798 config_dock_app_move_modifiers
= s
;
800 g_message(_("Invalid button \"%s\" specified in config file"), str
);
806 static void parse_menu(xmlNodePtr node
, gpointer d
)
809 node
= node
->children
;
811 if ((n
= obt_xml_find_node(node
, "hideDelay")))
812 config_menu_hide_delay
= obt_xml_node_int(n
);
813 if ((n
= obt_xml_find_node(node
, "middle")))
814 config_menu_middle
= obt_xml_node_bool(n
);
815 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
816 config_submenu_show_delay
= obt_xml_node_int(n
);
817 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
818 config_submenu_hide_delay
= obt_xml_node_int(n
);
819 if ((n
= obt_xml_find_node(node
, "applicationIcons")))
820 config_menu_client_list_icons
= obt_xml_node_bool(n
);
821 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
822 config_menu_manage_desktops
= obt_xml_node_bool(n
);
824 while ((node
= obt_xml_find_node(node
, "file"))) {
825 gchar
*c
= obt_xml_node_string(node
);
826 config_menu_files
= g_slist_append(config_menu_files
,
827 obt_paths_expand_tilde(c
));
833 static void parse_resistance(xmlNodePtr node
, gpointer d
)
837 node
= node
->children
;
838 if ((n
= obt_xml_find_node(node
, "strength")))
839 config_resist_win
= obt_xml_node_int(n
);
840 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
841 config_resist_edge
= obt_xml_node_int(n
);
847 const gchar
*actname
;
850 static void bind_default_keyboard(void)
853 ObDefKeyBind binds
[] = {
854 { "A-Tab", "NextWindow" },
855 { "S-A-Tab", "PreviousWindow" },
859 for (it
= binds
; it
->key
; ++it
) {
860 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
861 keyboard_bind(l
, actions_parse_string(it
->actname
));
868 const gchar
*context
;
869 const ObMouseAction mact
;
870 const gchar
*actname
;
873 static void bind_default_mouse(void)
876 ObDefMouseBind binds
[] = {
877 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
878 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
879 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
880 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
881 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
882 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
883 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
884 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
885 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
886 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
887 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
888 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
889 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
890 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
891 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
892 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
893 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
894 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
895 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
896 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
897 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
898 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
899 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
900 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
901 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
902 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
903 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
904 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
905 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
906 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
907 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
908 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
909 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
910 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
911 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
912 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
913 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
914 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
915 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
916 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
917 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
918 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
919 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
920 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
921 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
922 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
923 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
924 { NULL
, NULL
, 0, NULL
}
927 for (it
= binds
; it
->button
; ++it
)
928 mouse_bind(it
->button
, it
->context
, it
->mact
,
929 actions_parse_string(it
->actname
));
932 void config_startup(ObtXmlInst
*i
)
934 config_focus_new
= TRUE
;
935 config_focus_follow
= FALSE
;
936 config_focus_delay
= 0;
937 config_focus_raise
= FALSE
;
938 config_focus_last
= TRUE
;
939 config_focus_under_mouse
= FALSE
;
940 config_unfocus_leave
= FALSE
;
942 obt_xml_register(i
, "focus", parse_focus
, NULL
);
944 config_place_policy
= OB_PLACE_POLICY_SMART
;
945 config_place_center
= TRUE
;
946 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
948 config_primary_monitor_index
= 1;
949 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
951 obt_xml_register(i
, "placement", parse_placement
, NULL
);
953 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
955 obt_xml_register(i
, "margins", parse_margins
, NULL
);
959 config_animate_iconify
= TRUE
;
960 config_title_layout
= g_strdup("NLIMC");
961 config_theme_keepborder
= TRUE
;
962 config_theme_window_list_icon_size
= 36;
964 config_font_activewindow
= NULL
;
965 config_font_inactivewindow
= NULL
;
966 config_font_menuitem
= NULL
;
967 config_font_menutitle
= NULL
;
969 obt_xml_register(i
, "theme", parse_theme
, NULL
);
971 config_desktops_num
= 4;
972 config_screen_firstdesk
= 1;
973 config_desktops_names
= NULL
;
974 config_desktop_popup_time
= 875;
976 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
978 config_resize_redraw
= TRUE
;
979 config_resize_popup_show
= 1; /* nonpixel increments */
980 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
981 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
982 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
984 obt_xml_register(i
, "resize", parse_resize
, NULL
);
986 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
987 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
988 config_dock_floating
= FALSE
;
989 config_dock_nostrut
= FALSE
;
992 config_dock_orient
= OB_ORIENTATION_VERT
;
993 config_dock_hide
= FALSE
;
994 config_dock_hide_delay
= 300;
995 config_dock_show_delay
= 300;
996 config_dock_app_move_button
= 2; /* middle */
997 config_dock_app_move_modifiers
= 0;
999 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1001 translate_key("C-g", &config_keyboard_reset_state
,
1002 &config_keyboard_reset_keycode
);
1004 bind_default_keyboard();
1006 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1008 config_mouse_threshold
= 8;
1009 config_mouse_dclicktime
= 200;
1010 config_mouse_screenedgetime
= 400;
1012 bind_default_mouse();
1014 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1016 config_resist_win
= 10;
1017 config_resist_edge
= 20;
1019 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1021 config_menu_hide_delay
= 250;
1022 config_menu_middle
= FALSE
;
1023 config_submenu_show_delay
= 200;
1024 config_submenu_hide_delay
= 400;
1025 config_menu_client_list_icons
= TRUE
;
1026 config_menu_manage_desktops
= TRUE
;
1027 config_menu_files
= NULL
;
1029 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1031 config_per_app_settings
= NULL
;
1033 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1036 void config_shutdown(void)
1040 g_free(config_theme
);
1042 g_free(config_title_layout
);
1044 RrFontClose(config_font_activewindow
);
1045 RrFontClose(config_font_inactivewindow
);
1046 RrFontClose(config_font_menuitem
);
1047 RrFontClose(config_font_menutitle
);
1048 RrFontClose(config_font_activeosd
);
1049 RrFontClose(config_font_inactiveosd
);
1051 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1053 g_slist_free(config_desktops_names
);
1055 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1057 g_slist_free(config_menu_files
);
1059 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1060 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1061 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1062 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1063 if (itd
->class) g_pattern_spec_free(itd
->class);
1066 g_slist_free(config_per_app_settings
);