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