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