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;
81 gint config_mouse_screenedgetime;
83 guint config_menu_hide_delay;
84 gboolean config_menu_middle;
85 guint config_submenu_show_delay;
86 gboolean config_menu_client_list_icons;
88 GSList *config_menu_files;
90 gint config_resist_win;
91 gint config_resist_edge;
93 GSList *config_per_app_settings;
95 ObAppSettings* config_create_app_settings()
97 ObAppSettings *settings = g_new0(ObAppSettings, 1);
100 settings->monitor = -1;
101 settings->focus = -1;
102 settings->desktop = 0;
103 settings->layer = -2;
104 settings->iconic = -1;
105 settings->skip_pager = -1;
106 settings->skip_taskbar = -1;
107 settings->fullscreen = -1;
108 settings->max_horz = -1;
109 settings->max_vert = -1;
113 #define copy_if(setting, default) \
114 if (src->setting != default) dst->setting = src->setting
115 void config_app_settings_copy_non_defaults(const ObAppSettings *src,
118 g_assert(src != NULL);
119 g_assert(dst != NULL);
127 copy_if(skip_pager, -1);
128 copy_if(skip_taskbar, -1);
129 copy_if(fullscreen, -1);
130 copy_if(max_horz, -1);
131 copy_if(max_vert, -1);
133 if (src->pos_given) {
134 dst->pos_given = TRUE;
135 dst->center_x = src->center_x;
136 dst->center_y = src->center_y;
137 dst->opposite_x = src->opposite_x;
138 dst->opposite_y = src->opposite_y;
139 dst->position.x = src->position.x;
140 dst->position.y = src->position.y;
141 dst->monitor = src->monitor;
147 <application name="aterm">
150 <application name="Rhythmbox">
157 .. there is a lot more settings available
162 /* Manages settings for individual applications.
163 Some notes: monitor is the screen number in a multi monitor
164 (Xinerama) setup (starting from 0) or mouse, meaning the
165 monitor the pointer is on. Default: mouse.
166 Layer can be three values, above (Always on top), below
167 (Always on bottom) and everything else (normal behaviour).
168 Positions can be an integer value or center, which will
169 center the window in the specified axis. Position is within
170 the monitor, so <position><x>center</x></position><monitor>2</monitor>
171 will center the window on the second monitor.
173 static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
174 xmlNodePtr node, gpointer d)
176 xmlNodePtr app = parse_find_node("application", node->children);
177 gchar *name = NULL, *class = NULL, *role = NULL;
178 gboolean name_set, class_set;
179 gboolean x_pos_given;
182 name_set = class_set = x_pos_given = FALSE;
184 class_set = parse_attr_string("class", app, &class);
185 name_set = parse_attr_string("name", app, &name);
186 if (class_set || name_set) {
188 ObAppSettings *settings = config_create_app_settings();;
191 settings->name = g_pattern_spec_new(name);
194 settings->class = g_pattern_spec_new(class);
196 if (parse_attr_string("role", app, &role))
197 settings->role = g_pattern_spec_new(role);
199 if ((n = parse_find_node("decor", app->children)))
200 if (!parse_contains("default", doc, n))
201 settings->decor = parse_bool(doc, n);
203 if ((n = parse_find_node("shade", app->children)))
204 if (!parse_contains("default", doc, n))
205 settings->shade = parse_bool(doc, n);
207 if ((n = parse_find_node("position", app->children))) {
208 if ((c = parse_find_node("x", n->children)))
209 if (!parse_contains("default", doc, c)) {
210 gchar *s = parse_string(doc, c);
211 if (!strcmp(s, "center")) {
212 settings->center_x = TRUE;
216 settings->opposite_x = TRUE;
217 if (s[0] == '-' || s[0] == '+')
218 settings->position.x = atoi(s+1);
220 settings->position.x = atoi(s);
226 if (x_pos_given && (c = parse_find_node("y", n->children)))
227 if (!parse_contains("default", doc, c)) {
228 gchar *s = parse_string(doc, c);
229 if (!strcmp(s, "center")) {
230 settings->center_y = TRUE;
231 settings->pos_given = TRUE;
234 settings->opposite_y = TRUE;
235 if (s[0] == '-' || s[0] == '+')
236 settings->position.y = atoi(s+1);
238 settings->position.y = atoi(s);
239 settings->pos_given = TRUE;
244 if (settings->pos_given &&
245 (c = parse_find_node("monitor", n->children)))
246 if (!parse_contains("default", doc, c)) {
247 gchar *s = parse_string(doc, c);
248 if (!strcmp(s, "mouse"))
249 settings->monitor = 0;
251 settings->monitor = parse_int(doc, c) + 1;
256 if ((n = parse_find_node("focus", app->children)))
257 if (!parse_contains("default", doc, n))
258 settings->focus = parse_bool(doc, n);
260 if ((n = parse_find_node("desktop", app->children))) {
261 if (!parse_contains("default", doc, n)) {
262 gchar *s = parse_string(doc, n);
263 if (!strcmp(s, "all"))
264 settings->desktop = DESKTOP_ALL;
266 gint i = parse_int(doc, n);
268 settings->desktop = i;
274 if ((n = parse_find_node("layer", app->children)))
275 if (!parse_contains("default", doc, n)) {
276 gchar *s = parse_string(doc, n);
277 if (!strcmp(s, "above"))
279 else if (!strcmp(s, "below"))
280 settings->layer = -1;
286 if ((n = parse_find_node("iconic", app->children)))
287 if (!parse_contains("default", doc, n))
288 settings->iconic = parse_bool(doc, n);
290 if ((n = parse_find_node("skip_pager", app->children)))
291 if (!parse_contains("default", doc, n))
292 settings->skip_pager = parse_bool(doc, n);
294 if ((n = parse_find_node("skip_taskbar", app->children)))
295 if (!parse_contains("default", doc, n))
296 settings->skip_taskbar = parse_bool(doc, n);
298 if ((n = parse_find_node("fullscreen", app->children)))
299 if (!parse_contains("default", doc, n))
300 settings->fullscreen = parse_bool(doc, n);
302 if ((n = parse_find_node("maximized", app->children)))
303 if (!parse_contains("default", doc, n)) {
304 gchar *s = parse_string(doc, n);
305 if (!strcmp(s, "horizontal")) {
306 settings->max_horz = TRUE;
307 settings->max_vert = FALSE;
308 } else if (!strcmp(s, "vertical")) {
309 settings->max_horz = FALSE;
310 settings->max_vert = TRUE;
312 settings->max_horz = settings->max_vert =
317 config_per_app_settings = g_slist_append(config_per_app_settings,
318 (gpointer) settings);
321 app = parse_find_node("application", app->next);
332 <action name="ChangeDesktop">
339 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
344 gboolean is_chroot = FALSE;
346 if (!parse_attr_string("key", node, &key))
349 parse_attr_bool("chroot", node, &is_chroot);
351 keylist = g_list_append(keylist, key);
353 if ((n = parse_find_node("keybind", node->children))) {
355 parse_key(i, doc, n, keylist);
356 n = parse_find_node("keybind", n->next);
359 else if ((n = parse_find_node("action", node->children))) {
363 action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY);
365 keyboard_bind(keylist, action);
366 n = parse_find_node("action", n->next);
371 keyboard_chroot(keylist);
374 keylist = g_list_delete_link(keylist, g_list_last(keylist));
377 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
383 keyboard_unbind_all();
385 if ((n = parse_find_node("chainQuitKey", node->children))) {
386 key = parse_string(doc, n);
387 translate_key(key, &config_keyboard_reset_state,
388 &config_keyboard_reset_keycode);
392 if ((n = parse_find_node("keybind", node->children)))
394 parse_key(i, doc, n, NULL);
395 n = parse_find_node("keybind", n->next);
401 <context name="Titlebar">
402 <mousebind button="Left" action="Press">
403 <action name="Raise"></action>
409 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
412 xmlNodePtr n, nbut, nact;
421 node = node->children;
423 if ((n = parse_find_node("dragThreshold", node)))
424 config_mouse_threshold = parse_int(doc, n);
425 if ((n = parse_find_node("doubleClickTime", node)))
426 config_mouse_dclicktime = parse_int(doc, n);
427 if ((n = parse_find_node("screenEdgeWarpTime", node)))
428 config_mouse_screenedgetime = parse_int(doc, n);
430 n = parse_find_node("context", node);
432 if (!parse_attr_string("name", n, &contextstr))
434 nbut = parse_find_node("mousebind", n->children);
436 if (!parse_attr_string("button", nbut, &buttonstr))
438 if (parse_attr_contains("press", nbut, "action")) {
439 uact = OB_USER_ACTION_MOUSE_PRESS;
440 mact = OB_MOUSE_ACTION_PRESS;
441 } else if (parse_attr_contains("release", nbut, "action")) {
442 uact = OB_USER_ACTION_MOUSE_RELEASE;
443 mact = OB_MOUSE_ACTION_RELEASE;
444 } else if (parse_attr_contains("click", nbut, "action")) {
445 uact = OB_USER_ACTION_MOUSE_CLICK;
446 mact = OB_MOUSE_ACTION_CLICK;
447 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
448 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
449 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
450 } else if (parse_attr_contains("drag", nbut, "action")) {
451 uact = OB_USER_ACTION_MOUSE_MOTION;
452 mact = OB_MOUSE_ACTION_MOTION;
455 nact = parse_find_node("action", nbut->children);
457 if ((action = action_parse(i, doc, nact, uact)))
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) * 1000;
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);
506 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
511 node = node->children;
513 if ((n = parse_find_node("name", node))) {
516 g_free(config_theme);
517 c = parse_string(doc, n);
518 config_theme = parse_expand_tilde(c);
521 if ((n = parse_find_node("titleLayout", node))) {
524 g_free(config_title_layout);
525 config_title_layout = parse_string(doc, n);
527 /* replace duplicates with spaces */
528 for (c = config_title_layout; *c != '\0'; ++c)
529 for (d = c+1; *d != '\0'; ++d)
530 if (*c == *d) *d = ' ';
532 if ((n = parse_find_node("keepBorder", node)))
533 config_theme_keepborder = parse_bool(doc, n);
534 if ((n = parse_find_node("animateIconify", node)))
535 config_animate_iconify = parse_bool(doc, n);
537 n = parse_find_node("font", node);
541 gchar *name = g_strdup(RrDefaultFontFamily);
542 gint size = RrDefaultFontSize;
543 RrFontWeight weight = RrDefaultFontWeight;
544 RrFontSlant slant = RrDefaultFontSlant;
546 if (parse_attr_contains("ActiveWindow", n, "place"))
547 font = &config_font_activewindow;
548 else if (parse_attr_contains("InactiveWindow", n, "place"))
549 font = &config_font_inactivewindow;
550 else if (parse_attr_contains("MenuHeader", n, "place"))
551 font = &config_font_menutitle;
552 else if (parse_attr_contains("MenuItem", n, "place"))
553 font = &config_font_menuitem;
554 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
555 font = &config_font_osd;
559 if ((fnode = parse_find_node("name", n->children))) {
561 name = parse_string(doc, fnode);
563 if ((fnode = parse_find_node("size", n->children))) {
564 int s = parse_int(doc, fnode);
567 if ((fnode = parse_find_node("weight", n->children))) {
568 gchar *w = parse_string(doc, fnode);
569 if (!g_ascii_strcasecmp(w, "Bold"))
570 weight = RR_FONTWEIGHT_BOLD;
573 if ((fnode = parse_find_node("slant", n->children))) {
574 gchar *s = parse_string(doc, fnode);
575 if (!g_ascii_strcasecmp(s, "Italic"))
576 slant = RR_FONTSLANT_ITALIC;
577 if (!g_ascii_strcasecmp(s, "Oblique"))
578 slant = RR_FONTSLANT_OBLIQUE;
582 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
585 n = parse_find_node("font", n->next);
589 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
594 node = node->children;
596 if ((n = parse_find_node("number", node))) {
597 gint d = parse_int(doc, n);
599 config_desktops_num = d;
601 if ((n = parse_find_node("firstdesk", node))) {
602 gint d = parse_int(doc, n);
604 config_screen_firstdesk = (unsigned) d;
606 if ((n = parse_find_node("names", node))) {
610 for (it = config_desktops_names; it; it = it->next)
612 g_slist_free(config_desktops_names);
613 config_desktops_names = NULL;
615 nname = parse_find_node("name", n->children);
617 config_desktops_names = g_slist_append(config_desktops_names,
618 parse_string(doc, nname));
619 nname = parse_find_node("name", nname->next);
624 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
629 node = node->children;
631 if ((n = parse_find_node("drawContents", node)))
632 config_resize_redraw = parse_bool(doc, n);
633 if ((n = parse_find_node("popupShow", node))) {
634 config_resize_popup_show = parse_int(doc, n);
635 if (parse_contains("Always", doc, n))
636 config_resize_popup_show = 2;
637 else if (parse_contains("Never", doc, n))
638 config_resize_popup_show = 0;
639 else if (parse_contains("Nonpixel", doc, n))
640 config_resize_popup_show = 1;
642 if ((n = parse_find_node("popupPosition", node))) {
643 config_resize_popup_pos = parse_int(doc, n);
644 if (parse_contains("Top", doc, n))
645 config_resize_popup_pos = 1;
646 else if (parse_contains("Center", doc, n))
647 config_resize_popup_pos = 0;
651 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
656 node = node->children;
658 if ((n = parse_find_node("position", node))) {
659 if (parse_contains("TopLeft", doc, n))
660 config_dock_floating = FALSE,
661 config_dock_pos = OB_DIRECTION_NORTHWEST;
662 else if (parse_contains("Top", doc, n))
663 config_dock_floating = FALSE,
664 config_dock_pos = OB_DIRECTION_NORTH;
665 else if (parse_contains("TopRight", doc, n))
666 config_dock_floating = FALSE,
667 config_dock_pos = OB_DIRECTION_NORTHEAST;
668 else if (parse_contains("Right", doc, n))
669 config_dock_floating = FALSE,
670 config_dock_pos = OB_DIRECTION_EAST;
671 else if (parse_contains("BottomRight", doc, n))
672 config_dock_floating = FALSE,
673 config_dock_pos = OB_DIRECTION_SOUTHEAST;
674 else if (parse_contains("Bottom", doc, n))
675 config_dock_floating = FALSE,
676 config_dock_pos = OB_DIRECTION_SOUTH;
677 else if (parse_contains("BottomLeft", doc, n))
678 config_dock_floating = FALSE,
679 config_dock_pos = OB_DIRECTION_SOUTHWEST;
680 else if (parse_contains("Left", doc, n))
681 config_dock_floating = FALSE,
682 config_dock_pos = OB_DIRECTION_WEST;
683 else if (parse_contains("Floating", doc, n))
684 config_dock_floating = TRUE;
686 if (config_dock_floating) {
687 if ((n = parse_find_node("floatingX", node)))
688 config_dock_x = parse_int(doc, n);
689 if ((n = parse_find_node("floatingY", node)))
690 config_dock_y = parse_int(doc, n);
692 if ((n = parse_find_node("noStrut", node)))
693 config_dock_nostrut = parse_bool(doc, n);
695 if ((n = parse_find_node("stacking", node))) {
696 if (parse_contains("above", doc, n))
697 config_dock_layer = OB_STACKING_LAYER_ABOVE;
698 else if (parse_contains("normal", doc, n))
699 config_dock_layer = OB_STACKING_LAYER_NORMAL;
700 else if (parse_contains("below", doc, n))
701 config_dock_layer = OB_STACKING_LAYER_BELOW;
703 if ((n = parse_find_node("direction", node))) {
704 if (parse_contains("horizontal", doc, n))
705 config_dock_orient = OB_ORIENTATION_HORZ;
706 else if (parse_contains("vertical", doc, n))
707 config_dock_orient = OB_ORIENTATION_VERT;
709 if ((n = parse_find_node("autoHide", node)))
710 config_dock_hide = parse_bool(doc, n);
711 if ((n = parse_find_node("hideDelay", node)))
712 config_dock_hide_delay = parse_int(doc, n) * 1000;
713 if ((n = parse_find_node("showDelay", node)))
714 config_dock_show_delay = parse_int(doc, n) * 1000;
715 if ((n = parse_find_node("moveButton", node))) {
716 gchar *str = parse_string(doc, n);
718 if (translate_button(str, &s, &b)) {
719 config_dock_app_move_button = b;
720 config_dock_app_move_modifiers = s;
722 g_message(_("Invalid button '%s' specified in config file"), str);
728 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
732 for (node = node->children; node; node = node->next) {
733 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
736 c = parse_string(doc, node);
737 config_menu_files = g_slist_append(config_menu_files,
738 parse_expand_tilde(c));
741 if ((n = parse_find_node("hideDelay", node)))
742 config_menu_hide_delay = parse_int(doc, n);
743 if ((n = parse_find_node("middle", node)))
744 config_menu_middle = parse_bool(doc, n);
745 if ((n = parse_find_node("submenuShowDelay", node)))
746 config_submenu_show_delay = parse_int(doc, n);
747 if ((n = parse_find_node("applicationIcons", node)))
748 config_menu_client_list_icons = parse_bool(doc, n);
752 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
757 node = node->children;
758 if ((n = parse_find_node("strength", node)))
759 config_resist_win = parse_int(doc, n);
760 if ((n = parse_find_node("screen_edge_strength", node)))
761 config_resist_edge = parse_int(doc, n);
767 const gchar *actname;
770 static void bind_default_keyboard()
773 ObDefKeyBind binds[] = {
774 { "A-Tab", "NextWindow" },
775 { "S-A-Tab", "PreviousWindow" },
780 for (it = binds; it->key; ++it) {
781 GList *l = g_list_append(NULL, g_strdup(it->key));
782 keyboard_bind(l, action_from_string(it->actname,
783 OB_USER_ACTION_KEYBOARD_KEY));
790 const gchar *context;
791 const ObMouseAction mact;
792 const gchar *actname;
795 static void bind_default_mouse()
798 ObDefMouseBind binds[] = {
799 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
800 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
801 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
802 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
803 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
804 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
805 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
806 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
807 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
808 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
809 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
810 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
811 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
812 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
813 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
814 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
815 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
816 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
817 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
818 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
819 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
820 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
821 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
822 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
823 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
824 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
825 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
826 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
827 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
828 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
829 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
830 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
831 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
832 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
833 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
834 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
835 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
836 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
837 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
838 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
839 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
840 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
841 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
842 { NULL, NULL, 0, NULL }
845 for (it = binds; it->button; ++it) {
848 case OB_MOUSE_ACTION_PRESS:
849 uact = OB_USER_ACTION_MOUSE_PRESS; break;
850 case OB_MOUSE_ACTION_RELEASE:
851 uact = OB_USER_ACTION_MOUSE_RELEASE; break;
852 case OB_MOUSE_ACTION_CLICK:
853 uact = OB_USER_ACTION_MOUSE_CLICK; break;
854 case OB_MOUSE_ACTION_DOUBLE_CLICK:
855 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK; break;
856 case OB_MOUSE_ACTION_MOTION:
857 uact = OB_USER_ACTION_MOUSE_MOTION; break;
859 g_assert_not_reached();
861 mouse_bind(it->button, it->context, it->mact,
862 action_from_string(it->actname, uact));
866 void config_startup(ObParseInst *i)
868 config_focus_new = TRUE;
869 config_focus_follow = FALSE;
870 config_focus_delay = 0;
871 config_focus_raise = FALSE;
872 config_focus_last = TRUE;
873 config_focus_under_mouse = FALSE;
875 parse_register(i, "focus", parse_focus, NULL);
877 config_place_policy = OB_PLACE_POLICY_SMART;
878 config_place_center = TRUE;
880 parse_register(i, "placement", parse_placement, NULL);
884 config_animate_iconify = TRUE;
885 config_title_layout = g_strdup("NLIMC");
886 config_theme_keepborder = TRUE;
888 config_font_activewindow = NULL;
889 config_font_inactivewindow = NULL;
890 config_font_menuitem = NULL;
891 config_font_menutitle = NULL;
893 parse_register(i, "theme", parse_theme, NULL);
895 config_desktops_num = 4;
896 config_screen_firstdesk = 1;
897 config_desktops_names = NULL;
899 parse_register(i, "desktops", parse_desktops, NULL);
901 config_resize_redraw = TRUE;
902 config_resize_four_corners = FALSE;
903 config_resize_popup_show = 1; /* nonpixel increments */
904 config_resize_popup_pos = 0; /* center of client */
906 parse_register(i, "resize", parse_resize, NULL);
908 config_dock_layer = OB_STACKING_LAYER_ABOVE;
909 config_dock_pos = OB_DIRECTION_NORTHEAST;
910 config_dock_floating = FALSE;
911 config_dock_nostrut = FALSE;
914 config_dock_orient = OB_ORIENTATION_VERT;
915 config_dock_hide = FALSE;
916 config_dock_hide_delay = 300;
917 config_dock_show_delay = 300;
918 config_dock_app_move_button = 2; /* middle */
919 config_dock_app_move_modifiers = 0;
921 parse_register(i, "dock", parse_dock, NULL);
923 translate_key("C-g", &config_keyboard_reset_state,
924 &config_keyboard_reset_keycode);
926 bind_default_keyboard();
928 parse_register(i, "keyboard", parse_keyboard, NULL);
930 config_mouse_threshold = 8;
931 config_mouse_dclicktime = 200;
932 config_mouse_screenedgetime = 400;
934 bind_default_mouse();
936 parse_register(i, "mouse", parse_mouse, NULL);
938 config_resist_win = 10;
939 config_resist_edge = 20;
941 parse_register(i, "resistance", parse_resistance, NULL);
943 config_menu_hide_delay = 250;
944 config_menu_middle = FALSE;
945 config_submenu_show_delay = 0;
946 config_menu_client_list_icons = TRUE;
947 config_menu_files = NULL;
949 parse_register(i, "menu", parse_menu, NULL);
951 config_per_app_settings = NULL;
953 parse_register(i, "applications", parse_per_app_settings, NULL);
956 void config_shutdown()
960 g_free(config_theme);
962 g_free(config_title_layout);
964 RrFontClose(config_font_activewindow);
965 RrFontClose(config_font_inactivewindow);
966 RrFontClose(config_font_menuitem);
967 RrFontClose(config_font_menutitle);
969 for (it = config_desktops_names; it; it = g_slist_next(it))
971 g_slist_free(config_desktops_names);
973 for (it = config_menu_files; it; it = g_slist_next(it))
975 g_slist_free(config_menu_files);
977 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
978 ObAppSettings *itd = (ObAppSettings *)it->data;
979 if (itd->name) g_pattern_spec_free(itd->name);
980 if (itd->role) g_pattern_spec_free(itd->role);
981 if (itd->class) g_pattern_spec_free(itd->class);
984 g_slist_free(config_per_app_settings);