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"
27 #include "parser/parse.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;
38 ObPlacePolicy config_place_policy;
39 gboolean config_place_center;
42 gboolean config_theme_keepborder;
44 gchar *config_title_layout;
46 gboolean config_animate_iconify;
48 RrFont *config_font_activewindow;
49 RrFont *config_font_inactivewindow;
50 RrFont *config_font_menuitem;
51 RrFont *config_font_menutitle;
52 RrFont *config_font_osd;
54 gint config_desktops_num;
55 GSList *config_desktops_names;
56 guint config_screen_firstdesk;
58 gboolean config_resize_redraw;
59 gboolean config_resize_four_corners;
60 gint config_resize_popup_show;
61 gint config_resize_popup_pos;
63 ObStackingLayer config_dock_layer;
64 gboolean config_dock_floating;
65 gboolean config_dock_nostrut;
66 ObDirection config_dock_pos;
69 ObOrientation config_dock_orient;
70 gboolean config_dock_hide;
71 guint config_dock_hide_delay;
72 guint config_dock_show_delay;
73 guint config_dock_app_move_button;
74 guint config_dock_app_move_modifiers;
76 guint config_keyboard_reset_keycode;
77 guint config_keyboard_reset_state;
79 gint config_mouse_threshold;
80 gint config_mouse_dclicktime;
82 guint config_menu_hide_delay;
83 gboolean config_menu_middle;
84 guint config_submenu_show_delay;
85 gboolean config_menu_client_list_icons;
87 GSList *config_menu_files;
89 gint config_resist_win;
90 gint config_resist_edge;
92 GSList *config_per_app_settings;
94 ObAppSettings* config_create_app_settings()
96 ObAppSettings *settings = g_new0(ObAppSettings, 1);
99 settings->monitor = -1;
100 settings->focus = -1;
101 settings->desktop = 0;
102 settings->layer = -2;
103 settings->iconic = -1;
104 settings->skip_pager = -1;
105 settings->skip_taskbar = -1;
106 settings->fullscreen = -1;
107 settings->max_horz = -1;
108 settings->max_vert = -1;
112 #define copy_if(setting, default) \
113 if (src->setting != default) dst->setting = src->setting
114 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
117 g_assert(src != NULL);
118 g_assert(dst != NULL);
126 copy_if(skip_pager, -1);
127 copy_if(skip_taskbar, -1);
128 copy_if(fullscreen, -1);
129 copy_if(max_horz, -1);
130 copy_if(max_vert, -1);
132 if (src->pos_given) {
133 dst->pos_given = TRUE;
134 dst->center_x = src->center_x;
135 dst->center_y = src->center_y;
136 dst->opposite_x = src->opposite_x;
137 dst->opposite_y = src->opposite_y;
138 dst->position.x = src->position.x;
139 dst->position.y = src->position.y;
140 dst->monitor = src->monitor;
146 <application name="aterm">
149 <application name="Rhythmbox">
156 .. there is a lot more settings available
161 /* Manages settings for individual applications.
162 Some notes: monitor is the screen number in a multi monitor
163 (Xinerama) setup (starting from 0) or mouse, meaning the
164 monitor the pointer is on. Default: mouse.
165 Layer can be three values, above (Always on top), below
166 (Always on bottom) and everything else (normal behaviour).
167 Positions can be an integer value or center, which will
168 center the window in the specified axis. Position is within
169 the monitor, so <position><x>center</x></position><monitor>2</monitor>
170 will center the window on the second monitor.
172 static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
173 xmlNodePtr node, gpointer d)
175 xmlNodePtr app = parse_find_node("application", node->children);
176 gchar *name = NULL, *class = NULL, *role = NULL;
177 gboolean name_set, class_set;
178 gboolean x_pos_given;
181 name_set = class_set = x_pos_given = FALSE;
183 class_set = parse_attr_string("class", app, &class);
184 name_set = parse_attr_string("name", app, &name);
185 if (class_set || name_set) {
187 ObAppSettings *settings = config_create_app_settings();;
190 settings->name = g_pattern_spec_new(name);
193 settings->class = g_pattern_spec_new(class);
195 if (parse_attr_string("role", app, &role))
196 settings->role = g_pattern_spec_new(role);
198 if ((n = parse_find_node("decor", app->children)))
199 if (!parse_contains("default", doc, n))
200 settings->decor = parse_bool(doc, n);
202 if ((n = parse_find_node("shade", app->children)))
203 if (!parse_contains("default", doc, n))
204 settings->shade = parse_bool(doc, n);
206 if ((n = parse_find_node("position", app->children))) {
207 if ((c = parse_find_node("x", n->children)))
208 if (!parse_contains("default", doc, c)) {
209 gchar *s = parse_string(doc, c);
210 if (!strcmp(s, "center")) {
211 settings->center_x = TRUE;
215 settings->opposite_x = TRUE;
216 if (s[0] == '-' || s[0] == '+')
217 settings->position.x = atoi(s+1);
219 settings->position.x = atoi(s);
225 if (x_pos_given && (c = parse_find_node("y", n->children)))
226 if (!parse_contains("default", doc, c)) {
227 gchar *s = parse_string(doc, c);
228 if (!strcmp(s, "center")) {
229 settings->center_y = TRUE;
230 settings->pos_given = TRUE;
233 settings->opposite_y = TRUE;
234 if (s[0] == '-' || s[0] == '+')
235 settings->position.y = atoi(s+1);
237 settings->position.y = atoi(s);
238 settings->pos_given = TRUE;
243 if (settings->pos_given &&
244 (c = parse_find_node("monitor", n->children)))
245 if (!parse_contains("default", doc, c)) {
246 gchar *s = parse_string(doc, c);
247 if (!strcmp(s, "mouse"))
248 settings->monitor = 0;
250 settings->monitor = parse_int(doc, c) + 1;
255 if ((n = parse_find_node("focus", app->children)))
256 if (!parse_contains("default", doc, n))
257 settings->focus = parse_bool(doc, n);
259 if ((n = parse_find_node("desktop", app->children))) {
260 if (!parse_contains("default", doc, n)) {
261 gchar *s = parse_string(doc, n);
262 if (!strcmp(s, "all"))
263 settings->desktop = DESKTOP_ALL;
265 gint i = parse_int(doc, n);
267 settings->desktop = i;
273 if ((n = parse_find_node("layer", app->children)))
274 if (!parse_contains("default", doc, n)) {
275 gchar *s = parse_string(doc, n);
276 if (!strcmp(s, "above"))
278 else if (!strcmp(s, "below"))
279 settings->layer = -1;
285 if ((n = parse_find_node("iconic", app->children)))
286 if (!parse_contains("default", doc, n))
287 settings->iconic = parse_bool(doc, n);
289 if ((n = parse_find_node("skip_pager", app->children)))
290 if (!parse_contains("default", doc, n))
291 settings->skip_pager = parse_bool(doc, n);
293 if ((n = parse_find_node("skip_taskbar", app->children)))
294 if (!parse_contains("default", doc, n))
295 settings->skip_taskbar = parse_bool(doc, n);
297 if ((n = parse_find_node("fullscreen", app->children)))
298 if (!parse_contains("default", doc, n))
299 settings->fullscreen = parse_bool(doc, n);
301 if ((n = parse_find_node("maximized", app->children)))
302 if (!parse_contains("default", doc, n)) {
303 gchar *s = parse_string(doc, n);
304 if (!strcmp(s, "horizontal")) {
305 settings->max_horz = TRUE;
306 settings->max_vert = FALSE;
307 } else if (!strcmp(s, "vertical")) {
308 settings->max_horz = FALSE;
309 settings->max_vert = TRUE;
311 settings->max_horz = settings->max_vert =
316 config_per_app_settings = g_slist_append(config_per_app_settings,
317 (gpointer) settings);
320 app = parse_find_node("application", app->next);
331 <action name="ChangeDesktop">
338 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
343 gboolean is_chroot = FALSE;
345 if (!parse_attr_string("key", node, &key))
348 parse_attr_bool("chroot", node, &is_chroot);
350 keylist = g_list_append(keylist, key);
352 if ((n = parse_find_node("keybind", node->children))) {
354 parse_key(i, doc, n, keylist);
355 n = parse_find_node("keybind", n->next);
358 else if ((n = parse_find_node("action", node->children))) {
362 action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY);
364 keyboard_bind(keylist, action);
365 n = parse_find_node("action", n->next);
370 keyboard_chroot(keylist);
373 keylist = g_list_delete_link(keylist, g_list_last(keylist));
376 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
382 keyboard_unbind_all();
384 if ((n = parse_find_node("chainQuitKey", node->children))) {
385 key = parse_string(doc, n);
386 translate_key(key, &config_keyboard_reset_state,
387 &config_keyboard_reset_keycode);
391 if ((n = parse_find_node("keybind", node->children)))
393 parse_key(i, doc, n, NULL);
394 n = parse_find_node("keybind", n->next);
400 <context name="Titlebar">
401 <mousebind button="Left" action="Press">
402 <action name="Raise"></action>
408 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
411 xmlNodePtr n, nbut, nact;
420 node = node->children;
422 if ((n = parse_find_node("dragThreshold", node)))
423 config_mouse_threshold = parse_int(doc, n);
424 if ((n = parse_find_node("doubleClickTime", node)))
425 config_mouse_dclicktime = parse_int(doc, n);
427 n = parse_find_node("context", node);
429 if (!parse_attr_string("name", n, &contextstr))
431 nbut = parse_find_node("mousebind", n->children);
433 if (!parse_attr_string("button", nbut, &buttonstr))
435 if (parse_attr_contains("press", nbut, "action")) {
436 uact = OB_USER_ACTION_MOUSE_PRESS;
437 mact = OB_MOUSE_ACTION_PRESS;
438 } else if (parse_attr_contains("release", nbut, "action")) {
439 uact = OB_USER_ACTION_MOUSE_RELEASE;
440 mact = OB_MOUSE_ACTION_RELEASE;
441 } else if (parse_attr_contains("click", nbut, "action")) {
442 uact = OB_USER_ACTION_MOUSE_CLICK;
443 mact = OB_MOUSE_ACTION_CLICK;
444 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
445 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
446 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
447 } else if (parse_attr_contains("drag", nbut, "action")) {
448 uact = OB_USER_ACTION_MOUSE_MOTION;
449 mact = OB_MOUSE_ACTION_MOTION;
452 nact = parse_find_node("action", nbut->children);
454 if ((action = action_parse(i, doc, nact, uact)))
455 mouse_bind(buttonstr, contextstr, mact, action);
456 nact = parse_find_node("action", nact->next);
460 nbut = parse_find_node("mousebind", nbut->next);
464 n = parse_find_node("context", n->next);
468 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
473 node = node->children;
475 if ((n = parse_find_node("focusNew", node)))
476 config_focus_new = parse_bool(doc, n);
477 if ((n = parse_find_node("followMouse", node)))
478 config_focus_follow = parse_bool(doc, n);
479 if ((n = parse_find_node("focusDelay", node)))
480 config_focus_delay = parse_int(doc, n) * 1000;
481 if ((n = parse_find_node("raiseOnFocus", node)))
482 config_focus_raise = parse_bool(doc, n);
483 if ((n = parse_find_node("focusLast", node)))
484 config_focus_last = parse_bool(doc, n);
485 if ((n = parse_find_node("underMouse", node)))
486 config_focus_under_mouse = parse_bool(doc, n);
489 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
494 node = node->children;
496 if ((n = parse_find_node("policy", node)))
497 if (parse_contains("UnderMouse", doc, n))
498 config_place_policy = OB_PLACE_POLICY_MOUSE;
499 if ((n = parse_find_node("center", node)))
500 config_place_center = parse_bool(doc, n);
503 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
508 node = node->children;
510 if ((n = parse_find_node("name", node))) {
513 g_free(config_theme);
514 c = parse_string(doc, n);
515 config_theme = parse_expand_tilde(c);
518 if ((n = parse_find_node("titleLayout", node))) {
521 g_free(config_title_layout);
522 config_title_layout = parse_string(doc, n);
524 /* replace duplicates with spaces */
525 for (c = config_title_layout; *c != '\0'; ++c)
526 for (d = c+1; *d != '\0'; ++d)
527 if (*c == *d) *d = ' ';
529 if ((n = parse_find_node("keepBorder", node)))
530 config_theme_keepborder = parse_bool(doc, n);
531 if ((n = parse_find_node("animateIconify", node)))
532 config_animate_iconify = parse_bool(doc, n);
534 n = parse_find_node("font", node);
538 gchar *name = g_strdup(RrDefaultFontFamily);
539 gint size = RrDefaultFontSize;
540 RrFontWeight weight = RrDefaultFontWeight;
541 RrFontSlant slant = RrDefaultFontSlant;
543 if (parse_attr_contains("ActiveWindow", n, "place"))
544 font = &config_font_activewindow;
545 else if (parse_attr_contains("InactiveWindow", n, "place"))
546 font = &config_font_inactivewindow;
547 else if (parse_attr_contains("MenuHeader", n, "place"))
548 font = &config_font_menutitle;
549 else if (parse_attr_contains("MenuItem", n, "place"))
550 font = &config_font_menuitem;
551 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
552 font = &config_font_osd;
556 if ((fnode = parse_find_node("name", n->children))) {
558 name = parse_string(doc, fnode);
560 if ((fnode = parse_find_node("size", n->children))) {
561 int s = parse_int(doc, fnode);
564 if ((fnode = parse_find_node("weight", n->children))) {
565 gchar *w = parse_string(doc, fnode);
566 if (!g_ascii_strcasecmp(w, "Bold"))
567 weight = RR_FONTWEIGHT_BOLD;
570 if ((fnode = parse_find_node("slant", n->children))) {
571 gchar *s = parse_string(doc, fnode);
572 if (!g_ascii_strcasecmp(s, "Italic"))
573 slant = RR_FONTSLANT_ITALIC;
574 if (!g_ascii_strcasecmp(s, "Oblique"))
575 slant = RR_FONTSLANT_OBLIQUE;
579 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
582 n = parse_find_node("font", n->next);
586 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
591 node = node->children;
593 if ((n = parse_find_node("number", node))) {
594 gint d = parse_int(doc, n);
596 config_desktops_num = d;
598 if ((n = parse_find_node("firstdesk", node))) {
599 gint d = parse_int(doc, n);
601 config_screen_firstdesk = (unsigned) d;
603 if ((n = parse_find_node("names", node))) {
607 for (it = config_desktops_names; it; it = it->next)
609 g_slist_free(config_desktops_names);
610 config_desktops_names = NULL;
612 nname = parse_find_node("name", n->children);
614 config_desktops_names = g_slist_append(config_desktops_names,
615 parse_string(doc, nname));
616 nname = parse_find_node("name", nname->next);
621 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
626 node = node->children;
628 if ((n = parse_find_node("drawContents", node)))
629 config_resize_redraw = parse_bool(doc, n);
630 if ((n = parse_find_node("popupShow", node))) {
631 config_resize_popup_show = parse_int(doc, n);
632 if (parse_contains("Always", doc, n))
633 config_resize_popup_show = 2;
634 else if (parse_contains("Never", doc, n))
635 config_resize_popup_show = 0;
636 else if (parse_contains("Nonpixel", doc, n))
637 config_resize_popup_show = 1;
639 if ((n = parse_find_node("popupPosition", node))) {
640 config_resize_popup_pos = parse_int(doc, n);
641 if (parse_contains("Top", doc, n))
642 config_resize_popup_pos = 1;
643 else if (parse_contains("Center", doc, n))
644 config_resize_popup_pos = 0;
648 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
653 node = node->children;
655 if ((n = parse_find_node("position", node))) {
656 if (parse_contains("TopLeft", doc, n))
657 config_dock_floating = FALSE,
658 config_dock_pos = OB_DIRECTION_NORTHWEST;
659 else if (parse_contains("Top", doc, n))
660 config_dock_floating = FALSE,
661 config_dock_pos = OB_DIRECTION_NORTH;
662 else if (parse_contains("TopRight", doc, n))
663 config_dock_floating = FALSE,
664 config_dock_pos = OB_DIRECTION_NORTHEAST;
665 else if (parse_contains("Right", doc, n))
666 config_dock_floating = FALSE,
667 config_dock_pos = OB_DIRECTION_EAST;
668 else if (parse_contains("BottomRight", doc, n))
669 config_dock_floating = FALSE,
670 config_dock_pos = OB_DIRECTION_SOUTHEAST;
671 else if (parse_contains("Bottom", doc, n))
672 config_dock_floating = FALSE,
673 config_dock_pos = OB_DIRECTION_SOUTH;
674 else if (parse_contains("BottomLeft", doc, n))
675 config_dock_floating = FALSE,
676 config_dock_pos = OB_DIRECTION_SOUTHWEST;
677 else if (parse_contains("Left", doc, n))
678 config_dock_floating = FALSE,
679 config_dock_pos = OB_DIRECTION_WEST;
680 else if (parse_contains("Floating", doc, n))
681 config_dock_floating = TRUE;
683 if (config_dock_floating) {
684 if ((n = parse_find_node("floatingX", node)))
685 config_dock_x = parse_int(doc, n);
686 if ((n = parse_find_node("floatingY", node)))
687 config_dock_y = parse_int(doc, n);
689 if ((n = parse_find_node("noStrut", node)))
690 config_dock_nostrut = parse_bool(doc, n);
692 if ((n = parse_find_node("stacking", node))) {
693 if (parse_contains("above", doc, n))
694 config_dock_layer = OB_STACKING_LAYER_ABOVE;
695 else if (parse_contains("normal", doc, n))
696 config_dock_layer = OB_STACKING_LAYER_NORMAL;
697 else if (parse_contains("below", doc, n))
698 config_dock_layer = OB_STACKING_LAYER_BELOW;
700 if ((n = parse_find_node("direction", node))) {
701 if (parse_contains("horizontal", doc, n))
702 config_dock_orient = OB_ORIENTATION_HORZ;
703 else if (parse_contains("vertical", doc, n))
704 config_dock_orient = OB_ORIENTATION_VERT;
706 if ((n = parse_find_node("autoHide", node)))
707 config_dock_hide = parse_bool(doc, n);
708 if ((n = parse_find_node("hideDelay", node)))
709 config_dock_hide_delay = parse_int(doc, n) * 1000;
710 if ((n = parse_find_node("showDelay", node)))
711 config_dock_show_delay = parse_int(doc, n) * 1000;
712 if ((n = parse_find_node("moveButton", node))) {
713 gchar *str = parse_string(doc, n);
715 if (translate_button(str, &s, &b)) {
716 config_dock_app_move_button = b;
717 config_dock_app_move_modifiers = s;
719 g_message(_("Invalid button '%s' specified in config file"), str);
725 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
729 for (node = node->children; node; node = node->next) {
730 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
733 c = parse_string(doc, node);
734 config_menu_files = g_slist_append(config_menu_files,
735 parse_expand_tilde(c));
738 if ((n = parse_find_node("hideDelay", node)))
739 config_menu_hide_delay = parse_int(doc, n);
740 if ((n = parse_find_node("middle", node)))
741 config_menu_middle = parse_bool(doc, n);
742 if ((n = parse_find_node("submenuShowDelay", node)))
743 config_submenu_show_delay = parse_int(doc, n);
744 if ((n = parse_find_node("applicationIcons", node)))
745 config_menu_client_list_icons = parse_bool(doc, n);
749 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
754 node = node->children;
755 if ((n = parse_find_node("strength", node)))
756 config_resist_win = parse_int(doc, n);
757 if ((n = parse_find_node("screen_edge_strength", node)))
758 config_resist_edge = parse_int(doc, n);
764 const gchar *actname;
767 static void bind_default_keyboard()
770 ObDefKeyBind binds[] = {
771 { "A-Tab", "NextWindow" },
772 { "S-A-Tab", "PreviousWindow" },
777 for (it = binds; it->key; ++it) {
778 GList *l = g_list_append(NULL, g_strdup(it->key));
779 keyboard_bind(l, action_from_string(it->actname,
780 OB_USER_ACTION_KEYBOARD_KEY));
787 const gchar *context;
788 const ObMouseAction mact;
789 const gchar *actname;
792 static void bind_default_mouse()
795 ObDefMouseBind binds[] = {
796 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
797 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
798 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
799 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
800 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
801 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
802 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
803 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
804 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
805 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
806 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
807 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
808 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
809 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
810 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
811 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
812 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
813 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
814 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
815 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
816 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
817 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
818 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
819 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
820 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
821 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
822 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
823 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
824 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
825 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
826 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
827 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
828 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
829 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
830 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
831 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
832 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
833 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
834 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
835 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
836 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
837 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
838 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
839 { NULL, NULL, 0, NULL }
842 for (it = binds; it->button; ++it) {
845 case OB_MOUSE_ACTION_PRESS:
846 uact = OB_USER_ACTION_MOUSE_PRESS; break;
847 case OB_MOUSE_ACTION_RELEASE:
848 uact = OB_USER_ACTION_MOUSE_RELEASE; break;
849 case OB_MOUSE_ACTION_CLICK:
850 uact = OB_USER_ACTION_MOUSE_CLICK; break;
851 case OB_MOUSE_ACTION_DOUBLE_CLICK:
852 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK; break;
853 case OB_MOUSE_ACTION_MOTION:
854 uact = OB_USER_ACTION_MOUSE_MOTION; break;
856 g_assert_not_reached();
858 mouse_bind(it->button, it->context, it->mact,
859 action_from_string(it->actname, uact));
863 void config_startup(ObParseInst *i)
865 config_focus_new = TRUE;
866 config_focus_follow = FALSE;
867 config_focus_delay = 0;
868 config_focus_raise = FALSE;
869 config_focus_last = TRUE;
870 config_focus_under_mouse = FALSE;
872 parse_register(i, "focus", parse_focus, NULL);
874 config_place_policy = OB_PLACE_POLICY_SMART;
875 config_place_center = TRUE;
877 parse_register(i, "placement", parse_placement, NULL);
881 config_animate_iconify = TRUE;
882 config_title_layout = g_strdup("NLIMC");
883 config_theme_keepborder = TRUE;
885 config_font_activewindow = NULL;
886 config_font_inactivewindow = NULL;
887 config_font_menuitem = NULL;
888 config_font_menutitle = NULL;
890 parse_register(i, "theme", parse_theme, NULL);
892 config_desktops_num = 4;
893 config_screen_firstdesk = 1;
894 config_desktops_names = NULL;
896 parse_register(i, "desktops", parse_desktops, NULL);
898 config_resize_redraw = TRUE;
899 config_resize_four_corners = FALSE;
900 config_resize_popup_show = 1; /* nonpixel increments */
901 config_resize_popup_pos = 0; /* center of client */
903 parse_register(i, "resize", parse_resize, NULL);
905 config_dock_layer = OB_STACKING_LAYER_ABOVE;
906 config_dock_pos = OB_DIRECTION_NORTHEAST;
907 config_dock_floating = FALSE;
908 config_dock_nostrut = FALSE;
911 config_dock_orient = OB_ORIENTATION_VERT;
912 config_dock_hide = FALSE;
913 config_dock_hide_delay = 300;
914 config_dock_show_delay = 300;
915 config_dock_app_move_button = 2; /* middle */
916 config_dock_app_move_modifiers = 0;
918 parse_register(i, "dock", parse_dock, NULL);
920 translate_key("C-g", &config_keyboard_reset_state,
921 &config_keyboard_reset_keycode);
923 bind_default_keyboard();
925 parse_register(i, "keyboard", parse_keyboard, NULL);
927 config_mouse_threshold = 8;
928 config_mouse_dclicktime = 200;
930 bind_default_mouse();
932 parse_register(i, "mouse", parse_mouse, NULL);
934 config_resist_win = 10;
935 config_resist_edge = 20;
937 parse_register(i, "resistance", parse_resistance, NULL);
939 config_menu_hide_delay = 250;
940 config_menu_middle = FALSE;
941 config_submenu_show_delay = 0;
942 config_menu_client_list_icons = TRUE;
943 config_menu_files = NULL;
945 parse_register(i, "menu", parse_menu, NULL);
947 config_per_app_settings = NULL;
949 parse_register(i, "applications", parse_per_app_settings, NULL);
952 void config_shutdown()
956 g_free(config_theme);
958 g_free(config_title_layout);
960 RrFontClose(config_font_activewindow);
961 RrFontClose(config_font_inactivewindow);
962 RrFontClose(config_font_menuitem);
963 RrFontClose(config_font_menutitle);
965 for (it = config_desktops_names; it; it = g_slist_next(it))
967 g_slist_free(config_desktops_names);
969 for (it = config_menu_files; it; it = g_slist_next(it))
971 g_slist_free(config_menu_files);
973 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
974 ObAppSettings *itd = (ObAppSettings *)it->data;
975 if (itd->name) g_pattern_spec_free(itd->name);
976 if (itd->role) g_pattern_spec_free(itd->role);
977 if (itd->class) g_pattern_spec_free(itd->class);
980 g_slist_free(config_per_app_settings);