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