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