]> Dogcows Code - chaz/openbox/blob - openbox/config.c
c007de5368c0ea114cfc12a5a85b777676630112
[chaz/openbox] / openbox / config.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 config.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
6
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.
11
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.
16
17 See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "config.h"
21 #include "keyboard.h"
22 #include "mouse.h"
23 #include "prop.h"
24 #include "translate.h"
25 #include "client.h"
26 #include "screen.h"
27 #include "parser/parse.h"
28 #include "openbox.h"
29 #include "gettext.h"
30
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
37 ObPlacePolicy config_place_policy;
38
39 gchar *config_theme;
40 gboolean config_theme_keepborder;
41
42 gchar *config_title_layout;
43
44 gboolean config_animate_iconify;
45
46 RrFont *config_font_activewindow;
47 RrFont *config_font_inactivewindow;
48 RrFont *config_font_menuitem;
49 RrFont *config_font_menutitle;
50 RrFont *config_font_osd;
51
52 gint config_desktops_num;
53 GSList *config_desktops_names;
54 guint config_screen_firstdesk;
55
56 gboolean config_resize_redraw;
57 gboolean config_resize_four_corners;
58 gint config_resize_popup_show;
59 gint config_resize_popup_pos;
60
61 ObStackingLayer config_dock_layer;
62 gboolean config_dock_floating;
63 gboolean config_dock_nostrut;
64 ObDirection config_dock_pos;
65 gint config_dock_x;
66 gint config_dock_y;
67 ObOrientation config_dock_orient;
68 gboolean config_dock_hide;
69 guint config_dock_hide_delay;
70 guint config_dock_show_delay;
71 guint config_dock_app_move_button;
72 guint config_dock_app_move_modifiers;
73
74 guint config_keyboard_reset_keycode;
75 guint config_keyboard_reset_state;
76
77 gint config_mouse_threshold;
78 gint config_mouse_dclicktime;
79
80 guint config_menu_hide_delay;
81 gboolean config_menu_middle;
82 guint config_submenu_show_delay;
83 gboolean config_menu_client_list_icons;
84
85 GSList *config_menu_files;
86
87 gint config_resist_win;
88 gint config_resist_edge;
89
90 GSList *config_per_app_settings;
91
92 /*
93 <applications>
94 <application name="aterm">
95 <decor>false</decor>
96 </application>
97 <application name="Rhythmbox">
98 <layer>above</layer>
99 <position>
100 <x>700</x>
101 <y>0</y>
102 <monitor>1</monitor>
103 </position>
104 .. there is a lot more settings available
105 </application>
106 </applications>
107 */
108
109 /* Manages settings for individual applications.
110 Some notes: monitor is the screen number in a multi monitor
111 (Xinerama) setup (starting from 0) or mouse, meaning the
112 monitor the pointer is on. Default: mouse.
113 Layer can be three values, above (Always on top), below
114 (Always on bottom) and everything else (normal behaviour).
115 Positions can be an integer value or center, which will
116 center the window in the specified axis. Position is within
117 the monitor, so <position><x>center</x></position><monitor>2</monitor>
118 will center the window on the second monitor.
119 */
120 static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
121 xmlNodePtr node, gpointer d)
122 {
123 xmlNodePtr app = parse_find_node("application", node->children);
124 gchar *name, *class;
125 gboolean name_set, class_set;
126 gboolean x_pos_given;
127
128 while (app) {
129 name_set = class_set = x_pos_given = FALSE;
130
131 class_set = parse_attr_string("class", app, &class);
132 name_set = parse_attr_string("name", app, &name);
133 if (class_set || name_set) {
134 xmlNodePtr n, c;
135 ObAppSettings *settings = g_new0(ObAppSettings, 1);
136
137 if (name_set)
138 settings->name = name;
139 else
140 settings->name = NULL;
141
142 if (class_set)
143 settings->class = class;
144 else
145 settings->class = NULL;
146
147 if (!parse_attr_string("role", app, &settings->role))
148 settings->role = NULL;
149
150 settings->decor = -1;
151 if ((n = parse_find_node("decor", app->children)))
152 if (!parse_contains("default", doc, n))
153 settings->decor = parse_bool(doc, n);
154
155 settings->shade = -1;
156 if ((n = parse_find_node("shade", app->children)))
157 if (!parse_contains("default", doc, n))
158 settings->shade = parse_bool(doc, n);
159
160 settings->position.x = settings->position.y = 0;
161 settings->pos_given = FALSE;
162 if ((n = parse_find_node("position", app->children))) {
163 if ((c = parse_find_node("x", n->children)))
164 if (!parse_contains("default", doc, c)) {
165 gchar *s = parse_string(doc, c);
166 if (!strcmp(s, "center")) {
167 settings->center_x = TRUE;
168 x_pos_given = TRUE;
169 } else {
170 settings->position.x = parse_int(doc, c);
171 x_pos_given = TRUE;
172 }
173 g_free(s);
174 }
175
176 if (x_pos_given && (c = parse_find_node("y", n->children)))
177 if (!parse_contains("default", doc, c)) {
178 gchar *s = parse_string(doc, c);
179 if (!strcmp(s, "center")) {
180 settings->center_y = TRUE;
181 settings->pos_given = TRUE;
182 } else {
183 settings->position.y = parse_int(doc, c);
184 settings->pos_given = TRUE;
185 }
186 g_free(s);
187 }
188
189 if (settings->pos_given &&
190 (c = parse_find_node("monitor", n->children)))
191 if (!parse_contains("default", doc, c)) {
192 gchar *s = parse_string(doc, c);
193 if (!strcmp(s, "mouse"))
194 settings->monitor = 0;
195 else
196 settings->monitor = parse_int(doc, c) + 1;
197 g_free(s);
198 }
199 }
200
201 settings->focus = -1;
202 if ((n = parse_find_node("focus", app->children)))
203 if (!parse_contains("default", doc, n))
204 settings->focus = parse_bool(doc, n);
205
206 if ((n = parse_find_node("desktop", app->children))) {
207 if (!parse_contains("default", doc, n)) {
208 gchar *s = parse_string(doc, n);
209 if (!strcmp(s, "all"))
210 settings->desktop = DESKTOP_ALL;
211 else {
212 gint i = parse_int(doc, n);
213 if (i > 0)
214 settings->desktop = i;
215 }
216 g_free(s);
217 } else
218 settings->desktop = 0;
219 }
220
221 settings->layer = -2;
222 if ((n = parse_find_node("layer", app->children)))
223 if (!parse_contains("default", doc, n)) {
224 gchar *s = parse_string(doc, n);
225 if (!strcmp(s, "above"))
226 settings->layer = 1;
227 else if (!strcmp(s, "below"))
228 settings->layer = -1;
229 else
230 settings->layer = 0;
231 g_free(s);
232 }
233
234 settings->iconic = -1;
235 if ((n = parse_find_node("iconic", app->children)))
236 if (!parse_contains("default", doc, n))
237 settings->iconic = parse_bool(doc, n);
238
239 settings->skip_pager = -1;
240 if ((n = parse_find_node("skip_pager", app->children)))
241 if (!parse_contains("default", doc, n))
242 settings->skip_pager = parse_bool(doc, n);
243
244 settings->skip_taskbar = -1;
245 if ((n = parse_find_node("skip_taskbar", app->children)))
246 if (!parse_contains("default", doc, n))
247 settings->skip_taskbar = parse_bool(doc, n);
248
249 settings->fullscreen = -1;
250 if ((n = parse_find_node("fullscreen", app->children)))
251 if (!parse_contains("default", doc, n))
252 settings->fullscreen = parse_bool(doc, n);
253
254 settings->max_horz = -1;
255 settings->max_vert = -1;
256 if ((n = parse_find_node("maximized", app->children)))
257 if (!parse_contains("default", doc, n)) {
258 gchar *s = parse_string(doc, n);
259 if (!strcmp(s, "horizontal")) {
260 settings->max_horz = TRUE;
261 settings->max_vert = FALSE;
262 } else if (!strcmp(s, "vertical")) {
263 settings->max_horz = FALSE;
264 settings->max_vert = TRUE;
265 } else
266 settings->max_horz = settings->max_vert =
267 parse_bool(doc, n);
268 g_free(s);
269 }
270
271 config_per_app_settings = g_slist_append(config_per_app_settings,
272 (gpointer) settings);
273 }
274
275 app = parse_find_node("application", app->next);
276 }
277 }
278
279 /*
280
281 <keybind key="C-x">
282 <action name="ChangeDesktop">
283 <desktop>3</desktop>
284 </action>
285 </keybind>
286
287 */
288
289 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
290 GList *keylist)
291 {
292 gchar *key;
293 xmlNodePtr n;
294 gboolean is_chroot = FALSE;
295
296 if (!parse_attr_string("key", node, &key))
297 return;
298
299 parse_attr_bool("chroot", node, &is_chroot);
300
301 keylist = g_list_append(keylist, key);
302
303 if ((n = parse_find_node("keybind", node->children))) {
304 while (n) {
305 parse_key(i, doc, n, keylist);
306 n = parse_find_node("keybind", n->next);
307 }
308 }
309 else if ((n = parse_find_node("action", node->children))) {
310 while (n) {
311 ObAction *action;
312
313 action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY);
314 if (action)
315 keyboard_bind(keylist, action);
316 n = parse_find_node("action", n->next);
317 }
318 }
319
320 if (is_chroot)
321 keyboard_chroot(keylist);
322
323 g_free(key);
324 keylist = g_list_delete_link(keylist, g_list_last(keylist));
325 }
326
327 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
328 gpointer d)
329 {
330 xmlNodePtr n;
331 gchar *key;
332
333 keyboard_unbind_all();
334
335 if ((n = parse_find_node("chainQuitKey", node->children))) {
336 key = parse_string(doc, n);
337 translate_key(key, &config_keyboard_reset_state,
338 &config_keyboard_reset_keycode);
339 g_free(key);
340 }
341
342 if ((n = parse_find_node("keybind", node->children)))
343 while (n) {
344 parse_key(i, doc, n, NULL);
345 n = parse_find_node("keybind", n->next);
346 }
347 }
348
349 /*
350
351 <context name="Titlebar">
352 <mousebind button="Left" action="Press">
353 <action name="Raise"></action>
354 </mousebind>
355 </context>
356
357 */
358
359 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
360 gpointer d)
361 {
362 xmlNodePtr n, nbut, nact;
363 gchar *buttonstr;
364 gchar *contextstr;
365 ObUserAction uact;
366 ObMouseAction mact;
367 ObAction *action;
368
369 mouse_unbind_all();
370
371 node = node->children;
372
373 if ((n = parse_find_node("dragThreshold", node)))
374 config_mouse_threshold = parse_int(doc, n);
375 if ((n = parse_find_node("doubleClickTime", node)))
376 config_mouse_dclicktime = parse_int(doc, n);
377
378 n = parse_find_node("context", node);
379 while (n) {
380 if (!parse_attr_string("name", n, &contextstr))
381 goto next_n;
382 nbut = parse_find_node("mousebind", n->children);
383 while (nbut) {
384 if (!parse_attr_string("button", nbut, &buttonstr))
385 goto next_nbut;
386 if (parse_attr_contains("press", nbut, "action")) {
387 uact = OB_USER_ACTION_MOUSE_PRESS;
388 mact = OB_MOUSE_ACTION_PRESS;
389 } else if (parse_attr_contains("release", nbut, "action")) {
390 uact = OB_USER_ACTION_MOUSE_RELEASE;
391 mact = OB_MOUSE_ACTION_RELEASE;
392 } else if (parse_attr_contains("click", nbut, "action")) {
393 uact = OB_USER_ACTION_MOUSE_CLICK;
394 mact = OB_MOUSE_ACTION_CLICK;
395 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
396 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
397 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
398 } else if (parse_attr_contains("drag", nbut, "action")) {
399 uact = OB_USER_ACTION_MOUSE_MOTION;
400 mact = OB_MOUSE_ACTION_MOTION;
401 } else
402 goto next_nbut;
403 nact = parse_find_node("action", nbut->children);
404 while (nact) {
405 if ((action = action_parse(i, doc, nact, uact)))
406 mouse_bind(buttonstr, contextstr, mact, action);
407 nact = parse_find_node("action", nact->next);
408 }
409 g_free(buttonstr);
410 next_nbut:
411 nbut = parse_find_node("mousebind", nbut->next);
412 }
413 g_free(contextstr);
414 next_n:
415 n = parse_find_node("context", n->next);
416 }
417 }
418
419 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
420 gpointer d)
421 {
422 xmlNodePtr n;
423
424 node = node->children;
425
426 if ((n = parse_find_node("focusNew", node)))
427 config_focus_new = parse_bool(doc, n);
428 if ((n = parse_find_node("followMouse", node)))
429 config_focus_follow = parse_bool(doc, n);
430 if ((n = parse_find_node("focusDelay", node)))
431 config_focus_delay = parse_int(doc, n) * 1000;
432 if ((n = parse_find_node("raiseOnFocus", node)))
433 config_focus_raise = parse_bool(doc, n);
434 if ((n = parse_find_node("focusLast", node)))
435 config_focus_last = parse_bool(doc, n);
436 }
437
438 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
439 gpointer d)
440 {
441 xmlNodePtr n;
442
443 node = node->children;
444
445 if ((n = parse_find_node("policy", node)))
446 if (parse_contains("UnderMouse", doc, n))
447 config_place_policy = OB_PLACE_POLICY_MOUSE;
448 }
449
450 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
451 gpointer d)
452 {
453 xmlNodePtr n;
454
455 node = node->children;
456
457 if ((n = parse_find_node("name", node))) {
458 gchar *c;
459
460 g_free(config_theme);
461 c = parse_string(doc, n);
462 config_theme = parse_expand_tilde(c);
463 g_free(c);
464 }
465 if ((n = parse_find_node("titleLayout", node))) {
466 gchar *c, *d;
467
468 g_free(config_title_layout);
469 config_title_layout = parse_string(doc, n);
470
471 /* replace duplicates with spaces */
472 for (c = config_title_layout; *c != '\0'; ++c)
473 for (d = c+1; *d != '\0'; ++d)
474 if (*c == *d) *d = ' ';
475 }
476 if ((n = parse_find_node("keepBorder", node)))
477 config_theme_keepborder = parse_bool(doc, n);
478 if ((n = parse_find_node("animateIconify", node)))
479 config_animate_iconify = parse_bool(doc, n);
480
481 n = parse_find_node("font", node);
482 while (n) {
483 xmlNodePtr fnode;
484 RrFont **font;
485 gchar *name = g_strdup(RrDefaultFontFamily);
486 gint size = RrDefaultFontSize;
487 RrFontWeight weight = RrDefaultFontWeight;
488 RrFontSlant slant = RrDefaultFontSlant;
489
490 if (parse_attr_contains("ActiveWindow", n, "place"))
491 font = &config_font_activewindow;
492 else if (parse_attr_contains("InactiveWindow", n, "place"))
493 font = &config_font_inactivewindow;
494 else if (parse_attr_contains("MenuHeader", n, "place"))
495 font = &config_font_menutitle;
496 else if (parse_attr_contains("MenuItem", n, "place"))
497 font = &config_font_menuitem;
498 else if (parse_attr_contains("OnScreenDisplay", n, "place"))
499 font = &config_font_osd;
500 else
501 goto next_font;
502
503 if ((fnode = parse_find_node("name", n->children))) {
504 g_free(name);
505 name = parse_string(doc, fnode);
506 }
507 if ((fnode = parse_find_node("size", n->children))) {
508 int s = parse_int(doc, fnode);
509 if (s > 0) size = s;
510 }
511 if ((fnode = parse_find_node("weight", n->children))) {
512 gchar *w = parse_string(doc, fnode);
513 if (!g_ascii_strcasecmp(w, "Bold"))
514 weight = RR_FONTWEIGHT_BOLD;
515 g_free(w);
516 }
517 if ((fnode = parse_find_node("slant", n->children))) {
518 gchar *s = parse_string(doc, fnode);
519 if (!g_ascii_strcasecmp(s, "Italic"))
520 slant = RR_FONTSLANT_ITALIC;
521 if (!g_ascii_strcasecmp(s, "Oblique"))
522 slant = RR_FONTSLANT_OBLIQUE;
523 g_free(s);
524 }
525
526 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
527 g_free(name);
528 next_font:
529 n = parse_find_node("font", n->next);
530 }
531 }
532
533 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
534 gpointer d)
535 {
536 xmlNodePtr n;
537
538 node = node->children;
539
540 if ((n = parse_find_node("number", node))) {
541 gint d = parse_int(doc, n);
542 if (d > 0)
543 config_desktops_num = d;
544 }
545 if ((n = parse_find_node("firstdesk", node))) {
546 gint d = parse_int(doc, n);
547 if (d > 0)
548 config_screen_firstdesk = (unsigned) d;
549 }
550 if ((n = parse_find_node("names", node))) {
551 GSList *it;
552 xmlNodePtr nname;
553
554 for (it = config_desktops_names; it; it = it->next)
555 g_free(it->data);
556 g_slist_free(config_desktops_names);
557 config_desktops_names = NULL;
558
559 nname = parse_find_node("name", n->children);
560 while (nname) {
561 config_desktops_names = g_slist_append(config_desktops_names,
562 parse_string(doc, nname));
563 nname = parse_find_node("name", nname->next);
564 }
565 }
566 }
567
568 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
569 gpointer d)
570 {
571 xmlNodePtr n;
572
573 node = node->children;
574
575 if ((n = parse_find_node("drawContents", node)))
576 config_resize_redraw = parse_bool(doc, n);
577 if ((n = parse_find_node("popupShow", node))) {
578 config_resize_popup_show = parse_int(doc, n);
579 if (parse_contains("Always", doc, n))
580 config_resize_popup_show = 2;
581 else if (parse_contains("Never", doc, n))
582 config_resize_popup_show = 0;
583 else if (parse_contains("Nonpixel", doc, n))
584 config_resize_popup_show = 1;
585 }
586 if ((n = parse_find_node("popupPosition", node))) {
587 config_resize_popup_pos = parse_int(doc, n);
588 if (parse_contains("Top", doc, n))
589 config_resize_popup_pos = 1;
590 else if (parse_contains("Center", doc, n))
591 config_resize_popup_pos = 0;
592 }
593 }
594
595 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
596 gpointer d)
597 {
598 xmlNodePtr n;
599
600 node = node->children;
601
602 if ((n = parse_find_node("position", node))) {
603 if (parse_contains("TopLeft", doc, n))
604 config_dock_floating = FALSE,
605 config_dock_pos = OB_DIRECTION_NORTHWEST;
606 else if (parse_contains("Top", doc, n))
607 config_dock_floating = FALSE,
608 config_dock_pos = OB_DIRECTION_NORTH;
609 else if (parse_contains("TopRight", doc, n))
610 config_dock_floating = FALSE,
611 config_dock_pos = OB_DIRECTION_NORTHEAST;
612 else if (parse_contains("Right", doc, n))
613 config_dock_floating = FALSE,
614 config_dock_pos = OB_DIRECTION_EAST;
615 else if (parse_contains("BottomRight", doc, n))
616 config_dock_floating = FALSE,
617 config_dock_pos = OB_DIRECTION_SOUTHEAST;
618 else if (parse_contains("Bottom", doc, n))
619 config_dock_floating = FALSE,
620 config_dock_pos = OB_DIRECTION_SOUTH;
621 else if (parse_contains("BottomLeft", doc, n))
622 config_dock_floating = FALSE,
623 config_dock_pos = OB_DIRECTION_SOUTHWEST;
624 else if (parse_contains("Left", doc, n))
625 config_dock_floating = FALSE,
626 config_dock_pos = OB_DIRECTION_WEST;
627 else if (parse_contains("Floating", doc, n))
628 config_dock_floating = TRUE;
629 }
630 if (config_dock_floating) {
631 if ((n = parse_find_node("floatingX", node)))
632 config_dock_x = parse_int(doc, n);
633 if ((n = parse_find_node("floatingY", node)))
634 config_dock_y = parse_int(doc, n);
635 } else {
636 if ((n = parse_find_node("noStrut", node)))
637 config_dock_nostrut = parse_bool(doc, n);
638 }
639 if ((n = parse_find_node("stacking", node))) {
640 if (parse_contains("above", doc, n))
641 config_dock_layer = OB_STACKING_LAYER_ABOVE;
642 else if (parse_contains("normal", doc, n))
643 config_dock_layer = OB_STACKING_LAYER_NORMAL;
644 else if (parse_contains("below", doc, n))
645 config_dock_layer = OB_STACKING_LAYER_BELOW;
646 }
647 if ((n = parse_find_node("direction", node))) {
648 if (parse_contains("horizontal", doc, n))
649 config_dock_orient = OB_ORIENTATION_HORZ;
650 else if (parse_contains("vertical", doc, n))
651 config_dock_orient = OB_ORIENTATION_VERT;
652 }
653 if ((n = parse_find_node("autoHide", node)))
654 config_dock_hide = parse_bool(doc, n);
655 if ((n = parse_find_node("hideDelay", node)))
656 config_dock_hide_delay = parse_int(doc, n) * 1000;
657 if ((n = parse_find_node("showDelay", node)))
658 config_dock_show_delay = parse_int(doc, n) * 1000;
659 if ((n = parse_find_node("moveButton", node))) {
660 gchar *str = parse_string(doc, n);
661 guint b, s;
662 if (translate_button(str, &s, &b)) {
663 config_dock_app_move_button = b;
664 config_dock_app_move_modifiers = s;
665 } else {
666 g_message(_("Invalid button '%s' specified in config file"), str);
667 }
668 g_free(str);
669 }
670 }
671
672 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
673 gpointer d)
674 {
675 xmlNodePtr n;
676 for (node = node->children; node; node = node->next) {
677 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
678 gchar *c;
679
680 c = parse_string(doc, node);
681 config_menu_files = g_slist_append(config_menu_files,
682 parse_expand_tilde(c));
683 g_free(c);
684 }
685 if ((n = parse_find_node("hideDelay", node)))
686 config_menu_hide_delay = parse_int(doc, n);
687 if ((n = parse_find_node("middle", node)))
688 config_menu_middle = parse_bool(doc, n);
689 if ((n = parse_find_node("submenuShowDelay", node)))
690 config_submenu_show_delay = parse_int(doc, n);
691 if ((n = parse_find_node("applicationIcons", node)))
692 config_menu_client_list_icons = parse_bool(doc, n);
693 }
694 }
695
696 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
697 gpointer d)
698 {
699 xmlNodePtr n;
700
701 node = node->children;
702 if ((n = parse_find_node("strength", node)))
703 config_resist_win = parse_int(doc, n);
704 if ((n = parse_find_node("screen_edge_strength", node)))
705 config_resist_edge = parse_int(doc, n);
706 }
707
708 typedef struct
709 {
710 const gchar *key;
711 const gchar *actname;
712 } ObDefKeyBind;
713
714 static void bind_default_keyboard()
715 {
716 ObDefKeyBind *it;
717 ObDefKeyBind binds[] = {
718 { "A-Tab", "NextWindow" },
719 { "S-A-Tab", "PreviousWindow" },
720 { "A-F4", "Close" },
721 { NULL, NULL }
722 };
723
724 for (it = binds; it->key; ++it) {
725 GList *l = g_list_append(NULL, g_strdup(it->key));
726 keyboard_bind(l, action_from_string(it->actname,
727 OB_USER_ACTION_KEYBOARD_KEY));
728 }
729 }
730
731 typedef struct
732 {
733 const gchar *button;
734 const gchar *context;
735 const ObMouseAction mact;
736 const gchar *actname;
737 } ObDefMouseBind;
738
739 static void bind_default_mouse()
740 {
741 ObDefMouseBind *it;
742 ObDefMouseBind binds[] = {
743 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
744 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
745 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
746 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
747 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
748 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
749 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
750 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
751 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
752 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
753 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
754 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
755 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
756 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
757 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
758 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
759 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
760 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
761 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
762 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
763 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
764 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
765 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
766 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
767 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
768 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
769 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
770 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
771 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
772 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
773 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
774 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
775 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
776 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
777 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
778 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
779 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
780 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
781 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
782 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
783 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
784 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
785 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
786 { NULL, NULL, 0, NULL }
787 };
788
789 for (it = binds; it->button; ++it) {
790 ObUserAction uact;
791 switch (it->mact) {
792 case OB_MOUSE_ACTION_PRESS:
793 uact = OB_USER_ACTION_MOUSE_PRESS; break;
794 case OB_MOUSE_ACTION_RELEASE:
795 uact = OB_USER_ACTION_MOUSE_RELEASE; break;
796 case OB_MOUSE_ACTION_CLICK:
797 uact = OB_USER_ACTION_MOUSE_CLICK; break;
798 case OB_MOUSE_ACTION_DOUBLE_CLICK:
799 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK; break;
800 case OB_MOUSE_ACTION_MOTION:
801 uact = OB_USER_ACTION_MOUSE_MOTION; break;
802 default:
803 g_assert_not_reached();
804 }
805 mouse_bind(it->button, it->context, it->mact,
806 action_from_string(it->actname, uact));
807 }
808 }
809
810 void config_startup(ObParseInst *i)
811 {
812 config_focus_new = TRUE;
813 config_focus_follow = FALSE;
814 config_focus_delay = 0;
815 config_focus_raise = FALSE;
816 config_focus_last = FALSE;
817
818 parse_register(i, "focus", parse_focus, NULL);
819
820 config_place_policy = OB_PLACE_POLICY_SMART;
821
822 parse_register(i, "placement", parse_placement, NULL);
823
824 config_theme = NULL;
825
826 config_animate_iconify = TRUE;
827 config_title_layout = g_strdup("NLIMC");
828 config_theme_keepborder = TRUE;
829
830 config_font_activewindow = NULL;
831 config_font_inactivewindow = NULL;
832 config_font_menuitem = NULL;
833 config_font_menutitle = NULL;
834
835 parse_register(i, "theme", parse_theme, NULL);
836
837 config_desktops_num = 4;
838 config_screen_firstdesk = 1;
839 config_desktops_names = NULL;
840
841 parse_register(i, "desktops", parse_desktops, NULL);
842
843 config_resize_redraw = TRUE;
844 config_resize_four_corners = FALSE;
845 config_resize_popup_show = 1; /* nonpixel increments */
846 config_resize_popup_pos = 0; /* center of client */
847
848 parse_register(i, "resize", parse_resize, NULL);
849
850 config_dock_layer = OB_STACKING_LAYER_ABOVE;
851 config_dock_pos = OB_DIRECTION_NORTHEAST;
852 config_dock_floating = FALSE;
853 config_dock_nostrut = FALSE;
854 config_dock_x = 0;
855 config_dock_y = 0;
856 config_dock_orient = OB_ORIENTATION_VERT;
857 config_dock_hide = FALSE;
858 config_dock_hide_delay = 300;
859 config_dock_show_delay = 300;
860 config_dock_app_move_button = 2; /* middle */
861 config_dock_app_move_modifiers = 0;
862
863 parse_register(i, "dock", parse_dock, NULL);
864
865 translate_key("C-g", &config_keyboard_reset_state,
866 &config_keyboard_reset_keycode);
867
868 bind_default_keyboard();
869
870 parse_register(i, "keyboard", parse_keyboard, NULL);
871
872 config_mouse_threshold = 3;
873 config_mouse_dclicktime = 200;
874
875 bind_default_mouse();
876
877 parse_register(i, "mouse", parse_mouse, NULL);
878
879 config_resist_win = 10;
880 config_resist_edge = 20;
881
882 parse_register(i, "resistance", parse_resistance, NULL);
883
884 config_menu_hide_delay = 250;
885 config_menu_middle = FALSE;
886 config_submenu_show_delay = 0;
887 config_menu_client_list_icons = TRUE;
888 config_menu_files = NULL;
889
890 parse_register(i, "menu", parse_menu, NULL);
891
892 config_per_app_settings = NULL;
893
894 parse_register(i, "applications", parse_per_app_settings, NULL);
895 }
896
897 void config_shutdown()
898 {
899 GSList *it;
900
901 g_free(config_theme);
902
903 g_free(config_title_layout);
904
905 RrFontClose(config_font_activewindow);
906 RrFontClose(config_font_inactivewindow);
907 RrFontClose(config_font_menuitem);
908 RrFontClose(config_font_menutitle);
909
910 for (it = config_desktops_names; it; it = g_slist_next(it))
911 g_free(it->data);
912 g_slist_free(config_desktops_names);
913
914 for (it = config_menu_files; it; it = g_slist_next(it))
915 g_free(it->data);
916 g_slist_free(config_menu_files);
917
918 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
919 ObAppSettings *itd = (ObAppSettings *)it->data;
920 g_free(itd->name);
921 g_free(itd->role);
922 g_free(itd->class);
923 g_free(it->data);
924 }
925 g_slist_free(config_per_app_settings);
926 }
This page took 0.069849 seconds and 3 git commands to generate.