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