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