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