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