1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 config.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "translate.h"
29 #include "obt/paths.h"
31 gboolean config_focus_new
;
32 gboolean config_focus_follow
;
33 guint config_focus_delay
;
34 gboolean config_focus_raise
;
35 gboolean config_focus_last
;
36 gboolean config_focus_under_mouse
;
37 gboolean config_unfocus_leave
;
39 ObPlacePolicy config_place_policy
;
40 gboolean config_place_center
;
41 ObPlaceMonitor config_place_monitor
;
43 guint config_primary_monitor_index
;
44 ObPlaceMonitor config_primary_monitor
;
46 StrutPartial config_margins
;
49 gboolean config_theme_keepborder
;
50 guint config_theme_window_list_icon_size
;
52 gchar
*config_title_layout
;
54 gboolean config_animate_iconify
;
56 RrFont
*config_font_activewindow
;
57 RrFont
*config_font_inactivewindow
;
58 RrFont
*config_font_menuitem
;
59 RrFont
*config_font_menutitle
;
60 RrFont
*config_font_activeosd
;
61 RrFont
*config_font_inactiveosd
;
63 guint config_desktops_num
;
64 GSList
*config_desktops_names
;
65 guint config_screen_firstdesk
;
66 guint config_desktop_popup_time
;
68 gboolean config_resize_redraw
;
69 gint config_resize_popup_show
;
70 ObResizePopupPos config_resize_popup_pos
;
71 GravityPoint config_resize_popup_fixed
;
73 ObStackingLayer config_dock_layer
;
74 gboolean config_dock_floating
;
75 gboolean config_dock_nostrut
;
76 ObDirection config_dock_pos
;
79 ObOrientation config_dock_orient
;
80 gboolean config_dock_hide
;
81 guint config_dock_hide_delay
;
82 guint config_dock_show_delay
;
83 guint config_dock_app_move_button
;
84 guint config_dock_app_move_modifiers
;
86 guint config_keyboard_reset_keycode
;
87 guint config_keyboard_reset_state
;
89 gint config_mouse_threshold
;
90 gint config_mouse_dclicktime
;
91 gint config_mouse_screenedgetime
;
93 guint config_menu_hide_delay
;
94 gboolean config_menu_middle
;
95 guint config_submenu_show_delay
;
96 guint config_submenu_hide_delay
;
97 gboolean config_menu_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
= -1;
114 settings
->focus
= -1;
115 settings
->desktop
= 0;
116 settings
->layer
= -2;
117 settings
->iconic
= -1;
118 settings
->skip_pager
= -1;
119 settings
->skip_taskbar
= -1;
120 settings
->fullscreen
= -1;
121 settings
->max_horz
= -1;
122 settings
->max_vert
= -1;
126 #define copy_if(setting, default) \
127 if (src->setting != default) dst->setting = src->setting
128 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
131 g_assert(src
!= NULL
);
132 g_assert(dst
!= NULL
);
134 copy_if(type
, (ObClientType
)-1);
137 copy_if(monitor
, -1);
142 copy_if(skip_pager
, -1);
143 copy_if(skip_taskbar
, -1);
144 copy_if(fullscreen
, -1);
145 copy_if(max_horz
, -1);
146 copy_if(max_vert
, -1);
148 if (src
->pos_given
) {
149 dst
->pos_given
= TRUE
;
150 dst
->pos_force
= src
->pos_force
;
151 dst
->position
= src
->position
;
152 /* monitor is copied above */
156 static void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
158 gchar
*s
= obt_xml_node_string(node
);
159 if (!g_ascii_strcasecmp(s
, "center"))
164 if (s
[0] == '-' || s
[0] == '+')
174 <application name="aterm">
177 <application name="Rhythmbox">
184 .. there is a lot more settings available
189 /* Manages settings for individual applications.
190 Some notes: monitor is the screen number in a multi monitor
191 (Xinerama) setup (starting from 0) or mouse, meaning the
192 monitor the pointer is on. Default: mouse.
193 Layer can be three values, above (Always on top), below
194 (Always on bottom) and everything else (normal behaviour).
195 Positions can be an integer value or center, which will
196 center the window in the specified axis. Position is within
197 the monitor, so <position><x>center</x></position><monitor>2</monitor>
198 will center the window on the second monitor.
200 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
202 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
203 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *title
= NULL
,
205 gboolean name_set
, class_set
, type_set
, role_set
, title_set
;
207 gboolean x_pos_given
;
212 class_set
= obt_xml_attr_string(app
, "class", &class);
213 name_set
= obt_xml_attr_string(app
, "name", &name
);
214 type_set
= obt_xml_attr_string(app
, "type", &type_str
);
215 role_set
= obt_xml_attr_string(app
, "role", &role
);
216 title_set
= obt_xml_attr_string(app
, "title", &title
);
218 /* validate the type tho */
220 if (!g_ascii_strcasecmp(type_str
, "normal"))
221 type
= OB_CLIENT_TYPE_NORMAL
;
222 else if (!g_ascii_strcasecmp(type_str
, "dialog"))
223 type
= OB_CLIENT_TYPE_DIALOG
;
224 else if (!g_ascii_strcasecmp(type_str
, "splash"))
225 type
= OB_CLIENT_TYPE_SPLASH
;
226 else if (!g_ascii_strcasecmp(type_str
, "utility"))
227 type
= OB_CLIENT_TYPE_UTILITY
;
228 else if (!g_ascii_strcasecmp(type_str
, "menu"))
229 type
= OB_CLIENT_TYPE_MENU
;
230 else if (!g_ascii_strcasecmp(type_str
, "toolbar"))
231 type
= OB_CLIENT_TYPE_TOOLBAR
;
232 else if (!g_ascii_strcasecmp(type_str
, "dock"))
233 type
= OB_CLIENT_TYPE_DOCK
;
234 else if (!g_ascii_strcasecmp(type_str
, "desktop"))
235 type
= OB_CLIENT_TYPE_DESKTOP
;
237 type_set
= FALSE
; /* not valid! */
240 if (class_set
|| name_set
|| role_set
|| title_set
|| type_set
) {
242 ObAppSettings
*settings
= config_create_app_settings();
245 settings
->name
= g_pattern_spec_new(name
);
248 settings
->class = g_pattern_spec_new(class);
251 settings
->role
= g_pattern_spec_new(role
);
254 settings
->title
= g_pattern_spec_new(title
);
257 settings
->type
= type
;
259 if ((n
= obt_xml_find_node(app
->children
, "decor")))
260 if (!obt_xml_node_contains(n
, "default"))
261 settings
->decor
= obt_xml_node_bool(n
);
263 if ((n
= obt_xml_find_node(app
->children
, "shade")))
264 if (!obt_xml_node_contains(n
, "default"))
265 settings
->shade
= obt_xml_node_bool(n
);
267 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
268 if ((c
= obt_xml_find_node(n
->children
, "x")))
269 if (!obt_xml_node_contains(c
, "default")) {
270 config_parse_gravity_coord(c
, &settings
->position
.x
);
274 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
275 if (!obt_xml_node_contains(c
, "default")) {
276 config_parse_gravity_coord(c
, &settings
->position
.y
);
277 settings
->pos_given
= TRUE
;
280 if (settings
->pos_given
&&
281 (c
= obt_xml_find_node(n
->children
, "monitor")))
282 if (!obt_xml_node_contains(c
, "default")) {
283 gchar
*s
= obt_xml_node_string(c
);
284 if (!g_ascii_strcasecmp(s
, "mouse"))
285 settings
->monitor
= 0;
287 settings
->monitor
= obt_xml_node_int(c
);
291 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
294 if ((n
= obt_xml_find_node(app
->children
, "focus")))
295 if (!obt_xml_node_contains(n
, "default"))
296 settings
->focus
= obt_xml_node_bool(n
);
298 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
299 if (!obt_xml_node_contains(n
, "default")) {
300 gchar
*s
= obt_xml_node_string(n
);
301 if (!g_ascii_strcasecmp(s
, "all"))
302 settings
->desktop
= DESKTOP_ALL
;
304 gint i
= obt_xml_node_int(n
);
306 settings
->desktop
= i
;
312 if ((n
= obt_xml_find_node(app
->children
, "layer")))
313 if (!obt_xml_node_contains(n
, "default")) {
314 gchar
*s
= obt_xml_node_string(n
);
315 if (!g_ascii_strcasecmp(s
, "above"))
317 else if (!g_ascii_strcasecmp(s
, "below"))
318 settings
->layer
= -1;
324 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
325 if (!obt_xml_node_contains(n
, "default"))
326 settings
->iconic
= obt_xml_node_bool(n
);
328 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
329 if (!obt_xml_node_contains(n
, "default"))
330 settings
->skip_pager
= obt_xml_node_bool(n
);
332 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
333 if (!obt_xml_node_contains(n
, "default"))
334 settings
->skip_taskbar
= obt_xml_node_bool(n
);
336 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
337 if (!obt_xml_node_contains(n
, "default"))
338 settings
->fullscreen
= obt_xml_node_bool(n
);
340 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
341 if (!obt_xml_node_contains(n
, "default")) {
342 gchar
*s
= obt_xml_node_string(n
);
343 if (!g_ascii_strcasecmp(s
, "horizontal")) {
344 settings
->max_horz
= TRUE
;
345 settings
->max_vert
= FALSE
;
346 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
347 settings
->max_horz
= FALSE
;
348 settings
->max_vert
= TRUE
;
350 settings
->max_horz
= settings
->max_vert
=
351 obt_xml_node_bool(n
);
355 config_per_app_settings
= g_slist_append(config_per_app_settings
,
356 (gpointer
) settings
);
361 name
= class = role
= title
= NULL
;
364 app
= obt_xml_find_node(app
->next
, "application");
371 <action name="ChangeDesktop">
378 static void parse_key(xmlNodePtr node
, GList
*keylist
)
382 gboolean is_chroot
= FALSE
;
384 if (!obt_xml_attr_string(node
, "key", &key
))
387 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
389 keylist
= g_list_append(keylist
, key
);
391 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
393 parse_key(n
, keylist
);
394 n
= obt_xml_find_node(n
->next
, "keybind");
397 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
399 ObActionsAct
*action
;
401 action
= actions_parse(n
);
403 keyboard_bind(keylist
, action
);
404 n
= obt_xml_find_node(n
->next
, "action");
409 keyboard_chroot(keylist
);
412 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
415 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
420 keyboard_unbind_all();
422 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
423 key
= obt_xml_node_string(n
);
424 translate_key(key
, &config_keyboard_reset_state
,
425 &config_keyboard_reset_keycode
);
429 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
432 n
= obt_xml_find_node(n
->next
, "keybind");
438 <context name="Titlebar">
439 <mousebind button="Left" action="Press">
440 <action name="Raise"></action>
446 static void parse_mouse(xmlNodePtr node
, gpointer d
)
448 xmlNodePtr n
, nbut
, nact
;
455 node
= node
->children
;
457 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
458 config_mouse_threshold
= obt_xml_node_int(n
);
459 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
460 config_mouse_dclicktime
= obt_xml_node_int(n
);
461 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
462 config_mouse_screenedgetime
= obt_xml_node_int(n
);
463 /* minimum value of 25 for this property, when it is 1 and you hit the
464 edge it basically never stops */
465 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
466 config_mouse_screenedgetime
= 25;
469 n
= obt_xml_find_node(node
, "context");
471 if (!obt_xml_attr_string(n
, "name", &contextstr
))
473 nbut
= obt_xml_find_node(n
->children
, "mousebind");
475 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
477 if (obt_xml_attr_contains(nbut
, "action", "press")) {
478 mact
= OB_MOUSE_ACTION_PRESS
;
479 } else if (obt_xml_attr_contains(nbut
, "action", "release")) {
480 mact
= OB_MOUSE_ACTION_RELEASE
;
481 } else if (obt_xml_attr_contains(nbut
, "action", "click")) {
482 mact
= OB_MOUSE_ACTION_CLICK
;
483 } else if (obt_xml_attr_contains(nbut
, "action","doubleclick")) {
484 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
485 } else if (obt_xml_attr_contains(nbut
, "action", "drag")) {
486 mact
= OB_MOUSE_ACTION_MOTION
;
489 nact
= obt_xml_find_node(nbut
->children
, "action");
491 ObActionsAct
*action
;
493 if ((action
= actions_parse(nact
)))
494 mouse_bind(buttonstr
, contextstr
, mact
, action
);
495 nact
= obt_xml_find_node(nact
->next
, "action");
499 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
503 n
= obt_xml_find_node(n
->next
, "context");
507 static void parse_focus(xmlNodePtr node
, gpointer d
)
511 node
= node
->children
;
513 if ((n
= obt_xml_find_node(node
, "focusNew")))
514 config_focus_new
= obt_xml_node_bool(n
);
515 if ((n
= obt_xml_find_node(node
, "followMouse")))
516 config_focus_follow
= obt_xml_node_bool(n
);
517 if ((n
= obt_xml_find_node(node
, "focusDelay")))
518 config_focus_delay
= obt_xml_node_int(n
);
519 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
520 config_focus_raise
= obt_xml_node_bool(n
);
521 if ((n
= obt_xml_find_node(node
, "focusLast")))
522 config_focus_last
= obt_xml_node_bool(n
);
523 if ((n
= obt_xml_find_node(node
, "underMouse")))
524 config_focus_under_mouse
= obt_xml_node_bool(n
);
525 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
526 config_unfocus_leave
= obt_xml_node_bool(n
);
529 static void parse_placement(xmlNodePtr node
, gpointer d
)
533 node
= node
->children
;
535 if ((n
= obt_xml_find_node(node
, "policy")))
536 if (obt_xml_node_contains(n
, "UnderMouse"))
537 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
538 if ((n
= obt_xml_find_node(node
, "center")))
539 config_place_center
= obt_xml_node_bool(n
);
540 if ((n
= obt_xml_find_node(node
, "monitor"))) {
541 if (obt_xml_node_contains(n
, "active"))
542 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
543 else if (obt_xml_node_contains(n
, "mouse"))
544 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
546 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
547 config_primary_monitor_index
= obt_xml_node_int(n
);
548 if (!config_primary_monitor_index
) {
549 if (obt_xml_node_contains(n
, "mouse"))
550 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
555 static void parse_margins(xmlNodePtr node
, gpointer d
)
559 node
= node
->children
;
561 if ((n
= obt_xml_find_node(node
, "top")))
562 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
563 if ((n
= obt_xml_find_node(node
, "left")))
564 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
565 if ((n
= obt_xml_find_node(node
, "right")))
566 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
567 if ((n
= obt_xml_find_node(node
, "bottom")))
568 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
571 static void parse_theme(xmlNodePtr node
, gpointer d
)
575 node
= node
->children
;
577 if ((n
= obt_xml_find_node(node
, "name"))) {
580 g_free(config_theme
);
581 c
= obt_xml_node_string(n
);
582 config_theme
= obt_paths_expand_tilde(c
);
585 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
588 g_free(config_title_layout
);
589 config_title_layout
= obt_xml_node_string(n
);
591 /* replace duplicates with spaces */
592 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
593 for (d
= c
+1; *d
!= '\0'; ++d
)
594 if (*c
== *d
) *d
= ' ';
596 if ((n
= obt_xml_find_node(node
, "keepBorder")))
597 config_theme_keepborder
= obt_xml_node_bool(n
);
598 if ((n
= obt_xml_find_node(node
, "animateIconify")))
599 config_animate_iconify
= obt_xml_node_bool(n
);
600 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
601 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
602 if (config_theme_window_list_icon_size
< 16)
603 config_theme_window_list_icon_size
= 16;
604 else if (config_theme_window_list_icon_size
> 96)
605 config_theme_window_list_icon_size
= 96;
608 n
= obt_xml_find_node(node
, "font");
612 gchar
*name
= g_strdup(RrDefaultFontFamily
);
613 gint size
= RrDefaultFontSize
;
614 RrFontWeight weight
= RrDefaultFontWeight
;
615 RrFontSlant slant
= RrDefaultFontSlant
;
617 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
618 font
= &config_font_activewindow
;
619 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
620 font
= &config_font_inactivewindow
;
621 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
622 font
= &config_font_menutitle
;
623 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
624 font
= &config_font_menuitem
;
625 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
626 font
= &config_font_activeosd
;
627 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
628 font
= &config_font_activeosd
;
629 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
630 font
= &config_font_inactiveosd
;
634 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
636 name
= obt_xml_node_string(fnode
);
638 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
639 int s
= obt_xml_node_int(fnode
);
642 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
643 gchar
*w
= obt_xml_node_string(fnode
);
644 if (!g_ascii_strcasecmp(w
, "Bold"))
645 weight
= RR_FONTWEIGHT_BOLD
;
648 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
649 gchar
*s
= obt_xml_node_string(fnode
);
650 if (!g_ascii_strcasecmp(s
, "Italic"))
651 slant
= RR_FONTSLANT_ITALIC
;
652 if (!g_ascii_strcasecmp(s
, "Oblique"))
653 slant
= RR_FONTSLANT_OBLIQUE
;
657 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
660 n
= obt_xml_find_node(n
->next
, "font");
664 static void parse_desktops(xmlNodePtr node
, gpointer d
)
668 node
= node
->children
;
670 if ((n
= obt_xml_find_node(node
, "number"))) {
671 gint d
= obt_xml_node_int(n
);
673 config_desktops_num
= (unsigned) d
;
675 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
676 gint d
= obt_xml_node_int(n
);
678 config_screen_firstdesk
= (unsigned) d
;
680 if ((n
= obt_xml_find_node(node
, "names"))) {
684 for (it
= config_desktops_names
; it
; it
= it
->next
)
686 g_slist_free(config_desktops_names
);
687 config_desktops_names
= NULL
;
689 nname
= obt_xml_find_node(n
->children
, "name");
691 config_desktops_names
=
692 g_slist_append(config_desktops_names
,
693 obt_xml_node_string(nname
));
694 nname
= obt_xml_find_node(nname
->next
, "name");
697 if ((n
= obt_xml_find_node(node
, "popupTime")))
698 config_desktop_popup_time
= obt_xml_node_int(n
);
701 static void parse_resize(xmlNodePtr node
, gpointer d
)
705 node
= node
->children
;
707 if ((n
= obt_xml_find_node(node
, "drawContents")))
708 config_resize_redraw
= obt_xml_node_bool(n
);
709 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
710 config_resize_popup_show
= obt_xml_node_int(n
);
711 if (obt_xml_node_contains(n
, "Always"))
712 config_resize_popup_show
= 2;
713 else if (obt_xml_node_contains(n
, "Never"))
714 config_resize_popup_show
= 0;
715 else if (obt_xml_node_contains(n
, "Nonpixel"))
716 config_resize_popup_show
= 1;
718 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
719 if (obt_xml_node_contains(n
, "Top"))
720 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
721 else if (obt_xml_node_contains(n
, "Center"))
722 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
723 else if (obt_xml_node_contains(n
, "Fixed")) {
724 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
726 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
729 if ((n2
= obt_xml_find_node(n
->children
, "x")))
730 config_parse_gravity_coord(n2
,
731 &config_resize_popup_fixed
.x
);
732 if ((n2
= obt_xml_find_node(n
->children
, "y")))
733 config_parse_gravity_coord(n2
,
734 &config_resize_popup_fixed
.y
);
736 config_resize_popup_fixed
.x
.pos
=
737 MAX(config_resize_popup_fixed
.x
.pos
, 0);
738 config_resize_popup_fixed
.y
.pos
=
739 MAX(config_resize_popup_fixed
.y
.pos
, 0);
745 static void parse_dock(xmlNodePtr node
, gpointer d
)
749 node
= node
->children
;
751 if ((n
= obt_xml_find_node(node
, "position"))) {
752 if (obt_xml_node_contains(n
, "TopLeft"))
753 config_dock_floating
= FALSE
,
754 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
755 else if (obt_xml_node_contains(n
, "Top"))
756 config_dock_floating
= FALSE
,
757 config_dock_pos
= OB_DIRECTION_NORTH
;
758 else if (obt_xml_node_contains(n
, "TopRight"))
759 config_dock_floating
= FALSE
,
760 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
761 else if (obt_xml_node_contains(n
, "Right"))
762 config_dock_floating
= FALSE
,
763 config_dock_pos
= OB_DIRECTION_EAST
;
764 else if (obt_xml_node_contains(n
, "BottomRight"))
765 config_dock_floating
= FALSE
,
766 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
767 else if (obt_xml_node_contains(n
, "Bottom"))
768 config_dock_floating
= FALSE
,
769 config_dock_pos
= OB_DIRECTION_SOUTH
;
770 else if (obt_xml_node_contains(n
, "BottomLeft"))
771 config_dock_floating
= FALSE
,
772 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
773 else if (obt_xml_node_contains(n
, "Left"))
774 config_dock_floating
= FALSE
,
775 config_dock_pos
= OB_DIRECTION_WEST
;
776 else if (obt_xml_node_contains(n
, "Floating"))
777 config_dock_floating
= TRUE
;
779 if (config_dock_floating
) {
780 if ((n
= obt_xml_find_node(node
, "floatingX")))
781 config_dock_x
= obt_xml_node_int(n
);
782 if ((n
= obt_xml_find_node(node
, "floatingY")))
783 config_dock_y
= obt_xml_node_int(n
);
785 if ((n
= obt_xml_find_node(node
, "noStrut")))
786 config_dock_nostrut
= obt_xml_node_bool(n
);
788 if ((n
= obt_xml_find_node(node
, "stacking"))) {
789 if (obt_xml_node_contains(n
, "normal"))
790 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
791 else if (obt_xml_node_contains(n
, "below"))
792 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
793 else if (obt_xml_node_contains(n
, "above"))
794 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
796 if ((n
= obt_xml_find_node(node
, "direction"))) {
797 if (obt_xml_node_contains(n
, "horizontal"))
798 config_dock_orient
= OB_ORIENTATION_HORZ
;
799 else if (obt_xml_node_contains(n
, "vertical"))
800 config_dock_orient
= OB_ORIENTATION_VERT
;
802 if ((n
= obt_xml_find_node(node
, "autoHide")))
803 config_dock_hide
= obt_xml_node_bool(n
);
804 if ((n
= obt_xml_find_node(node
, "hideDelay")))
805 config_dock_hide_delay
= obt_xml_node_int(n
);
806 if ((n
= obt_xml_find_node(node
, "showDelay")))
807 config_dock_show_delay
= obt_xml_node_int(n
);
808 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
809 gchar
*str
= obt_xml_node_string(n
);
811 if (translate_button(str
, &s
, &b
)) {
812 config_dock_app_move_button
= b
;
813 config_dock_app_move_modifiers
= s
;
815 g_message(_("Invalid button \"%s\" specified in config file"), str
);
821 static void parse_menu(xmlNodePtr node
, gpointer d
)
824 node
= node
->children
;
826 if ((n
= obt_xml_find_node(node
, "hideDelay")))
827 config_menu_hide_delay
= obt_xml_node_int(n
);
828 if ((n
= obt_xml_find_node(node
, "middle")))
829 config_menu_middle
= obt_xml_node_bool(n
);
830 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
831 config_submenu_show_delay
= obt_xml_node_int(n
);
832 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
833 config_submenu_hide_delay
= obt_xml_node_int(n
);
834 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
835 config_menu_manage_desktops
= obt_xml_node_bool(n
);
836 if ((n
= obt_xml_find_node(node
, "showIcons"))) {
837 config_menu_show_icons
= obt_xml_node_bool(n
);
839 if (config_menu_show_icons
)
840 g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
844 while ((node
= obt_xml_find_node(node
, "file"))) {
845 gchar
*c
= obt_xml_node_string(node
);
846 config_menu_files
= g_slist_append(config_menu_files
,
847 obt_paths_expand_tilde(c
));
853 static void parse_resistance(xmlNodePtr node
, gpointer d
)
857 node
= node
->children
;
858 if ((n
= obt_xml_find_node(node
, "strength")))
859 config_resist_win
= obt_xml_node_int(n
);
860 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
861 config_resist_edge
= obt_xml_node_int(n
);
867 const gchar
*actname
;
870 static void bind_default_keyboard(void)
873 ObDefKeyBind binds
[] = {
874 { "A-Tab", "NextWindow" },
875 { "S-A-Tab", "PreviousWindow" },
879 for (it
= binds
; it
->key
; ++it
) {
880 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
881 keyboard_bind(l
, actions_parse_string(it
->actname
));
888 const gchar
*context
;
889 const ObMouseAction mact
;
890 const gchar
*actname
;
893 static void bind_default_mouse(void)
896 ObDefMouseBind binds
[] = {
897 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
898 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
899 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
900 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
901 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
902 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
903 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
904 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
905 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
906 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
907 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
908 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
909 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
910 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
911 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
912 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
913 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
914 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
915 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
916 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
917 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
918 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
919 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
920 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
921 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
922 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
923 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
924 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
925 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
926 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
927 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
928 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
929 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
930 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
931 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
932 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
933 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
934 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
935 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
936 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
937 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
938 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
939 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
940 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
941 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
942 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
943 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
944 { NULL
, NULL
, 0, NULL
}
947 for (it
= binds
; it
->button
; ++it
)
948 mouse_bind(it
->button
, it
->context
, it
->mact
,
949 actions_parse_string(it
->actname
));
952 void config_startup(ObtXmlInst
*i
)
954 config_focus_new
= TRUE
;
955 config_focus_follow
= FALSE
;
956 config_focus_delay
= 0;
957 config_focus_raise
= FALSE
;
958 config_focus_last
= TRUE
;
959 config_focus_under_mouse
= FALSE
;
960 config_unfocus_leave
= FALSE
;
962 obt_xml_register(i
, "focus", parse_focus
, NULL
);
964 config_place_policy
= OB_PLACE_POLICY_SMART
;
965 config_place_center
= TRUE
;
966 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
968 config_primary_monitor_index
= 1;
969 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
971 obt_xml_register(i
, "placement", parse_placement
, NULL
);
973 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
975 obt_xml_register(i
, "margins", parse_margins
, NULL
);
979 config_animate_iconify
= TRUE
;
980 config_title_layout
= g_strdup("NLIMC");
981 config_theme_keepborder
= TRUE
;
982 config_theme_window_list_icon_size
= 36;
984 config_font_activewindow
= NULL
;
985 config_font_inactivewindow
= NULL
;
986 config_font_menuitem
= NULL
;
987 config_font_menutitle
= NULL
;
988 config_font_activeosd
= NULL
;
989 config_font_inactiveosd
= NULL
;
991 obt_xml_register(i
, "theme", parse_theme
, NULL
);
993 config_desktops_num
= 4;
994 config_screen_firstdesk
= 1;
995 config_desktops_names
= NULL
;
996 config_desktop_popup_time
= 875;
998 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
1000 config_resize_redraw
= TRUE
;
1001 config_resize_popup_show
= 1; /* nonpixel increments */
1002 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
1003 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
1004 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
1006 obt_xml_register(i
, "resize", parse_resize
, NULL
);
1008 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
1009 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
1010 config_dock_floating
= FALSE
;
1011 config_dock_nostrut
= FALSE
;
1014 config_dock_orient
= OB_ORIENTATION_VERT
;
1015 config_dock_hide
= FALSE
;
1016 config_dock_hide_delay
= 300;
1017 config_dock_show_delay
= 300;
1018 config_dock_app_move_button
= 2; /* middle */
1019 config_dock_app_move_modifiers
= 0;
1021 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1023 translate_key("C-g", &config_keyboard_reset_state
,
1024 &config_keyboard_reset_keycode
);
1026 bind_default_keyboard();
1028 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1030 config_mouse_threshold
= 8;
1031 config_mouse_dclicktime
= 200;
1032 config_mouse_screenedgetime
= 400;
1034 bind_default_mouse();
1036 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1038 config_resist_win
= 10;
1039 config_resist_edge
= 20;
1041 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1043 config_menu_hide_delay
= 250;
1044 config_menu_middle
= FALSE
;
1045 config_submenu_show_delay
= 100;
1046 config_submenu_hide_delay
= 400;
1047 config_menu_manage_desktops
= TRUE
;
1048 config_menu_files
= NULL
;
1049 config_menu_show_icons
= TRUE
;
1051 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1053 config_per_app_settings
= NULL
;
1055 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1058 void config_shutdown(void)
1062 g_free(config_theme
);
1064 g_free(config_title_layout
);
1066 RrFontClose(config_font_activewindow
);
1067 RrFontClose(config_font_inactivewindow
);
1068 RrFontClose(config_font_menuitem
);
1069 RrFontClose(config_font_menutitle
);
1070 RrFontClose(config_font_activeosd
);
1071 RrFontClose(config_font_inactiveosd
);
1073 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1075 g_slist_free(config_desktops_names
);
1077 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1079 g_slist_free(config_menu_files
);
1081 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1082 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1083 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1084 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1085 if (itd
->title
) g_pattern_spec_free(itd
->title
);
1086 if (itd
->class) g_pattern_spec_free(itd
->class);
1087 g_slice_free(ObAppSettings
, it
->data
);
1089 g_slist_free(config_per_app_settings
);