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