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