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 gboolean config_menu_client_list_icons
;
97 gboolean config_menu_manage_desktops
;
99 GSList
*config_menu_files
;
101 gint config_resist_win
;
102 gint config_resist_edge
;
104 GSList
*config_per_app_settings
;
106 ObAppSettings
* config_create_app_settings(void)
108 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
110 settings
->decor
= -1;
111 settings
->shade
= -1;
112 settings
->monitor
= -1;
113 settings
->focus
= -1;
114 settings
->desktop
= 0;
115 settings
->layer
= -2;
116 settings
->iconic
= -1;
117 settings
->skip_pager
= -1;
118 settings
->skip_taskbar
= -1;
119 settings
->fullscreen
= -1;
120 settings
->max_horz
= -1;
121 settings
->max_vert
= -1;
125 #define copy_if(setting, default) \
126 if (src->setting != default) dst->setting = src->setting
127 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
130 g_assert(src
!= NULL
);
131 g_assert(dst
!= NULL
);
133 copy_if(type
, (ObClientType
)-1);
136 copy_if(monitor
, -1);
141 copy_if(skip_pager
, -1);
142 copy_if(skip_taskbar
, -1);
143 copy_if(fullscreen
, -1);
144 copy_if(max_horz
, -1);
145 copy_if(max_vert
, -1);
147 if (src
->pos_given
) {
148 dst
->pos_given
= TRUE
;
149 dst
->pos_force
= src
->pos_force
;
150 dst
->position
= src
->position
;
151 dst
->monitor
= src
->monitor
;
155 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
157 gchar
*s
= obt_parse_node_string(node
);
158 if (!g_ascii_strcasecmp(s
, "center"))
163 if (s
[0] == '-' || s
[0] == '+')
173 <application name="aterm">
176 <application name="Rhythmbox">
183 .. there is a lot more settings available
188 /* Manages settings for individual applications.
189 Some notes: monitor is the screen number in a multi monitor
190 (Xinerama) setup (starting from 0) or mouse, meaning the
191 monitor the pointer is on. Default: mouse.
192 Layer can be three values, above (Always on top), below
193 (Always on bottom) and everything else (normal behaviour).
194 Positions can be an integer value or center, which will
195 center the window in the specified axis. Position is within
196 the monitor, so <position><x>center</x></position><monitor>2</monitor>
197 will center the window on the second monitor.
199 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
201 xmlNodePtr app
= obt_parse_find_node(node
->children
, "application");
202 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
203 gboolean name_set
, class_set
, type_set
;
204 gboolean x_pos_given
;
209 class_set
= obt_parse_attr_string(app
, "class", &class);
210 name_set
= obt_parse_attr_string(app
, "name", &name
);
211 type_set
= obt_parse_attr_string(app
, "type", &type
);
212 if (class_set
|| name_set
) {
214 ObAppSettings
*settings
= config_create_app_settings();;
217 settings
->name
= g_pattern_spec_new(name
);
220 settings
->class = g_pattern_spec_new(class);
223 if (!g_ascii_strcasecmp(type
, "normal"))
224 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
225 else if (!g_ascii_strcasecmp(type
, "dialog"))
226 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
227 else if (!g_ascii_strcasecmp(type
, "splash"))
228 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
229 else if (!g_ascii_strcasecmp(type
, "utility"))
230 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
231 else if (!g_ascii_strcasecmp(type
, "menu"))
232 settings
->type
= OB_CLIENT_TYPE_MENU
;
233 else if (!g_ascii_strcasecmp(type
, "toolbar"))
234 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
235 else if (!g_ascii_strcasecmp(type
, "dock"))
236 settings
->type
= OB_CLIENT_TYPE_DOCK
;
237 else if (!g_ascii_strcasecmp(type
, "desktop"))
238 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
241 if (obt_parse_attr_string(app
, "role", &role
))
242 settings
->role
= g_pattern_spec_new(role
);
244 if ((n
= obt_parse_find_node(app
->children
, "decor")))
245 if (!obt_parse_node_contains(n
, "default"))
246 settings
->decor
= obt_parse_node_bool(n
);
248 if ((n
= obt_parse_find_node(app
->children
, "shade")))
249 if (!obt_parse_node_contains(n
, "default"))
250 settings
->shade
= obt_parse_node_bool(n
);
252 if ((n
= obt_parse_find_node(app
->children
, "position"))) {
253 if ((c
= obt_parse_find_node(n
->children
, "x")))
254 if (!obt_parse_node_contains(c
, "default")) {
255 config_parse_gravity_coord(c
, &settings
->position
.x
);
259 if (x_pos_given
&& (c
= obt_parse_find_node(n
->children
, "y")))
260 if (!obt_parse_node_contains(c
, "default")) {
261 config_parse_gravity_coord(c
, &settings
->position
.y
);
262 settings
->pos_given
= TRUE
;
265 if (settings
->pos_given
&&
266 (c
= obt_parse_find_node(n
->children
, "monitor")))
267 if (!obt_parse_node_contains(c
, "default")) {
268 gchar
*s
= obt_parse_node_string(c
);
269 if (!g_ascii_strcasecmp(s
, "mouse"))
270 settings
->monitor
= 0;
272 settings
->monitor
= obt_parse_node_int(c
);
276 obt_parse_attr_bool(n
, "force", &settings
->pos_force
);
279 if ((n
= obt_parse_find_node(app
->children
, "focus")))
280 if (!obt_parse_node_contains(n
, "default"))
281 settings
->focus
= obt_parse_node_bool(n
);
283 if ((n
= obt_parse_find_node(app
->children
, "desktop"))) {
284 if (!obt_parse_node_contains(n
, "default")) {
285 gchar
*s
= obt_parse_node_string(n
);
286 if (!g_ascii_strcasecmp(s
, "all"))
287 settings
->desktop
= DESKTOP_ALL
;
289 gint i
= obt_parse_node_int(n
);
291 settings
->desktop
= i
;
297 if ((n
= obt_parse_find_node(app
->children
, "layer")))
298 if (!obt_parse_node_contains(n
, "default")) {
299 gchar
*s
= obt_parse_node_string(n
);
300 if (!g_ascii_strcasecmp(s
, "above"))
302 else if (!g_ascii_strcasecmp(s
, "below"))
303 settings
->layer
= -1;
309 if ((n
= obt_parse_find_node(app
->children
, "iconic")))
310 if (!obt_parse_node_contains(n
, "default"))
311 settings
->iconic
= obt_parse_node_bool(n
);
313 if ((n
= obt_parse_find_node(app
->children
, "skip_pager")))
314 if (!obt_parse_node_contains(n
, "default"))
315 settings
->skip_pager
= obt_parse_node_bool(n
);
317 if ((n
= obt_parse_find_node(app
->children
, "skip_taskbar")))
318 if (!obt_parse_node_contains(n
, "default"))
319 settings
->skip_taskbar
= obt_parse_node_bool(n
);
321 if ((n
= obt_parse_find_node(app
->children
, "fullscreen")))
322 if (!obt_parse_node_contains(n
, "default"))
323 settings
->fullscreen
= obt_parse_node_bool(n
);
325 if ((n
= obt_parse_find_node(app
->children
, "maximized")))
326 if (!obt_parse_node_contains(n
, "default")) {
327 gchar
*s
= obt_parse_node_string(n
);
328 if (!g_ascii_strcasecmp(s
, "horizontal")) {
329 settings
->max_horz
= TRUE
;
330 settings
->max_vert
= FALSE
;
331 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
332 settings
->max_horz
= FALSE
;
333 settings
->max_vert
= TRUE
;
335 settings
->max_horz
= settings
->max_vert
=
336 obt_parse_node_bool(n
);
340 config_per_app_settings
= g_slist_append(config_per_app_settings
,
341 (gpointer
) settings
);
345 name
= class = role
= NULL
;
348 app
= obt_parse_find_node(app
->next
, "application");
355 <action name="ChangeDesktop">
362 static void parse_key(xmlNodePtr node
, GList
*keylist
)
366 gboolean is_chroot
= FALSE
;
368 if (!obt_parse_attr_string(node
, "key", &key
))
371 obt_parse_attr_bool(node
, "chroot", &is_chroot
);
373 keylist
= g_list_append(keylist
, key
);
375 if ((n
= obt_parse_find_node(node
->children
, "keybind"))) {
377 parse_key(n
, keylist
);
378 n
= obt_parse_find_node(n
->next
, "keybind");
381 else if ((n
= obt_parse_find_node(node
->children
, "action"))) {
383 ObActionsAct
*action
;
385 action
= actions_parse(n
);
387 keyboard_bind(keylist
, action
);
388 n
= obt_parse_find_node(n
->next
, "action");
393 keyboard_chroot(keylist
);
396 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
399 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
404 keyboard_unbind_all();
406 if ((n
= obt_parse_find_node(node
->children
, "chainQuitKey"))) {
407 key
= obt_parse_node_string(n
);
408 translate_key(key
, &config_keyboard_reset_state
,
409 &config_keyboard_reset_keycode
);
413 if ((n
= obt_parse_find_node(node
->children
, "keybind")))
416 n
= obt_parse_find_node(n
->next
, "keybind");
422 <context name="Titlebar">
423 <mousebind button="Left" action="Press">
424 <action name="Raise"></action>
430 static void parse_mouse(xmlNodePtr node
, gpointer d
)
432 xmlNodePtr n
, nbut
, nact
;
439 node
= node
->children
;
441 if ((n
= obt_parse_find_node(node
, "dragThreshold")))
442 config_mouse_threshold
= obt_parse_node_int(n
);
443 if ((n
= obt_parse_find_node(node
, "doubleClickTime")))
444 config_mouse_dclicktime
= obt_parse_node_int(n
);
445 if ((n
= obt_parse_find_node(node
, "screenEdgeWarpTime"))) {
446 config_mouse_screenedgetime
= obt_parse_node_int(n
);
447 /* minimum value of 25 for this property, when it is 1 and you hit the
448 edge it basically never stops */
449 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
450 config_mouse_screenedgetime
= 25;
453 n
= obt_parse_find_node(node
, "context");
455 if (!obt_parse_attr_string(n
, "name", &contextstr
))
457 nbut
= obt_parse_find_node(n
->children
, "mousebind");
459 if (!obt_parse_attr_string(nbut
, "button", &buttonstr
))
461 if (obt_parse_attr_contains(nbut
, "action", "press")) {
462 mact
= OB_MOUSE_ACTION_PRESS
;
463 } else if (obt_parse_attr_contains(nbut
, "action", "release")) {
464 mact
= OB_MOUSE_ACTION_RELEASE
;
465 } else if (obt_parse_attr_contains(nbut
, "action", "click")) {
466 mact
= OB_MOUSE_ACTION_CLICK
;
467 } else if (obt_parse_attr_contains(nbut
, "action","doubleclick")) {
468 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
469 } else if (obt_parse_attr_contains(nbut
, "action", "drag")) {
470 mact
= OB_MOUSE_ACTION_MOTION
;
473 nact
= obt_parse_find_node(nbut
->children
, "action");
475 ObActionsAct
*action
;
477 if ((action
= actions_parse(nact
)))
478 mouse_bind(buttonstr
, contextstr
, mact
, action
);
479 nact
= obt_parse_find_node(nact
->next
, "action");
483 nbut
= obt_parse_find_node(nbut
->next
, "mousebind");
487 n
= obt_parse_find_node(n
->next
, "context");
491 static void parse_focus(xmlNodePtr node
, gpointer d
)
495 node
= node
->children
;
497 if ((n
= obt_parse_find_node(node
, "focusNew")))
498 config_focus_new
= obt_parse_node_bool(n
);
499 if ((n
= obt_parse_find_node(node
, "followMouse")))
500 config_focus_follow
= obt_parse_node_bool(n
);
501 if ((n
= obt_parse_find_node(node
, "focusDelay")))
502 config_focus_delay
= obt_parse_node_int(n
);
503 if ((n
= obt_parse_find_node(node
, "raiseOnFocus")))
504 config_focus_raise
= obt_parse_node_bool(n
);
505 if ((n
= obt_parse_find_node(node
, "focusLast")))
506 config_focus_last
= obt_parse_node_bool(n
);
507 if ((n
= obt_parse_find_node(node
, "underMouse")))
508 config_focus_under_mouse
= obt_parse_node_bool(n
);
509 if ((n
= obt_parse_find_node(node
, "unfocusOnLeave")))
510 config_unfocus_leave
= obt_parse_node_bool(n
);
513 static void parse_placement(xmlNodePtr node
, gpointer d
)
517 node
= node
->children
;
519 if ((n
= obt_parse_find_node(node
, "policy")))
520 if (obt_parse_node_contains(n
, "UnderMouse"))
521 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
522 if ((n
= obt_parse_find_node(node
, "center")))
523 config_place_center
= obt_parse_node_bool(n
);
524 if ((n
= obt_parse_find_node(node
, "monitor"))) {
525 if (obt_parse_node_contains(n
, "active"))
526 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
527 else if (obt_parse_node_contains(n
, "mouse"))
528 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
530 if ((n
= obt_parse_find_node(node
, "primaryMonitor"))) {
531 config_primary_monitor_index
= obt_parse_node_int(n
);
532 if (!config_primary_monitor_index
) {
533 if (obt_parse_node_contains(n
, "mouse"))
534 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
539 static void parse_margins(xmlNodePtr node
, gpointer d
)
543 node
= node
->children
;
545 if ((n
= obt_parse_find_node(node
, "top")))
546 config_margins
.top
= MAX(0, obt_parse_node_int(n
));
547 if ((n
= obt_parse_find_node(node
, "left")))
548 config_margins
.left
= MAX(0, obt_parse_node_int(n
));
549 if ((n
= obt_parse_find_node(node
, "right")))
550 config_margins
.right
= MAX(0, obt_parse_node_int(n
));
551 if ((n
= obt_parse_find_node(node
, "bottom")))
552 config_margins
.bottom
= MAX(0, obt_parse_node_int(n
));
555 static void parse_theme(xmlNodePtr node
, gpointer d
)
559 node
= node
->children
;
561 if ((n
= obt_parse_find_node(node
, "name"))) {
564 g_free(config_theme
);
565 c
= obt_parse_node_string(n
);
566 config_theme
= obt_paths_expand_tilde(c
);
569 if ((n
= obt_parse_find_node(node
, "titleLayout"))) {
572 g_free(config_title_layout
);
573 config_title_layout
= obt_parse_node_string(n
);
575 /* replace duplicates with spaces */
576 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
577 for (d
= c
+1; *d
!= '\0'; ++d
)
578 if (*c
== *d
) *d
= ' ';
580 if ((n
= obt_parse_find_node(node
, "keepBorder")))
581 config_theme_keepborder
= obt_parse_node_bool(n
);
582 if ((n
= obt_parse_find_node(node
, "animateIconify")))
583 config_animate_iconify
= obt_parse_node_bool(n
);
584 if ((n
= obt_parse_find_node(node
, "windowListIconSize"))) {
585 config_theme_window_list_icon_size
= obt_parse_node_int(n
);
586 if (config_theme_window_list_icon_size
< 16)
587 config_theme_window_list_icon_size
= 16;
588 else if (config_theme_window_list_icon_size
> 96)
589 config_theme_window_list_icon_size
= 96;
592 n
= obt_parse_find_node(node
, "font");
596 gchar
*name
= g_strdup(RrDefaultFontFamily
);
597 gint size
= RrDefaultFontSize
;
598 RrFontWeight weight
= RrDefaultFontWeight
;
599 RrFontSlant slant
= RrDefaultFontSlant
;
601 if (obt_parse_attr_contains(n
, "place", "ActiveWindow"))
602 font
= &config_font_activewindow
;
603 else if (obt_parse_attr_contains(n
, "place", "InactiveWindow"))
604 font
= &config_font_inactivewindow
;
605 else if (obt_parse_attr_contains(n
, "place", "MenuHeader"))
606 font
= &config_font_menutitle
;
607 else if (obt_parse_attr_contains(n
, "place", "MenuItem"))
608 font
= &config_font_menuitem
;
609 else if (obt_parse_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
610 font
= &config_font_activeosd
;
611 else if (obt_parse_attr_contains(n
, "place", "OnScreenDisplay"))
612 font
= &config_font_activeosd
;
613 else if (obt_parse_attr_contains(n
, "place","InactiveOnScreenDisplay"))
614 font
= &config_font_inactiveosd
;
618 if ((fnode
= obt_parse_find_node(n
->children
, "name"))) {
620 name
= obt_parse_node_string(fnode
);
622 if ((fnode
= obt_parse_find_node(n
->children
, "size"))) {
623 int s
= obt_parse_node_int(fnode
);
626 if ((fnode
= obt_parse_find_node(n
->children
, "weight"))) {
627 gchar
*w
= obt_parse_node_string(fnode
);
628 if (!g_ascii_strcasecmp(w
, "Bold"))
629 weight
= RR_FONTWEIGHT_BOLD
;
632 if ((fnode
= obt_parse_find_node(n
->children
, "slant"))) {
633 gchar
*s
= obt_parse_node_string(fnode
);
634 if (!g_ascii_strcasecmp(s
, "Italic"))
635 slant
= RR_FONTSLANT_ITALIC
;
636 if (!g_ascii_strcasecmp(s
, "Oblique"))
637 slant
= RR_FONTSLANT_OBLIQUE
;
641 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
644 n
= obt_parse_find_node(n
->next
, "font");
648 static void parse_desktops(xmlNodePtr node
, gpointer d
)
652 node
= node
->children
;
654 if ((n
= obt_parse_find_node(node
, "number"))) {
655 gint d
= obt_parse_node_int(n
);
657 config_desktops_num
= (unsigned) d
;
659 if ((n
= obt_parse_find_node(node
, "firstdesk"))) {
660 gint d
= obt_parse_node_int(n
);
662 config_screen_firstdesk
= (unsigned) d
;
664 if ((n
= obt_parse_find_node(node
, "names"))) {
668 for (it
= config_desktops_names
; it
; it
= it
->next
)
670 g_slist_free(config_desktops_names
);
671 config_desktops_names
= NULL
;
673 nname
= obt_parse_find_node(n
->children
, "name");
675 config_desktops_names
=
676 g_slist_append(config_desktops_names
,
677 obt_parse_node_string(nname
));
678 nname
= obt_parse_find_node(nname
->next
, "name");
681 if ((n
= obt_parse_find_node(node
, "popupTime")))
682 config_desktop_popup_time
= obt_parse_node_int(n
);
685 static void parse_resize(xmlNodePtr node
, gpointer d
)
689 node
= node
->children
;
691 if ((n
= obt_parse_find_node(node
, "drawContents")))
692 config_resize_redraw
= obt_parse_node_bool(n
);
693 if ((n
= obt_parse_find_node(node
, "popupShow"))) {
694 config_resize_popup_show
= obt_parse_node_int(n
);
695 if (obt_parse_node_contains(n
, "Always"))
696 config_resize_popup_show
= 2;
697 else if (obt_parse_node_contains(n
, "Never"))
698 config_resize_popup_show
= 0;
699 else if (obt_parse_node_contains(n
, "Nonpixel"))
700 config_resize_popup_show
= 1;
702 if ((n
= obt_parse_find_node(node
, "popupPosition"))) {
703 if (obt_parse_node_contains(n
, "Top"))
704 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
705 else if (obt_parse_node_contains(n
, "Center"))
706 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
707 else if (obt_parse_node_contains(n
, "Fixed")) {
708 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
710 if ((n
= obt_parse_find_node(node
, "popupFixedPosition"))) {
713 if ((n2
= obt_parse_find_node(n
->children
, "x")))
714 config_parse_gravity_coord(n2
,
715 &config_resize_popup_fixed
.x
);
716 if ((n2
= obt_parse_find_node(n
->children
, "y")))
717 config_parse_gravity_coord(n2
,
718 &config_resize_popup_fixed
.y
);
720 config_resize_popup_fixed
.x
.pos
=
721 MAX(config_resize_popup_fixed
.x
.pos
, 0);
722 config_resize_popup_fixed
.y
.pos
=
723 MAX(config_resize_popup_fixed
.y
.pos
, 0);
729 static void parse_dock(xmlNodePtr node
, gpointer d
)
733 node
= node
->children
;
735 if ((n
= obt_parse_find_node(node
, "position"))) {
736 if (obt_parse_node_contains(n
, "TopLeft"))
737 config_dock_floating
= FALSE
,
738 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
739 else if (obt_parse_node_contains(n
, "Top"))
740 config_dock_floating
= FALSE
,
741 config_dock_pos
= OB_DIRECTION_NORTH
;
742 else if (obt_parse_node_contains(n
, "TopRight"))
743 config_dock_floating
= FALSE
,
744 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
745 else if (obt_parse_node_contains(n
, "Right"))
746 config_dock_floating
= FALSE
,
747 config_dock_pos
= OB_DIRECTION_EAST
;
748 else if (obt_parse_node_contains(n
, "BottomRight"))
749 config_dock_floating
= FALSE
,
750 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
751 else if (obt_parse_node_contains(n
, "Bottom"))
752 config_dock_floating
= FALSE
,
753 config_dock_pos
= OB_DIRECTION_SOUTH
;
754 else if (obt_parse_node_contains(n
, "BottomLeft"))
755 config_dock_floating
= FALSE
,
756 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
757 else if (obt_parse_node_contains(n
, "Left"))
758 config_dock_floating
= FALSE
,
759 config_dock_pos
= OB_DIRECTION_WEST
;
760 else if (obt_parse_node_contains(n
, "Floating"))
761 config_dock_floating
= TRUE
;
763 if (config_dock_floating
) {
764 if ((n
= obt_parse_find_node(node
, "floatingX")))
765 config_dock_x
= obt_parse_node_int(n
);
766 if ((n
= obt_parse_find_node(node
, "floatingY")))
767 config_dock_y
= obt_parse_node_int(n
);
769 if ((n
= obt_parse_find_node(node
, "noStrut")))
770 config_dock_nostrut
= obt_parse_node_bool(n
);
772 if ((n
= obt_parse_find_node(node
, "stacking"))) {
773 if (obt_parse_node_contains(n
, "normal"))
774 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
775 else if (obt_parse_node_contains(n
, "below"))
776 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
777 else if (obt_parse_node_contains(n
, "above"))
778 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
780 if ((n
= obt_parse_find_node(node
, "direction"))) {
781 if (obt_parse_node_contains(n
, "horizontal"))
782 config_dock_orient
= OB_ORIENTATION_HORZ
;
783 else if (obt_parse_node_contains(n
, "vertical"))
784 config_dock_orient
= OB_ORIENTATION_VERT
;
786 if ((n
= obt_parse_find_node(node
, "autoHide")))
787 config_dock_hide
= obt_parse_node_bool(n
);
788 if ((n
= obt_parse_find_node(node
, "hideDelay")))
789 config_dock_hide_delay
= obt_parse_node_int(n
);
790 if ((n
= obt_parse_find_node(node
, "showDelay")))
791 config_dock_show_delay
= obt_parse_node_int(n
);
792 if ((n
= obt_parse_find_node(node
, "moveButton"))) {
793 gchar
*str
= obt_parse_node_string(n
);
795 if (translate_button(str
, &s
, &b
)) {
796 config_dock_app_move_button
= b
;
797 config_dock_app_move_modifiers
= s
;
799 g_message(_("Invalid button \"%s\" specified in config file"), str
);
805 static void parse_menu(xmlNodePtr node
, gpointer d
)
808 node
= node
->children
;
810 if ((n
= obt_parse_find_node(node
, "hideDelay")))
811 config_menu_hide_delay
= obt_parse_node_int(n
);
812 if ((n
= obt_parse_find_node(node
, "middle")))
813 config_menu_middle
= obt_parse_node_bool(n
);
814 if ((n
= obt_parse_find_node(node
, "submenuShowDelay")))
815 config_submenu_show_delay
= obt_parse_node_int(n
);
816 if ((n
= obt_parse_find_node(node
, "applicationIcons")))
817 config_menu_client_list_icons
= obt_parse_node_bool(n
);
818 if ((n
= obt_parse_find_node(node
, "manageDesktops")))
819 config_menu_manage_desktops
= obt_parse_node_bool(n
);
821 while ((node
= obt_parse_find_node(node
, "file"))) {
822 gchar
*c
= obt_parse_node_string(node
);
823 config_menu_files
= g_slist_append(config_menu_files
,
824 obt_paths_expand_tilde(c
));
830 static void parse_resistance(xmlNodePtr node
, gpointer d
)
834 node
= node
->children
;
835 if ((n
= obt_parse_find_node(node
, "strength")))
836 config_resist_win
= obt_parse_node_int(n
);
837 if ((n
= obt_parse_find_node(node
, "screen_edge_strength")))
838 config_resist_edge
= obt_parse_node_int(n
);
844 const gchar
*actname
;
847 static void bind_default_keyboard(void)
850 ObDefKeyBind binds
[] = {
851 { "A-Tab", "NextWindow" },
852 { "S-A-Tab", "PreviousWindow" },
856 for (it
= binds
; it
->key
; ++it
) {
857 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
858 keyboard_bind(l
, actions_parse_string(it
->actname
));
865 const gchar
*context
;
866 const ObMouseAction mact
;
867 const gchar
*actname
;
870 static void bind_default_mouse(void)
873 ObDefMouseBind binds
[] = {
874 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
875 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
876 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
877 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
878 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
879 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
880 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
881 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
882 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
883 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
884 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
885 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
886 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
887 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
888 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
889 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
890 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
891 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
892 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
893 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
894 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
895 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
896 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
897 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
898 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
899 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
900 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
901 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
902 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
903 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
904 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
905 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
906 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
907 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
908 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
909 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
910 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
911 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
912 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
913 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
914 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
915 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
916 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
917 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
918 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
919 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
920 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
921 { NULL
, NULL
, 0, NULL
}
924 for (it
= binds
; it
->button
; ++it
)
925 mouse_bind(it
->button
, it
->context
, it
->mact
,
926 actions_parse_string(it
->actname
));
929 void config_startup(ObtParseInst
*i
)
931 config_focus_new
= TRUE
;
932 config_focus_follow
= FALSE
;
933 config_focus_delay
= 0;
934 config_focus_raise
= FALSE
;
935 config_focus_last
= TRUE
;
936 config_focus_under_mouse
= FALSE
;
937 config_unfocus_leave
= FALSE
;
939 obt_parse_register(i
, "focus", parse_focus
, NULL
);
941 config_place_policy
= OB_PLACE_POLICY_SMART
;
942 config_place_center
= TRUE
;
943 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
945 config_primary_monitor_index
= 1;
946 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
948 obt_parse_register(i
, "placement", parse_placement
, NULL
);
950 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
952 obt_parse_register(i
, "margins", parse_margins
, NULL
);
956 config_animate_iconify
= TRUE
;
957 config_title_layout
= g_strdup("NLIMC");
958 config_theme_keepborder
= TRUE
;
959 config_theme_window_list_icon_size
= 36;
961 config_font_activewindow
= NULL
;
962 config_font_inactivewindow
= NULL
;
963 config_font_menuitem
= NULL
;
964 config_font_menutitle
= NULL
;
966 obt_parse_register(i
, "theme", parse_theme
, NULL
);
968 config_desktops_num
= 4;
969 config_screen_firstdesk
= 1;
970 config_desktops_names
= NULL
;
971 config_desktop_popup_time
= 875;
973 obt_parse_register(i
, "desktops", parse_desktops
, NULL
);
975 config_resize_redraw
= TRUE
;
976 config_resize_popup_show
= 1; /* nonpixel increments */
977 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
978 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
979 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
981 obt_parse_register(i
, "resize", parse_resize
, NULL
);
983 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
984 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
985 config_dock_floating
= FALSE
;
986 config_dock_nostrut
= FALSE
;
989 config_dock_orient
= OB_ORIENTATION_VERT
;
990 config_dock_hide
= FALSE
;
991 config_dock_hide_delay
= 300;
992 config_dock_show_delay
= 300;
993 config_dock_app_move_button
= 2; /* middle */
994 config_dock_app_move_modifiers
= 0;
996 obt_parse_register(i
, "dock", parse_dock
, NULL
);
998 translate_key("C-g", &config_keyboard_reset_state
,
999 &config_keyboard_reset_keycode
);
1001 bind_default_keyboard();
1003 obt_parse_register(i
, "keyboard", parse_keyboard
, NULL
);
1005 config_mouse_threshold
= 8;
1006 config_mouse_dclicktime
= 200;
1007 config_mouse_screenedgetime
= 400;
1009 bind_default_mouse();
1011 obt_parse_register(i
, "mouse", parse_mouse
, NULL
);
1013 config_resist_win
= 10;
1014 config_resist_edge
= 20;
1016 obt_parse_register(i
, "resistance", parse_resistance
, NULL
);
1018 config_menu_hide_delay
= 250;
1019 config_menu_middle
= FALSE
;
1020 config_submenu_show_delay
= 0;
1021 config_menu_client_list_icons
= TRUE
;
1022 config_menu_manage_desktops
= TRUE
;
1023 config_menu_files
= NULL
;
1025 obt_parse_register(i
, "menu", parse_menu
, NULL
);
1027 config_per_app_settings
= NULL
;
1029 obt_parse_register(i
, "applications", parse_per_app_settings
, NULL
);
1032 void config_shutdown(void)
1036 g_free(config_theme
);
1038 g_free(config_title_layout
);
1040 RrFontClose(config_font_activewindow
);
1041 RrFontClose(config_font_inactivewindow
);
1042 RrFontClose(config_font_menuitem
);
1043 RrFontClose(config_font_menutitle
);
1044 RrFontClose(config_font_activeosd
);
1045 RrFontClose(config_font_inactiveosd
);
1047 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1049 g_slist_free(config_desktops_names
);
1051 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1053 g_slist_free(config_menu_files
);
1055 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1056 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1057 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1058 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1059 if (itd
->class) g_pattern_spec_free(itd
->class);
1062 g_slist_free(config_per_app_settings
);