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 ObPlaceMonitor config_place_monitor
;
42 guint config_primary_monitor_index
;
43 ObPlaceMonitor config_primary_monitor
;
45 StrutPartial config_margins
;
48 gboolean config_theme_keepborder
;
49 guint config_theme_window_list_icon_size
;
51 gchar
*config_title_layout
;
53 gboolean config_animate_iconify
;
55 RrFont
*config_font_activewindow
;
56 RrFont
*config_font_inactivewindow
;
57 RrFont
*config_font_menuitem
;
58 RrFont
*config_font_menutitle
;
59 RrFont
*config_font_activeosd
;
60 RrFont
*config_font_inactiveosd
;
62 guint config_desktops_num
;
63 GSList
*config_desktops_names
;
64 guint config_screen_firstdesk
;
65 guint config_desktop_popup_time
;
67 gboolean config_resize_redraw
;
68 gint config_resize_popup_show
;
69 ObResizePopupPos config_resize_popup_pos
;
70 GravityPoint config_resize_popup_fixed
;
72 ObStackingLayer config_dock_layer
;
73 gboolean config_dock_floating
;
74 gboolean config_dock_nostrut
;
75 ObDirection config_dock_pos
;
78 ObOrientation config_dock_orient
;
79 gboolean config_dock_hide
;
80 guint config_dock_hide_delay
;
81 guint config_dock_show_delay
;
82 guint config_dock_app_move_button
;
83 guint config_dock_app_move_modifiers
;
85 guint config_keyboard_reset_keycode
;
86 guint config_keyboard_reset_state
;
88 gint config_mouse_threshold
;
89 gint config_mouse_dclicktime
;
90 gint config_mouse_screenedgetime
;
91 gboolean config_mouse_screenedgewarp
;
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_manage_desktops
;
98 gboolean config_menu_show_icons
;
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_slice_new0(ObAppSettings
);
111 settings
->decor
= -1;
112 settings
->shade
= -1;
113 settings
->monitor_type
= OB_PLACE_MONITOR_ANY
;
114 settings
->monitor
= -1;
115 settings
->focus
= -1;
116 settings
->desktop
= 0;
117 settings
->layer
= -2;
118 settings
->iconic
= -1;
119 settings
->skip_pager
= -1;
120 settings
->skip_taskbar
= -1;
121 settings
->fullscreen
= -1;
122 settings
->max_horz
= -1;
123 settings
->max_vert
= -1;
127 #define copy_if(setting, default) \
128 if (src->setting != default) dst->setting = src->setting
129 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
132 g_assert(src
!= NULL
);
133 g_assert(dst
!= NULL
);
135 copy_if(type
, (ObClientType
)-1);
138 copy_if(monitor_type
, OB_PLACE_MONITOR_ANY
);
139 copy_if(monitor
, -1);
144 copy_if(skip_pager
, -1);
145 copy_if(skip_taskbar
, -1);
146 copy_if(fullscreen
, -1);
147 copy_if(max_horz
, -1);
148 copy_if(max_vert
, -1);
150 if (src
->pos_given
) {
151 dst
->pos_given
= TRUE
;
152 dst
->pos_force
= src
->pos_force
;
153 dst
->position
= src
->position
;
154 /* monitor is copied above */
158 void config_parse_relative_number(gchar
*s
, gint
*num
, gint
*denom
)
160 *num
= strtol(s
, &s
, 10);
164 } else if (*s
== '/') {
169 void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
171 gchar
*s
= obt_xml_node_string(node
);
172 if (!g_ascii_strcasecmp(s
, "center"))
178 if (s
[0] == '-' || s
[0] == '+')
180 config_parse_relative_number(ps
, &c
->pos
, &c
->denom
);
187 <application name="aterm">
190 <application name="Rhythmbox">
197 .. there is a lot more settings available
202 /* Manages settings for individual applications.
203 Some notes: monitor is the screen number in a multi monitor
204 (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
205 is on, active: the active monitor, primary: the primary monitor.
206 Layer can be three values, above (Always on top), below
207 (Always on bottom) and everything else (normal behaviour).
208 Positions can be an integer value or center, which will
209 center the window in the specified axis. Position is within
210 the monitor, so <position><x>center</x></position><monitor>2</monitor>
211 will center the window on the second monitor.
213 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
215 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
216 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *title
= NULL
,
217 *type_str
= NULL
, *group_name
= NULL
, *group_class
= NULL
;
218 gboolean name_set
, class_set
, type_set
, role_set
, title_set
,
219 group_name_set
, group_class_set
;
221 gboolean x_pos_given
;
226 class_set
= obt_xml_attr_string(app
, "class", &class);
227 name_set
= obt_xml_attr_string(app
, "name", &name
);
228 group_class_set
= obt_xml_attr_string(app
, "groupclass", &group_class
);
229 group_name_set
= obt_xml_attr_string(app
, "groupname", &group_name
);
230 type_set
= obt_xml_attr_string(app
, "type", &type_str
);
231 role_set
= obt_xml_attr_string(app
, "role", &role
);
232 title_set
= obt_xml_attr_string(app
, "title", &title
);
234 /* validate the type tho */
236 if (!g_ascii_strcasecmp(type_str
, "normal"))
237 type
= OB_CLIENT_TYPE_NORMAL
;
238 else if (!g_ascii_strcasecmp(type_str
, "dialog"))
239 type
= OB_CLIENT_TYPE_DIALOG
;
240 else if (!g_ascii_strcasecmp(type_str
, "splash"))
241 type
= OB_CLIENT_TYPE_SPLASH
;
242 else if (!g_ascii_strcasecmp(type_str
, "utility"))
243 type
= OB_CLIENT_TYPE_UTILITY
;
244 else if (!g_ascii_strcasecmp(type_str
, "menu"))
245 type
= OB_CLIENT_TYPE_MENU
;
246 else if (!g_ascii_strcasecmp(type_str
, "toolbar"))
247 type
= OB_CLIENT_TYPE_TOOLBAR
;
248 else if (!g_ascii_strcasecmp(type_str
, "dock"))
249 type
= OB_CLIENT_TYPE_DOCK
;
250 else if (!g_ascii_strcasecmp(type_str
, "desktop"))
251 type
= OB_CLIENT_TYPE_DESKTOP
;
253 type_set
= FALSE
; /* not valid! */
256 if (class_set
|| name_set
|| role_set
|| title_set
|| type_set
||
257 group_class_set
|| group_name_set
)
260 ObAppSettings
*settings
= config_create_app_settings();
263 settings
->name
= g_pattern_spec_new(name
);
266 settings
->class = g_pattern_spec_new(class);
269 settings
->group_name
= g_pattern_spec_new(group_name
);
272 settings
->group_class
= g_pattern_spec_new(group_class
);
275 settings
->role
= g_pattern_spec_new(role
);
278 settings
->title
= g_pattern_spec_new(title
);
281 settings
->type
= type
;
283 if ((n
= obt_xml_find_node(app
->children
, "decor")))
284 if (!obt_xml_node_contains(n
, "default"))
285 settings
->decor
= obt_xml_node_bool(n
);
287 if ((n
= obt_xml_find_node(app
->children
, "shade")))
288 if (!obt_xml_node_contains(n
, "default"))
289 settings
->shade
= obt_xml_node_bool(n
);
291 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
292 if ((c
= obt_xml_find_node(n
->children
, "x")))
293 if (!obt_xml_node_contains(c
, "default")) {
294 config_parse_gravity_coord(c
, &settings
->position
.x
);
298 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
299 if (!obt_xml_node_contains(c
, "default")) {
300 config_parse_gravity_coord(c
, &settings
->position
.y
);
301 settings
->pos_given
= TRUE
;
304 /* monitor can be set without setting x or y */
305 if ((c
= obt_xml_find_node(n
->children
, "monitor")))
306 if (!obt_xml_node_contains(c
, "default")) {
307 gchar
*s
= obt_xml_node_string(c
);
308 if (!g_ascii_strcasecmp(s
, "mouse"))
309 settings
->monitor_type
=
310 OB_PLACE_MONITOR_MOUSE
;
311 else if (!g_ascii_strcasecmp(s
, "active"))
312 settings
->monitor_type
=
313 OB_PLACE_MONITOR_ACTIVE
;
314 else if (!g_ascii_strcasecmp(s
, "primary"))
315 settings
->monitor_type
=
316 OB_PLACE_MONITOR_PRIMARY
;
318 settings
->monitor
= obt_xml_node_int(c
);
322 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
325 if ((n
= obt_xml_find_node(app
->children
, "focus")))
326 if (!obt_xml_node_contains(n
, "default"))
327 settings
->focus
= obt_xml_node_bool(n
);
329 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
330 if (!obt_xml_node_contains(n
, "default")) {
331 gchar
*s
= obt_xml_node_string(n
);
332 if (!g_ascii_strcasecmp(s
, "all"))
333 settings
->desktop
= DESKTOP_ALL
;
335 gint i
= obt_xml_node_int(n
);
337 settings
->desktop
= i
;
343 if ((n
= obt_xml_find_node(app
->children
, "layer")))
344 if (!obt_xml_node_contains(n
, "default")) {
345 gchar
*s
= obt_xml_node_string(n
);
346 if (!g_ascii_strcasecmp(s
, "above"))
348 else if (!g_ascii_strcasecmp(s
, "below"))
349 settings
->layer
= -1;
355 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
356 if (!obt_xml_node_contains(n
, "default"))
357 settings
->iconic
= obt_xml_node_bool(n
);
359 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
360 if (!obt_xml_node_contains(n
, "default"))
361 settings
->skip_pager
= obt_xml_node_bool(n
);
363 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
364 if (!obt_xml_node_contains(n
, "default"))
365 settings
->skip_taskbar
= obt_xml_node_bool(n
);
367 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
368 if (!obt_xml_node_contains(n
, "default"))
369 settings
->fullscreen
= obt_xml_node_bool(n
);
371 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
372 if (!obt_xml_node_contains(n
, "default")) {
373 gchar
*s
= obt_xml_node_string(n
);
374 if (!g_ascii_strcasecmp(s
, "horizontal")) {
375 settings
->max_horz
= TRUE
;
376 settings
->max_vert
= FALSE
;
377 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
378 settings
->max_horz
= FALSE
;
379 settings
->max_vert
= TRUE
;
381 settings
->max_horz
= settings
->max_vert
=
382 obt_xml_node_bool(n
);
386 config_per_app_settings
= g_slist_append(config_per_app_settings
,
387 (gpointer
) settings
);
395 name
= class = group_name
= group_class
= role
= title
= type_str
=
399 app
= obt_xml_find_node(app
->next
, "application");
406 <action name="ChangeDesktop">
413 static void parse_key(xmlNodePtr node
, GList
*keylist
)
415 gchar
*keystring
, **keys
, **key
;
417 gboolean is_chroot
= FALSE
;
419 if (!obt_xml_attr_string(node
, "key", &keystring
))
422 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
424 keys
= g_strsplit(keystring
, " ", 0);
425 for (key
= keys
; *key
; ++key
) {
426 keylist
= g_list_append(keylist
, *key
);
428 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
430 parse_key(n
, keylist
);
431 n
= obt_xml_find_node(n
->next
, "keybind");
434 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
436 ObActionsAct
*action
;
438 action
= actions_parse(n
);
440 keyboard_bind(keylist
, action
);
441 n
= obt_xml_find_node(n
->next
, "action");
447 keyboard_chroot(keylist
);
448 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
455 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
460 keyboard_unbind_all();
462 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
463 key
= obt_xml_node_string(n
);
464 translate_key(key
, &config_keyboard_reset_state
,
465 &config_keyboard_reset_keycode
);
469 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
472 n
= obt_xml_find_node(n
->next
, "keybind");
478 <context name="Titlebar">
479 <mousebind button="Left" action="Press">
480 <action name="Raise"></action>
486 static void parse_mouse(xmlNodePtr node
, gpointer d
)
488 xmlNodePtr n
, nbut
, nact
;
495 node
= node
->children
;
497 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
498 config_mouse_threshold
= obt_xml_node_int(n
);
499 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
500 config_mouse_dclicktime
= obt_xml_node_int(n
);
501 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
502 config_mouse_screenedgetime
= obt_xml_node_int(n
);
503 /* minimum value of 25 for this property, when it is 1 and you hit the
504 edge it basically never stops */
505 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
506 config_mouse_screenedgetime
= 25;
508 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpMouse")))
509 config_mouse_screenedgewarp
= obt_xml_node_bool(n
);
511 n
= obt_xml_find_node(node
, "context");
516 if (!obt_xml_attr_string(n
, "name", &cxstr
))
519 modcxstr
= g_strdup(cxstr
); /* make a copy to mutilate */
520 while (frame_next_context_from_string(modcxstr
, &cx
)) {
522 gchar
*s
= strchr(modcxstr
, ' ');
525 g_message(_("Invalid context \"%s\" in mouse binding"),
532 nbut
= obt_xml_find_node(n
->children
, "mousebind");
534 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
536 if (obt_xml_attr_contains(nbut
, "action", "press"))
537 mact
= OB_MOUSE_ACTION_PRESS
;
538 else if (obt_xml_attr_contains(nbut
, "action", "release"))
539 mact
= OB_MOUSE_ACTION_RELEASE
;
540 else if (obt_xml_attr_contains(nbut
, "action", "click"))
541 mact
= OB_MOUSE_ACTION_CLICK
;
542 else if (obt_xml_attr_contains(nbut
, "action","doubleclick"))
543 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
544 else if (obt_xml_attr_contains(nbut
, "action", "drag"))
545 mact
= OB_MOUSE_ACTION_MOTION
;
549 nact
= obt_xml_find_node(nbut
->children
, "action");
551 ObActionsAct
*action
;
553 if ((action
= actions_parse(nact
)))
554 mouse_bind(buttonstr
, cx
, mact
, action
);
555 nact
= obt_xml_find_node(nact
->next
, "action");
559 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
565 n
= obt_xml_find_node(n
->next
, "context");
569 static void parse_focus(xmlNodePtr node
, gpointer d
)
573 node
= node
->children
;
575 if ((n
= obt_xml_find_node(node
, "focusNew")))
576 config_focus_new
= obt_xml_node_bool(n
);
577 if ((n
= obt_xml_find_node(node
, "followMouse")))
578 config_focus_follow
= obt_xml_node_bool(n
);
579 if ((n
= obt_xml_find_node(node
, "focusDelay")))
580 config_focus_delay
= obt_xml_node_int(n
);
581 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
582 config_focus_raise
= obt_xml_node_bool(n
);
583 if ((n
= obt_xml_find_node(node
, "focusLast")))
584 config_focus_last
= obt_xml_node_bool(n
);
585 if ((n
= obt_xml_find_node(node
, "underMouse")))
586 config_focus_under_mouse
= obt_xml_node_bool(n
);
587 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
588 config_unfocus_leave
= obt_xml_node_bool(n
);
591 static void parse_placement(xmlNodePtr node
, gpointer d
)
595 node
= node
->children
;
597 if ((n
= obt_xml_find_node(node
, "policy")))
598 if (obt_xml_node_contains(n
, "UnderMouse"))
599 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
600 if ((n
= obt_xml_find_node(node
, "monitor"))) {
601 if (obt_xml_node_contains(n
, "active"))
602 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
603 else if (obt_xml_node_contains(n
, "mouse"))
604 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
605 else if (obt_xml_node_contains(n
, "any"))
606 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
608 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
609 config_primary_monitor_index
= obt_xml_node_int(n
);
610 if (!config_primary_monitor_index
) {
611 if (obt_xml_node_contains(n
, "mouse"))
612 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
617 static void parse_margins(xmlNodePtr node
, gpointer d
)
621 node
= node
->children
;
623 if ((n
= obt_xml_find_node(node
, "top")))
624 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
625 if ((n
= obt_xml_find_node(node
, "left")))
626 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
627 if ((n
= obt_xml_find_node(node
, "right")))
628 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
629 if ((n
= obt_xml_find_node(node
, "bottom")))
630 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
633 static void parse_theme(xmlNodePtr node
, gpointer d
)
637 node
= node
->children
;
639 if ((n
= obt_xml_find_node(node
, "name"))) {
642 g_free(config_theme
);
643 c
= obt_xml_node_string(n
);
644 config_theme
= obt_paths_expand_tilde(c
);
647 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
650 g_free(config_title_layout
);
651 config_title_layout
= obt_xml_node_string(n
);
653 /* replace duplicates with spaces */
654 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
655 for (d
= c
+1; *d
!= '\0'; ++d
)
656 if (*c
== *d
) *d
= ' ';
658 if ((n
= obt_xml_find_node(node
, "keepBorder")))
659 config_theme_keepborder
= obt_xml_node_bool(n
);
660 if ((n
= obt_xml_find_node(node
, "animateIconify")))
661 config_animate_iconify
= obt_xml_node_bool(n
);
662 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
663 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
664 if (config_theme_window_list_icon_size
< 16)
665 config_theme_window_list_icon_size
= 16;
666 else if (config_theme_window_list_icon_size
> 96)
667 config_theme_window_list_icon_size
= 96;
670 n
= obt_xml_find_node(node
, "font");
674 gchar
*name
= g_strdup(RrDefaultFontFamily
);
675 gint size
= RrDefaultFontSize
;
676 RrFontWeight weight
= RrDefaultFontWeight
;
677 RrFontSlant slant
= RrDefaultFontSlant
;
679 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
680 font
= &config_font_activewindow
;
681 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
682 font
= &config_font_inactivewindow
;
683 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
684 font
= &config_font_menutitle
;
685 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
686 font
= &config_font_menuitem
;
687 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
688 font
= &config_font_activeosd
;
689 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
690 font
= &config_font_activeosd
;
691 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
692 font
= &config_font_inactiveosd
;
696 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
698 name
= obt_xml_node_string(fnode
);
700 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
701 int s
= obt_xml_node_int(fnode
);
704 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
705 gchar
*w
= obt_xml_node_string(fnode
);
706 if (!g_ascii_strcasecmp(w
, "Bold"))
707 weight
= RR_FONTWEIGHT_BOLD
;
710 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
711 gchar
*s
= obt_xml_node_string(fnode
);
712 if (!g_ascii_strcasecmp(s
, "Italic"))
713 slant
= RR_FONTSLANT_ITALIC
;
714 if (!g_ascii_strcasecmp(s
, "Oblique"))
715 slant
= RR_FONTSLANT_OBLIQUE
;
719 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
722 n
= obt_xml_find_node(n
->next
, "font");
726 static void parse_desktops(xmlNodePtr node
, gpointer d
)
730 node
= node
->children
;
732 if ((n
= obt_xml_find_node(node
, "number"))) {
733 gint d
= obt_xml_node_int(n
);
735 config_desktops_num
= (unsigned) d
;
737 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
738 gint d
= obt_xml_node_int(n
);
740 config_screen_firstdesk
= (unsigned) d
;
742 if ((n
= obt_xml_find_node(node
, "names"))) {
746 for (it
= config_desktops_names
; it
; it
= it
->next
)
748 g_slist_free(config_desktops_names
);
749 config_desktops_names
= NULL
;
751 nname
= obt_xml_find_node(n
->children
, "name");
753 config_desktops_names
=
754 g_slist_append(config_desktops_names
,
755 obt_xml_node_string(nname
));
756 nname
= obt_xml_find_node(nname
->next
, "name");
759 if ((n
= obt_xml_find_node(node
, "popupTime")))
760 config_desktop_popup_time
= obt_xml_node_int(n
);
763 static void parse_resize(xmlNodePtr node
, gpointer d
)
767 node
= node
->children
;
769 if ((n
= obt_xml_find_node(node
, "drawContents")))
770 config_resize_redraw
= obt_xml_node_bool(n
);
771 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
772 config_resize_popup_show
= obt_xml_node_int(n
);
773 if (obt_xml_node_contains(n
, "Always"))
774 config_resize_popup_show
= 2;
775 else if (obt_xml_node_contains(n
, "Never"))
776 config_resize_popup_show
= 0;
777 else if (obt_xml_node_contains(n
, "Nonpixel"))
778 config_resize_popup_show
= 1;
780 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
781 if (obt_xml_node_contains(n
, "Top"))
782 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
783 else if (obt_xml_node_contains(n
, "Center"))
784 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
785 else if (obt_xml_node_contains(n
, "Fixed")) {
786 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
788 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
791 if ((n2
= obt_xml_find_node(n
->children
, "x")))
792 config_parse_gravity_coord(n2
,
793 &config_resize_popup_fixed
.x
);
794 if ((n2
= obt_xml_find_node(n
->children
, "y")))
795 config_parse_gravity_coord(n2
,
796 &config_resize_popup_fixed
.y
);
798 config_resize_popup_fixed
.x
.pos
=
799 MAX(config_resize_popup_fixed
.x
.pos
, 0);
800 config_resize_popup_fixed
.y
.pos
=
801 MAX(config_resize_popup_fixed
.y
.pos
, 0);
807 static void parse_dock(xmlNodePtr node
, gpointer d
)
811 node
= node
->children
;
813 if ((n
= obt_xml_find_node(node
, "position"))) {
814 if (obt_xml_node_contains(n
, "TopLeft"))
815 config_dock_floating
= FALSE
,
816 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
817 else if (obt_xml_node_contains(n
, "Top"))
818 config_dock_floating
= FALSE
,
819 config_dock_pos
= OB_DIRECTION_NORTH
;
820 else if (obt_xml_node_contains(n
, "TopRight"))
821 config_dock_floating
= FALSE
,
822 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
823 else if (obt_xml_node_contains(n
, "Right"))
824 config_dock_floating
= FALSE
,
825 config_dock_pos
= OB_DIRECTION_EAST
;
826 else if (obt_xml_node_contains(n
, "BottomRight"))
827 config_dock_floating
= FALSE
,
828 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
829 else if (obt_xml_node_contains(n
, "Bottom"))
830 config_dock_floating
= FALSE
,
831 config_dock_pos
= OB_DIRECTION_SOUTH
;
832 else if (obt_xml_node_contains(n
, "BottomLeft"))
833 config_dock_floating
= FALSE
,
834 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
835 else if (obt_xml_node_contains(n
, "Left"))
836 config_dock_floating
= FALSE
,
837 config_dock_pos
= OB_DIRECTION_WEST
;
838 else if (obt_xml_node_contains(n
, "Floating"))
839 config_dock_floating
= TRUE
;
841 if (config_dock_floating
) {
842 if ((n
= obt_xml_find_node(node
, "floatingX")))
843 config_dock_x
= obt_xml_node_int(n
);
844 if ((n
= obt_xml_find_node(node
, "floatingY")))
845 config_dock_y
= obt_xml_node_int(n
);
847 if ((n
= obt_xml_find_node(node
, "noStrut")))
848 config_dock_nostrut
= obt_xml_node_bool(n
);
850 if ((n
= obt_xml_find_node(node
, "stacking"))) {
851 if (obt_xml_node_contains(n
, "normal"))
852 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
853 else if (obt_xml_node_contains(n
, "below"))
854 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
855 else if (obt_xml_node_contains(n
, "above"))
856 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
858 if ((n
= obt_xml_find_node(node
, "direction"))) {
859 if (obt_xml_node_contains(n
, "horizontal"))
860 config_dock_orient
= OB_ORIENTATION_HORZ
;
861 else if (obt_xml_node_contains(n
, "vertical"))
862 config_dock_orient
= OB_ORIENTATION_VERT
;
864 if ((n
= obt_xml_find_node(node
, "autoHide")))
865 config_dock_hide
= obt_xml_node_bool(n
);
866 if ((n
= obt_xml_find_node(node
, "hideDelay")))
867 config_dock_hide_delay
= obt_xml_node_int(n
);
868 if ((n
= obt_xml_find_node(node
, "showDelay")))
869 config_dock_show_delay
= obt_xml_node_int(n
);
870 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
871 gchar
*str
= obt_xml_node_string(n
);
873 if (translate_button(str
, &s
, &b
)) {
874 config_dock_app_move_button
= b
;
875 config_dock_app_move_modifiers
= s
;
877 g_message(_("Invalid button \"%s\" specified in config file"), str
);
883 static void parse_menu(xmlNodePtr node
, gpointer d
)
886 node
= node
->children
;
888 if ((n
= obt_xml_find_node(node
, "hideDelay")))
889 config_menu_hide_delay
= obt_xml_node_int(n
);
890 if ((n
= obt_xml_find_node(node
, "middle")))
891 config_menu_middle
= obt_xml_node_bool(n
);
892 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
893 config_submenu_show_delay
= obt_xml_node_int(n
);
894 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
895 config_submenu_hide_delay
= obt_xml_node_int(n
);
896 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
897 config_menu_manage_desktops
= obt_xml_node_bool(n
);
898 if ((n
= obt_xml_find_node(node
, "showIcons"))) {
899 config_menu_show_icons
= obt_xml_node_bool(n
);
901 if (config_menu_show_icons
)
902 g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
906 while ((node
= obt_xml_find_node(node
, "file"))) {
907 gchar
*c
= obt_xml_node_string(node
);
908 config_menu_files
= g_slist_append(config_menu_files
,
909 obt_paths_expand_tilde(c
));
915 static void parse_resistance(xmlNodePtr node
, gpointer d
)
919 node
= node
->children
;
920 if ((n
= obt_xml_find_node(node
, "strength")))
921 config_resist_win
= obt_xml_node_int(n
);
922 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
923 config_resist_edge
= obt_xml_node_int(n
);
929 const gchar
*actname
;
932 static void bind_default_keyboard(void)
935 ObDefKeyBind binds
[] = {
936 { "A-Tab", "NextWindow" },
937 { "S-A-Tab", "PreviousWindow" },
941 for (it
= binds
; it
->key
; ++it
) {
942 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
943 keyboard_bind(l
, actions_parse_string(it
->actname
));
950 const gchar
*context
;
951 const ObMouseAction mact
;
952 const gchar
*actname
;
955 static void bind_default_mouse(void)
958 ObDefMouseBind binds
[] = {
959 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
960 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
961 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
962 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
963 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
964 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
965 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
966 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
967 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
968 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
969 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
970 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
971 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
972 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
973 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
974 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
975 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
976 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
977 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
978 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
979 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
980 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
981 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
982 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
983 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
984 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
985 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
986 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
987 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
988 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
989 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
990 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
991 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
992 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
993 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
994 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
995 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
996 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
997 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
998 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
999 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
1000 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
1001 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
1002 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
1003 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
1004 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
1005 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
1006 { NULL
, NULL
, 0, NULL
}
1009 for (it
= binds
; it
->button
; ++it
)
1010 mouse_bind(it
->button
, frame_context_from_string(it
->context
),
1011 it
->mact
, actions_parse_string(it
->actname
));
1014 void config_startup(ObtXmlInst
*i
)
1016 config_focus_new
= TRUE
;
1017 config_focus_follow
= FALSE
;
1018 config_focus_delay
= 0;
1019 config_focus_raise
= FALSE
;
1020 config_focus_last
= TRUE
;
1021 config_focus_under_mouse
= FALSE
;
1022 config_unfocus_leave
= FALSE
;
1024 obt_xml_register(i
, "focus", parse_focus
, NULL
);
1026 config_place_policy
= OB_PLACE_POLICY_SMART
;
1027 config_place_monitor
= OB_PLACE_MONITOR_PRIMARY
;
1029 config_primary_monitor_index
= 1;
1030 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
1032 obt_xml_register(i
, "placement", parse_placement
, NULL
);
1034 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1036 obt_xml_register(i
, "margins", parse_margins
, NULL
);
1038 config_theme
= NULL
;
1040 config_animate_iconify
= TRUE
;
1041 config_title_layout
= g_strdup("NLIMC");
1042 config_theme_keepborder
= TRUE
;
1043 config_theme_window_list_icon_size
= 36;
1045 config_font_activewindow
= NULL
;
1046 config_font_inactivewindow
= NULL
;
1047 config_font_menuitem
= NULL
;
1048 config_font_menutitle
= NULL
;
1049 config_font_activeosd
= NULL
;
1050 config_font_inactiveosd
= NULL
;
1052 obt_xml_register(i
, "theme", parse_theme
, NULL
);
1054 config_desktops_num
= 4;
1055 config_screen_firstdesk
= 1;
1056 config_desktops_names
= NULL
;
1057 config_desktop_popup_time
= 875;
1059 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
1061 config_resize_redraw
= TRUE
;
1062 config_resize_popup_show
= 1; /* nonpixel increments */
1063 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
1064 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
1065 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
1067 obt_xml_register(i
, "resize", parse_resize
, NULL
);
1069 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
1070 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
1071 config_dock_floating
= FALSE
;
1072 config_dock_nostrut
= FALSE
;
1075 config_dock_orient
= OB_ORIENTATION_VERT
;
1076 config_dock_hide
= FALSE
;
1077 config_dock_hide_delay
= 300;
1078 config_dock_show_delay
= 300;
1079 config_dock_app_move_button
= 2; /* middle */
1080 config_dock_app_move_modifiers
= 0;
1082 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1084 translate_key("C-g", &config_keyboard_reset_state
,
1085 &config_keyboard_reset_keycode
);
1087 bind_default_keyboard();
1089 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1091 config_mouse_threshold
= 8;
1092 config_mouse_dclicktime
= 500;
1093 config_mouse_screenedgetime
= 400;
1094 config_mouse_screenedgewarp
= FALSE
;
1096 bind_default_mouse();
1098 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1100 config_resist_win
= 10;
1101 config_resist_edge
= 20;
1103 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1105 config_menu_hide_delay
= 250;
1106 config_menu_middle
= FALSE
;
1107 config_submenu_show_delay
= 100;
1108 config_submenu_hide_delay
= 400;
1109 config_menu_manage_desktops
= TRUE
;
1110 config_menu_files
= NULL
;
1111 config_menu_show_icons
= TRUE
;
1113 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1115 config_per_app_settings
= NULL
;
1117 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1120 void config_shutdown(void)
1124 g_free(config_theme
);
1126 g_free(config_title_layout
);
1128 RrFontClose(config_font_activewindow
);
1129 RrFontClose(config_font_inactivewindow
);
1130 RrFontClose(config_font_menuitem
);
1131 RrFontClose(config_font_menutitle
);
1132 RrFontClose(config_font_activeosd
);
1133 RrFontClose(config_font_inactiveosd
);
1135 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1137 g_slist_free(config_desktops_names
);
1139 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1141 g_slist_free(config_menu_files
);
1143 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1144 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1145 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1146 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1147 if (itd
->title
) g_pattern_spec_free(itd
->title
);
1148 if (itd
->class) g_pattern_spec_free(itd
->class);
1149 if (itd
->group_name
) g_pattern_spec_free(itd
->group_name
);
1150 if (itd
->group_class
) g_pattern_spec_free(itd
->group_class
);
1151 g_slice_free(ObAppSettings
, it
->data
);
1153 g_slist_free(config_per_app_settings
);