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 gboolean config_place_active;
43 StrutPartial config_margins;
46 gboolean config_theme_keepborder;
48 gchar *config_title_layout;
50 gboolean config_animate_iconify;
52 RrFont *config_font_activewindow;
53 RrFont *config_font_inactivewindow;
54 RrFont *config_font_menuitem;
55 RrFont *config_font_menutitle;
56 RrFont *config_font_osd;
58 gint config_desktops_num;
59 GSList *config_desktops_names;
60 guint config_screen_firstdesk;
61 guint config_desktop_popup_time;
63 gboolean config_resize_redraw;
64 gboolean config_resize_four_corners;
65 gint config_resize_popup_show;
66 gint config_resize_popup_pos;
68 ObStackingLayer config_dock_layer;
69 gboolean config_dock_floating;
70 gboolean config_dock_nostrut;
71 ObDirection config_dock_pos;
74 ObOrientation config_dock_orient;
75 gboolean config_dock_hide;
76 guint config_dock_hide_delay;
77 guint config_dock_show_delay;
78 guint config_dock_app_move_button;
79 guint config_dock_app_move_modifiers;
81 guint config_keyboard_reset_keycode;
82 guint config_keyboard_reset_state;
84 gint config_mouse_threshold;
85 gint config_mouse_dclicktime;
86 gint config_mouse_screenedgetime;
88 guint config_menu_hide_delay;
89 gboolean config_menu_middle;
90 guint config_submenu_show_delay;
91 gboolean config_menu_client_list_icons;
93 GSList *config_menu_files;
95 gint config_resist_win;
96 gint config_resist_edge;
98 GSList *config_per_app_settings;
100 ObAppSettings* config_create_app_settings(void)
102 ObAppSettings *settings = g_new0(ObAppSettings, 1);
103 settings->decor = -1;
104 settings->shade = -1;
105 settings->monitor = -1;
106 settings->focus = -1;
107 settings->desktop = 0;
108 settings->layer = -2;
109 settings->iconic = -1;
110 settings->skip_pager = -1;
111 settings->skip_taskbar = -1;
112 settings->fullscreen = -1;
113 settings->max_horz = -1;
114 settings->max_vert = -1;
118 #define copy_if(setting, default) \
119 if (src->setting != default) dst->setting = src->setting
120 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
123 g_assert(src != NULL);
124 g_assert(dst != NULL);
132 copy_if(skip_pager, -1);
133 copy_if(skip_taskbar, -1);
134 copy_if(fullscreen, -1);
135 copy_if(max_horz, -1);
136 copy_if(max_vert, -1);
138 if (src->pos_given) {
139 dst->pos_given = TRUE;
140 dst->center_x = src->center_x;
141 dst->center_y = src->center_y;
142 dst->opposite_x = src->opposite_x;
143 dst->opposite_y = src->opposite_y;
144 dst->position.x = src->position.x;
145 dst->position.y = src->position.y;
146 dst->monitor = src->monitor;
152 <application name="aterm">
155 <application name="Rhythmbox">
162 .. there is a lot more settings available
167 /* Manages settings for individual applications.
168 Some notes: monitor is the screen number in a multi monitor
169 (Xinerama) setup (starting from 0) or mouse, meaning the
170 monitor the pointer is on. Default: mouse.
171 Layer can be three values, above (Always on top), below
172 (Always on bottom) and everything else (normal behaviour).
173 Positions can be an integer value or center, which will
174 center the window in the specified axis. Position is within
175 the monitor, so <position><x>center</x></position><monitor>2</monitor>
176 will center the window on the second monitor.
178 static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
179 xmlNodePtr node, gpointer data)
181 xmlNodePtr app = parse_find_node("application", node->children);
182 gchar *name = NULL, *class = NULL, *role = NULL;
183 gboolean name_set, class_set;
184 gboolean x_pos_given;
187 name_set = class_set = x_pos_given = FALSE;
189 class_set = parse_attr_string("class", app, &class);
190 name_set = parse_attr_string("name", app, &name);
191 if (class_set || name_set) {
193 ObAppSettings *settings = config_create_app_settings();;
196 settings->name = g_pattern_spec_new(name);
199 settings->class = g_pattern_spec_new(class);
201 if (parse_attr_string("role", app, &role))
202 settings->role = g_pattern_spec_new(role);
204 if ((n = parse_find_node("decor", app->children)))
205 if (!parse_contains("default", doc, n))
206 settings->decor = parse_bool(doc, n);
208 if ((n = parse_find_node("shade", app->children)))
209 if (!parse_contains("default", doc, n))
210 settings->shade = parse_bool(doc, n);
212 if ((n = parse_find_node("position", app->children))) {
213 if ((c = parse_find_node("x", n->children)))
214 if (!parse_contains("default", doc, c)) {
215 gchar *s = parse_string(doc, c);
216 if (!g_ascii_strcasecmp(s, "center")) {
217 settings->center_x = TRUE;
221 settings->opposite_x = TRUE;
222 if (s[0] == '-' || s[0] == '+')
223 settings->position.x = atoi(s+1);
225 settings->position.x = atoi(s);
231 if (x_pos_given && (c = parse_find_node("y", n->children)))
232 if (!parse_contains("default", doc, c)) {
233 gchar *s = parse_string(doc, c);
234 if (!g_ascii_strcasecmp(s, "center")) {
235 settings->center_y = TRUE;
236 settings->pos_given = TRUE;
239 settings->opposite_y = TRUE;
240 if (s[0] == '-' || s[0] == '+')
241 settings->position.y = atoi(s+1);
243 settings->position.y = atoi(s);
244 settings->pos_given = TRUE;
249 if (settings->pos_given &&
250 (c = parse_find_node("monitor", n->children)))
251 if (!parse_contains("default", doc, c)) {
252 gchar *s = parse_string(doc, c);
253 if (!g_ascii_strcasecmp(s, "mouse"))
254 settings->monitor = 0;
256 settings->monitor = parse_int(doc, c) + 1;
261 if ((n = parse_find_node("focus", app->children)))
262 if (!parse_contains("default", doc, n))
263 settings->focus = parse_bool(doc, n);
265 if ((n = parse_find_node("desktop", app->children))) {
266 if (!parse_contains("default", doc, n)) {
267 gchar *s = parse_string(doc, n);
268 if (!g_ascii_strcasecmp(s, "all"))
269 settings->desktop = DESKTOP_ALL;
271 gint i = parse_int(doc, n);
273 settings->desktop = i;
279 if ((n = parse_find_node("layer", app->children)))
280 if (!parse_contains("default", doc, n)) {
281 gchar *s = parse_string(doc, n);
282 if (!g_ascii_strcasecmp(s, "above"))
284 else if (!g_ascii_strcasecmp(s, "below"))
285 settings->layer = -1;
291 if ((n = parse_find_node("iconic", app->children)))
292 if (!parse_contains("default", doc, n))
293 settings->iconic = parse_bool(doc, n);
295 if ((n = parse_find_node("skip_pager", app->children)))
296 if (!parse_contains("default", doc, n))
297 settings->skip_pager = parse_bool(doc, n);
299 if ((n = parse_find_node("skip_taskbar", app->children)))
300 if (!parse_contains("default", doc, n))
301 settings->skip_taskbar = parse_bool(doc, n);
303 if ((n = parse_find_node("fullscreen", app->children)))
304 if (!parse_contains("default", doc, n))
305 settings->fullscreen = parse_bool(doc, n);
307 if ((n = parse_find_node("maximized", app->children)))
308 if (!parse_contains("default", doc, n)) {
309 gchar *s = parse_string(doc, n);
310 if (!g_ascii_strcasecmp(s, "horizontal")) {
311 settings->max_horz = TRUE;
312 settings->max_vert = FALSE;
313 } else if (!g_ascii_strcasecmp(s, "vertical")) {
314 settings->max_horz = FALSE;
315 settings->max_vert = TRUE;
317 settings->max_horz = settings->max_vert =
322 config_per_app_settings = g_slist_append(config_per_app_settings,
323 (gpointer) settings);
327 name = class = role = NULL;
330 app = parse_find_node("application", app->next);
337 <action name="ChangeDesktop">
344 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
349 gboolean is_chroot = FALSE;
351 if (!parse_attr_string("key", node, &key))
354 parse_attr_bool("chroot", node, &is_chroot);
356 keylist = g_list_append(keylist, key);
358 if ((n = parse_find_node("keybind", node->children))) {
360 parse_key(i, doc, n, keylist);
361 n = parse_find_node("keybind", n->next);
364 else if ((n = parse_find_node("action", node->children))) {
366 ObActionsAct *action;
368 action = actions_parse(i, doc, n);
370 keyboard_bind(keylist, action);
371 n = parse_find_node("action", n->next);
376 keyboard_chroot(keylist);
379 keylist = g_list_delete_link(keylist, g_list_last(keylist));
382 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
388 keyboard_unbind_all();
390 if ((n = parse_find_node("chainQuitKey", node->children))) {
391 key = parse_string(doc, n);
392 translate_key(key, &config_keyboard_reset_state,
393 &config_keyboard_reset_keycode);
397 if ((n = parse_find_node("keybind", node->children)))
399 parse_key(i, doc, n, NULL);
400 n = parse_find_node("keybind", n->next);
406 <context name="Titlebar">
407 <mousebind button="Left" action="Press">
408 <action name="Raise"></action>
414 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
417 xmlNodePtr n, nbut, nact;
424 node = node->children;
426 if ((n = parse_find_node("dragThreshold", node)))
427 config_mouse_threshold = parse_int(doc, n);
428 if ((n = parse_find_node("doubleClickTime", node)))
429 config_mouse_dclicktime = parse_int(doc, n);
430 if ((n = parse_find_node("screenEdgeWarpTime", node)))
431 config_mouse_screenedgetime = parse_int(doc, n);
433 n = parse_find_node("context", node);
435 if (!parse_attr_string("name", n, &contextstr))
437 nbut = parse_find_node("mousebind", n->children);
439 if (!parse_attr_string("button", nbut, &buttonstr))
441 if (parse_attr_contains("press", nbut, "action")) {
442 mact = OB_MOUSE_ACTION_PRESS;
443 } else if (parse_attr_contains("release", nbut, "action")) {
444 mact = OB_MOUSE_ACTION_RELEASE;
445 } else if (parse_attr_contains("click", nbut, "action")) {
446 mact = OB_MOUSE_ACTION_CLICK;
447 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
448 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
449 } else if (parse_attr_contains("drag", nbut, "action")) {
450 mact = OB_MOUSE_ACTION_MOTION;
453 nact = parse_find_node("action", nbut->children);
455 ObActionsAct *action;
457 if ((action = actions_parse(i, doc, nact)))
458 mouse_bind(buttonstr, contextstr, mact, action);
459 nact = parse_find_node("action", nact->next);
463 nbut = parse_find_node("mousebind", nbut->next);
467 n = parse_find_node("context", n->next);
471 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
476 node = node->children;
478 if ((n = parse_find_node("focusNew", node)))
479 config_focus_new = parse_bool(doc, n);
480 if ((n = parse_find_node("followMouse", node)))
481 config_focus_follow = parse_bool(doc, n);
482 if ((n = parse_find_node("focusDelay", node)))
483 config_focus_delay = parse_int(doc, n);
484 if ((n = parse_find_node("raiseOnFocus", node)))
485 config_focus_raise = parse_bool(doc, n);
486 if ((n = parse_find_node("focusLast", node)))
487 config_focus_last = parse_bool(doc, n);
488 if ((n = parse_find_node("underMouse", node)))
489 config_focus_under_mouse = parse_bool(doc, n);
492 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
497 node = node->children;
499 if ((n = parse_find_node("policy", node)))
500 if (parse_contains("UnderMouse", doc, n))
501 config_place_policy = OB_PLACE_POLICY_MOUSE;
502 if ((n = parse_find_node("center", node)))
503 config_place_center = parse_bool(doc, n);
504 if ((n = parse_find_node("active", node)))
505 config_place_active = parse_bool(doc, n);
508 static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
513 node = node->children;
515 if ((n = parse_find_node("top", node)))
516 config_margins.top = MAX(0, parse_int(doc, n));
517 if ((n = parse_find_node("left", node)))
518 config_margins.left = MAX(0, parse_int(doc, n));
519 if ((n = parse_find_node("right", node)))
520 config_margins.right = MAX(0, parse_int(doc, n));
521 if ((n = parse_find_node("bottom", node)))
522 config_margins.bottom = MAX(0, parse_int(doc, n));
525 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
530 node = node->children;
532 if ((n = parse_find_node("name", node))) {
535 g_free(config_theme);
536 c = parse_string(doc, n);
537 config_theme = parse_expand_tilde(c);
540 if ((n = parse_find_node("titleLayout", node))) {
543 g_free(config_title_layout);
544 config_title_layout = parse_string(doc, n);
546 /* replace duplicates with spaces */
547 for (c = config_title_layout; *c != '\0'; ++c)
548 for (d = c+1; *d != '\0'; ++d)
549 if (*c == *d) *d = ' ';
551 if ((n = parse_find_node("keepBorder", node)))
552 config_theme_keepborder = parse_bool(doc, n);
553 if ((n = parse_find_node("animateIconify", node)))
554 config_animate_iconify = parse_bool(doc, n);
556 n = parse_find_node("font", node);
560 gchar *name = g_strdup(RrDefaultFontFamily);
561 gint size = RrDefaultFontSize;
562 RrFontWeight weight = RrDefaultFontWeight;
563 RrFontSlant slant = RrDefaultFontSlant;
565 if (parse_attr_contains("ActiveWindow", n, "place"))
566 font = &config_font_activewindow;
567 else if (parse_attr_contains("InactiveWindow", n, "place"))
568 font = &config_font_inactivewindow;
569 else if (parse_attr_contains("MenuHeader", n, "place"))
570 font = &config_font_menutitle;
571 else if (parse_attr_contains("MenuItem", n, "place"))
572 font = &config_font_menuitem;
573 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
574 font = &config_font_osd;
578 if ((fnode = parse_find_node("name", n->children))) {
580 name = parse_string(doc, fnode);
582 if ((fnode = parse_find_node("size", n->children))) {
583 int s = parse_int(doc, fnode);
586 if ((fnode = parse_find_node("weight", n->children))) {
587 gchar *w = parse_string(doc, fnode);
588 if (!g_ascii_strcasecmp(w, "Bold"))
589 weight = RR_FONTWEIGHT_BOLD;
592 if ((fnode = parse_find_node("slant", n->children))) {
593 gchar *s = parse_string(doc, fnode);
594 if (!g_ascii_strcasecmp(s, "Italic"))
595 slant = RR_FONTSLANT_ITALIC;
596 if (!g_ascii_strcasecmp(s, "Oblique"))
597 slant = RR_FONTSLANT_OBLIQUE;
601 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
604 n = parse_find_node("font", n->next);
608 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
613 node = node->children;
615 if ((n = parse_find_node("number", node))) {
616 gint d = parse_int(doc, n);
618 config_desktops_num = d;
620 if ((n = parse_find_node("firstdesk", node))) {
621 gint d = parse_int(doc, n);
623 config_screen_firstdesk = (unsigned) d;
625 if ((n = parse_find_node("names", node))) {
629 for (it = config_desktops_names; it; it = it->next)
631 g_slist_free(config_desktops_names);
632 config_desktops_names = NULL;
634 nname = parse_find_node("name", n->children);
636 config_desktops_names = g_slist_append(config_desktops_names,
637 parse_string(doc, nname));
638 nname = parse_find_node("name", nname->next);
641 if ((n = parse_find_node("popupTime", node)))
642 config_desktop_popup_time = parse_int(doc, n);
645 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
650 node = node->children;
652 if ((n = parse_find_node("drawContents", node)))
653 config_resize_redraw = parse_bool(doc, n);
654 if ((n = parse_find_node("popupShow", node))) {
655 config_resize_popup_show = parse_int(doc, n);
656 if (parse_contains("Always", doc, n))
657 config_resize_popup_show = 2;
658 else if (parse_contains("Never", doc, n))
659 config_resize_popup_show = 0;
660 else if (parse_contains("Nonpixel", doc, n))
661 config_resize_popup_show = 1;
663 if ((n = parse_find_node("popupPosition", node))) {
664 config_resize_popup_pos = parse_int(doc, n);
665 if (parse_contains("Top", doc, n))
666 config_resize_popup_pos = 1;
667 else if (parse_contains("Center", doc, n))
668 config_resize_popup_pos = 0;
672 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
677 node = node->children;
679 if ((n = parse_find_node("position", node))) {
680 if (parse_contains("TopLeft", doc, n))
681 config_dock_floating = FALSE,
682 config_dock_pos = OB_DIRECTION_NORTHWEST;
683 else if (parse_contains("Top", doc, n))
684 config_dock_floating = FALSE,
685 config_dock_pos = OB_DIRECTION_NORTH;
686 else if (parse_contains("TopRight", doc, n))
687 config_dock_floating = FALSE,
688 config_dock_pos = OB_DIRECTION_NORTHEAST;
689 else if (parse_contains("Right", doc, n))
690 config_dock_floating = FALSE,
691 config_dock_pos = OB_DIRECTION_EAST;
692 else if (parse_contains("BottomRight", doc, n))
693 config_dock_floating = FALSE,
694 config_dock_pos = OB_DIRECTION_SOUTHEAST;
695 else if (parse_contains("Bottom", doc, n))
696 config_dock_floating = FALSE,
697 config_dock_pos = OB_DIRECTION_SOUTH;
698 else if (parse_contains("BottomLeft", doc, n))
699 config_dock_floating = FALSE,
700 config_dock_pos = OB_DIRECTION_SOUTHWEST;
701 else if (parse_contains("Left", doc, n))
702 config_dock_floating = FALSE,
703 config_dock_pos = OB_DIRECTION_WEST;
704 else if (parse_contains("Floating", doc, n))
705 config_dock_floating = TRUE;
707 if (config_dock_floating) {
708 if ((n = parse_find_node("floatingX", node)))
709 config_dock_x = parse_int(doc, n);
710 if ((n = parse_find_node("floatingY", node)))
711 config_dock_y = parse_int(doc, n);
713 if ((n = parse_find_node("noStrut", node)))
714 config_dock_nostrut = parse_bool(doc, n);
716 if ((n = parse_find_node("stacking", node))) {
717 if (parse_contains("above", doc, n))
718 config_dock_layer = OB_STACKING_LAYER_ABOVE;
719 else if (parse_contains("normal", doc, n))
720 config_dock_layer = OB_STACKING_LAYER_NORMAL;
721 else if (parse_contains("below", doc, n))
722 config_dock_layer = OB_STACKING_LAYER_BELOW;
724 if ((n = parse_find_node("direction", node))) {
725 if (parse_contains("horizontal", doc, n))
726 config_dock_orient = OB_ORIENTATION_HORZ;
727 else if (parse_contains("vertical", doc, n))
728 config_dock_orient = OB_ORIENTATION_VERT;
730 if ((n = parse_find_node("autoHide", node)))
731 config_dock_hide = parse_bool(doc, n);
732 if ((n = parse_find_node("hideDelay", node)))
733 config_dock_hide_delay = parse_int(doc, n);
734 if ((n = parse_find_node("showDelay", node)))
735 config_dock_show_delay = parse_int(doc, n);
736 if ((n = parse_find_node("moveButton", node))) {
737 gchar *str = parse_string(doc, n);
739 if (translate_button(str, &s, &b)) {
740 config_dock_app_move_button = b;
741 config_dock_app_move_modifiers = s;
743 g_message(_("Invalid button '%s' specified in config file"), str);
749 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
753 for (node = node->children; node; node = node->next) {
754 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
757 c = parse_string(doc, node);
758 config_menu_files = g_slist_append(config_menu_files,
759 parse_expand_tilde(c));
762 if ((n = parse_find_node("hideDelay", node)))
763 config_menu_hide_delay = parse_int(doc, n);
764 if ((n = parse_find_node("middle", node)))
765 config_menu_middle = parse_bool(doc, n);
766 if ((n = parse_find_node("submenuShowDelay", node)))
767 config_submenu_show_delay = parse_int(doc, n);
768 if ((n = parse_find_node("applicationIcons", node)))
769 config_menu_client_list_icons = parse_bool(doc, n);
773 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
778 node = node->children;
779 if ((n = parse_find_node("strength", node)))
780 config_resist_win = parse_int(doc, n);
781 if ((n = parse_find_node("screen_edge_strength", node)))
782 config_resist_edge = parse_int(doc, n);
788 const gchar *actname;
791 static void bind_default_keyboard(void)
794 ObDefKeyBind binds[] = {
795 { "A-Tab", "NextWindow" },
796 { "S-A-Tab", "PreviousWindow" },
800 for (it = binds; it->key; ++it) {
801 GList *l = g_list_append(NULL, g_strdup(it->key));
802 keyboard_bind(l, actions_parse_string(it->actname));
809 const gchar *context;
810 const ObMouseAction mact;
811 const gchar *actname;
814 static void bind_default_mouse(void)
817 ObDefMouseBind binds[] = {
818 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
819 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
820 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
821 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
822 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
823 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
824 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
825 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
826 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
827 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
828 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
829 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
830 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
831 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
832 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
833 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
834 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
835 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
836 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
837 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
838 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
839 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
840 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
841 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
842 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
843 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
844 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
845 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
846 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
847 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
848 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
849 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
850 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
851 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
852 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
853 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
854 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
855 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
856 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
857 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
858 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
859 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
860 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
861 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
862 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
863 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
864 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
865 { NULL, NULL, 0, NULL }
868 for (it = binds; it->button; ++it)
869 mouse_bind(it->button, it->context, it->mact,
870 actions_parse_string(it->actname));
873 void config_startup(ObParseInst *i)
875 config_focus_new = TRUE;
876 config_focus_follow = FALSE;
877 config_focus_delay = 0;
878 config_focus_raise = FALSE;
879 config_focus_last = TRUE;
880 config_focus_under_mouse = FALSE;
882 parse_register(i, "focus", parse_focus, NULL);
884 config_place_policy = OB_PLACE_POLICY_SMART;
885 config_place_center = TRUE;
886 config_place_active = FALSE;
888 parse_register(i, "placement", parse_placement, NULL);
890 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
892 parse_register(i, "margins", parse_margins, NULL);
896 config_animate_iconify = TRUE;
897 config_title_layout = g_strdup("NLIMC");
898 config_theme_keepborder = TRUE;
900 config_font_activewindow = NULL;
901 config_font_inactivewindow = NULL;
902 config_font_menuitem = NULL;
903 config_font_menutitle = NULL;
905 parse_register(i, "theme", parse_theme, NULL);
907 config_desktops_num = 4;
908 config_screen_firstdesk = 1;
909 config_desktops_names = NULL;
910 config_desktop_popup_time = 875;
912 parse_register(i, "desktops", parse_desktops, NULL);
914 config_resize_redraw = TRUE;
915 config_resize_four_corners = FALSE;
916 config_resize_popup_show = 1; /* nonpixel increments */
917 config_resize_popup_pos = 0; /* center of client */
919 parse_register(i, "resize", parse_resize, NULL);
921 config_dock_layer = OB_STACKING_LAYER_ABOVE;
922 config_dock_pos = OB_DIRECTION_NORTHEAST;
923 config_dock_floating = FALSE;
924 config_dock_nostrut = FALSE;
927 config_dock_orient = OB_ORIENTATION_VERT;
928 config_dock_hide = FALSE;
929 config_dock_hide_delay = 300;
930 config_dock_show_delay = 300;
931 config_dock_app_move_button = 2; /* middle */
932 config_dock_app_move_modifiers = 0;
934 parse_register(i, "dock", parse_dock, NULL);
936 translate_key("C-g", &config_keyboard_reset_state,
937 &config_keyboard_reset_keycode);
939 bind_default_keyboard();
941 parse_register(i, "keyboard", parse_keyboard, NULL);
943 config_mouse_threshold = 8;
944 config_mouse_dclicktime = 200;
945 config_mouse_screenedgetime = 400;
947 bind_default_mouse();
949 parse_register(i, "mouse", parse_mouse, NULL);
951 config_resist_win = 10;
952 config_resist_edge = 20;
954 parse_register(i, "resistance", parse_resistance, NULL);
956 config_menu_hide_delay = 250;
957 config_menu_middle = FALSE;
958 config_submenu_show_delay = 0;
959 config_menu_client_list_icons = TRUE;
960 config_menu_files = NULL;
962 parse_register(i, "menu", parse_menu, NULL);
964 config_per_app_settings = NULL;
966 parse_register(i, "applications", parse_per_app_settings, NULL);
969 void config_shutdown(void)
973 g_free(config_theme);
975 g_free(config_title_layout);
977 RrFontClose(config_font_activewindow);
978 RrFontClose(config_font_inactivewindow);
979 RrFontClose(config_font_menuitem);
980 RrFontClose(config_font_menutitle);
982 for (it = config_desktops_names; it; it = g_slist_next(it))
984 g_slist_free(config_desktops_names);
986 for (it = config_menu_files; it; it = g_slist_next(it))
988 g_slist_free(config_menu_files);
990 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
991 ObAppSettings *itd = (ObAppSettings *)it->data;
992 if (itd->name) g_pattern_spec_free(itd->name);
993 if (itd->role) g_pattern_spec_free(itd->role);
994 if (itd->class) g_pattern_spec_free(itd->class);
997 g_slist_free(config_per_app_settings);