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