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
;
51 guint config_frame_flash_delay
;
52 guint config_frame_flash_duration
;
54 gchar
*config_title_layout
;
56 gboolean config_animate_iconify
;
58 RrFont
*config_font_activewindow
;
59 RrFont
*config_font_inactivewindow
;
60 RrFont
*config_font_menuitem
;
61 RrFont
*config_font_menutitle
;
62 RrFont
*config_font_activeosd
;
63 RrFont
*config_font_inactiveosd
;
65 guint config_desktops_num
;
66 GSList
*config_desktops_names
;
67 guint config_screen_firstdesk
;
68 guint config_desktop_popup_time
;
70 gboolean config_resize_redraw
;
71 gint config_resize_popup_show
;
72 ObResizePopupPos config_resize_popup_pos
;
73 GravityPoint config_resize_popup_fixed
;
75 ObStackingLayer config_dock_layer
;
76 gboolean config_dock_floating
;
77 gboolean config_dock_nostrut
;
78 ObDirection config_dock_pos
;
81 ObOrientation config_dock_orient
;
82 gboolean config_dock_hide
;
83 guint config_dock_hide_delay
;
84 guint config_dock_show_delay
;
85 guint config_dock_app_move_button
;
86 guint config_dock_app_move_modifiers
;
88 guint config_keyboard_reset_keycode
;
89 guint config_keyboard_reset_state
;
91 gint config_mouse_threshold
;
92 gint config_mouse_dclicktime
;
93 gint config_mouse_screenedgetime
;
94 gboolean config_mouse_screenedgewarp
;
96 guint config_menu_hide_delay
;
97 gboolean config_menu_middle
;
98 guint config_submenu_show_delay
;
99 guint config_submenu_hide_delay
;
100 gboolean config_menu_manage_desktops
;
101 gboolean config_menu_show_icons
;
103 GSList
*config_menu_files
;
105 gint config_resist_win
;
106 gint config_resist_edge
;
108 GSList
*config_per_app_settings
;
110 ObAppSettings
* config_create_app_settings(void)
112 ObAppSettings
*settings
= g_slice_new0(ObAppSettings
);
114 settings
->decor
= -1;
115 settings
->shade
= -1;
116 settings
->monitor_type
= OB_PLACE_MONITOR_ANY
;
117 settings
->monitor
= -1;
118 settings
->focus
= -1;
119 settings
->desktop
= 0;
120 settings
->layer
= -2;
121 settings
->iconic
= -1;
122 settings
->skip_pager
= -1;
123 settings
->skip_taskbar
= -1;
124 settings
->fullscreen
= -1;
125 settings
->max_horz
= -1;
126 settings
->max_vert
= -1;
127 settings
->opacity
= -1;
131 #define copy_if(setting, default) \
132 if (src->setting != default) dst->setting = src->setting
133 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
136 g_assert(src
!= NULL
);
137 g_assert(dst
!= NULL
);
139 copy_if(type
, (ObClientType
)-1);
142 copy_if(monitor_type
, OB_PLACE_MONITOR_ANY
);
143 copy_if(monitor
, -1);
148 copy_if(skip_pager
, -1);
149 copy_if(skip_taskbar
, -1);
150 copy_if(fullscreen
, -1);
151 copy_if(max_horz
, -1);
152 copy_if(max_vert
, -1);
153 copy_if(opacity
, -1);
155 if (src
->pos_given
) {
156 dst
->pos_given
= TRUE
;
157 dst
->pos_force
= src
->pos_force
;
158 dst
->position
= src
->position
;
159 /* monitor is copied above */
163 void config_parse_relative_number(gchar
*s
, gint
*num
, gint
*denom
)
165 *num
= strtol(s
, &s
, 10);
169 } else if (*s
== '/') {
174 void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
176 gchar
*s
= obt_xml_node_string(node
);
177 if (!g_ascii_strcasecmp(s
, "center"))
183 if (s
[0] == '-' || s
[0] == '+')
185 config_parse_relative_number(ps
, &c
->pos
, &c
->denom
);
192 <application name="aterm">
195 <application name="Rhythmbox">
202 .. there is a lot more settings available
207 /* Manages settings for individual applications.
208 Some notes: monitor is the screen number in a multi monitor
209 (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
210 is on, active: the active monitor, primary: the primary monitor.
211 Layer can be three values, above (Always on top), below
212 (Always on bottom) and everything else (normal behaviour).
213 Positions can be an integer value or center, which will
214 center the window in the specified axis. Position is within
215 the monitor, so <position><x>center</x></position><monitor>2</monitor>
216 will center the window on the second monitor.
218 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
220 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
221 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *title
= NULL
,
223 gboolean name_set
, class_set
, type_set
, role_set
, title_set
;
225 gboolean x_pos_given
;
230 class_set
= obt_xml_attr_string(app
, "class", &class);
231 name_set
= obt_xml_attr_string(app
, "name", &name
);
232 type_set
= obt_xml_attr_string(app
, "type", &type_str
);
233 role_set
= obt_xml_attr_string(app
, "role", &role
);
234 title_set
= obt_xml_attr_string(app
, "title", &title
);
236 /* validate the type tho */
238 if (!g_ascii_strcasecmp(type_str
, "normal"))
239 type
= OB_CLIENT_TYPE_NORMAL
;
240 else if (!g_ascii_strcasecmp(type_str
, "dialog"))
241 type
= OB_CLIENT_TYPE_DIALOG
;
242 else if (!g_ascii_strcasecmp(type_str
, "splash"))
243 type
= OB_CLIENT_TYPE_SPLASH
;
244 else if (!g_ascii_strcasecmp(type_str
, "utility"))
245 type
= OB_CLIENT_TYPE_UTILITY
;
246 else if (!g_ascii_strcasecmp(type_str
, "menu"))
247 type
= OB_CLIENT_TYPE_MENU
;
248 else if (!g_ascii_strcasecmp(type_str
, "toolbar"))
249 type
= OB_CLIENT_TYPE_TOOLBAR
;
250 else if (!g_ascii_strcasecmp(type_str
, "dock"))
251 type
= OB_CLIENT_TYPE_DOCK
;
252 else if (!g_ascii_strcasecmp(type_str
, "desktop"))
253 type
= OB_CLIENT_TYPE_DESKTOP
;
255 type_set
= FALSE
; /* not valid! */
258 if (class_set
|| name_set
|| role_set
|| title_set
|| type_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
->role
= g_pattern_spec_new(role
);
272 settings
->title
= g_pattern_spec_new(title
);
275 settings
->type
= type
;
277 if ((n
= obt_xml_find_node(app
->children
, "decor")))
278 if (!obt_xml_node_contains(n
, "default"))
279 settings
->decor
= obt_xml_node_bool(n
);
281 if ((n
= obt_xml_find_node(app
->children
, "shade")))
282 if (!obt_xml_node_contains(n
, "default"))
283 settings
->shade
= obt_xml_node_bool(n
);
285 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
286 if ((c
= obt_xml_find_node(n
->children
, "x")))
287 if (!obt_xml_node_contains(c
, "default")) {
288 config_parse_gravity_coord(c
, &settings
->position
.x
);
292 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
293 if (!obt_xml_node_contains(c
, "default")) {
294 config_parse_gravity_coord(c
, &settings
->position
.y
);
295 settings
->pos_given
= TRUE
;
298 /* monitor can be set without setting x or y */
299 if ((c
= obt_xml_find_node(n
->children
, "monitor")))
300 if (!obt_xml_node_contains(c
, "default")) {
301 gchar
*s
= obt_xml_node_string(c
);
302 if (!g_ascii_strcasecmp(s
, "mouse"))
303 settings
->monitor_type
=
304 OB_PLACE_MONITOR_MOUSE
;
305 else if (!g_ascii_strcasecmp(s
, "active"))
306 settings
->monitor_type
=
307 OB_PLACE_MONITOR_ACTIVE
;
308 else if (!g_ascii_strcasecmp(s
, "primary"))
309 settings
->monitor_type
=
310 OB_PLACE_MONITOR_PRIMARY
;
312 settings
->monitor
= obt_xml_node_int(c
);
316 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
319 if ((n
= obt_xml_find_node(app
->children
, "focus")))
320 if (!obt_xml_node_contains(n
, "default"))
321 settings
->focus
= obt_xml_node_bool(n
);
323 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
324 if (!obt_xml_node_contains(n
, "default")) {
325 gchar
*s
= obt_xml_node_string(n
);
326 if (!g_ascii_strcasecmp(s
, "all"))
327 settings
->desktop
= DESKTOP_ALL
;
329 gint i
= obt_xml_node_int(n
);
331 settings
->desktop
= i
;
337 if ((n
= obt_xml_find_node(app
->children
, "layer")))
338 if (!obt_xml_node_contains(n
, "default")) {
339 gchar
*s
= obt_xml_node_string(n
);
340 if (!g_ascii_strcasecmp(s
, "above"))
342 else if (!g_ascii_strcasecmp(s
, "below"))
343 settings
->layer
= -1;
349 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
350 if (!obt_xml_node_contains(n
, "default"))
351 settings
->iconic
= obt_xml_node_bool(n
);
353 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
354 if (!obt_xml_node_contains(n
, "default"))
355 settings
->skip_pager
= obt_xml_node_bool(n
);
357 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
358 if (!obt_xml_node_contains(n
, "default"))
359 settings
->skip_taskbar
= obt_xml_node_bool(n
);
361 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
362 if (!obt_xml_node_contains(n
, "default"))
363 settings
->fullscreen
= obt_xml_node_bool(n
);
365 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
366 if (!obt_xml_node_contains(n
, "default")) {
367 gchar
*s
= obt_xml_node_string(n
);
368 if (!g_ascii_strcasecmp(s
, "horizontal")) {
369 settings
->max_horz
= TRUE
;
370 settings
->max_vert
= FALSE
;
371 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
372 settings
->max_horz
= FALSE
;
373 settings
->max_vert
= TRUE
;
375 settings
->max_horz
= settings
->max_vert
=
376 obt_xml_node_bool(n
);
380 if ((n
= obt_xml_find_node(app
->children
, "opacity")))
381 if (!obt_xml_node_contains(n
, "default"))
382 settings
->opacity
= obt_xml_node_int(n
);
384 config_per_app_settings
= g_slist_append(config_per_app_settings
,
385 (gpointer
) settings
);
391 name
= class = role
= title
= type_str
= NULL
;
394 app
= obt_xml_find_node(app
->next
, "application");
401 <action name="ChangeDesktop">
408 static void parse_key(xmlNodePtr node
, GList
*keylist
)
410 gchar
*keystring
, **keys
, **key
;
412 gboolean is_chroot
= FALSE
;
414 if (!obt_xml_attr_string(node
, "key", &keystring
))
417 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
419 keys
= g_strsplit(keystring
, " ", 0);
420 for (key
= keys
; *key
; ++key
) {
421 keylist
= g_list_append(keylist
, *key
);
423 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
425 parse_key(n
, keylist
);
426 n
= obt_xml_find_node(n
->next
, "keybind");
429 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
431 ObActionsAct
*action
;
433 action
= actions_parse(n
);
435 keyboard_bind(keylist
, action
);
436 n
= obt_xml_find_node(n
->next
, "action");
442 keyboard_chroot(keylist
);
443 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
450 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
455 keyboard_unbind_all();
457 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
458 key
= obt_xml_node_string(n
);
459 translate_key(key
, &config_keyboard_reset_state
,
460 &config_keyboard_reset_keycode
);
464 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
467 n
= obt_xml_find_node(n
->next
, "keybind");
473 <context name="Titlebar">
474 <mousebind button="Left" action="Press">
475 <action name="Raise"></action>
481 static void parse_mouse(xmlNodePtr node
, gpointer d
)
483 xmlNodePtr n
, nbut
, nact
;
490 node
= node
->children
;
492 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
493 config_mouse_threshold
= obt_xml_node_int(n
);
494 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
495 config_mouse_dclicktime
= obt_xml_node_int(n
);
496 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
497 config_mouse_screenedgetime
= obt_xml_node_int(n
);
498 /* minimum value of 25 for this property, when it is 1 and you hit the
499 edge it basically never stops */
500 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
501 config_mouse_screenedgetime
= 25;
503 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpMouse")))
504 config_mouse_screenedgewarp
= obt_xml_node_bool(n
);
506 n
= obt_xml_find_node(node
, "context");
511 if (!obt_xml_attr_string(n
, "name", &cxstr
))
514 modcxstr
= g_strdup(cxstr
); /* make a copy to mutilate */
515 while (frame_next_context_from_string(modcxstr
, &cx
)) {
517 gchar
*s
= strchr(modcxstr
, ' ');
520 g_message(_("Invalid context \"%s\" in mouse binding"),
527 nbut
= obt_xml_find_node(n
->children
, "mousebind");
529 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
531 if (obt_xml_attr_contains(nbut
, "action", "press"))
532 mact
= OB_MOUSE_ACTION_PRESS
;
533 else if (obt_xml_attr_contains(nbut
, "action", "release"))
534 mact
= OB_MOUSE_ACTION_RELEASE
;
535 else if (obt_xml_attr_contains(nbut
, "action", "click"))
536 mact
= OB_MOUSE_ACTION_CLICK
;
537 else if (obt_xml_attr_contains(nbut
, "action","doubleclick"))
538 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
539 else if (obt_xml_attr_contains(nbut
, "action", "drag"))
540 mact
= OB_MOUSE_ACTION_MOTION
;
544 nact
= obt_xml_find_node(nbut
->children
, "action");
546 ObActionsAct
*action
;
548 if ((action
= actions_parse(nact
)))
549 mouse_bind(buttonstr
, cx
, mact
, action
);
550 nact
= obt_xml_find_node(nact
->next
, "action");
554 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
560 n
= obt_xml_find_node(n
->next
, "context");
564 static void parse_focus(xmlNodePtr node
, gpointer d
)
568 node
= node
->children
;
570 if ((n
= obt_xml_find_node(node
, "focusNew")))
571 config_focus_new
= obt_xml_node_bool(n
);
572 if ((n
= obt_xml_find_node(node
, "followMouse")))
573 config_focus_follow
= obt_xml_node_bool(n
);
574 if ((n
= obt_xml_find_node(node
, "focusDelay")))
575 config_focus_delay
= obt_xml_node_int(n
);
576 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
577 config_focus_raise
= obt_xml_node_bool(n
);
578 if ((n
= obt_xml_find_node(node
, "focusLast")))
579 config_focus_last
= obt_xml_node_bool(n
);
580 if ((n
= obt_xml_find_node(node
, "underMouse")))
581 config_focus_under_mouse
= obt_xml_node_bool(n
);
582 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
583 config_unfocus_leave
= obt_xml_node_bool(n
);
586 static void parse_placement(xmlNodePtr node
, gpointer d
)
590 node
= node
->children
;
592 if ((n
= obt_xml_find_node(node
, "policy")))
593 if (obt_xml_node_contains(n
, "UnderMouse"))
594 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
595 if ((n
= obt_xml_find_node(node
, "center")))
596 config_place_center
= obt_xml_node_bool(n
);
597 if ((n
= obt_xml_find_node(node
, "monitor"))) {
598 if (obt_xml_node_contains(n
, "active"))
599 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
600 else if (obt_xml_node_contains(n
, "mouse"))
601 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
602 else if (obt_xml_node_contains(n
, "any"))
603 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
605 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
606 config_primary_monitor_index
= obt_xml_node_int(n
);
607 if (!config_primary_monitor_index
) {
608 if (obt_xml_node_contains(n
, "mouse"))
609 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
614 static void parse_margins(xmlNodePtr node
, gpointer d
)
618 node
= node
->children
;
620 if ((n
= obt_xml_find_node(node
, "top")))
621 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
622 if ((n
= obt_xml_find_node(node
, "left")))
623 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
624 if ((n
= obt_xml_find_node(node
, "right")))
625 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
626 if ((n
= obt_xml_find_node(node
, "bottom")))
627 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
630 static void parse_theme(xmlNodePtr node
, gpointer d
)
634 node
= node
->children
;
636 if ((n
= obt_xml_find_node(node
, "name"))) {
639 g_free(config_theme
);
640 c
= obt_xml_node_string(n
);
641 config_theme
= obt_paths_expand_tilde(c
);
644 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
647 g_free(config_title_layout
);
648 config_title_layout
= obt_xml_node_string(n
);
650 /* replace duplicates with spaces */
651 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
652 for (d
= c
+1; *d
!= '\0'; ++d
)
653 if (*c
== *d
) *d
= ' ';
655 if ((n
= obt_xml_find_node(node
, "keepBorder")))
656 config_theme_keepborder
= obt_xml_node_bool(n
);
657 if ((n
= obt_xml_find_node(node
, "animateIconify")))
658 config_animate_iconify
= obt_xml_node_bool(n
);
659 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
660 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
661 if (config_theme_window_list_icon_size
< 16)
662 config_theme_window_list_icon_size
= 16;
663 else if (config_theme_window_list_icon_size
> 96)
664 config_theme_window_list_icon_size
= 96;
666 if ((n
= obt_xml_find_node(node
, "flashFrameDelay")))
667 config_frame_flash_delay
= obt_xml_node_int(n
);
668 if ((n
= obt_xml_find_node(node
, "flashFrameDuration")))
669 config_frame_flash_duration
= obt_xml_node_int(n
);
671 n
= obt_xml_find_node(node
, "font");
675 gchar
*name
= g_strdup(RrDefaultFontFamily
);
676 gint size
= RrDefaultFontSize
;
677 RrFontWeight weight
= RrDefaultFontWeight
;
678 RrFontSlant slant
= RrDefaultFontSlant
;
680 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
681 font
= &config_font_activewindow
;
682 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
683 font
= &config_font_inactivewindow
;
684 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
685 font
= &config_font_menutitle
;
686 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
687 font
= &config_font_menuitem
;
688 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
689 font
= &config_font_activeosd
;
690 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
691 font
= &config_font_activeosd
;
692 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
693 font
= &config_font_inactiveosd
;
697 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
699 name
= obt_xml_node_string(fnode
);
701 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
702 int s
= obt_xml_node_int(fnode
);
705 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
706 gchar
*w
= obt_xml_node_string(fnode
);
707 if (!g_ascii_strcasecmp(w
, "Bold"))
708 weight
= RR_FONTWEIGHT_BOLD
;
711 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
712 gchar
*s
= obt_xml_node_string(fnode
);
713 if (!g_ascii_strcasecmp(s
, "Italic"))
714 slant
= RR_FONTSLANT_ITALIC
;
715 if (!g_ascii_strcasecmp(s
, "Oblique"))
716 slant
= RR_FONTSLANT_OBLIQUE
;
720 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
723 n
= obt_xml_find_node(n
->next
, "font");
727 static void parse_desktops(xmlNodePtr node
, gpointer d
)
731 node
= node
->children
;
733 if ((n
= obt_xml_find_node(node
, "number"))) {
734 gint d
= obt_xml_node_int(n
);
736 config_desktops_num
= (unsigned) d
;
738 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
739 gint d
= obt_xml_node_int(n
);
741 config_screen_firstdesk
= (unsigned) d
;
743 if ((n
= obt_xml_find_node(node
, "names"))) {
747 for (it
= config_desktops_names
; it
; it
= it
->next
)
749 g_slist_free(config_desktops_names
);
750 config_desktops_names
= NULL
;
752 nname
= obt_xml_find_node(n
->children
, "name");
754 config_desktops_names
=
755 g_slist_append(config_desktops_names
,
756 obt_xml_node_string(nname
));
757 nname
= obt_xml_find_node(nname
->next
, "name");
760 if ((n
= obt_xml_find_node(node
, "popupTime")))
761 config_desktop_popup_time
= obt_xml_node_int(n
);
764 static void parse_resize(xmlNodePtr node
, gpointer d
)
768 node
= node
->children
;
770 if ((n
= obt_xml_find_node(node
, "drawContents")))
771 config_resize_redraw
= obt_xml_node_bool(n
);
772 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
773 config_resize_popup_show
= obt_xml_node_int(n
);
774 if (obt_xml_node_contains(n
, "Always"))
775 config_resize_popup_show
= 2;
776 else if (obt_xml_node_contains(n
, "Never"))
777 config_resize_popup_show
= 0;
778 else if (obt_xml_node_contains(n
, "Nonpixel"))
779 config_resize_popup_show
= 1;
781 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
782 if (obt_xml_node_contains(n
, "Top"))
783 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
784 else if (obt_xml_node_contains(n
, "Center"))
785 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
786 else if (obt_xml_node_contains(n
, "Fixed")) {
787 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
789 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
792 if ((n2
= obt_xml_find_node(n
->children
, "x")))
793 config_parse_gravity_coord(n2
,
794 &config_resize_popup_fixed
.x
);
795 if ((n2
= obt_xml_find_node(n
->children
, "y")))
796 config_parse_gravity_coord(n2
,
797 &config_resize_popup_fixed
.y
);
799 config_resize_popup_fixed
.x
.pos
=
800 MAX(config_resize_popup_fixed
.x
.pos
, 0);
801 config_resize_popup_fixed
.y
.pos
=
802 MAX(config_resize_popup_fixed
.y
.pos
, 0);
808 static void parse_dock(xmlNodePtr node
, gpointer d
)
812 node
= node
->children
;
814 if ((n
= obt_xml_find_node(node
, "position"))) {
815 if (obt_xml_node_contains(n
, "TopLeft"))
816 config_dock_floating
= FALSE
,
817 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
818 else if (obt_xml_node_contains(n
, "Top"))
819 config_dock_floating
= FALSE
,
820 config_dock_pos
= OB_DIRECTION_NORTH
;
821 else if (obt_xml_node_contains(n
, "TopRight"))
822 config_dock_floating
= FALSE
,
823 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
824 else if (obt_xml_node_contains(n
, "Right"))
825 config_dock_floating
= FALSE
,
826 config_dock_pos
= OB_DIRECTION_EAST
;
827 else if (obt_xml_node_contains(n
, "BottomRight"))
828 config_dock_floating
= FALSE
,
829 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
830 else if (obt_xml_node_contains(n
, "Bottom"))
831 config_dock_floating
= FALSE
,
832 config_dock_pos
= OB_DIRECTION_SOUTH
;
833 else if (obt_xml_node_contains(n
, "BottomLeft"))
834 config_dock_floating
= FALSE
,
835 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
836 else if (obt_xml_node_contains(n
, "Left"))
837 config_dock_floating
= FALSE
,
838 config_dock_pos
= OB_DIRECTION_WEST
;
839 else if (obt_xml_node_contains(n
, "Floating"))
840 config_dock_floating
= TRUE
;
842 if (config_dock_floating
) {
843 if ((n
= obt_xml_find_node(node
, "floatingX")))
844 config_dock_x
= obt_xml_node_int(n
);
845 if ((n
= obt_xml_find_node(node
, "floatingY")))
846 config_dock_y
= obt_xml_node_int(n
);
848 if ((n
= obt_xml_find_node(node
, "noStrut")))
849 config_dock_nostrut
= obt_xml_node_bool(n
);
851 if ((n
= obt_xml_find_node(node
, "stacking"))) {
852 if (obt_xml_node_contains(n
, "normal"))
853 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
854 else if (obt_xml_node_contains(n
, "below"))
855 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
856 else if (obt_xml_node_contains(n
, "above"))
857 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
859 if ((n
= obt_xml_find_node(node
, "direction"))) {
860 if (obt_xml_node_contains(n
, "horizontal"))
861 config_dock_orient
= OB_ORIENTATION_HORZ
;
862 else if (obt_xml_node_contains(n
, "vertical"))
863 config_dock_orient
= OB_ORIENTATION_VERT
;
865 if ((n
= obt_xml_find_node(node
, "autoHide")))
866 config_dock_hide
= obt_xml_node_bool(n
);
867 if ((n
= obt_xml_find_node(node
, "hideDelay")))
868 config_dock_hide_delay
= obt_xml_node_int(n
);
869 if ((n
= obt_xml_find_node(node
, "showDelay")))
870 config_dock_show_delay
= obt_xml_node_int(n
);
871 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
872 gchar
*str
= obt_xml_node_string(n
);
874 if (translate_button(str
, &s
, &b
)) {
875 config_dock_app_move_button
= b
;
876 config_dock_app_move_modifiers
= s
;
878 g_message(_("Invalid button \"%s\" specified in config file"), str
);
884 static void parse_menu(xmlNodePtr node
, gpointer d
)
887 node
= node
->children
;
889 if ((n
= obt_xml_find_node(node
, "hideDelay")))
890 config_menu_hide_delay
= obt_xml_node_int(n
);
891 if ((n
= obt_xml_find_node(node
, "middle")))
892 config_menu_middle
= obt_xml_node_bool(n
);
893 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
894 config_submenu_show_delay
= obt_xml_node_int(n
);
895 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
896 config_submenu_hide_delay
= obt_xml_node_int(n
);
897 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
898 config_menu_manage_desktops
= obt_xml_node_bool(n
);
899 if ((n
= obt_xml_find_node(node
, "showIcons"))) {
900 config_menu_show_icons
= obt_xml_node_bool(n
);
902 if (config_menu_show_icons
)
903 g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
907 while ((node
= obt_xml_find_node(node
, "file"))) {
908 gchar
*c
= obt_xml_node_string(node
);
909 config_menu_files
= g_slist_append(config_menu_files
,
910 obt_paths_expand_tilde(c
));
916 static void parse_resistance(xmlNodePtr node
, gpointer d
)
920 node
= node
->children
;
921 if ((n
= obt_xml_find_node(node
, "strength")))
922 config_resist_win
= obt_xml_node_int(n
);
923 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
924 config_resist_edge
= obt_xml_node_int(n
);
930 const gchar
*actname
;
933 static void bind_default_keyboard(void)
936 ObDefKeyBind binds
[] = {
937 { "A-Tab", "NextWindow" },
938 { "S-A-Tab", "PreviousWindow" },
942 for (it
= binds
; it
->key
; ++it
) {
943 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
944 keyboard_bind(l
, actions_parse_string(it
->actname
));
951 const gchar
*context
;
952 const ObMouseAction mact
;
953 const gchar
*actname
;
956 static void bind_default_mouse(void)
959 ObDefMouseBind binds
[] = {
960 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
961 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
962 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
963 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
964 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
965 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
966 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
967 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
968 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
969 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
970 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
971 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
972 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
973 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
974 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
975 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
976 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
977 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
978 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
979 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
980 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
981 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
982 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
983 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
984 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
985 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
986 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
987 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
988 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
989 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
990 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
991 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
992 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
993 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
994 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
995 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
996 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
997 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
998 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
999 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
1000 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
1001 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
1002 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
1003 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
1004 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
1005 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
1006 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
1007 { NULL
, NULL
, 0, NULL
}
1010 for (it
= binds
; it
->button
; ++it
)
1011 mouse_bind(it
->button
, frame_context_from_string(it
->context
),
1012 it
->mact
, actions_parse_string(it
->actname
));
1015 void config_startup(ObtXmlInst
*i
)
1017 config_focus_new
= TRUE
;
1018 config_focus_follow
= FALSE
;
1019 config_focus_delay
= 0;
1020 config_focus_raise
= FALSE
;
1021 config_focus_last
= TRUE
;
1022 config_focus_under_mouse
= FALSE
;
1023 config_unfocus_leave
= FALSE
;
1025 obt_xml_register(i
, "focus", parse_focus
, NULL
);
1027 config_place_policy
= OB_PLACE_POLICY_SMART
;
1028 config_place_center
= TRUE
;
1029 config_place_monitor
= OB_PLACE_MONITOR_PRIMARY
;
1031 config_primary_monitor_index
= 1;
1032 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
1034 obt_xml_register(i
, "placement", parse_placement
, NULL
);
1036 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1038 obt_xml_register(i
, "margins", parse_margins
, NULL
);
1040 config_theme
= NULL
;
1042 config_animate_iconify
= TRUE
;
1043 config_title_layout
= g_strdup("NLIMC");
1044 config_theme_keepborder
= TRUE
;
1045 config_theme_window_list_icon_size
= 36;
1046 config_frame_flash_delay
= 600;
1047 config_frame_flash_duration
= 5000;
1049 config_font_activewindow
= NULL
;
1050 config_font_inactivewindow
= NULL
;
1051 config_font_menuitem
= NULL
;
1052 config_font_menutitle
= NULL
;
1053 config_font_activeosd
= NULL
;
1054 config_font_inactiveosd
= NULL
;
1056 obt_xml_register(i
, "theme", parse_theme
, NULL
);
1058 config_desktops_num
= 4;
1059 config_screen_firstdesk
= 1;
1060 config_desktops_names
= NULL
;
1061 config_desktop_popup_time
= 875;
1063 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
1065 config_resize_redraw
= TRUE
;
1066 config_resize_popup_show
= 1; /* nonpixel increments */
1067 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
1068 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
1069 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
1071 obt_xml_register(i
, "resize", parse_resize
, NULL
);
1073 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
1074 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
1075 config_dock_floating
= FALSE
;
1076 config_dock_nostrut
= FALSE
;
1079 config_dock_orient
= OB_ORIENTATION_VERT
;
1080 config_dock_hide
= FALSE
;
1081 config_dock_hide_delay
= 300;
1082 config_dock_show_delay
= 300;
1083 config_dock_app_move_button
= 2; /* middle */
1084 config_dock_app_move_modifiers
= 0;
1086 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1088 translate_key("C-g", &config_keyboard_reset_state
,
1089 &config_keyboard_reset_keycode
);
1091 bind_default_keyboard();
1093 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1095 config_mouse_threshold
= 8;
1096 config_mouse_dclicktime
= 500;
1097 config_mouse_screenedgetime
= 400;
1098 config_mouse_screenedgewarp
= FALSE
;
1100 bind_default_mouse();
1102 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1104 config_resist_win
= 10;
1105 config_resist_edge
= 20;
1107 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1109 config_menu_hide_delay
= 250;
1110 config_menu_middle
= FALSE
;
1111 config_submenu_show_delay
= 100;
1112 config_submenu_hide_delay
= 400;
1113 config_menu_manage_desktops
= TRUE
;
1114 config_menu_files
= NULL
;
1115 config_menu_show_icons
= TRUE
;
1117 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1119 config_per_app_settings
= NULL
;
1121 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1124 void config_shutdown(void)
1128 g_free(config_theme
);
1130 g_free(config_title_layout
);
1132 RrFontClose(config_font_activewindow
);
1133 RrFontClose(config_font_inactivewindow
);
1134 RrFontClose(config_font_menuitem
);
1135 RrFontClose(config_font_menutitle
);
1136 RrFontClose(config_font_activeosd
);
1137 RrFontClose(config_font_inactiveosd
);
1139 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1141 g_slist_free(config_desktops_names
);
1143 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1145 g_slist_free(config_menu_files
);
1147 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1148 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1149 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1150 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1151 if (itd
->title
) g_pattern_spec_free(itd
->title
);
1152 if (itd
->class) g_pattern_spec_free(itd
->class);
1153 g_slice_free(ObAppSettings
, it
->data
);
1155 g_slist_free(config_per_app_settings
);