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.
25 #include "translate.h"
28 #include "parser/parse.h"
32 gboolean config_focus_new
;
33 gboolean config_focus_follow
;
34 guint config_focus_delay
;
35 gboolean config_focus_raise
;
36 gboolean config_focus_last
;
37 gboolean config_focus_under_mouse
;
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
;
51 gchar
*config_title_layout
;
53 gboolean config_animate_iconify
;
55 RrFont
*config_font_activewindow
;
56 RrFont
*config_font_inactivewindow
;
57 RrFont
*config_font_menuitem
;
58 RrFont
*config_font_menutitle
;
59 RrFont
*config_font_osd
;
61 guint config_desktops_num
;
62 GSList
*config_desktops_names
;
63 guint config_screen_firstdesk
;
64 guint config_desktop_popup_time
;
66 gboolean config_resize_redraw
;
67 gint config_resize_popup_show
;
68 ObResizePopupPos config_resize_popup_pos
;
69 GravityPoint config_resize_popup_fixed
;
71 ObStackingLayer config_dock_layer
;
72 gboolean config_dock_floating
;
73 gboolean config_dock_nostrut
;
74 ObDirection config_dock_pos
;
77 ObOrientation config_dock_orient
;
78 gboolean config_dock_hide
;
79 guint config_dock_hide_delay
;
80 guint config_dock_show_delay
;
81 guint config_dock_app_move_button
;
82 guint config_dock_app_move_modifiers
;
84 guint config_keyboard_reset_keycode
;
85 guint config_keyboard_reset_state
;
87 gint config_mouse_threshold
;
88 gint config_mouse_dclicktime
;
89 gint config_mouse_screenedgetime
;
91 guint config_menu_hide_delay
;
92 gboolean config_menu_middle
;
93 guint config_submenu_show_delay
;
94 gboolean config_menu_client_list_icons
;
95 gboolean config_menu_manage_desktops
;
97 GSList
*config_menu_files
;
99 gint config_resist_win
;
100 gint config_resist_edge
;
102 GSList
*config_per_app_settings
;
104 ObAppSettings
* config_create_app_settings(void)
106 ObAppSettings
*settings
= g_new0(ObAppSettings
, 1);
108 settings
->decor
= -1;
109 settings
->shade
= -1;
110 settings
->monitor
= -1;
111 settings
->focus
= -1;
112 settings
->desktop
= 0;
113 settings
->layer
= -2;
114 settings
->iconic
= -1;
115 settings
->skip_pager
= -1;
116 settings
->skip_taskbar
= -1;
117 settings
->fullscreen
= -1;
118 settings
->max_horz
= -1;
119 settings
->max_vert
= -1;
123 #define copy_if(setting, default) \
124 if (src->setting != default) dst->setting = src->setting
125 void config_app_settings_copy_non_defaults(const ObAppSettings
*src
,
128 g_assert(src
!= NULL
);
129 g_assert(dst
!= NULL
);
131 copy_if(type
, (ObClientType
)-1);
134 copy_if(monitor
, -1);
139 copy_if(skip_pager
, -1);
140 copy_if(skip_taskbar
, -1);
141 copy_if(fullscreen
, -1);
142 copy_if(max_horz
, -1);
143 copy_if(max_vert
, -1);
145 if (src
->pos_given
) {
146 dst
->pos_given
= TRUE
;
147 dst
->pos_force
= src
->pos_force
;
148 dst
->position
= src
->position
;
149 dst
->monitor
= src
->monitor
;
153 static void config_parse_gravity_coord(xmlDocPtr doc
, xmlNodePtr node
,
156 gchar
*s
= parse_string(doc
, node
);
157 if (!g_ascii_strcasecmp(s
, "center"))
162 if (s
[0] == '-' || s
[0] == '+')
172 <application name="aterm">
175 <application name="Rhythmbox">
182 .. there is a lot more settings available
187 /* Manages settings for individual applications.
188 Some notes: monitor is the screen number in a multi monitor
189 (Xinerama) setup (starting from 0) or mouse, meaning the
190 monitor the pointer is on. Default: mouse.
191 Layer can be three values, above (Always on top), below
192 (Always on bottom) and everything else (normal behaviour).
193 Positions can be an integer value or center, which will
194 center the window in the specified axis. Position is within
195 the monitor, so <position><x>center</x></position><monitor>2</monitor>
196 will center the window on the second monitor.
198 static void parse_per_app_settings(ObParseInst
*inst
, xmlDocPtr doc
,
199 xmlNodePtr node
, gpointer data
)
201 xmlNodePtr app
= parse_find_node("application", node
->children
);
202 gchar
*name
= NULL
, *class = NULL
, *role
= NULL
, *type
= NULL
;
203 gboolean name_set
, class_set
, type_set
;
204 gboolean x_pos_given
;
207 name_set
= class_set
= type_set
= x_pos_given
= FALSE
;
209 class_set
= parse_attr_string("class", app
, &class);
210 name_set
= parse_attr_string("name", app
, &name
);
211 type_set
= parse_attr_string("type", app
, &type
);
212 if (class_set
|| name_set
) {
214 ObAppSettings
*settings
= config_create_app_settings();;
217 settings
->name
= g_pattern_spec_new(name
);
220 settings
->class = g_pattern_spec_new(class);
223 if (!g_ascii_strcasecmp(type
, "normal"))
224 settings
->type
= OB_CLIENT_TYPE_NORMAL
;
225 else if (!g_ascii_strcasecmp(type
, "dialog"))
226 settings
->type
= OB_CLIENT_TYPE_DIALOG
;
227 else if (!g_ascii_strcasecmp(type
, "splash"))
228 settings
->type
= OB_CLIENT_TYPE_SPLASH
;
229 else if (!g_ascii_strcasecmp(type
, "utility"))
230 settings
->type
= OB_CLIENT_TYPE_UTILITY
;
231 else if (!g_ascii_strcasecmp(type
, "menu"))
232 settings
->type
= OB_CLIENT_TYPE_MENU
;
233 else if (!g_ascii_strcasecmp(type
, "toolbar"))
234 settings
->type
= OB_CLIENT_TYPE_TOOLBAR
;
235 else if (!g_ascii_strcasecmp(type
, "dock"))
236 settings
->type
= OB_CLIENT_TYPE_DOCK
;
237 else if (!g_ascii_strcasecmp(type
, "desktop"))
238 settings
->type
= OB_CLIENT_TYPE_DESKTOP
;
241 if (parse_attr_string("role", app
, &role
))
242 settings
->role
= g_pattern_spec_new(role
);
244 if ((n
= parse_find_node("decor", app
->children
)))
245 if (!parse_contains("default", doc
, n
))
246 settings
->decor
= parse_bool(doc
, n
);
248 if ((n
= parse_find_node("shade", app
->children
)))
249 if (!parse_contains("default", doc
, n
))
250 settings
->shade
= parse_bool(doc
, n
);
252 if ((n
= parse_find_node("position", app
->children
))) {
253 if ((c
= parse_find_node("x", n
->children
)))
254 if (!parse_contains("default", doc
, c
)) {
255 config_parse_gravity_coord(doc
, c
,
256 &settings
->position
.x
);
260 if (x_pos_given
&& (c
= parse_find_node("y", n
->children
)))
261 if (!parse_contains("default", doc
, c
)) {
262 config_parse_gravity_coord(doc
, c
,
263 &settings
->position
.y
);
264 settings
->pos_given
= TRUE
;
267 if (settings
->pos_given
&&
268 (c
= parse_find_node("monitor", n
->children
)))
269 if (!parse_contains("default", doc
, c
)) {
270 gchar
*s
= parse_string(doc
, c
);
271 if (!g_ascii_strcasecmp(s
, "mouse"))
272 settings
->monitor
= 0;
274 settings
->monitor
= parse_int(doc
, c
);
278 parse_attr_bool("force", n
, &settings
->pos_force
);
281 if ((n
= parse_find_node("focus", app
->children
)))
282 if (!parse_contains("default", doc
, n
))
283 settings
->focus
= parse_bool(doc
, n
);
285 if ((n
= parse_find_node("desktop", app
->children
))) {
286 if (!parse_contains("default", doc
, n
)) {
287 gchar
*s
= parse_string(doc
, n
);
288 if (!g_ascii_strcasecmp(s
, "all"))
289 settings
->desktop
= DESKTOP_ALL
;
291 gint i
= parse_int(doc
, n
);
293 settings
->desktop
= i
;
299 if ((n
= parse_find_node("layer", app
->children
)))
300 if (!parse_contains("default", doc
, n
)) {
301 gchar
*s
= parse_string(doc
, n
);
302 if (!g_ascii_strcasecmp(s
, "above"))
304 else if (!g_ascii_strcasecmp(s
, "below"))
305 settings
->layer
= -1;
311 if ((n
= parse_find_node("iconic", app
->children
)))
312 if (!parse_contains("default", doc
, n
))
313 settings
->iconic
= parse_bool(doc
, n
);
315 if ((n
= parse_find_node("skip_pager", app
->children
)))
316 if (!parse_contains("default", doc
, n
))
317 settings
->skip_pager
= parse_bool(doc
, n
);
319 if ((n
= parse_find_node("skip_taskbar", app
->children
)))
320 if (!parse_contains("default", doc
, n
))
321 settings
->skip_taskbar
= parse_bool(doc
, n
);
323 if ((n
= parse_find_node("fullscreen", app
->children
)))
324 if (!parse_contains("default", doc
, n
))
325 settings
->fullscreen
= parse_bool(doc
, n
);
327 if ((n
= parse_find_node("maximized", app
->children
)))
328 if (!parse_contains("default", doc
, n
)) {
329 gchar
*s
= parse_string(doc
, n
);
330 if (!g_ascii_strcasecmp(s
, "horizontal")) {
331 settings
->max_horz
= TRUE
;
332 settings
->max_vert
= FALSE
;
333 } else if (!g_ascii_strcasecmp(s
, "vertical")) {
334 settings
->max_horz
= FALSE
;
335 settings
->max_vert
= TRUE
;
337 settings
->max_horz
= settings
->max_vert
=
342 config_per_app_settings
= g_slist_append(config_per_app_settings
,
343 (gpointer
) settings
);
347 name
= class = role
= NULL
;
350 app
= parse_find_node("application", app
->next
);
357 <action name="ChangeDesktop">
364 static void parse_key(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
369 gboolean is_chroot
= FALSE
;
371 if (!parse_attr_string("key", node
, &key
))
374 parse_attr_bool("chroot", node
, &is_chroot
);
376 keylist
= g_list_append(keylist
, key
);
378 if ((n
= parse_find_node("keybind", node
->children
))) {
380 parse_key(i
, doc
, n
, keylist
);
381 n
= parse_find_node("keybind", n
->next
);
384 else if ((n
= parse_find_node("action", node
->children
))) {
386 ObActionsAct
*action
;
388 action
= actions_parse(i
, doc
, n
);
390 keyboard_bind(keylist
, action
);
391 n
= parse_find_node("action", n
->next
);
396 keyboard_chroot(keylist
);
399 keylist
= g_list_delete_link(keylist
, g_list_last(keylist
));
402 static void parse_keyboard(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
408 keyboard_unbind_all();
410 if ((n
= parse_find_node("chainQuitKey", node
->children
))) {
411 key
= parse_string(doc
, n
);
412 translate_key(key
, &config_keyboard_reset_state
,
413 &config_keyboard_reset_keycode
);
417 if ((n
= parse_find_node("keybind", node
->children
)))
419 parse_key(i
, doc
, n
, NULL
);
420 n
= parse_find_node("keybind", n
->next
);
426 <context name="Titlebar">
427 <mousebind button="Left" action="Press">
428 <action name="Raise"></action>
434 static void parse_mouse(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
437 xmlNodePtr n
, nbut
, nact
;
444 node
= node
->children
;
446 if ((n
= parse_find_node("dragThreshold", node
)))
447 config_mouse_threshold
= parse_int(doc
, n
);
448 if ((n
= parse_find_node("doubleClickTime", node
)))
449 config_mouse_dclicktime
= parse_int(doc
, n
);
450 if ((n
= parse_find_node("screenEdgeWarpTime", node
))) {
451 config_mouse_screenedgetime
= parse_int(doc
, n
);
452 /* minimum value of 25 for this property, when it is 1 and you hit the
453 edge it basically never stops */
454 if (config_mouse_screenedgetime
&& config_mouse_screenedgetime
< 25)
455 config_mouse_screenedgetime
= 25;
458 n
= parse_find_node("context", node
);
460 if (!parse_attr_string("name", n
, &contextstr
))
462 nbut
= parse_find_node("mousebind", n
->children
);
464 if (!parse_attr_string("button", nbut
, &buttonstr
))
466 if (parse_attr_contains("press", nbut
, "action")) {
467 mact
= OB_MOUSE_ACTION_PRESS
;
468 } else if (parse_attr_contains("release", nbut
, "action")) {
469 mact
= OB_MOUSE_ACTION_RELEASE
;
470 } else if (parse_attr_contains("click", nbut
, "action")) {
471 mact
= OB_MOUSE_ACTION_CLICK
;
472 } else if (parse_attr_contains("doubleclick", nbut
,"action")) {
473 mact
= OB_MOUSE_ACTION_DOUBLE_CLICK
;
474 } else if (parse_attr_contains("drag", nbut
, "action")) {
475 mact
= OB_MOUSE_ACTION_MOTION
;
478 nact
= parse_find_node("action", nbut
->children
);
480 ObActionsAct
*action
;
482 if ((action
= actions_parse(i
, doc
, nact
)))
483 mouse_bind(buttonstr
, contextstr
, mact
, action
);
484 nact
= parse_find_node("action", nact
->next
);
488 nbut
= parse_find_node("mousebind", nbut
->next
);
492 n
= parse_find_node("context", n
->next
);
496 static void parse_focus(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
501 node
= node
->children
;
503 if ((n
= parse_find_node("focusNew", node
)))
504 config_focus_new
= parse_bool(doc
, n
);
505 if ((n
= parse_find_node("followMouse", node
)))
506 config_focus_follow
= parse_bool(doc
, n
);
507 if ((n
= parse_find_node("focusDelay", node
)))
508 config_focus_delay
= parse_int(doc
, n
);
509 if ((n
= parse_find_node("raiseOnFocus", node
)))
510 config_focus_raise
= parse_bool(doc
, n
);
511 if ((n
= parse_find_node("focusLast", node
)))
512 config_focus_last
= parse_bool(doc
, n
);
513 if ((n
= parse_find_node("underMouse", node
)))
514 config_focus_under_mouse
= parse_bool(doc
, n
);
517 static void parse_placement(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
522 node
= node
->children
;
524 if ((n
= parse_find_node("policy", node
)))
525 if (parse_contains("UnderMouse", doc
, n
))
526 config_place_policy
= OB_PLACE_POLICY_MOUSE
;
527 if ((n
= parse_find_node("center", node
)))
528 config_place_center
= parse_bool(doc
, n
);
529 if ((n
= parse_find_node("monitor", node
))) {
530 if (parse_contains("active", doc
, n
))
531 config_place_monitor
= OB_PLACE_MONITOR_ACTIVE
;
532 else if (parse_contains("mouse", doc
, n
))
533 config_place_monitor
= OB_PLACE_MONITOR_MOUSE
;
535 if ((n
= parse_find_node("primaryMonitor", node
))) {
536 config_primary_monitor_index
= parse_int(doc
, n
);
537 if (!config_primary_monitor_index
) {
538 if (parse_contains("mouse", doc
, n
))
539 config_primary_monitor
= OB_PLACE_MONITOR_MOUSE
;
544 static void parse_margins(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
549 node
= node
->children
;
551 if ((n
= parse_find_node("top", node
)))
552 config_margins
.top
= MAX(0, parse_int(doc
, n
));
553 if ((n
= parse_find_node("left", node
)))
554 config_margins
.left
= MAX(0, parse_int(doc
, n
));
555 if ((n
= parse_find_node("right", node
)))
556 config_margins
.right
= MAX(0, parse_int(doc
, n
));
557 if ((n
= parse_find_node("bottom", node
)))
558 config_margins
.bottom
= MAX(0, parse_int(doc
, n
));
561 static void parse_theme(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
566 node
= node
->children
;
568 if ((n
= parse_find_node("name", node
))) {
571 g_free(config_theme
);
572 c
= parse_string(doc
, n
);
573 config_theme
= parse_expand_tilde(c
);
576 if ((n
= parse_find_node("titleLayout", node
))) {
579 g_free(config_title_layout
);
580 config_title_layout
= parse_string(doc
, n
);
582 /* replace duplicates with spaces */
583 for (c
= config_title_layout
; *c
!= '\0'; ++c
)
584 for (d
= c
+1; *d
!= '\0'; ++d
)
585 if (*c
== *d
) *d
= ' ';
587 if ((n
= parse_find_node("keepBorder", node
)))
588 config_theme_keepborder
= parse_bool(doc
, n
);
589 if ((n
= parse_find_node("animateIconify", node
)))
590 config_animate_iconify
= parse_bool(doc
, n
);
592 n
= parse_find_node("font", node
);
596 gchar
*name
= g_strdup(RrDefaultFontFamily
);
597 gint size
= RrDefaultFontSize
;
598 RrFontWeight weight
= RrDefaultFontWeight
;
599 RrFontSlant slant
= RrDefaultFontSlant
;
601 if (parse_attr_contains("ActiveWindow", n
, "place"))
602 font
= &config_font_activewindow
;
603 else if (parse_attr_contains("InactiveWindow", n
, "place"))
604 font
= &config_font_inactivewindow
;
605 else if (parse_attr_contains("MenuHeader", n
, "place"))
606 font
= &config_font_menutitle
;
607 else if (parse_attr_contains("MenuItem", n
, "place"))
608 font
= &config_font_menuitem
;
609 else if (parse_attr_contains("OnScreenDisplay", n
, "place"))
610 font
= &config_font_osd
;
614 if ((fnode
= parse_find_node("name", n
->children
))) {
616 name
= parse_string(doc
, fnode
);
618 if ((fnode
= parse_find_node("size", n
->children
))) {
619 int s
= parse_int(doc
, fnode
);
622 if ((fnode
= parse_find_node("weight", n
->children
))) {
623 gchar
*w
= parse_string(doc
, fnode
);
624 if (!g_ascii_strcasecmp(w
, "Bold"))
625 weight
= RR_FONTWEIGHT_BOLD
;
628 if ((fnode
= parse_find_node("slant", n
->children
))) {
629 gchar
*s
= parse_string(doc
, fnode
);
630 if (!g_ascii_strcasecmp(s
, "Italic"))
631 slant
= RR_FONTSLANT_ITALIC
;
632 if (!g_ascii_strcasecmp(s
, "Oblique"))
633 slant
= RR_FONTSLANT_OBLIQUE
;
637 *font
= RrFontOpen(ob_rr_inst
, name
, size
, weight
, slant
);
640 n
= parse_find_node("font", n
->next
);
644 static void parse_desktops(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
649 node
= node
->children
;
651 if ((n
= parse_find_node("number", node
))) {
652 gint d
= parse_int(doc
, n
);
654 config_desktops_num
= (unsigned) d
;
656 if ((n
= parse_find_node("firstdesk", node
))) {
657 gint d
= parse_int(doc
, n
);
659 config_screen_firstdesk
= (unsigned) d
;
661 if ((n
= parse_find_node("names", node
))) {
665 for (it
= config_desktops_names
; it
; it
= it
->next
)
667 g_slist_free(config_desktops_names
);
668 config_desktops_names
= NULL
;
670 nname
= parse_find_node("name", n
->children
);
672 config_desktops_names
= g_slist_append(config_desktops_names
,
673 parse_string(doc
, nname
));
674 nname
= parse_find_node("name", nname
->next
);
677 if ((n
= parse_find_node("popupTime", node
)))
678 config_desktop_popup_time
= parse_int(doc
, n
);
681 static void parse_resize(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
686 node
= node
->children
;
688 if ((n
= parse_find_node("drawContents", node
)))
689 config_resize_redraw
= parse_bool(doc
, n
);
690 if ((n
= parse_find_node("popupShow", node
))) {
691 config_resize_popup_show
= parse_int(doc
, n
);
692 if (parse_contains("Always", doc
, n
))
693 config_resize_popup_show
= 2;
694 else if (parse_contains("Never", doc
, n
))
695 config_resize_popup_show
= 0;
696 else if (parse_contains("Nonpixel", doc
, n
))
697 config_resize_popup_show
= 1;
699 if ((n
= parse_find_node("popupPosition", node
))) {
700 if (parse_contains("Top", doc
, n
))
701 config_resize_popup_pos
= OB_RESIZE_POS_TOP
;
702 else if (parse_contains("Center", doc
, n
))
703 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
704 else if (parse_contains("Fixed", doc
, n
)) {
705 config_resize_popup_pos
= OB_RESIZE_POS_FIXED
;
707 if ((n
= parse_find_node("popupFixedPosition", node
))) {
710 if ((n2
= parse_find_node("x", n
->children
)))
711 config_parse_gravity_coord(doc
, n2
,
712 &config_resize_popup_fixed
.x
);
713 if ((n2
= parse_find_node("y", n
->children
)))
714 config_parse_gravity_coord(doc
, n2
,
715 &config_resize_popup_fixed
.y
);
717 config_resize_popup_fixed
.x
.pos
=
718 MAX(config_resize_popup_fixed
.x
.pos
, 0);
719 config_resize_popup_fixed
.y
.pos
=
720 MAX(config_resize_popup_fixed
.y
.pos
, 0);
726 static void parse_dock(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
731 node
= node
->children
;
733 if ((n
= parse_find_node("position", node
))) {
734 if (parse_contains("TopLeft", doc
, n
))
735 config_dock_floating
= FALSE
,
736 config_dock_pos
= OB_DIRECTION_NORTHWEST
;
737 else if (parse_contains("Top", doc
, n
))
738 config_dock_floating
= FALSE
,
739 config_dock_pos
= OB_DIRECTION_NORTH
;
740 else if (parse_contains("TopRight", doc
, n
))
741 config_dock_floating
= FALSE
,
742 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
743 else if (parse_contains("Right", doc
, n
))
744 config_dock_floating
= FALSE
,
745 config_dock_pos
= OB_DIRECTION_EAST
;
746 else if (parse_contains("BottomRight", doc
, n
))
747 config_dock_floating
= FALSE
,
748 config_dock_pos
= OB_DIRECTION_SOUTHEAST
;
749 else if (parse_contains("Bottom", doc
, n
))
750 config_dock_floating
= FALSE
,
751 config_dock_pos
= OB_DIRECTION_SOUTH
;
752 else if (parse_contains("BottomLeft", doc
, n
))
753 config_dock_floating
= FALSE
,
754 config_dock_pos
= OB_DIRECTION_SOUTHWEST
;
755 else if (parse_contains("Left", doc
, n
))
756 config_dock_floating
= FALSE
,
757 config_dock_pos
= OB_DIRECTION_WEST
;
758 else if (parse_contains("Floating", doc
, n
))
759 config_dock_floating
= TRUE
;
761 if (config_dock_floating
) {
762 if ((n
= parse_find_node("floatingX", node
)))
763 config_dock_x
= parse_int(doc
, n
);
764 if ((n
= parse_find_node("floatingY", node
)))
765 config_dock_y
= parse_int(doc
, n
);
767 if ((n
= parse_find_node("noStrut", node
)))
768 config_dock_nostrut
= parse_bool(doc
, n
);
770 if ((n
= parse_find_node("stacking", node
))) {
771 if (parse_contains("above", doc
, n
))
772 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
773 else if (parse_contains("normal", doc
, n
))
774 config_dock_layer
= OB_STACKING_LAYER_NORMAL
;
775 else if (parse_contains("below", doc
, n
))
776 config_dock_layer
= OB_STACKING_LAYER_BELOW
;
778 if ((n
= parse_find_node("direction", node
))) {
779 if (parse_contains("horizontal", doc
, n
))
780 config_dock_orient
= OB_ORIENTATION_HORZ
;
781 else if (parse_contains("vertical", doc
, n
))
782 config_dock_orient
= OB_ORIENTATION_VERT
;
784 if ((n
= parse_find_node("autoHide", node
)))
785 config_dock_hide
= parse_bool(doc
, n
);
786 if ((n
= parse_find_node("hideDelay", node
)))
787 config_dock_hide_delay
= parse_int(doc
, n
);
788 if ((n
= parse_find_node("showDelay", node
)))
789 config_dock_show_delay
= parse_int(doc
, n
);
790 if ((n
= parse_find_node("moveButton", node
))) {
791 gchar
*str
= parse_string(doc
, n
);
793 if (translate_button(str
, &s
, &b
)) {
794 config_dock_app_move_button
= b
;
795 config_dock_app_move_modifiers
= s
;
797 g_message(_("Invalid button \"%s\" specified in config file"), str
);
803 static void parse_menu(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
807 node
= node
->children
;
809 if ((n
= parse_find_node("hideDelay", node
)))
810 config_menu_hide_delay
= parse_int(doc
, n
);
811 if ((n
= parse_find_node("middle", node
)))
812 config_menu_middle
= parse_bool(doc
, n
);
813 if ((n
= parse_find_node("submenuShowDelay", node
)))
814 config_submenu_show_delay
= parse_int(doc
, n
);
815 if ((n
= parse_find_node("applicationIcons", node
)))
816 config_menu_client_list_icons
= parse_bool(doc
, n
);
817 if ((n
= parse_find_node("manageDesktops", node
)))
818 config_menu_manage_desktops
= parse_bool(doc
, n
);
820 while ((node
= parse_find_node("file", node
))) {
821 gchar
*c
= parse_string(doc
, node
);
822 config_menu_files
= g_slist_append(config_menu_files
,
823 parse_expand_tilde(c
));
829 static void parse_resistance(ObParseInst
*i
, xmlDocPtr doc
, xmlNodePtr node
,
834 node
= node
->children
;
835 if ((n
= parse_find_node("strength", node
)))
836 config_resist_win
= parse_int(doc
, n
);
837 if ((n
= parse_find_node("screen_edge_strength", node
)))
838 config_resist_edge
= parse_int(doc
, n
);
844 const gchar
*actname
;
847 static void bind_default_keyboard(void)
850 ObDefKeyBind binds
[] = {
851 { "A-Tab", "NextWindow" },
852 { "S-A-Tab", "PreviousWindow" },
856 for (it
= binds
; it
->key
; ++it
) {
857 GList
*l
= g_list_append(NULL
, g_strdup(it
->key
));
858 keyboard_bind(l
, actions_parse_string(it
->actname
));
865 const gchar
*context
;
866 const ObMouseAction mact
;
867 const gchar
*actname
;
870 static void bind_default_mouse(void)
873 ObDefMouseBind binds
[] = {
874 { "Left", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
875 { "Middle", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
876 { "Right", "Client", OB_MOUSE_ACTION_PRESS
, "Focus" },
877 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
878 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
879 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS
, "Focus" },
880 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS
, "Focus" },
881 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS
, "Focus" },
882 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
883 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
884 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
885 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS
, "Focus" },
886 { "Left", "Close", OB_MOUSE_ACTION_PRESS
, "Focus" },
887 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS
, "Focus" },
888 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS
, "Focus" },
889 { "Left", "Icon", OB_MOUSE_ACTION_PRESS
, "Focus" },
890 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS
, "Focus" },
891 { "Left", "Shade", OB_MOUSE_ACTION_PRESS
, "Focus" },
892 { "Left", "Client", OB_MOUSE_ACTION_CLICK
, "Raise" },
893 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Raise" },
894 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK
, "Lower" },
895 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
896 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
897 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
898 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK
, "Raise" },
899 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Raise" },
900 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "Raise" },
901 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Raise" },
902 { "Left", "Icon", OB_MOUSE_ACTION_CLICK
, "Raise" },
903 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "Raise" },
904 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "Raise" },
905 { "Left", "Close", OB_MOUSE_ACTION_CLICK
, "Close" },
906 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK
, "ToggleMaximize" },
907 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK
, "Iconify" },
908 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK
, "ToggleOmnipresent" },
909 { "Left", "Shade", OB_MOUSE_ACTION_CLICK
, "ToggleShade" },
910 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
911 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
912 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
913 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION
, "Resize" },
914 { "Left", "Top", OB_MOUSE_ACTION_MOTION
, "Resize" },
915 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION
, "Resize" },
916 { "Left", "Left", OB_MOUSE_ACTION_MOTION
, "Resize" },
917 { "Left", "Right", OB_MOUSE_ACTION_MOTION
, "Resize" },
918 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION
, "Move" },
919 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION
, "Move" },
920 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION
, "Resize" },
921 { NULL
, NULL
, 0, NULL
}
924 for (it
= binds
; it
->button
; ++it
)
925 mouse_bind(it
->button
, it
->context
, it
->mact
,
926 actions_parse_string(it
->actname
));
929 void config_startup(ObParseInst
*i
)
931 config_focus_new
= TRUE
;
932 config_focus_follow
= FALSE
;
933 config_focus_delay
= 0;
934 config_focus_raise
= FALSE
;
935 config_focus_last
= TRUE
;
936 config_focus_under_mouse
= FALSE
;
938 parse_register(i
, "focus", parse_focus
, NULL
);
940 config_place_policy
= OB_PLACE_POLICY_SMART
;
941 config_place_center
= TRUE
;
942 config_place_monitor
= OB_PLACE_MONITOR_ANY
;
944 config_primary_monitor_index
= 1;
945 config_primary_monitor
= OB_PLACE_MONITOR_ACTIVE
;
947 parse_register(i
, "placement", parse_placement
, NULL
);
949 STRUT_PARTIAL_SET(config_margins
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
951 parse_register(i
, "margins", parse_margins
, NULL
);
955 config_animate_iconify
= TRUE
;
956 config_title_layout
= g_strdup("NLIMC");
957 config_theme_keepborder
= TRUE
;
959 config_font_activewindow
= NULL
;
960 config_font_inactivewindow
= NULL
;
961 config_font_menuitem
= NULL
;
962 config_font_menutitle
= NULL
;
964 parse_register(i
, "theme", parse_theme
, NULL
);
966 config_desktops_num
= 4;
967 config_screen_firstdesk
= 1;
968 config_desktops_names
= NULL
;
969 config_desktop_popup_time
= 875;
971 parse_register(i
, "desktops", parse_desktops
, NULL
);
973 config_resize_redraw
= TRUE
;
974 config_resize_popup_show
= 1; /* nonpixel increments */
975 config_resize_popup_pos
= OB_RESIZE_POS_CENTER
;
976 GRAVITY_COORD_SET(config_resize_popup_fixed
.x
, 0, FALSE
, FALSE
);
977 GRAVITY_COORD_SET(config_resize_popup_fixed
.y
, 0, FALSE
, FALSE
);
979 parse_register(i
, "resize", parse_resize
, NULL
);
981 config_dock_layer
= OB_STACKING_LAYER_ABOVE
;
982 config_dock_pos
= OB_DIRECTION_NORTHEAST
;
983 config_dock_floating
= FALSE
;
984 config_dock_nostrut
= FALSE
;
987 config_dock_orient
= OB_ORIENTATION_VERT
;
988 config_dock_hide
= FALSE
;
989 config_dock_hide_delay
= 300;
990 config_dock_show_delay
= 300;
991 config_dock_app_move_button
= 2; /* middle */
992 config_dock_app_move_modifiers
= 0;
994 parse_register(i
, "dock", parse_dock
, NULL
);
996 translate_key("C-g", &config_keyboard_reset_state
,
997 &config_keyboard_reset_keycode
);
999 bind_default_keyboard();
1001 parse_register(i
, "keyboard", parse_keyboard
, NULL
);
1003 config_mouse_threshold
= 8;
1004 config_mouse_dclicktime
= 200;
1005 config_mouse_screenedgetime
= 400;
1007 bind_default_mouse();
1009 parse_register(i
, "mouse", parse_mouse
, NULL
);
1011 config_resist_win
= 10;
1012 config_resist_edge
= 20;
1014 parse_register(i
, "resistance", parse_resistance
, NULL
);
1016 config_menu_hide_delay
= 250;
1017 config_menu_middle
= FALSE
;
1018 config_submenu_show_delay
= 0;
1019 config_menu_client_list_icons
= TRUE
;
1020 config_menu_manage_desktops
= TRUE
;
1021 config_menu_files
= NULL
;
1023 parse_register(i
, "menu", parse_menu
, NULL
);
1025 config_per_app_settings
= NULL
;
1027 parse_register(i
, "applications", parse_per_app_settings
, NULL
);
1030 void config_shutdown(void)
1034 g_free(config_theme
);
1036 g_free(config_title_layout
);
1038 RrFontClose(config_font_activewindow
);
1039 RrFontClose(config_font_inactivewindow
);
1040 RrFontClose(config_font_menuitem
);
1041 RrFontClose(config_font_menutitle
);
1042 RrFontClose(config_font_osd
);
1044 for (it
= config_desktops_names
; it
; it
= g_slist_next(it
))
1046 g_slist_free(config_desktops_names
);
1048 for (it
= config_menu_files
; it
; it
= g_slist_next(it
))
1050 g_slist_free(config_menu_files
);
1052 for (it
= config_per_app_settings
; it
; it
= g_slist_next(it
)) {
1053 ObAppSettings
*itd
= (ObAppSettings
*)it
->data
;
1054 if (itd
->name
) g_pattern_spec_free(itd
->name
);
1055 if (itd
->role
) g_pattern_spec_free(itd
->role
);
1056 if (itd
->class) g_pattern_spec_free(itd
->class);
1059 g_slist_free(config_per_app_settings
);