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