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;
40 gboolean config_place_active;
42 StrutPartial config_margins;
45 gboolean config_theme_keepborder;
47 gchar *config_title_layout;
49 gboolean config_animate_iconify;
51 RrFont *config_font_activewindow;
52 RrFont *config_font_inactivewindow;
53 RrFont *config_font_menuitem;
54 RrFont *config_font_menutitle;
55 RrFont *config_font_osd;
57 gint config_desktops_num;
58 GSList *config_desktops_names;
59 guint config_screen_firstdesk;
60 guint config_desktop_popup_time;
62 gboolean config_resize_redraw;
63 gint config_resize_popup_show;
64 ObResizePopupPos config_resize_popup_pos;
65 GravityPoint config_resize_popup_fixed;
67 ObStackingLayer config_dock_layer;
68 gboolean config_dock_floating;
69 gboolean config_dock_nostrut;
70 ObDirection config_dock_pos;
73 ObOrientation config_dock_orient;
74 gboolean config_dock_hide;
75 guint config_dock_hide_delay;
76 guint config_dock_show_delay;
77 guint config_dock_app_move_button;
78 guint config_dock_app_move_modifiers;
80 guint config_keyboard_reset_keycode;
81 guint config_keyboard_reset_state;
83 gint config_mouse_threshold;
84 gint config_mouse_dclicktime;
85 gint config_mouse_screenedgetime;
87 guint config_menu_hide_delay;
88 gboolean config_menu_middle;
89 guint config_submenu_show_delay;
90 gboolean config_menu_client_list_icons;
92 GSList *config_menu_files;
94 gint config_resist_win;
95 gint config_resist_edge;
97 GSList *config_per_app_settings;
99 ObAppSettings* config_create_app_settings(void)
101 ObAppSettings *settings = g_new0(ObAppSettings, 1);
102 settings->decor = -1;
103 settings->shade = -1;
104 settings->monitor = -1;
105 settings->focus = -1;
106 settings->desktop = 0;
107 settings->layer = -2;
108 settings->iconic = -1;
109 settings->skip_pager = -1;
110 settings->skip_taskbar = -1;
111 settings->fullscreen = -1;
112 settings->max_horz = -1;
113 settings->max_vert = -1;
117 #define copy_if(setting, default) \
118 if (src->setting != default) dst->setting = src->setting
119 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
122 g_assert(src != NULL);
123 g_assert(dst != NULL);
131 copy_if(skip_pager, -1);
132 copy_if(skip_taskbar, -1);
133 copy_if(fullscreen, -1);
134 copy_if(max_horz, -1);
135 copy_if(max_vert, -1);
137 if (src->pos_given) {
138 dst->pos_given = TRUE;
139 dst->position = src->position;
140 dst->monitor = src->monitor;
144 static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
147 gchar *s = parse_string(doc, node);
148 if (!g_ascii_strcasecmp(s, "center"))
153 if (s[0] == '-' || s[0] == '+')
163 <application name="aterm">
166 <application name="Rhythmbox">
173 .. there is a lot more settings available
178 /* Manages settings for individual applications.
179 Some notes: monitor is the screen number in a multi monitor
180 (Xinerama) setup (starting from 0) or mouse, meaning the
181 monitor the pointer is on. Default: mouse.
182 Layer can be three values, above (Always on top), below
183 (Always on bottom) and everything else (normal behaviour).
184 Positions can be an integer value or center, which will
185 center the window in the specified axis. Position is within
186 the monitor, so <position><x>center</x></position><monitor>2</monitor>
187 will center the window on the second monitor.
189 static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
190 xmlNodePtr node, gpointer data)
192 xmlNodePtr app = parse_find_node("application", node->children);
193 gchar *name = NULL, *class = NULL, *role = NULL;
194 gboolean name_set, class_set;
195 gboolean x_pos_given;
198 name_set = class_set = x_pos_given = FALSE;
200 class_set = parse_attr_string("class", app, &class);
201 name_set = parse_attr_string("name", app, &name);
202 if (class_set || name_set) {
204 ObAppSettings *settings = config_create_app_settings();;
207 settings->name = g_pattern_spec_new(name);
210 settings->class = g_pattern_spec_new(class);
212 if (parse_attr_string("role", app, &role))
213 settings->role = g_pattern_spec_new(role);
215 if ((n = parse_find_node("decor", app->children)))
216 if (!parse_contains("default", doc, n))
217 settings->decor = parse_bool(doc, n);
219 if ((n = parse_find_node("shade", app->children)))
220 if (!parse_contains("default", doc, n))
221 settings->shade = parse_bool(doc, n);
223 if ((n = parse_find_node("position", app->children))) {
224 if ((c = parse_find_node("x", n->children)))
225 if (!parse_contains("default", doc, c)) {
226 config_parse_gravity_coord(doc, c,
227 &settings->position.x);
231 if (x_pos_given && (c = parse_find_node("y", n->children)))
232 if (!parse_contains("default", doc, c)) {
233 config_parse_gravity_coord(doc, c,
234 &settings->position.y);
235 settings->pos_given = TRUE;
238 if (settings->pos_given &&
239 (c = parse_find_node("monitor", n->children)))
240 if (!parse_contains("default", doc, c)) {
241 gchar *s = parse_string(doc, c);
242 if (!g_ascii_strcasecmp(s, "mouse"))
243 settings->monitor = 0;
245 settings->monitor = parse_int(doc, c) + 1;
250 if ((n = parse_find_node("focus", app->children)))
251 if (!parse_contains("default", doc, n))
252 settings->focus = parse_bool(doc, n);
254 if ((n = parse_find_node("desktop", app->children))) {
255 if (!parse_contains("default", doc, n)) {
256 gchar *s = parse_string(doc, n);
257 if (!g_ascii_strcasecmp(s, "all"))
258 settings->desktop = DESKTOP_ALL;
260 gint i = parse_int(doc, n);
262 settings->desktop = i;
268 if ((n = parse_find_node("layer", app->children)))
269 if (!parse_contains("default", doc, n)) {
270 gchar *s = parse_string(doc, n);
271 if (!g_ascii_strcasecmp(s, "above"))
273 else if (!g_ascii_strcasecmp(s, "below"))
274 settings->layer = -1;
280 if ((n = parse_find_node("iconic", app->children)))
281 if (!parse_contains("default", doc, n))
282 settings->iconic = parse_bool(doc, n);
284 if ((n = parse_find_node("skip_pager", app->children)))
285 if (!parse_contains("default", doc, n))
286 settings->skip_pager = parse_bool(doc, n);
288 if ((n = parse_find_node("skip_taskbar", app->children)))
289 if (!parse_contains("default", doc, n))
290 settings->skip_taskbar = parse_bool(doc, n);
292 if ((n = parse_find_node("fullscreen", app->children)))
293 if (!parse_contains("default", doc, n))
294 settings->fullscreen = parse_bool(doc, n);
296 if ((n = parse_find_node("maximized", app->children)))
297 if (!parse_contains("default", doc, n)) {
298 gchar *s = parse_string(doc, n);
299 if (!g_ascii_strcasecmp(s, "horizontal")) {
300 settings->max_horz = TRUE;
301 settings->max_vert = FALSE;
302 } else if (!g_ascii_strcasecmp(s, "vertical")) {
303 settings->max_horz = FALSE;
304 settings->max_vert = TRUE;
306 settings->max_horz = settings->max_vert =
311 config_per_app_settings = g_slist_append(config_per_app_settings,
312 (gpointer) settings);
316 name = class = role = NULL;
319 app = parse_find_node("application", app->next);
326 <action name="ChangeDesktop">
333 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
338 gboolean is_chroot = FALSE;
340 if (!parse_attr_string("key", node, &key))
343 parse_attr_bool("chroot", node, &is_chroot);
345 keylist = g_list_append(keylist, key);
347 if ((n = parse_find_node("keybind", node->children))) {
349 parse_key(i, doc, n, keylist);
350 n = parse_find_node("keybind", n->next);
353 else if ((n = parse_find_node("action", node->children))) {
355 ObActionsAct *action;
357 action = actions_parse(i, doc, n);
359 keyboard_bind(keylist, action);
360 n = parse_find_node("action", n->next);
365 keyboard_chroot(keylist);
368 keylist = g_list_delete_link(keylist, g_list_last(keylist));
371 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
377 keyboard_unbind_all();
379 if ((n = parse_find_node("chainQuitKey", node->children))) {
380 key = parse_string(doc, n);
381 translate_key(key, &config_keyboard_reset_state,
382 &config_keyboard_reset_keycode);
386 if ((n = parse_find_node("keybind", node->children)))
388 parse_key(i, doc, n, NULL);
389 n = parse_find_node("keybind", n->next);
395 <context name="Titlebar">
396 <mousebind button="Left" action="Press">
397 <action name="Raise"></action>
403 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
406 xmlNodePtr n, nbut, nact;
413 node = node->children;
415 if ((n = parse_find_node("dragThreshold", node)))
416 config_mouse_threshold = parse_int(doc, n);
417 if ((n = parse_find_node("doubleClickTime", node)))
418 config_mouse_dclicktime = parse_int(doc, n);
419 if ((n = parse_find_node("screenEdgeWarpTime", node)))
420 config_mouse_screenedgetime = parse_int(doc, n);
422 n = parse_find_node("context", node);
424 if (!parse_attr_string("name", n, &contextstr))
426 nbut = parse_find_node("mousebind", n->children);
428 if (!parse_attr_string("button", nbut, &buttonstr))
430 if (parse_attr_contains("press", nbut, "action")) {
431 mact = OB_MOUSE_ACTION_PRESS;
432 } else if (parse_attr_contains("release", nbut, "action")) {
433 mact = OB_MOUSE_ACTION_RELEASE;
434 } else if (parse_attr_contains("click", nbut, "action")) {
435 mact = OB_MOUSE_ACTION_CLICK;
436 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
437 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
438 } else if (parse_attr_contains("drag", nbut, "action")) {
439 mact = OB_MOUSE_ACTION_MOTION;
442 nact = parse_find_node("action", nbut->children);
444 ObActionsAct *action;
446 if ((action = actions_parse(i, doc, nact)))
447 mouse_bind(buttonstr, contextstr, mact, action);
448 nact = parse_find_node("action", nact->next);
452 nbut = parse_find_node("mousebind", nbut->next);
456 n = parse_find_node("context", n->next);
460 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
465 node = node->children;
467 if ((n = parse_find_node("focusNew", node)))
468 config_focus_new = parse_bool(doc, n);
469 if ((n = parse_find_node("followMouse", node)))
470 config_focus_follow = parse_bool(doc, n);
471 if ((n = parse_find_node("focusDelay", node)))
472 config_focus_delay = parse_int(doc, n);
473 if ((n = parse_find_node("raiseOnFocus", node)))
474 config_focus_raise = parse_bool(doc, n);
475 if ((n = parse_find_node("focusLast", node)))
476 config_focus_last = parse_bool(doc, n);
477 if ((n = parse_find_node("underMouse", node)))
478 config_focus_under_mouse = parse_bool(doc, n);
481 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
486 node = node->children;
488 if ((n = parse_find_node("policy", node)))
489 if (parse_contains("UnderMouse", doc, n))
490 config_place_policy = OB_PLACE_POLICY_MOUSE;
491 if ((n = parse_find_node("center", node)))
492 config_place_center = parse_bool(doc, n);
493 if ((n = parse_find_node("active", node)))
494 config_place_active = parse_bool(doc, n);
497 static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
502 node = node->children;
504 if ((n = parse_find_node("top", node)))
505 config_margins.top = MAX(0, parse_int(doc, n));
506 if ((n = parse_find_node("left", node)))
507 config_margins.left = MAX(0, parse_int(doc, n));
508 if ((n = parse_find_node("right", node)))
509 config_margins.right = MAX(0, parse_int(doc, n));
510 if ((n = parse_find_node("bottom", node)))
511 config_margins.bottom = MAX(0, parse_int(doc, n));
514 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
519 node = node->children;
521 if ((n = parse_find_node("name", node))) {
524 g_free(config_theme);
525 c = parse_string(doc, n);
526 config_theme = parse_expand_tilde(c);
529 if ((n = parse_find_node("titleLayout", node))) {
532 g_free(config_title_layout);
533 config_title_layout = parse_string(doc, n);
535 /* replace duplicates with spaces */
536 for (c = config_title_layout; *c != '\0'; ++c)
537 for (d = c+1; *d != '\0'; ++d)
538 if (*c == *d) *d = ' ';
540 if ((n = parse_find_node("keepBorder", node)))
541 config_theme_keepborder = parse_bool(doc, n);
542 if ((n = parse_find_node("animateIconify", node)))
543 config_animate_iconify = parse_bool(doc, n);
545 n = parse_find_node("font", node);
549 gchar *name = g_strdup(RrDefaultFontFamily);
550 gint size = RrDefaultFontSize;
551 RrFontWeight weight = RrDefaultFontWeight;
552 RrFontSlant slant = RrDefaultFontSlant;
554 if (parse_attr_contains("ActiveWindow", n, "place"))
555 font = &config_font_activewindow;
556 else if (parse_attr_contains("InactiveWindow", n, "place"))
557 font = &config_font_inactivewindow;
558 else if (parse_attr_contains("MenuHeader", n, "place"))
559 font = &config_font_menutitle;
560 else if (parse_attr_contains("MenuItem", n, "place"))
561 font = &config_font_menuitem;
562 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
563 font = &config_font_osd;
567 if ((fnode = parse_find_node("name", n->children))) {
569 name = parse_string(doc, fnode);
571 if ((fnode = parse_find_node("size", n->children))) {
572 int s = parse_int(doc, fnode);
575 if ((fnode = parse_find_node("weight", n->children))) {
576 gchar *w = parse_string(doc, fnode);
577 if (!g_ascii_strcasecmp(w, "Bold"))
578 weight = RR_FONTWEIGHT_BOLD;
581 if ((fnode = parse_find_node("slant", n->children))) {
582 gchar *s = parse_string(doc, fnode);
583 if (!g_ascii_strcasecmp(s, "Italic"))
584 slant = RR_FONTSLANT_ITALIC;
585 if (!g_ascii_strcasecmp(s, "Oblique"))
586 slant = RR_FONTSLANT_OBLIQUE;
590 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
593 n = parse_find_node("font", n->next);
597 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
602 node = node->children;
604 if ((n = parse_find_node("number", node))) {
605 gint d = parse_int(doc, n);
607 config_desktops_num = d;
609 if ((n = parse_find_node("firstdesk", node))) {
610 gint d = parse_int(doc, n);
612 config_screen_firstdesk = (unsigned) d;
614 if ((n = parse_find_node("names", node))) {
618 for (it = config_desktops_names; it; it = it->next)
620 g_slist_free(config_desktops_names);
621 config_desktops_names = NULL;
623 nname = parse_find_node("name", n->children);
625 config_desktops_names = g_slist_append(config_desktops_names,
626 parse_string(doc, nname));
627 nname = parse_find_node("name", nname->next);
630 if ((n = parse_find_node("popupTime", node)))
631 config_desktop_popup_time = parse_int(doc, n);
634 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
639 node = node->children;
641 if ((n = parse_find_node("drawContents", node)))
642 config_resize_redraw = parse_bool(doc, n);
643 if ((n = parse_find_node("popupShow", node))) {
644 config_resize_popup_show = parse_int(doc, n);
645 if (parse_contains("Always", doc, n))
646 config_resize_popup_show = 2;
647 else if (parse_contains("Never", doc, n))
648 config_resize_popup_show = 0;
649 else if (parse_contains("Nonpixel", doc, n))
650 config_resize_popup_show = 1;
652 if ((n = parse_find_node("popupPosition", node))) {
653 if (parse_contains("Top", doc, n))
654 config_resize_popup_pos = OB_RESIZE_POS_TOP;
655 else if (parse_contains("Center", doc, n))
656 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
657 else if (parse_contains("Fixed", doc, n)) {
658 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
660 if ((n = parse_find_node("popupFixedPosition", node))) {
663 if ((n2 = parse_find_node("x", n->children)))
664 config_parse_gravity_coord(doc, n2,
665 &config_resize_popup_fixed.x);
666 if ((n2 = parse_find_node("y", n->children)))
667 config_parse_gravity_coord(doc, n2,
668 &config_resize_popup_fixed.y);
674 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
679 node = node->children;
681 if ((n = parse_find_node("position", node))) {
682 if (parse_contains("TopLeft", doc, n))
683 config_dock_floating = FALSE,
684 config_dock_pos = OB_DIRECTION_NORTHWEST;
685 else if (parse_contains("Top", doc, n))
686 config_dock_floating = FALSE,
687 config_dock_pos = OB_DIRECTION_NORTH;
688 else if (parse_contains("TopRight", doc, n))
689 config_dock_floating = FALSE,
690 config_dock_pos = OB_DIRECTION_NORTHEAST;
691 else if (parse_contains("Right", doc, n))
692 config_dock_floating = FALSE,
693 config_dock_pos = OB_DIRECTION_EAST;
694 else if (parse_contains("BottomRight", doc, n))
695 config_dock_floating = FALSE,
696 config_dock_pos = OB_DIRECTION_SOUTHEAST;
697 else if (parse_contains("Bottom", doc, n))
698 config_dock_floating = FALSE,
699 config_dock_pos = OB_DIRECTION_SOUTH;
700 else if (parse_contains("BottomLeft", doc, n))
701 config_dock_floating = FALSE,
702 config_dock_pos = OB_DIRECTION_SOUTHWEST;
703 else if (parse_contains("Left", doc, n))
704 config_dock_floating = FALSE,
705 config_dock_pos = OB_DIRECTION_WEST;
706 else if (parse_contains("Floating", doc, n))
707 config_dock_floating = TRUE;
709 if (config_dock_floating) {
710 if ((n = parse_find_node("floatingX", node)))
711 config_dock_x = parse_int(doc, n);
712 if ((n = parse_find_node("floatingY", node)))
713 config_dock_y = parse_int(doc, n);
715 if ((n = parse_find_node("noStrut", node)))
716 config_dock_nostrut = parse_bool(doc, n);
718 if ((n = parse_find_node("stacking", node))) {
719 if (parse_contains("above", doc, n))
720 config_dock_layer = OB_STACKING_LAYER_ABOVE;
721 else if (parse_contains("normal", doc, n))
722 config_dock_layer = OB_STACKING_LAYER_NORMAL;
723 else if (parse_contains("below", doc, n))
724 config_dock_layer = OB_STACKING_LAYER_BELOW;
726 if ((n = parse_find_node("direction", node))) {
727 if (parse_contains("horizontal", doc, n))
728 config_dock_orient = OB_ORIENTATION_HORZ;
729 else if (parse_contains("vertical", doc, n))
730 config_dock_orient = OB_ORIENTATION_VERT;
732 if ((n = parse_find_node("autoHide", node)))
733 config_dock_hide = parse_bool(doc, n);
734 if ((n = parse_find_node("hideDelay", node)))
735 config_dock_hide_delay = parse_int(doc, n);
736 if ((n = parse_find_node("showDelay", node)))
737 config_dock_show_delay = parse_int(doc, n);
738 if ((n = parse_find_node("moveButton", node))) {
739 gchar *str = parse_string(doc, n);
741 if (translate_button(str, &s, &b)) {
742 config_dock_app_move_button = b;
743 config_dock_app_move_modifiers = s;
745 g_message(_("Invalid button '%s' specified in config file"), str);
751 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
755 for (node = node->children; node; node = node->next) {
756 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
759 c = parse_string(doc, node);
760 config_menu_files = g_slist_append(config_menu_files,
761 parse_expand_tilde(c));
764 if ((n = parse_find_node("hideDelay", node)))
765 config_menu_hide_delay = parse_int(doc, n);
766 if ((n = parse_find_node("middle", node)))
767 config_menu_middle = parse_bool(doc, n);
768 if ((n = parse_find_node("submenuShowDelay", node)))
769 config_submenu_show_delay = parse_int(doc, n);
770 if ((n = parse_find_node("applicationIcons", node)))
771 config_menu_client_list_icons = parse_bool(doc, n);
775 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
780 node = node->children;
781 if ((n = parse_find_node("strength", node)))
782 config_resist_win = parse_int(doc, n);
783 if ((n = parse_find_node("screen_edge_strength", node)))
784 config_resist_edge = parse_int(doc, n);
790 const gchar *actname;
793 static void bind_default_keyboard(void)
796 ObDefKeyBind binds[] = {
797 { "A-Tab", "NextWindow" },
798 { "S-A-Tab", "PreviousWindow" },
802 for (it = binds; it->key; ++it) {
803 GList *l = g_list_append(NULL, g_strdup(it->key));
804 keyboard_bind(l, actions_parse_string(it->actname));
811 const gchar *context;
812 const ObMouseAction mact;
813 const gchar *actname;
816 static void bind_default_mouse(void)
819 ObDefMouseBind binds[] = {
820 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
821 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
822 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
823 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
824 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
825 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
826 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
827 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
828 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
829 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
830 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
831 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
832 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
833 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
834 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
835 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
836 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
837 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
838 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
839 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
840 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
841 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
842 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
843 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
844 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
845 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
846 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
847 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
848 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
849 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
850 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
851 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
852 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
853 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
854 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
855 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
856 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
857 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
858 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
859 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
860 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
861 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
862 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
863 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
864 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
865 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
866 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
867 { NULL, NULL, 0, NULL }
870 for (it = binds; it->button; ++it)
871 mouse_bind(it->button, it->context, it->mact,
872 actions_parse_string(it->actname));
875 void config_startup(ObParseInst *i)
877 config_focus_new = TRUE;
878 config_focus_follow = FALSE;
879 config_focus_delay = 0;
880 config_focus_raise = FALSE;
881 config_focus_last = TRUE;
882 config_focus_under_mouse = FALSE;
884 parse_register(i, "focus", parse_focus, NULL);
886 config_place_policy = OB_PLACE_POLICY_SMART;
887 config_place_center = TRUE;
888 config_place_active = FALSE;
890 parse_register(i, "placement", parse_placement, NULL);
892 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
894 parse_register(i, "margins", parse_margins, NULL);
898 config_animate_iconify = TRUE;
899 config_title_layout = g_strdup("NLIMC");
900 config_theme_keepborder = TRUE;
902 config_font_activewindow = NULL;
903 config_font_inactivewindow = NULL;
904 config_font_menuitem = NULL;
905 config_font_menutitle = NULL;
907 parse_register(i, "theme", parse_theme, NULL);
909 config_desktops_num = 4;
910 config_screen_firstdesk = 1;
911 config_desktops_names = NULL;
912 config_desktop_popup_time = 875;
914 parse_register(i, "desktops", parse_desktops, NULL);
916 config_resize_redraw = TRUE;
917 config_resize_popup_show = 1; /* nonpixel increments */
918 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
919 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
920 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
922 parse_register(i, "resize", parse_resize, NULL);
924 config_dock_layer = OB_STACKING_LAYER_ABOVE;
925 config_dock_pos = OB_DIRECTION_NORTHEAST;
926 config_dock_floating = FALSE;
927 config_dock_nostrut = FALSE;
930 config_dock_orient = OB_ORIENTATION_VERT;
931 config_dock_hide = FALSE;
932 config_dock_hide_delay = 300;
933 config_dock_show_delay = 300;
934 config_dock_app_move_button = 2; /* middle */
935 config_dock_app_move_modifiers = 0;
937 parse_register(i, "dock", parse_dock, NULL);
939 translate_key("C-g", &config_keyboard_reset_state,
940 &config_keyboard_reset_keycode);
942 bind_default_keyboard();
944 parse_register(i, "keyboard", parse_keyboard, NULL);
946 config_mouse_threshold = 8;
947 config_mouse_dclicktime = 200;
948 config_mouse_screenedgetime = 400;
950 bind_default_mouse();
952 parse_register(i, "mouse", parse_mouse, NULL);
954 config_resist_win = 10;
955 config_resist_edge = 20;
957 parse_register(i, "resistance", parse_resistance, NULL);
959 config_menu_hide_delay = 250;
960 config_menu_middle = FALSE;
961 config_submenu_show_delay = 0;
962 config_menu_client_list_icons = TRUE;
963 config_menu_files = NULL;
965 parse_register(i, "menu", parse_menu, NULL);
967 config_per_app_settings = NULL;
969 parse_register(i, "applications", parse_per_app_settings, NULL);
972 void config_shutdown(void)
976 g_free(config_theme);
978 g_free(config_title_layout);
980 RrFontClose(config_font_activewindow);
981 RrFontClose(config_font_inactivewindow);
982 RrFontClose(config_font_menuitem);
983 RrFontClose(config_font_menutitle);
985 for (it = config_desktops_names; it; it = g_slist_next(it))
987 g_slist_free(config_desktops_names);
989 for (it = config_menu_files; it; it = g_slist_next(it))
991 g_slist_free(config_menu_files);
993 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
994 ObAppSettings *itd = (ObAppSettings *)it->data;
995 if (itd->name) g_pattern_spec_free(itd->name);
996 if (itd->role) g_pattern_spec_free(itd->role);
997 if (itd->class) g_pattern_spec_free(itd->class);
1000 g_slist_free(config_per_app_settings);