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