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 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 guint 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 gint config_resize_popup_show;
65 ObResizePopupPos config_resize_popup_pos;
66 GravityPoint config_resize_popup_fixed;
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->pos_force = src->pos_force;
141 dst->position = src->position;
142 dst->monitor = src->monitor;
146 static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
149 gchar *s = parse_string(doc, node);
150 if (!g_ascii_strcasecmp(s, "center"))
155 if (s[0] == '-' || s[0] == '+')
165 <application name="aterm">
168 <application name="Rhythmbox">
175 .. there is a lot more settings available
180 /* Manages settings for individual applications.
181 Some notes: monitor is the screen number in a multi monitor
182 (Xinerama) setup (starting from 0) or mouse, meaning the
183 monitor the pointer is on. Default: mouse.
184 Layer can be three values, above (Always on top), below
185 (Always on bottom) and everything else (normal behaviour).
186 Positions can be an integer value or center, which will
187 center the window in the specified axis. Position is within
188 the monitor, so <position><x>center</x></position><monitor>2</monitor>
189 will center the window on the second monitor.
191 static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
192 xmlNodePtr node, gpointer data)
194 xmlNodePtr app = parse_find_node("application", node->children);
195 gchar *name = NULL, *class = NULL, *role = NULL;
196 gboolean name_set, class_set;
197 gboolean x_pos_given;
200 name_set = class_set = x_pos_given = FALSE;
202 class_set = parse_attr_string("class", app, &class);
203 name_set = parse_attr_string("name", app, &name);
204 if (class_set || name_set) {
206 ObAppSettings *settings = config_create_app_settings();;
209 settings->name = g_pattern_spec_new(name);
212 settings->class = g_pattern_spec_new(class);
214 if (parse_attr_string("role", app, &role))
215 settings->role = g_pattern_spec_new(role);
217 if ((n = parse_find_node("decor", app->children)))
218 if (!parse_contains("default", doc, n))
219 settings->decor = parse_bool(doc, n);
221 if ((n = parse_find_node("shade", app->children)))
222 if (!parse_contains("default", doc, n))
223 settings->shade = parse_bool(doc, n);
225 if ((n = parse_find_node("position", app->children))) {
226 if ((c = parse_find_node("x", n->children)))
227 if (!parse_contains("default", doc, c)) {
228 config_parse_gravity_coord(doc, c,
229 &settings->position.x);
233 if (x_pos_given && (c = parse_find_node("y", n->children)))
234 if (!parse_contains("default", doc, c)) {
235 config_parse_gravity_coord(doc, c,
236 &settings->position.y);
237 settings->pos_given = TRUE;
240 if (settings->pos_given &&
241 (c = parse_find_node("monitor", n->children)))
242 if (!parse_contains("default", doc, c)) {
243 gchar *s = parse_string(doc, c);
244 if (!g_ascii_strcasecmp(s, "mouse"))
245 settings->monitor = 0;
247 settings->monitor = parse_int(doc, c) + 1;
251 parse_attr_bool("force", n, &settings->pos_force);
254 if ((n = parse_find_node("focus", app->children)))
255 if (!parse_contains("default", doc, n))
256 settings->focus = parse_bool(doc, n);
258 if ((n = parse_find_node("desktop", app->children))) {
259 if (!parse_contains("default", doc, n)) {
260 gchar *s = parse_string(doc, n);
261 if (!g_ascii_strcasecmp(s, "all"))
262 settings->desktop = DESKTOP_ALL;
264 gint i = parse_int(doc, n);
266 settings->desktop = i;
272 if ((n = parse_find_node("layer", app->children)))
273 if (!parse_contains("default", doc, n)) {
274 gchar *s = parse_string(doc, n);
275 if (!g_ascii_strcasecmp(s, "above"))
277 else if (!g_ascii_strcasecmp(s, "below"))
278 settings->layer = -1;
284 if ((n = parse_find_node("iconic", app->children)))
285 if (!parse_contains("default", doc, n))
286 settings->iconic = parse_bool(doc, n);
288 if ((n = parse_find_node("skip_pager", app->children)))
289 if (!parse_contains("default", doc, n))
290 settings->skip_pager = parse_bool(doc, n);
292 if ((n = parse_find_node("skip_taskbar", app->children)))
293 if (!parse_contains("default", doc, n))
294 settings->skip_taskbar = parse_bool(doc, n);
296 if ((n = parse_find_node("fullscreen", app->children)))
297 if (!parse_contains("default", doc, n))
298 settings->fullscreen = parse_bool(doc, n);
300 if ((n = parse_find_node("maximized", app->children)))
301 if (!parse_contains("default", doc, n)) {
302 gchar *s = parse_string(doc, n);
303 if (!g_ascii_strcasecmp(s, "horizontal")) {
304 settings->max_horz = TRUE;
305 settings->max_vert = FALSE;
306 } else if (!g_ascii_strcasecmp(s, "vertical")) {
307 settings->max_horz = FALSE;
308 settings->max_vert = TRUE;
310 settings->max_horz = settings->max_vert =
315 config_per_app_settings = g_slist_append(config_per_app_settings,
316 (gpointer) settings);
320 name = class = role = NULL;
323 app = parse_find_node("application", app->next);
330 <action name="ChangeDesktop">
337 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
342 gboolean is_chroot = FALSE;
344 if (!parse_attr_string("key", node, &key))
347 parse_attr_bool("chroot", node, &is_chroot);
349 keylist = g_list_append(keylist, key);
351 if ((n = parse_find_node("keybind", node->children))) {
353 parse_key(i, doc, n, keylist);
354 n = parse_find_node("keybind", n->next);
357 else if ((n = parse_find_node("action", node->children))) {
359 ObActionsAct *action;
361 action = actions_parse(i, doc, n);
363 keyboard_bind(keylist, action);
364 n = parse_find_node("action", n->next);
369 keyboard_chroot(keylist);
372 keylist = g_list_delete_link(keylist, g_list_last(keylist));
375 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
381 keyboard_unbind_all();
383 if ((n = parse_find_node("chainQuitKey", node->children))) {
384 key = parse_string(doc, n);
385 translate_key(key, &config_keyboard_reset_state,
386 &config_keyboard_reset_keycode);
390 if ((n = parse_find_node("keybind", node->children)))
392 parse_key(i, doc, n, NULL);
393 n = parse_find_node("keybind", n->next);
399 <context name="Titlebar">
400 <mousebind button="Left" action="Press">
401 <action name="Raise"></action>
407 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
410 xmlNodePtr n, nbut, nact;
417 node = node->children;
419 if ((n = parse_find_node("dragThreshold", node)))
420 config_mouse_threshold = parse_int(doc, n);
421 if ((n = parse_find_node("doubleClickTime", node)))
422 config_mouse_dclicktime = parse_int(doc, n);
423 if ((n = parse_find_node("screenEdgeWarpTime", node)))
424 config_mouse_screenedgetime = parse_int(doc, n);
426 n = parse_find_node("context", node);
428 if (!parse_attr_string("name", n, &contextstr))
430 nbut = parse_find_node("mousebind", n->children);
432 if (!parse_attr_string("button", nbut, &buttonstr))
434 if (parse_attr_contains("press", nbut, "action")) {
435 mact = OB_MOUSE_ACTION_PRESS;
436 } else if (parse_attr_contains("release", nbut, "action")) {
437 mact = OB_MOUSE_ACTION_RELEASE;
438 } else if (parse_attr_contains("click", nbut, "action")) {
439 mact = OB_MOUSE_ACTION_CLICK;
440 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
441 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
442 } else if (parse_attr_contains("drag", nbut, "action")) {
443 mact = OB_MOUSE_ACTION_MOTION;
446 nact = parse_find_node("action", nbut->children);
448 ObActionsAct *action;
450 if ((action = actions_parse(i, doc, nact)))
451 mouse_bind(buttonstr, contextstr, mact, action);
452 nact = parse_find_node("action", nact->next);
456 nbut = parse_find_node("mousebind", nbut->next);
460 n = parse_find_node("context", n->next);
464 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
469 node = node->children;
471 if ((n = parse_find_node("focusNew", node)))
472 config_focus_new = parse_bool(doc, n);
473 if ((n = parse_find_node("followMouse", node)))
474 config_focus_follow = parse_bool(doc, n);
475 if ((n = parse_find_node("focusDelay", node)))
476 config_focus_delay = parse_int(doc, n);
477 if ((n = parse_find_node("raiseOnFocus", node)))
478 config_focus_raise = parse_bool(doc, n);
479 if ((n = parse_find_node("focusLast", node)))
480 config_focus_last = parse_bool(doc, n);
481 if ((n = parse_find_node("underMouse", node)))
482 config_focus_under_mouse = parse_bool(doc, n);
485 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
490 node = node->children;
492 if ((n = parse_find_node("policy", node)))
493 if (parse_contains("UnderMouse", doc, n))
494 config_place_policy = OB_PLACE_POLICY_MOUSE;
495 if ((n = parse_find_node("center", node)))
496 config_place_center = parse_bool(doc, n);
497 if ((n = parse_find_node("monitor", node))) {
498 if (parse_contains("active", doc, n))
499 config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
500 else if (parse_contains("mouse", doc, n))
501 config_place_monitor = OB_PLACE_MONITOR_MOUSE;
505 static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
510 node = node->children;
512 if ((n = parse_find_node("top", node)))
513 config_margins.top = MAX(0, parse_int(doc, n));
514 if ((n = parse_find_node("left", node)))
515 config_margins.left = MAX(0, parse_int(doc, n));
516 if ((n = parse_find_node("right", node)))
517 config_margins.right = MAX(0, parse_int(doc, n));
518 if ((n = parse_find_node("bottom", node)))
519 config_margins.bottom = MAX(0, parse_int(doc, n));
522 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
527 node = node->children;
529 if ((n = parse_find_node("name", node))) {
532 g_free(config_theme);
533 c = parse_string(doc, n);
534 config_theme = parse_expand_tilde(c);
537 if ((n = parse_find_node("titleLayout", node))) {
540 g_free(config_title_layout);
541 config_title_layout = parse_string(doc, n);
543 /* replace duplicates with spaces */
544 for (c = config_title_layout; *c != '\0'; ++c)
545 for (d = c+1; *d != '\0'; ++d)
546 if (*c == *d) *d = ' ';
548 if ((n = parse_find_node("keepBorder", node)))
549 config_theme_keepborder = parse_bool(doc, n);
550 if ((n = parse_find_node("animateIconify", node)))
551 config_animate_iconify = parse_bool(doc, n);
553 n = parse_find_node("font", node);
557 gchar *name = g_strdup(RrDefaultFontFamily);
558 gint size = RrDefaultFontSize;
559 RrFontWeight weight = RrDefaultFontWeight;
560 RrFontSlant slant = RrDefaultFontSlant;
562 if (parse_attr_contains("ActiveWindow", n, "place"))
563 font = &config_font_activewindow;
564 else if (parse_attr_contains("InactiveWindow", n, "place"))
565 font = &config_font_inactivewindow;
566 else if (parse_attr_contains("MenuHeader", n, "place"))
567 font = &config_font_menutitle;
568 else if (parse_attr_contains("MenuItem", n, "place"))
569 font = &config_font_menuitem;
570 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
571 font = &config_font_osd;
575 if ((fnode = parse_find_node("name", n->children))) {
577 name = parse_string(doc, fnode);
579 if ((fnode = parse_find_node("size", n->children))) {
580 int s = parse_int(doc, fnode);
583 if ((fnode = parse_find_node("weight", n->children))) {
584 gchar *w = parse_string(doc, fnode);
585 if (!g_ascii_strcasecmp(w, "Bold"))
586 weight = RR_FONTWEIGHT_BOLD;
589 if ((fnode = parse_find_node("slant", n->children))) {
590 gchar *s = parse_string(doc, fnode);
591 if (!g_ascii_strcasecmp(s, "Italic"))
592 slant = RR_FONTSLANT_ITALIC;
593 if (!g_ascii_strcasecmp(s, "Oblique"))
594 slant = RR_FONTSLANT_OBLIQUE;
598 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
601 n = parse_find_node("font", n->next);
605 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
610 node = node->children;
612 if ((n = parse_find_node("number", node))) {
613 gint d = parse_int(doc, n);
615 config_desktops_num = (unsigned) d;
617 if ((n = parse_find_node("firstdesk", node))) {
618 gint d = parse_int(doc, n);
620 config_screen_firstdesk = (unsigned) d;
622 if ((n = parse_find_node("names", node))) {
626 for (it = config_desktops_names; it; it = it->next)
628 g_slist_free(config_desktops_names);
629 config_desktops_names = NULL;
631 nname = parse_find_node("name", n->children);
633 config_desktops_names = g_slist_append(config_desktops_names,
634 parse_string(doc, nname));
635 nname = parse_find_node("name", nname->next);
638 if ((n = parse_find_node("popupTime", node)))
639 config_desktop_popup_time = parse_int(doc, n);
642 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
647 node = node->children;
649 if ((n = parse_find_node("drawContents", node)))
650 config_resize_redraw = parse_bool(doc, n);
651 if ((n = parse_find_node("popupShow", node))) {
652 config_resize_popup_show = parse_int(doc, n);
653 if (parse_contains("Always", doc, n))
654 config_resize_popup_show = 2;
655 else if (parse_contains("Never", doc, n))
656 config_resize_popup_show = 0;
657 else if (parse_contains("Nonpixel", doc, n))
658 config_resize_popup_show = 1;
660 if ((n = parse_find_node("popupPosition", node))) {
661 if (parse_contains("Top", doc, n))
662 config_resize_popup_pos = OB_RESIZE_POS_TOP;
663 else if (parse_contains("Center", doc, n))
664 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
665 else if (parse_contains("Fixed", doc, n)) {
666 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
668 if ((n = parse_find_node("popupFixedPosition", node))) {
671 if ((n2 = parse_find_node("x", n->children)))
672 config_parse_gravity_coord(doc, n2,
673 &config_resize_popup_fixed.x);
674 if ((n2 = parse_find_node("y", n->children)))
675 config_parse_gravity_coord(doc, n2,
676 &config_resize_popup_fixed.y);
682 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
687 node = node->children;
689 if ((n = parse_find_node("position", node))) {
690 if (parse_contains("TopLeft", doc, n))
691 config_dock_floating = FALSE,
692 config_dock_pos = OB_DIRECTION_NORTHWEST;
693 else if (parse_contains("Top", doc, n))
694 config_dock_floating = FALSE,
695 config_dock_pos = OB_DIRECTION_NORTH;
696 else if (parse_contains("TopRight", doc, n))
697 config_dock_floating = FALSE,
698 config_dock_pos = OB_DIRECTION_NORTHEAST;
699 else if (parse_contains("Right", doc, n))
700 config_dock_floating = FALSE,
701 config_dock_pos = OB_DIRECTION_EAST;
702 else if (parse_contains("BottomRight", doc, n))
703 config_dock_floating = FALSE,
704 config_dock_pos = OB_DIRECTION_SOUTHEAST;
705 else if (parse_contains("Bottom", doc, n))
706 config_dock_floating = FALSE,
707 config_dock_pos = OB_DIRECTION_SOUTH;
708 else if (parse_contains("BottomLeft", doc, n))
709 config_dock_floating = FALSE,
710 config_dock_pos = OB_DIRECTION_SOUTHWEST;
711 else if (parse_contains("Left", doc, n))
712 config_dock_floating = FALSE,
713 config_dock_pos = OB_DIRECTION_WEST;
714 else if (parse_contains("Floating", doc, n))
715 config_dock_floating = TRUE;
717 if (config_dock_floating) {
718 if ((n = parse_find_node("floatingX", node)))
719 config_dock_x = parse_int(doc, n);
720 if ((n = parse_find_node("floatingY", node)))
721 config_dock_y = parse_int(doc, n);
723 if ((n = parse_find_node("noStrut", node)))
724 config_dock_nostrut = parse_bool(doc, n);
726 if ((n = parse_find_node("stacking", node))) {
727 if (parse_contains("above", doc, n))
728 config_dock_layer = OB_STACKING_LAYER_ABOVE;
729 else if (parse_contains("normal", doc, n))
730 config_dock_layer = OB_STACKING_LAYER_NORMAL;
731 else if (parse_contains("below", doc, n))
732 config_dock_layer = OB_STACKING_LAYER_BELOW;
734 if ((n = parse_find_node("direction", node))) {
735 if (parse_contains("horizontal", doc, n))
736 config_dock_orient = OB_ORIENTATION_HORZ;
737 else if (parse_contains("vertical", doc, n))
738 config_dock_orient = OB_ORIENTATION_VERT;
740 if ((n = parse_find_node("autoHide", node)))
741 config_dock_hide = parse_bool(doc, n);
742 if ((n = parse_find_node("hideDelay", node)))
743 config_dock_hide_delay = parse_int(doc, n);
744 if ((n = parse_find_node("showDelay", node)))
745 config_dock_show_delay = parse_int(doc, n);
746 if ((n = parse_find_node("moveButton", node))) {
747 gchar *str = parse_string(doc, n);
749 if (translate_button(str, &s, &b)) {
750 config_dock_app_move_button = b;
751 config_dock_app_move_modifiers = s;
753 g_message(_("Invalid button '%s' specified in config file"), str);
759 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
763 for (node = node->children; node; node = node->next) {
764 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
767 c = parse_string(doc, node);
768 config_menu_files = g_slist_append(config_menu_files,
769 parse_expand_tilde(c));
772 if ((n = parse_find_node("hideDelay", node)))
773 config_menu_hide_delay = parse_int(doc, n);
774 if ((n = parse_find_node("middle", node)))
775 config_menu_middle = parse_bool(doc, n);
776 if ((n = parse_find_node("submenuShowDelay", node)))
777 config_submenu_show_delay = parse_int(doc, n);
778 if ((n = parse_find_node("applicationIcons", node)))
779 config_menu_client_list_icons = parse_bool(doc, n);
783 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
788 node = node->children;
789 if ((n = parse_find_node("strength", node)))
790 config_resist_win = parse_int(doc, n);
791 if ((n = parse_find_node("screen_edge_strength", node)))
792 config_resist_edge = parse_int(doc, n);
798 const gchar *actname;
801 static void bind_default_keyboard(void)
804 ObDefKeyBind binds[] = {
805 { "A-Tab", "NextWindow" },
806 { "S-A-Tab", "PreviousWindow" },
810 for (it = binds; it->key; ++it) {
811 GList *l = g_list_append(NULL, g_strdup(it->key));
812 keyboard_bind(l, actions_parse_string(it->actname));
819 const gchar *context;
820 const ObMouseAction mact;
821 const gchar *actname;
824 static void bind_default_mouse(void)
827 ObDefMouseBind binds[] = {
828 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
829 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
830 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
831 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
832 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
833 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
834 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
835 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
836 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
837 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
838 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
839 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
840 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
841 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
842 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
843 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
844 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
845 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
846 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
847 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
848 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
849 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
850 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
851 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
852 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
853 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
854 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
855 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
856 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
857 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
858 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
859 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
860 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
861 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
862 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
863 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
864 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
865 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
866 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
867 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
868 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
869 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
870 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
871 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
872 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
873 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
874 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
875 { NULL, NULL, 0, NULL }
878 for (it = binds; it->button; ++it)
879 mouse_bind(it->button, it->context, it->mact,
880 actions_parse_string(it->actname));
883 void config_startup(ObParseInst *i)
885 config_focus_new = TRUE;
886 config_focus_follow = FALSE;
887 config_focus_delay = 0;
888 config_focus_raise = FALSE;
889 config_focus_last = TRUE;
890 config_focus_under_mouse = FALSE;
892 parse_register(i, "focus", parse_focus, NULL);
894 config_place_policy = OB_PLACE_POLICY_SMART;
895 config_place_center = TRUE;
896 config_place_monitor = OB_PLACE_MONITOR_ANY;
898 parse_register(i, "placement", parse_placement, NULL);
900 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
902 parse_register(i, "margins", parse_margins, NULL);
906 config_animate_iconify = TRUE;
907 config_title_layout = g_strdup("NLIMC");
908 config_theme_keepborder = TRUE;
910 config_font_activewindow = NULL;
911 config_font_inactivewindow = NULL;
912 config_font_menuitem = NULL;
913 config_font_menutitle = NULL;
915 parse_register(i, "theme", parse_theme, NULL);
917 config_desktops_num = 4;
918 config_screen_firstdesk = 1;
919 config_desktops_names = NULL;
920 config_desktop_popup_time = 875;
922 parse_register(i, "desktops", parse_desktops, NULL);
924 config_resize_redraw = TRUE;
925 config_resize_popup_show = 1; /* nonpixel increments */
926 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
927 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
928 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
930 parse_register(i, "resize", parse_resize, NULL);
932 config_dock_layer = OB_STACKING_LAYER_ABOVE;
933 config_dock_pos = OB_DIRECTION_NORTHEAST;
934 config_dock_floating = FALSE;
935 config_dock_nostrut = FALSE;
938 config_dock_orient = OB_ORIENTATION_VERT;
939 config_dock_hide = FALSE;
940 config_dock_hide_delay = 300;
941 config_dock_show_delay = 300;
942 config_dock_app_move_button = 2; /* middle */
943 config_dock_app_move_modifiers = 0;
945 parse_register(i, "dock", parse_dock, NULL);
947 translate_key("C-g", &config_keyboard_reset_state,
948 &config_keyboard_reset_keycode);
950 bind_default_keyboard();
952 parse_register(i, "keyboard", parse_keyboard, NULL);
954 config_mouse_threshold = 8;
955 config_mouse_dclicktime = 200;
956 config_mouse_screenedgetime = 400;
958 bind_default_mouse();
960 parse_register(i, "mouse", parse_mouse, NULL);
962 config_resist_win = 10;
963 config_resist_edge = 20;
965 parse_register(i, "resistance", parse_resistance, NULL);
967 config_menu_hide_delay = 250;
968 config_menu_middle = FALSE;
969 config_submenu_show_delay = 0;
970 config_menu_client_list_icons = TRUE;
971 config_menu_files = NULL;
973 parse_register(i, "menu", parse_menu, NULL);
975 config_per_app_settings = NULL;
977 parse_register(i, "applications", parse_per_app_settings, NULL);
980 void config_shutdown(void)
984 g_free(config_theme);
986 g_free(config_title_layout);
988 RrFontClose(config_font_activewindow);
989 RrFontClose(config_font_inactivewindow);
990 RrFontClose(config_font_menuitem);
991 RrFontClose(config_font_menutitle);
992 RrFontClose(config_font_osd);
994 for (it = config_desktops_names; it; it = g_slist_next(it))
996 g_slist_free(config_desktops_names);
998 for (it = config_menu_files; it; it = g_slist_next(it))
1000 g_slist_free(config_menu_files);
1002 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
1003 ObAppSettings *itd = (ObAppSettings *)it->data;
1004 if (itd->name) g_pattern_spec_free(itd->name);
1005 if (itd->role) g_pattern_spec_free(itd->role);
1006 if (itd->class) g_pattern_spec_free(itd->class);
1009 g_slist_free(config_per_app_settings);