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
;
92 gboolean config_mouse_screenedgewarp
;
94 guint config_menu_hide_delay
;
95 gboolean config_menu_middle
;
96 guint config_submenu_show_delay
;
97 guint config_submenu_hide_delay
;
98 gboolean config_menu_manage_desktops
;
99 gboolean config_menu_show_icons
;
101 GSList
*config_menu_files
;
103 gint config_resist_win
;
104 gint config_resist_edge
;
106 GSList
*config_per_app_settings
;
108 ObAppSettings
* config_create_app_settings(void)
110 ObAppSettings
*settings
= g_slice_new0(ObAppSettings
);
112 settings
->decor
= -1;
113 settings
->shade
= -1;
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
, -1);
143 copy_if(skip_pager
, -1);
144 copy_if(skip_taskbar
, -1);
145 copy_if(fullscreen
, -1);
146 copy_if(max_horz
, -1);
147 copy_if(max_vert
, -1);
149 if (src
->pos_given
) {
150 dst
->pos_given
= TRUE
;
151 dst
->pos_force
= src
->pos_force
;
152 dst
->position
= src
->position
;
153 /* monitor is copied above */
157 void config_parse_relative_number(gchar
*s
, gint
*num
, gint
*denom
)
159 *num
= strtol(s
, &s
, 10);
163 } else if (*s
== '/') {
168 void config_parse_gravity_coord(xmlNodePtr node
, GravityCoord
*c
)
170 gchar
*s
= obt_xml_node_string(node
);
171 if (!g_ascii_strcasecmp(s
, "center"))
177 if (s
[0] == '-' || s
[0] == '+')
179 config_parse_relative_number(ps
, &c
->pos
, &c
->denom
);
186 <application name="aterm">
189 <application name="Rhythmbox">
196 .. there is a lot more settings available
201 /* Manages settings for individual applications.
202 Some notes: monitor is the screen number in a multi monitor
203 (Xinerama) setup (starting from 0) or mouse, meaning the
204 monitor the pointer is on. Default: mouse.
205 Layer can be three values, above (Always on top), below
206 (Always on bottom) and everything else (normal behaviour).
207 Positions can be an integer value or center, which will
208 center the window in the specified axis. Position is within
209 the monitor, so <position><x>center</x></position><monitor>2</monitor>
210 will center the window on the second monitor.
212 static void parse_per_app_settings(xmlNodePtr node
, gpointer d
)
214 xmlNodePtr app
= obt_xml_find_node(node
->children
, "application");
215 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *title
= NULL
,
217 gboolean name_set
, class_set
, type_set
, role_set
, title_set
;
219 gboolean x_pos_given
;
224 class_set
= obt_xml_attr_string(app
, "class", &class);
225 name_set
= obt_xml_attr_string(app
, "name", &name
);
226 type_set
= obt_xml_attr_string(app
, "type", &type_str
);
227 role_set
= obt_xml_attr_string(app
, "role", &role
);
228 title_set
= obt_xml_attr_string(app
, "title", &title
);
230 /* validate the type tho */
232 if (!g_ascii_strcasecmp(type_str
, "normal"))
233 type
= OB_CLIENT_TYPE_NORMAL
;
234 else if (!g_ascii_strcasecmp(type_str
, "dialog"))
235 type
= OB_CLIENT_TYPE_DIALOG
;
236 else if (!g_ascii_strcasecmp(type_str
, "splash"))
237 type
= OB_CLIENT_TYPE_SPLASH
;
238 else if (!g_ascii_strcasecmp(type_str
, "utility"))
239 type
= OB_CLIENT_TYPE_UTILITY
;
240 else if (!g_ascii_strcasecmp(type_str
, "menu"))
241 type
= OB_CLIENT_TYPE_MENU
;
242 else if (!g_ascii_strcasecmp(type_str
, "toolbar"))
243 type
= OB_CLIENT_TYPE_TOOLBAR
;
244 else if (!g_ascii_strcasecmp(type_str
, "dock"))
245 type
= OB_CLIENT_TYPE_DOCK
;
246 else if (!g_ascii_strcasecmp(type_str
, "desktop"))
247 type
= OB_CLIENT_TYPE_DESKTOP
;
249 type_set
= FALSE
; /* not valid! */
252 if (class_set
|| name_set
|| role_set
|| title_set
|| type_set
) {
254 ObAppSettings
*settings
= config_create_app_settings();
257 settings
->name
= g_pattern_spec_new(name
);
260 settings
->class = g_pattern_spec_new(class);
263 settings
->role
= g_pattern_spec_new(role
);
266 settings
->title
= g_pattern_spec_new(title
);
269 settings
->type
= type
;
271 if ((n
= obt_xml_find_node(app
->children
, "decor")))
272 if (!obt_xml_node_contains(n
, "default"))
273 settings
->decor
= obt_xml_node_bool(n
);
275 if ((n
= obt_xml_find_node(app
->children
, "shade")))
276 if (!obt_xml_node_contains(n
, "default"))
277 settings
->shade
= obt_xml_node_bool(n
);
279 if ((n
= obt_xml_find_node(app
->children
, "position"))) {
280 if ((c
= obt_xml_find_node(n
->children
, "x")))
281 if (!obt_xml_node_contains(c
, "default")) {
282 config_parse_gravity_coord(c
, &settings
->position
.x
);
286 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y")))
287 if (!obt_xml_node_contains(c
, "default")) {
288 config_parse_gravity_coord(c
, &settings
->position
.y
);
289 settings
->pos_given
= TRUE
;
292 if (settings
->pos_given
&&
293 (c
= obt_xml_find_node(n
->children
, "monitor")))
294 if (!obt_xml_node_contains(c
, "default")) {
295 gchar
*s
= obt_xml_node_string(c
);
296 if (!g_ascii_strcasecmp(s
, "mouse"))
297 settings
->monitor
= 0;
299 settings
->monitor
= obt_xml_node_int(c
);
303 obt_xml_attr_bool(n
, "force", &settings
->pos_force
);
306 if ((n
= obt_xml_find_node(app
->children
, "focus")))
307 if (!obt_xml_node_contains(n
, "default"))
308 settings
->focus
= obt_xml_node_bool(n
);
310 if ((n
= obt_xml_find_node(app
->children
, "desktop"))) {
311 if (!obt_xml_node_contains(n
, "default")) {
312 gchar
*s
= obt_xml_node_string(n
);
313 if (!g_ascii_strcasecmp(s
, "all"))
314 settings
->desktop
= DESKTOP_ALL
;
316 gint i
= obt_xml_node_int(n
);
318 settings
->desktop
= i
;
324 if ((n
= obt_xml_find_node(app
->children
, "layer")))
325 if (!obt_xml_node_contains(n
, "default")) {
326 gchar
*s
= obt_xml_node_string(n
);
327 if (!g_ascii_strcasecmp(s
, "above"))
329 else if (!g_ascii_strcasecmp(s
, "below"))
330 settings
->layer
= -1;
336 if ((n
= obt_xml_find_node(app
->children
, "iconic")))
337 if (!obt_xml_node_contains(n
, "default"))
338 settings
->iconic
= obt_xml_node_bool(n
);
340 if ((n
= obt_xml_find_node(app
->children
, "skip_pager")))
341 if (!obt_xml_node_contains(n
, "default"))
342 settings
->skip_pager
= obt_xml_node_bool(n
);
344 if ((n
= obt_xml_find_node(app
->children
, "skip_taskbar")))
345 if (!obt_xml_node_contains(n
, "default"))
346 settings
->skip_taskbar
= obt_xml_node_bool(n
);
348 if ((n
= obt_xml_find_node(app
->children
, "fullscreen")))
349 if (!obt_xml_node_contains(n
, "default"))
350 settings
->fullscreen
= obt_xml_node_bool(n
);
352 if ((n
= obt_xml_find_node(app
->children
, "maximized")))
353 if (!obt_xml_node_contains(n
, "default")) {
354 gchar
*s
= obt_xml_node_string(n
);
355 if (!g_ascii_strcasecmp(s
, "horizontal")) {
356 settings
->max_horz
= TRUE
;
357 settings
->max_vert
= FALSE
;
358 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
359 settings
->max_horz
= FALSE
;
360 settings
->max_vert
= TRUE
;
362 settings
->max_horz
= settings
->max_vert
=
363 obt_xml_node_bool(n
);
367 config_per_app_settings
= g_slist_append(config_per_app_settings
,
368 (gpointer
) settings
);
373 name
= class = role
= title
= NULL
;
376 app
= obt_xml_find_node(app
->next
, "application");
383 <action name="ChangeDesktop">
390 static void parse_key(xmlNodePtr node
, GList
*keylist
)
394 gboolean is_chroot
= FALSE
;
396 if (!obt_xml_attr_string(node
, "key", &key
))
399 obt_xml_attr_bool(node
, "chroot", &is_chroot
);
401 keylist
= g_list_append(keylist
, key
);
403 if ((n
= obt_xml_find_node(node
->children
, "keybind"))) {
405 parse_key(n
, keylist
);
406 n
= obt_xml_find_node(n
->next
, "keybind");
409 else if ((n
= obt_xml_find_node(node
->children
, "action"))) {
411 ObActionsAct
*action
;
413 action
= actions_parse(n
);
415 keyboard_bind(keylist
, action
);
416 n
= obt_xml_find_node(n
->next
, "action");
421 keyboard_chroot(keylist
);
424 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
427 static void parse_keyboard(xmlNodePtr node
, gpointer d
)
432 keyboard_unbind_all();
434 if ((n
= obt_xml_find_node(node
->children
, "chainQuitKey"))) {
435 key
= obt_xml_node_string(n
);
436 translate_key(key
, &config_keyboard_reset_state
,
437 &config_keyboard_reset_keycode
);
441 if ((n
= obt_xml_find_node(node
->children
, "keybind")))
444 n
= obt_xml_find_node(n
->next
, "keybind");
450 <context name="Titlebar">
451 <mousebind button="Left" action="Press">
452 <action name="Raise"></action>
458 static void parse_mouse(xmlNodePtr node
, gpointer d
)
460 xmlNodePtr n
, nbut
, nact
;
467 node
= node
->children
;
469 if ((n
= obt_xml_find_node(node
, "dragThreshold")))
470 config_mouse_threshold
= obt_xml_node_int(n
);
471 if ((n
= obt_xml_find_node(node
, "doubleClickTime")))
472 config_mouse_dclicktime
= obt_xml_node_int(n
);
473 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpTime"))) {
474 config_mouse_screenedgetime
= obt_xml_node_int(n
);
475 /* minimum value of 25 for this property, when it is 1 and you hit the
476 edge it basically never stops */
477 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
478 config_mouse_screenedgetime
= 25;
480 if ((n
= obt_xml_find_node(node
, "screenEdgeWarpMouse")))
481 config_mouse_screenedgewarp
= obt_xml_node_bool(n
);
483 n
= obt_xml_find_node(node
, "context");
485 if (!obt_xml_attr_string(n
, "name", &contextstr
))
487 nbut
= obt_xml_find_node(n
->children
, "mousebind");
489 if (!obt_xml_attr_string(nbut
, "button", &buttonstr
))
491 if (obt_xml_attr_contains(nbut
, "action", "press")) {
492 mact
= OB_MOUSE_ACTION_PRESS
;
493 } else if (obt_xml_attr_contains(nbut
, "action", "release")) {
494 mact
= OB_MOUSE_ACTION_RELEASE
;
495 } else if (obt_xml_attr_contains(nbut
, "action", "click")) {
496 mact
= OB_MOUSE_ACTION_CLICK
;
497 } else if (obt_xml_attr_contains(nbut
, "action","doubleclick")) {
498 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
499 } else if (obt_xml_attr_contains(nbut
, "action", "drag")) {
500 mact
= OB_MOUSE_ACTION_MOTION
;
503 nact
= obt_xml_find_node(nbut
->children
, "action");
505 ObActionsAct
*action
;
507 if ((action
= actions_parse(nact
)))
508 mouse_bind(buttonstr
, contextstr
, mact
, action
);
509 nact
= obt_xml_find_node(nact
->next
, "action");
513 nbut
= obt_xml_find_node(nbut
->next
, "mousebind");
517 n
= obt_xml_find_node(n
->next
, "context");
521 static void parse_focus(xmlNodePtr node
, gpointer d
)
525 node
= node
->children
;
527 if ((n
= obt_xml_find_node(node
, "focusNew")))
528 config_focus_new
= obt_xml_node_bool(n
);
529 if ((n
= obt_xml_find_node(node
, "followMouse")))
530 config_focus_follow
= obt_xml_node_bool(n
);
531 if ((n
= obt_xml_find_node(node
, "focusDelay")))
532 config_focus_delay
= obt_xml_node_int(n
);
533 if ((n
= obt_xml_find_node(node
, "raiseOnFocus")))
534 config_focus_raise
= obt_xml_node_bool(n
);
535 if ((n
= obt_xml_find_node(node
, "focusLast")))
536 config_focus_last
= obt_xml_node_bool(n
);
537 if ((n
= obt_xml_find_node(node
, "underMouse")))
538 config_focus_under_mouse
= obt_xml_node_bool(n
);
539 if ((n
= obt_xml_find_node(node
, "unfocusOnLeave")))
540 config_unfocus_leave
= obt_xml_node_bool(n
);
543 static void parse_placement(xmlNodePtr node
, gpointer d
)
547 node
= node
->children
;
549 if ((n
= obt_xml_find_node(node
, "policy")))
550 if (obt_xml_node_contains(n
, "UnderMouse"))
551 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
552 if ((n
= obt_xml_find_node(node
, "center")))
553 config_place_center
= obt_xml_node_bool(n
);
554 if ((n
= obt_xml_find_node(node
, "monitor"))) {
555 if (obt_xml_node_contains(n
, "active"))
556 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
557 else if (obt_xml_node_contains(n
, "mouse"))
558 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
560 if ((n
= obt_xml_find_node(node
, "primaryMonitor"))) {
561 config_primary_monitor_index
= obt_xml_node_int(n
);
562 if (!config_primary_monitor_index
) {
563 if (obt_xml_node_contains(n
, "mouse"))
564 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
569 static void parse_margins(xmlNodePtr node
, gpointer d
)
573 node
= node
->children
;
575 if ((n
= obt_xml_find_node(node
, "top")))
576 config_margins
.top
= MAX(0, obt_xml_node_int(n
));
577 if ((n
= obt_xml_find_node(node
, "left")))
578 config_margins
.left
= MAX(0, obt_xml_node_int(n
));
579 if ((n
= obt_xml_find_node(node
, "right")))
580 config_margins
.right
= MAX(0, obt_xml_node_int(n
));
581 if ((n
= obt_xml_find_node(node
, "bottom")))
582 config_margins
.bottom
= MAX(0, obt_xml_node_int(n
));
585 static void parse_theme(xmlNodePtr node
, gpointer d
)
589 node
= node
->children
;
591 if ((n
= obt_xml_find_node(node
, "name"))) {
594 g_free(config_theme
);
595 c
= obt_xml_node_string(n
);
596 config_theme
= obt_paths_expand_tilde(c
);
599 if ((n
= obt_xml_find_node(node
, "titleLayout"))) {
602 g_free(config_title_layout
);
603 config_title_layout
= obt_xml_node_string(n
);
605 /* replace duplicates with spaces */
606 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
607 for (d
= c
+1; *d
!= '\0'; ++d
)
608 if (*c
== *d
) *d
= ' ';
610 if ((n
= obt_xml_find_node(node
, "keepBorder")))
611 config_theme_keepborder
= obt_xml_node_bool(n
);
612 if ((n
= obt_xml_find_node(node
, "animateIconify")))
613 config_animate_iconify
= obt_xml_node_bool(n
);
614 if ((n
= obt_xml_find_node(node
, "windowListIconSize"))) {
615 config_theme_window_list_icon_size
= obt_xml_node_int(n
);
616 if (config_theme_window_list_icon_size
< 16)
617 config_theme_window_list_icon_size
= 16;
618 else if (config_theme_window_list_icon_size
> 96)
619 config_theme_window_list_icon_size
= 96;
622 n
= obt_xml_find_node(node
, "font");
626 gchar
*name
= g_strdup(RrDefaultFontFamily
);
627 gint size
= RrDefaultFontSize
;
628 RrFontWeight weight
= RrDefaultFontWeight
;
629 RrFontSlant slant
= RrDefaultFontSlant
;
631 if (obt_xml_attr_contains(n
, "place", "ActiveWindow"))
632 font
= &config_font_activewindow
;
633 else if (obt_xml_attr_contains(n
, "place", "InactiveWindow"))
634 font
= &config_font_inactivewindow
;
635 else if (obt_xml_attr_contains(n
, "place", "MenuHeader"))
636 font
= &config_font_menutitle
;
637 else if (obt_xml_attr_contains(n
, "place", "MenuItem"))
638 font
= &config_font_menuitem
;
639 else if (obt_xml_attr_contains(n
, "place", "ActiveOnScreenDisplay"))
640 font
= &config_font_activeosd
;
641 else if (obt_xml_attr_contains(n
, "place", "OnScreenDisplay"))
642 font
= &config_font_activeosd
;
643 else if (obt_xml_attr_contains(n
, "place","InactiveOnScreenDisplay"))
644 font
= &config_font_inactiveosd
;
648 if ((fnode
= obt_xml_find_node(n
->children
, "name"))) {
650 name
= obt_xml_node_string(fnode
);
652 if ((fnode
= obt_xml_find_node(n
->children
, "size"))) {
653 int s
= obt_xml_node_int(fnode
);
656 if ((fnode
= obt_xml_find_node(n
->children
, "weight"))) {
657 gchar
*w
= obt_xml_node_string(fnode
);
658 if (!g_ascii_strcasecmp(w
, "Bold"))
659 weight
= RR_FONTWEIGHT_BOLD
;
662 if ((fnode
= obt_xml_find_node(n
->children
, "slant"))) {
663 gchar
*s
= obt_xml_node_string(fnode
);
664 if (!g_ascii_strcasecmp(s
, "Italic"))
665 slant
= RR_FONTSLANT_ITALIC
;
666 if (!g_ascii_strcasecmp(s
, "Oblique"))
667 slant
= RR_FONTSLANT_OBLIQUE
;
671 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
674 n
= obt_xml_find_node(n
->next
, "font");
678 static void parse_desktops(xmlNodePtr node
, gpointer d
)
682 node
= node
->children
;
684 if ((n
= obt_xml_find_node(node
, "number"))) {
685 gint d
= obt_xml_node_int(n
);
687 config_desktops_num
= (unsigned) d
;
689 if ((n
= obt_xml_find_node(node
, "firstdesk"))) {
690 gint d
= obt_xml_node_int(n
);
692 config_screen_firstdesk
= (unsigned) d
;
694 if ((n
= obt_xml_find_node(node
, "names"))) {
698 for (it
= config_desktops_names
; it
; it
= it
->next
)
700 g_slist_free(config_desktops_names
);
701 config_desktops_names
= NULL
;
703 nname
= obt_xml_find_node(n
->children
, "name");
705 config_desktops_names
=
706 g_slist_append(config_desktops_names
,
707 obt_xml_node_string(nname
));
708 nname
= obt_xml_find_node(nname
->next
, "name");
711 if ((n
= obt_xml_find_node(node
, "popupTime")))
712 config_desktop_popup_time
= obt_xml_node_int(n
);
715 static void parse_resize(xmlNodePtr node
, gpointer d
)
719 node
= node
->children
;
721 if ((n
= obt_xml_find_node(node
, "drawContents")))
722 config_resize_redraw
= obt_xml_node_bool(n
);
723 if ((n
= obt_xml_find_node(node
, "popupShow"))) {
724 config_resize_popup_show
= obt_xml_node_int(n
);
725 if (obt_xml_node_contains(n
, "Always"))
726 config_resize_popup_show
= 2;
727 else if (obt_xml_node_contains(n
, "Never"))
728 config_resize_popup_show
= 0;
729 else if (obt_xml_node_contains(n
, "Nonpixel"))
730 config_resize_popup_show
= 1;
732 if ((n
= obt_xml_find_node(node
, "popupPosition"))) {
733 if (obt_xml_node_contains(n
, "Top"))
734 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
735 else if (obt_xml_node_contains(n
, "Center"))
736 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
737 else if (obt_xml_node_contains(n
, "Fixed")) {
738 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
740 if ((n
= obt_xml_find_node(node
, "popupFixedPosition"))) {
743 if ((n2
= obt_xml_find_node(n
->children
, "x")))
744 config_parse_gravity_coord(n2
,
745 &config_resize_popup_fixed
.x
);
746 if ((n2
= obt_xml_find_node(n
->children
, "y")))
747 config_parse_gravity_coord(n2
,
748 &config_resize_popup_fixed
.y
);
750 config_resize_popup_fixed
.x
.pos
=
751 MAX(config_resize_popup_fixed
.x
.pos
, 0);
752 config_resize_popup_fixed
.y
.pos
=
753 MAX(config_resize_popup_fixed
.y
.pos
, 0);
759 static void parse_dock(xmlNodePtr node
, gpointer d
)
763 node
= node
->children
;
765 if ((n
= obt_xml_find_node(node
, "position"))) {
766 if (obt_xml_node_contains(n
, "TopLeft"))
767 config_dock_floating
= FALSE
,
768 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
769 else if (obt_xml_node_contains(n
, "Top"))
770 config_dock_floating
= FALSE
,
771 config_dock_pos
= OB_DIRECTION_NORTH
;
772 else if (obt_xml_node_contains(n
, "TopRight"))
773 config_dock_floating
= FALSE
,
774 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
775 else if (obt_xml_node_contains(n
, "Right"))
776 config_dock_floating
= FALSE
,
777 config_dock_pos
= OB_DIRECTION_EAST
;
778 else if (obt_xml_node_contains(n
, "BottomRight"))
779 config_dock_floating
= FALSE
,
780 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
781 else if (obt_xml_node_contains(n
, "Bottom"))
782 config_dock_floating
= FALSE
,
783 config_dock_pos
= OB_DIRECTION_SOUTH
;
784 else if (obt_xml_node_contains(n
, "BottomLeft"))
785 config_dock_floating
= FALSE
,
786 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
787 else if (obt_xml_node_contains(n
, "Left"))
788 config_dock_floating
= FALSE
,
789 config_dock_pos
= OB_DIRECTION_WEST
;
790 else if (obt_xml_node_contains(n
, "Floating"))
791 config_dock_floating
= TRUE
;
793 if (config_dock_floating
) {
794 if ((n
= obt_xml_find_node(node
, "floatingX")))
795 config_dock_x
= obt_xml_node_int(n
);
796 if ((n
= obt_xml_find_node(node
, "floatingY")))
797 config_dock_y
= obt_xml_node_int(n
);
799 if ((n
= obt_xml_find_node(node
, "noStrut")))
800 config_dock_nostrut
= obt_xml_node_bool(n
);
802 if ((n
= obt_xml_find_node(node
, "stacking"))) {
803 if (obt_xml_node_contains(n
, "normal"))
804 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
805 else if (obt_xml_node_contains(n
, "below"))
806 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
807 else if (obt_xml_node_contains(n
, "above"))
808 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
810 if ((n
= obt_xml_find_node(node
, "direction"))) {
811 if (obt_xml_node_contains(n
, "horizontal"))
812 config_dock_orient
= OB_ORIENTATION_HORZ
;
813 else if (obt_xml_node_contains(n
, "vertical"))
814 config_dock_orient
= OB_ORIENTATION_VERT
;
816 if ((n
= obt_xml_find_node(node
, "autoHide")))
817 config_dock_hide
= obt_xml_node_bool(n
);
818 if ((n
= obt_xml_find_node(node
, "hideDelay")))
819 config_dock_hide_delay
= obt_xml_node_int(n
);
820 if ((n
= obt_xml_find_node(node
, "showDelay")))
821 config_dock_show_delay
= obt_xml_node_int(n
);
822 if ((n
= obt_xml_find_node(node
, "moveButton"))) {
823 gchar
*str
= obt_xml_node_string(n
);
825 if (translate_button(str
, &s
, &b
)) {
826 config_dock_app_move_button
= b
;
827 config_dock_app_move_modifiers
= s
;
829 g_message(_("Invalid button \"%s\" specified in config file"), str
);
835 static void parse_menu(xmlNodePtr node
, gpointer d
)
838 node
= node
->children
;
840 if ((n
= obt_xml_find_node(node
, "hideDelay")))
841 config_menu_hide_delay
= obt_xml_node_int(n
);
842 if ((n
= obt_xml_find_node(node
, "middle")))
843 config_menu_middle
= obt_xml_node_bool(n
);
844 if ((n
= obt_xml_find_node(node
, "submenuShowDelay")))
845 config_submenu_show_delay
= obt_xml_node_int(n
);
846 if ((n
= obt_xml_find_node(node
, "submenuHideDelay")))
847 config_submenu_hide_delay
= obt_xml_node_int(n
);
848 if ((n
= obt_xml_find_node(node
, "manageDesktops")))
849 config_menu_manage_desktops
= obt_xml_node_bool(n
);
850 if ((n
= obt_xml_find_node(node
, "showIcons"))) {
851 config_menu_show_icons
= obt_xml_node_bool(n
);
853 if (config_menu_show_icons
)
854 g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
858 while ((node
= obt_xml_find_node(node
, "file"))) {
859 gchar
*c
= obt_xml_node_string(node
);
860 config_menu_files
= g_slist_append(config_menu_files
,
861 obt_paths_expand_tilde(c
));
867 static void parse_resistance(xmlNodePtr node
, gpointer d
)
871 node
= node
->children
;
872 if ((n
= obt_xml_find_node(node
, "strength")))
873 config_resist_win
= obt_xml_node_int(n
);
874 if ((n
= obt_xml_find_node(node
, "screen_edge_strength")))
875 config_resist_edge
= obt_xml_node_int(n
);
881 const gchar
*actname
;
884 static void bind_default_keyboard(void)
887 ObDefKeyBind binds
[] = {
888 { "A-Tab", "NextWindow" },
889 { "S-A-Tab", "PreviousWindow" },
893 for (it
= binds
; it
->key
; ++it
) {
894 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
895 keyboard_bind(l
, actions_parse_string(it
->actname
));
902 const gchar
*context
;
903 const ObMouseAction mact
;
904 const gchar
*actname
;
907 static void bind_default_mouse(void)
910 ObDefMouseBind binds
[] = {
911 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
912 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
913 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
914 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
915 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
916 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
917 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
918 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
919 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
920 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
921 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
922 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
923 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
924 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
925 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
926 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
927 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
928 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
929 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
930 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
931 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
932 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
933 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
934 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
935 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
936 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
937 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
938 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
939 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
940 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
941 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
942 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
943 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
944 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
945 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
946 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
947 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
948 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
949 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
950 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
951 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
952 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
953 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
954 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
955 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
956 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
957 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
958 { NULL
, NULL
, 0, NULL
}
961 for (it
= binds
; it
->button
; ++it
)
962 mouse_bind(it
->button
, it
->context
, it
->mact
,
963 actions_parse_string(it
->actname
));
966 void config_startup(ObtXmlInst
*i
)
968 config_focus_new
= TRUE
;
969 config_focus_follow
= FALSE
;
970 config_focus_delay
= 0;
971 config_focus_raise
= FALSE
;
972 config_focus_last
= TRUE
;
973 config_focus_under_mouse
= FALSE
;
974 config_unfocus_leave
= FALSE
;
976 obt_xml_register(i
, "focus", parse_focus
, NULL
);
978 config_place_policy
= OB_PLACE_POLICY_SMART
;
979 config_place_center
= TRUE
;
980 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
982 config_primary_monitor_index
= 1;
983 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
985 obt_xml_register(i
, "placement", parse_placement
, NULL
);
987 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
989 obt_xml_register(i
, "margins", parse_margins
, NULL
);
993 config_animate_iconify
= TRUE
;
994 config_title_layout
= g_strdup("NLIMC");
995 config_theme_keepborder
= TRUE
;
996 config_theme_window_list_icon_size
= 36;
998 config_font_activewindow
= NULL
;
999 config_font_inactivewindow
= NULL
;
1000 config_font_menuitem
= NULL
;
1001 config_font_menutitle
= NULL
;
1002 config_font_activeosd
= NULL
;
1003 config_font_inactiveosd
= NULL
;
1005 obt_xml_register(i
, "theme", parse_theme
, NULL
);
1007 config_desktops_num
= 4;
1008 config_screen_firstdesk
= 1;
1009 config_desktops_names
= NULL
;
1010 config_desktop_popup_time
= 875;
1012 obt_xml_register(i
, "desktops", parse_desktops
, NULL
);
1014 config_resize_redraw
= TRUE
;
1015 config_resize_popup_show
= 1; /* nonpixel increments */
1016 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
1017 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
1018 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
1020 obt_xml_register(i
, "resize", parse_resize
, NULL
);
1022 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
1023 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
1024 config_dock_floating
= FALSE
;
1025 config_dock_nostrut
= FALSE
;
1028 config_dock_orient
= OB_ORIENTATION_VERT
;
1029 config_dock_hide
= FALSE
;
1030 config_dock_hide_delay
= 300;
1031 config_dock_show_delay
= 300;
1032 config_dock_app_move_button
= 2; /* middle */
1033 config_dock_app_move_modifiers
= 0;
1035 obt_xml_register(i
, "dock", parse_dock
, NULL
);
1037 translate_key("C-g", &config_keyboard_reset_state
,
1038 &config_keyboard_reset_keycode
);
1040 bind_default_keyboard();
1042 obt_xml_register(i
, "keyboard", parse_keyboard
, NULL
);
1044 config_mouse_threshold
= 8;
1045 config_mouse_dclicktime
= 200;
1046 config_mouse_screenedgetime
= 400;
1047 config_mouse_screenedgewarp
= FALSE
;
1049 bind_default_mouse();
1051 obt_xml_register(i
, "mouse", parse_mouse
, NULL
);
1053 config_resist_win
= 10;
1054 config_resist_edge
= 20;
1056 obt_xml_register(i
, "resistance", parse_resistance
, NULL
);
1058 config_menu_hide_delay
= 250;
1059 config_menu_middle
= FALSE
;
1060 config_submenu_show_delay
= 100;
1061 config_submenu_hide_delay
= 400;
1062 config_menu_manage_desktops
= TRUE
;
1063 config_menu_files
= NULL
;
1064 config_menu_show_icons
= TRUE
;
1066 obt_xml_register(i
, "menu", parse_menu
, NULL
);
1068 config_per_app_settings
= NULL
;
1070 obt_xml_register(i
, "applications", parse_per_app_settings
, NULL
);
1073 void config_shutdown(void)
1077 g_free(config_theme
);
1079 g_free(config_title_layout
);
1081 RrFontClose(config_font_activewindow
);
1082 RrFontClose(config_font_inactivewindow
);
1083 RrFontClose(config_font_menuitem
);
1084 RrFontClose(config_font_menutitle
);
1085 RrFontClose(config_font_activeosd
);
1086 RrFontClose(config_font_inactiveosd
);
1088 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1090 g_slist_free(config_desktops_names
);
1092 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1094 g_slist_free(config_menu_files
);
1096 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1097 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1098 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1099 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1100 if (itd
->title
) g_pattern_spec_free(itd
->title
);
1101 if (itd
->class) g_pattern_spec_free(itd
->class);
1102 g_slice_free(ObAppSettings
, it
->data
);
1104 g_slist_free(config_per_app_settings
);