]> Dogcows Code - chaz/openbox/blob - openbox/config.c
Merge branch 'backport' into work
[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 ObPlaceMonitor config_place_monitor;
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 guint 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(c, "default")) {
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, "monitor"))) {
485 if (obt_parse_node_contains(n, "active"))
486 config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
487 else if (obt_parse_node_contains(n, "mouse"))
488 config_place_monitor = OB_PLACE_MONITOR_MOUSE;
489 }
490 }
491
492 static void parse_margins(xmlNodePtr node, gpointer d)
493 {
494 xmlNodePtr n;
495
496 node = node->children;
497
498 if ((n = obt_parse_find_node(node, "top")))
499 config_margins.top = MAX(0, obt_parse_node_int(n));
500 if ((n = obt_parse_find_node(node, "left")))
501 config_margins.left = MAX(0, obt_parse_node_int(n));
502 if ((n = obt_parse_find_node(node, "right")))
503 config_margins.right = MAX(0, obt_parse_node_int(n));
504 if ((n = obt_parse_find_node(node, "bottom")))
505 config_margins.bottom = MAX(0, obt_parse_node_int(n));
506 }
507
508 static void parse_theme(xmlNodePtr node, gpointer d)
509 {
510 xmlNodePtr n;
511
512 node = node->children;
513
514 if ((n = obt_parse_find_node(node, "name"))) {
515 gchar *c;
516
517 g_free(config_theme);
518 c = obt_parse_node_string(n);
519 config_theme = obt_paths_expand_tilde(c);
520 g_free(c);
521 }
522 if ((n = obt_parse_find_node(node, "titleLayout"))) {
523 gchar *c, *d;
524
525 g_free(config_title_layout);
526 config_title_layout = obt_parse_node_string(n);
527
528 /* replace duplicates with spaces */
529 for (c = config_title_layout; *c != '\0'; ++c)
530 for (d = c+1; *d != '\0'; ++d)
531 if (*c == *d) *d = ' ';
532 }
533 if ((n = obt_parse_find_node(node, "keepBorder")))
534 config_theme_keepborder = obt_parse_node_bool(n);
535 if ((n = obt_parse_find_node(node, "animateIconify")))
536 config_animate_iconify = obt_parse_node_bool(n);
537
538 n = obt_parse_find_node(node, "font");
539 while (n) {
540 xmlNodePtr fnode;
541 RrFont **font;
542 gchar *name = g_strdup(RrDefaultFontFamily);
543 gint size = RrDefaultFontSize;
544 RrFontWeight weight = RrDefaultFontWeight;
545 RrFontSlant slant = RrDefaultFontSlant;
546
547 if (obt_parse_attr_contains(n, "place", "ActiveWindow"))
548 font = &config_font_activewindow;
549 else if (obt_parse_attr_contains(n, "place", "InactiveWindow"))
550 font = &config_font_inactivewindow;
551 else if (obt_parse_attr_contains(n, "place", "MenuHeader"))
552 font = &config_font_menutitle;
553 else if (obt_parse_attr_contains(n, "place", "MenuItem"))
554 font = &config_font_menuitem;
555 else if (obt_parse_attr_contains(n, "place", "OnScreenDisplay"))
556 font = &config_font_osd;
557 else
558 goto next_font;
559
560 if ((fnode = obt_parse_find_node(n->children, "name"))) {
561 g_free(name);
562 name = obt_parse_node_string(fnode);
563 }
564 if ((fnode = obt_parse_find_node(n->children, "size"))) {
565 int s = obt_parse_node_int(fnode);
566 if (s > 0) size = s;
567 }
568 if ((fnode = obt_parse_find_node(n->children, "weight"))) {
569 gchar *w = obt_parse_node_string(fnode);
570 if (!g_ascii_strcasecmp(w, "Bold"))
571 weight = RR_FONTWEIGHT_BOLD;
572 g_free(w);
573 }
574 if ((fnode = obt_parse_find_node(n->children, "slant"))) {
575 gchar *s = obt_parse_node_string(fnode);
576 if (!g_ascii_strcasecmp(s, "Italic"))
577 slant = RR_FONTSLANT_ITALIC;
578 if (!g_ascii_strcasecmp(s, "Oblique"))
579 slant = RR_FONTSLANT_OBLIQUE;
580 g_free(s);
581 }
582
583 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
584 g_free(name);
585 next_font:
586 n = obt_parse_find_node(n->next, "font");
587 }
588 }
589
590 static void parse_desktops(xmlNodePtr node, gpointer d)
591 {
592 xmlNodePtr n;
593
594 node = node->children;
595
596 if ((n = obt_parse_find_node(node, "number"))) {
597 gint d = obt_parse_node_int(n);
598 if (d > 0)
599 config_desktops_num = (unsigned) d;
600 }
601 if ((n = obt_parse_find_node(node, "firstdesk"))) {
602 gint d = obt_parse_node_int(n);
603 if (d > 0)
604 config_screen_firstdesk = (unsigned) d;
605 }
606 if ((n = obt_parse_find_node(node, "names"))) {
607 GSList *it;
608 xmlNodePtr nname;
609
610 for (it = config_desktops_names; it; it = it->next)
611 g_free(it->data);
612 g_slist_free(config_desktops_names);
613 config_desktops_names = NULL;
614
615 nname = obt_parse_find_node(n->children, "name");
616 while (nname) {
617 config_desktops_names =
618 g_slist_append(config_desktops_names,
619 obt_parse_node_string(nname));
620 nname = obt_parse_find_node(nname->next, "name");
621 }
622 }
623 if ((n = obt_parse_find_node(node, "popupTime")))
624 config_desktop_popup_time = obt_parse_node_int(n);
625 }
626
627 static void parse_resize(xmlNodePtr node, gpointer d)
628 {
629 xmlNodePtr n;
630
631 node = node->children;
632
633 if ((n = obt_parse_find_node(node, "drawContents")))
634 config_resize_redraw = obt_parse_node_bool(n);
635 if ((n = obt_parse_find_node(node, "popupShow"))) {
636 config_resize_popup_show = obt_parse_node_int(n);
637 if (obt_parse_node_contains(n, "Always"))
638 config_resize_popup_show = 2;
639 else if (obt_parse_node_contains(n, "Never"))
640 config_resize_popup_show = 0;
641 else if (obt_parse_node_contains(n, "Nonpixel"))
642 config_resize_popup_show = 1;
643 }
644 if ((n = obt_parse_find_node(node, "popupPosition"))) {
645 if (obt_parse_node_contains(n, "Top"))
646 config_resize_popup_pos = OB_RESIZE_POS_TOP;
647 else if (obt_parse_node_contains(n, "Center"))
648 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
649 else if (obt_parse_node_contains(n, "Fixed")) {
650 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
651
652 if ((n = obt_parse_find_node(node, "popupFixedPosition"))) {
653 xmlNodePtr n2;
654
655 if ((n2 = obt_parse_find_node(n->children, "x")))
656 config_parse_gravity_coord(n2,
657 &config_resize_popup_fixed.x);
658 if ((n2 = obt_parse_find_node(n->children, "y")))
659 config_parse_gravity_coord(n2,
660 &config_resize_popup_fixed.y);
661 }
662 }
663 }
664 }
665
666 static void parse_dock(xmlNodePtr node, gpointer d)
667 {
668 xmlNodePtr n;
669
670 node = node->children;
671
672 if ((n = obt_parse_find_node(node, "position"))) {
673 if (obt_parse_node_contains(n, "TopLeft"))
674 config_dock_floating = FALSE,
675 config_dock_pos = OB_DIRECTION_NORTHWEST;
676 else if (obt_parse_node_contains(n, "Top"))
677 config_dock_floating = FALSE,
678 config_dock_pos = OB_DIRECTION_NORTH;
679 else if (obt_parse_node_contains(n, "TopRight"))
680 config_dock_floating = FALSE,
681 config_dock_pos = OB_DIRECTION_NORTHEAST;
682 else if (obt_parse_node_contains(n, "Right"))
683 config_dock_floating = FALSE,
684 config_dock_pos = OB_DIRECTION_EAST;
685 else if (obt_parse_node_contains(n, "BottomRight"))
686 config_dock_floating = FALSE,
687 config_dock_pos = OB_DIRECTION_SOUTHEAST;
688 else if (obt_parse_node_contains(n, "Bottom"))
689 config_dock_floating = FALSE,
690 config_dock_pos = OB_DIRECTION_SOUTH;
691 else if (obt_parse_node_contains(n, "BottomLeft"))
692 config_dock_floating = FALSE,
693 config_dock_pos = OB_DIRECTION_SOUTHWEST;
694 else if (obt_parse_node_contains(n, "Left"))
695 config_dock_floating = FALSE,
696 config_dock_pos = OB_DIRECTION_WEST;
697 else if (obt_parse_node_contains(n, "Floating"))
698 config_dock_floating = TRUE;
699 }
700 if (config_dock_floating) {
701 if ((n = obt_parse_find_node(node, "floatingX")))
702 config_dock_x = obt_parse_node_int(n);
703 if ((n = obt_parse_find_node(node, "floatingY")))
704 config_dock_y = obt_parse_node_int(n);
705 } else {
706 if ((n = obt_parse_find_node(node, "noStrut")))
707 config_dock_nostrut = obt_parse_node_bool(n);
708 }
709 if ((n = obt_parse_find_node(node, "stacking"))) {
710 if (obt_parse_node_contains(n, "normal"))
711 config_dock_layer = OB_STACKING_LAYER_NORMAL;
712 else if (obt_parse_node_contains(n, "below"))
713 config_dock_layer = OB_STACKING_LAYER_BELOW;
714 else if (obt_parse_node_contains(n, "above"))
715 config_dock_layer = OB_STACKING_LAYER_ABOVE;
716 }
717 if ((n = obt_parse_find_node(node, "direction"))) {
718 if (obt_parse_node_contains(n, "horizontal"))
719 config_dock_orient = OB_ORIENTATION_HORZ;
720 else if (obt_parse_node_contains(n, "vertical"))
721 config_dock_orient = OB_ORIENTATION_VERT;
722 }
723 if ((n = obt_parse_find_node(node, "autoHide")))
724 config_dock_hide = obt_parse_node_bool(n);
725 if ((n = obt_parse_find_node(node, "hideDelay")))
726 config_dock_hide_delay = obt_parse_node_int(n);
727 if ((n = obt_parse_find_node(node, "showDelay")))
728 config_dock_show_delay = obt_parse_node_int(n);
729 if ((n = obt_parse_find_node(node, "moveButton"))) {
730 gchar *str = obt_parse_node_string(n);
731 guint b, s;
732 if (translate_button(str, &s, &b)) {
733 config_dock_app_move_button = b;
734 config_dock_app_move_modifiers = s;
735 } else {
736 g_message(_("Invalid button '%s' specified in config file"), str);
737 }
738 g_free(str);
739 }
740 }
741
742 static void parse_menu(xmlNodePtr node, gpointer d)
743 {
744 xmlNodePtr n;
745 for (node = node->children; node; node = node->next) {
746 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
747 gchar *c;
748
749 c = obt_parse_node_string(node);
750 config_menu_files = g_slist_append(config_menu_files,
751 obt_paths_expand_tilde(c));
752 g_free(c);
753 }
754 if ((n = obt_parse_find_node(node, "hideDelay")))
755 config_menu_hide_delay = obt_parse_node_int(n);
756 if ((n = obt_parse_find_node(node, "middle")))
757 config_menu_middle = obt_parse_node_bool(n);
758 if ((n = obt_parse_find_node(node, "submenuShowDelay")))
759 config_submenu_show_delay = obt_parse_node_int(n);
760 if ((n = obt_parse_find_node(node, "applicationIcons")))
761 config_menu_client_list_icons = obt_parse_node_bool(n);
762 }
763 }
764
765 static void parse_resistance(xmlNodePtr node, gpointer d)
766 {
767 xmlNodePtr n;
768
769 node = node->children;
770 if ((n = obt_parse_find_node(node, "strength")))
771 config_resist_win = obt_parse_node_int(n);
772 if ((n = obt_parse_find_node(node, "screen_edge_strength")))
773 config_resist_edge = obt_parse_node_int(n);
774 }
775
776 typedef struct
777 {
778 const gchar *key;
779 const gchar *actname;
780 } ObDefKeyBind;
781
782 static void bind_default_keyboard(void)
783 {
784 ObDefKeyBind *it;
785 ObDefKeyBind binds[] = {
786 { "A-Tab", "NextWindow" },
787 { "S-A-Tab", "PreviousWindow" },
788 { "A-F4", "Close" },
789 { NULL, NULL }
790 };
791 for (it = binds; it->key; ++it) {
792 GList *l = g_list_append(NULL, g_strdup(it->key));
793 keyboard_bind(l, actions_parse_string(it->actname));
794 }
795 }
796
797 typedef struct
798 {
799 const gchar *button;
800 const gchar *context;
801 const ObMouseAction mact;
802 const gchar *actname;
803 } ObDefMouseBind;
804
805 static void bind_default_mouse(void)
806 {
807 ObDefMouseBind *it;
808 ObDefMouseBind binds[] = {
809 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
810 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
811 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
812 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
813 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
814 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
815 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
816 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
817 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
818 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
819 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
820 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
821 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
822 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
823 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
824 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
825 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
826 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
827 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
828 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
829 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
830 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
831 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
832 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
833 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
834 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
835 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
836 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
837 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
838 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
839 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
840 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
841 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
842 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
843 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
844 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
845 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
846 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
847 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
848 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
849 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
850 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
851 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
852 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
853 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
854 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
855 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
856 { NULL, NULL, 0, NULL }
857 };
858
859 for (it = binds; it->button; ++it)
860 mouse_bind(it->button, it->context, it->mact,
861 actions_parse_string(it->actname));
862 }
863
864 void config_startup(ObtParseInst *i)
865 {
866 config_focus_new = TRUE;
867 config_focus_follow = FALSE;
868 config_focus_delay = 0;
869 config_focus_raise = FALSE;
870 config_focus_last = TRUE;
871 config_focus_under_mouse = FALSE;
872
873 obt_parse_register(i, "focus", parse_focus, NULL);
874
875 config_place_policy = OB_PLACE_POLICY_SMART;
876 config_place_center = TRUE;
877 config_place_monitor = OB_PLACE_MONITOR_ANY;
878
879 obt_parse_register(i, "placement", parse_placement, NULL);
880
881 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
882
883 obt_parse_register(i, "margins", parse_margins, NULL);
884
885 config_theme = NULL;
886
887 config_animate_iconify = TRUE;
888 config_title_layout = g_strdup("NLIMC");
889 config_theme_keepborder = TRUE;
890
891 config_font_activewindow = NULL;
892 config_font_inactivewindow = NULL;
893 config_font_menuitem = NULL;
894 config_font_menutitle = NULL;
895
896 obt_parse_register(i, "theme", parse_theme, NULL);
897
898 config_desktops_num = 4;
899 config_screen_firstdesk = 1;
900 config_desktops_names = NULL;
901 config_desktop_popup_time = 875;
902
903 obt_parse_register(i, "desktops", parse_desktops, NULL);
904
905 config_resize_redraw = TRUE;
906 config_resize_popup_show = 1; /* nonpixel increments */
907 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
908 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
909 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
910
911 obt_parse_register(i, "resize", parse_resize, NULL);
912
913 config_dock_layer = OB_STACKING_LAYER_ABOVE;
914 config_dock_pos = OB_DIRECTION_NORTHEAST;
915 config_dock_floating = FALSE;
916 config_dock_nostrut = FALSE;
917 config_dock_x = 0;
918 config_dock_y = 0;
919 config_dock_orient = OB_ORIENTATION_VERT;
920 config_dock_hide = FALSE;
921 config_dock_hide_delay = 300;
922 config_dock_show_delay = 300;
923 config_dock_app_move_button = 2; /* middle */
924 config_dock_app_move_modifiers = 0;
925
926 obt_parse_register(i, "dock", parse_dock, NULL);
927
928 translate_key("C-g", &config_keyboard_reset_state,
929 &config_keyboard_reset_keycode);
930
931 bind_default_keyboard();
932
933 obt_parse_register(i, "keyboard", parse_keyboard, NULL);
934
935 config_mouse_threshold = 8;
936 config_mouse_dclicktime = 200;
937 config_mouse_screenedgetime = 400;
938
939 bind_default_mouse();
940
941 obt_parse_register(i, "mouse", parse_mouse, NULL);
942
943 config_resist_win = 10;
944 config_resist_edge = 20;
945
946 obt_parse_register(i, "resistance", parse_resistance, NULL);
947
948 config_menu_hide_delay = 250;
949 config_menu_middle = FALSE;
950 config_submenu_show_delay = 0;
951 config_menu_client_list_icons = TRUE;
952 config_menu_files = NULL;
953
954 obt_parse_register(i, "menu", parse_menu, NULL);
955
956 config_per_app_settings = NULL;
957
958 obt_parse_register(i, "applications", parse_per_app_settings, NULL);
959 }
960
961 void config_shutdown(void)
962 {
963 GSList *it;
964
965 g_free(config_theme);
966
967 g_free(config_title_layout);
968
969 RrFontClose(config_font_activewindow);
970 RrFontClose(config_font_inactivewindow);
971 RrFontClose(config_font_menuitem);
972 RrFontClose(config_font_menutitle);
973 RrFontClose(config_font_osd);
974
975 for (it = config_desktops_names; it; it = g_slist_next(it))
976 g_free(it->data);
977 g_slist_free(config_desktops_names);
978
979 for (it = config_menu_files; it; it = g_slist_next(it))
980 g_free(it->data);
981 g_slist_free(config_menu_files);
982
983 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
984 ObAppSettings *itd = (ObAppSettings *)it->data;
985 if (itd->name) g_pattern_spec_free(itd->name);
986 if (itd->role) g_pattern_spec_free(itd->role);
987 if (itd->class) g_pattern_spec_free(itd->class);
988 g_free(it->data);
989 }
990 g_slist_free(config_per_app_settings);
991 }
This page took 0.080339 seconds and 5 git commands to generate.