]> Dogcows Code - chaz/openbox/blob - openbox/config.c
mem leak in config.c
[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 g_free(type_str);
374 name = class = role = title = type_str = NULL;
375 }
376
377 app = obt_xml_find_node(app->next, "application");
378 }
379 }
380
381 /*
382
383 <keybind key="C-x">
384 <action name="ChangeDesktop">
385 <desktop>3</desktop>
386 </action>
387 </keybind>
388
389 */
390
391 static void parse_key(xmlNodePtr node, GList *keylist)
392 {
393 gchar *keystring, **keys, **key;
394 xmlNodePtr n;
395 gboolean is_chroot = FALSE;
396
397 if (!obt_xml_attr_string(node, "key", &keystring))
398 return;
399
400 obt_xml_attr_bool(node, "chroot", &is_chroot);
401
402 keys = g_strsplit(keystring, " ", 0);
403 for (key = keys; *key; ++key) {
404 keylist = g_list_append(keylist, *key);
405
406 if ((n = obt_xml_find_node(node->children, "keybind"))) {
407 while (n) {
408 parse_key(n, keylist);
409 n = obt_xml_find_node(n->next, "keybind");
410 }
411 }
412 else if ((n = obt_xml_find_node(node->children, "action"))) {
413 while (n) {
414 ObActionsAct *action;
415
416 action = actions_parse(n);
417 if (action)
418 keyboard_bind(keylist, action);
419 n = obt_xml_find_node(n->next, "action");
420 }
421 }
422
423
424 if (is_chroot)
425 keyboard_chroot(keylist);
426 keylist = g_list_delete_link(keylist, g_list_last(keylist));
427 }
428
429 g_strfreev(keys);
430 g_free(keystring);
431 }
432
433 static void parse_keyboard(xmlNodePtr node, gpointer d)
434 {
435 xmlNodePtr n;
436 gchar *key;
437
438 keyboard_unbind_all();
439
440 if ((n = obt_xml_find_node(node->children, "chainQuitKey"))) {
441 key = obt_xml_node_string(n);
442 translate_key(key, &config_keyboard_reset_state,
443 &config_keyboard_reset_keycode);
444 g_free(key);
445 }
446
447 if ((n = obt_xml_find_node(node->children, "keybind")))
448 while (n) {
449 parse_key(n, NULL);
450 n = obt_xml_find_node(n->next, "keybind");
451 }
452 }
453
454 /*
455
456 <context name="Titlebar">
457 <mousebind button="Left" action="Press">
458 <action name="Raise"></action>
459 </mousebind>
460 </context>
461
462 */
463
464 static void parse_mouse(xmlNodePtr node, gpointer d)
465 {
466 xmlNodePtr n, nbut, nact;
467 gchar *buttonstr;
468 gchar *cxstr;
469 ObMouseAction mact;
470
471 mouse_unbind_all();
472
473 node = node->children;
474
475 if ((n = obt_xml_find_node(node, "dragThreshold")))
476 config_mouse_threshold = obt_xml_node_int(n);
477 if ((n = obt_xml_find_node(node, "doubleClickTime")))
478 config_mouse_dclicktime = obt_xml_node_int(n);
479 if ((n = obt_xml_find_node(node, "screenEdgeWarpTime"))) {
480 config_mouse_screenedgetime = obt_xml_node_int(n);
481 /* minimum value of 25 for this property, when it is 1 and you hit the
482 edge it basically never stops */
483 if (config_mouse_screenedgetime && config_mouse_screenedgetime < 25)
484 config_mouse_screenedgetime = 25;
485 }
486 if ((n = obt_xml_find_node(node, "screenEdgeWarpMouse")))
487 config_mouse_screenedgewarp = obt_xml_node_bool(n);
488
489 n = obt_xml_find_node(node, "context");
490 while (n) {
491 gchar *modcxstr;
492 ObFrameContext cx;
493
494 if (!obt_xml_attr_string(n, "name", &cxstr))
495 goto next_n;
496
497 modcxstr = g_strdup(cxstr); /* make a copy to mutilate */
498 while (frame_next_context_from_string(modcxstr, &cx)) {
499 if (!cx) {
500 gchar *s = strchr(modcxstr, ' ');
501 if (s) {
502 *s = '\0';
503 g_message(_("Invalid context \"%s\" in mouse binding"),
504 modcxstr);
505 *s = ' ';
506 }
507 continue;
508 }
509
510 nbut = obt_xml_find_node(n->children, "mousebind");
511 while (nbut) {
512 if (!obt_xml_attr_string(nbut, "button", &buttonstr))
513 goto next_nbut;
514 if (obt_xml_attr_contains(nbut, "action", "press"))
515 mact = OB_MOUSE_ACTION_PRESS;
516 else if (obt_xml_attr_contains(nbut, "action", "release"))
517 mact = OB_MOUSE_ACTION_RELEASE;
518 else if (obt_xml_attr_contains(nbut, "action", "click"))
519 mact = OB_MOUSE_ACTION_CLICK;
520 else if (obt_xml_attr_contains(nbut, "action","doubleclick"))
521 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
522 else if (obt_xml_attr_contains(nbut, "action", "drag"))
523 mact = OB_MOUSE_ACTION_MOTION;
524 else
525 goto next_nbut;
526
527 nact = obt_xml_find_node(nbut->children, "action");
528 while (nact) {
529 ObActionsAct *action;
530
531 if ((action = actions_parse(nact)))
532 mouse_bind(buttonstr, cx, mact, action);
533 nact = obt_xml_find_node(nact->next, "action");
534 }
535 g_free(buttonstr);
536 next_nbut:
537 nbut = obt_xml_find_node(nbut->next, "mousebind");
538 }
539 }
540 g_free(modcxstr);
541 g_free(cxstr);
542 next_n:
543 n = obt_xml_find_node(n->next, "context");
544 }
545 }
546
547 static void parse_focus(xmlNodePtr node, gpointer d)
548 {
549 xmlNodePtr n;
550
551 node = node->children;
552
553 if ((n = obt_xml_find_node(node, "focusNew")))
554 config_focus_new = obt_xml_node_bool(n);
555 if ((n = obt_xml_find_node(node, "followMouse")))
556 config_focus_follow = obt_xml_node_bool(n);
557 if ((n = obt_xml_find_node(node, "focusDelay")))
558 config_focus_delay = obt_xml_node_int(n);
559 if ((n = obt_xml_find_node(node, "raiseOnFocus")))
560 config_focus_raise = obt_xml_node_bool(n);
561 if ((n = obt_xml_find_node(node, "focusLast")))
562 config_focus_last = obt_xml_node_bool(n);
563 if ((n = obt_xml_find_node(node, "underMouse")))
564 config_focus_under_mouse = obt_xml_node_bool(n);
565 if ((n = obt_xml_find_node(node, "unfocusOnLeave")))
566 config_unfocus_leave = obt_xml_node_bool(n);
567 }
568
569 static void parse_placement(xmlNodePtr node, gpointer d)
570 {
571 xmlNodePtr n;
572
573 node = node->children;
574
575 if ((n = obt_xml_find_node(node, "policy")))
576 if (obt_xml_node_contains(n, "UnderMouse"))
577 config_place_policy = OB_PLACE_POLICY_MOUSE;
578 if ((n = obt_xml_find_node(node, "center")))
579 config_place_center = obt_xml_node_bool(n);
580 if ((n = obt_xml_find_node(node, "monitor"))) {
581 if (obt_xml_node_contains(n, "active"))
582 config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
583 else if (obt_xml_node_contains(n, "mouse"))
584 config_place_monitor = OB_PLACE_MONITOR_MOUSE;
585 }
586 if ((n = obt_xml_find_node(node, "primaryMonitor"))) {
587 config_primary_monitor_index = obt_xml_node_int(n);
588 if (!config_primary_monitor_index) {
589 if (obt_xml_node_contains(n, "mouse"))
590 config_primary_monitor = OB_PLACE_MONITOR_MOUSE;
591 }
592 }
593 }
594
595 static void parse_margins(xmlNodePtr node, gpointer d)
596 {
597 xmlNodePtr n;
598
599 node = node->children;
600
601 if ((n = obt_xml_find_node(node, "top")))
602 config_margins.top = MAX(0, obt_xml_node_int(n));
603 if ((n = obt_xml_find_node(node, "left")))
604 config_margins.left = MAX(0, obt_xml_node_int(n));
605 if ((n = obt_xml_find_node(node, "right")))
606 config_margins.right = MAX(0, obt_xml_node_int(n));
607 if ((n = obt_xml_find_node(node, "bottom")))
608 config_margins.bottom = MAX(0, obt_xml_node_int(n));
609 }
610
611 static void parse_theme(xmlNodePtr node, gpointer d)
612 {
613 xmlNodePtr n;
614
615 node = node->children;
616
617 if ((n = obt_xml_find_node(node, "name"))) {
618 gchar *c;
619
620 g_free(config_theme);
621 c = obt_xml_node_string(n);
622 config_theme = obt_paths_expand_tilde(c);
623 g_free(c);
624 }
625 if ((n = obt_xml_find_node(node, "titleLayout"))) {
626 gchar *c, *d;
627
628 g_free(config_title_layout);
629 config_title_layout = obt_xml_node_string(n);
630
631 /* replace duplicates with spaces */
632 for (c = config_title_layout; *c != '\0'; ++c)
633 for (d = c+1; *d != '\0'; ++d)
634 if (*c == *d) *d = ' ';
635 }
636 if ((n = obt_xml_find_node(node, "keepBorder")))
637 config_theme_keepborder = obt_xml_node_bool(n);
638 if ((n = obt_xml_find_node(node, "animateIconify")))
639 config_animate_iconify = obt_xml_node_bool(n);
640 if ((n = obt_xml_find_node(node, "windowListIconSize"))) {
641 config_theme_window_list_icon_size = obt_xml_node_int(n);
642 if (config_theme_window_list_icon_size < 16)
643 config_theme_window_list_icon_size = 16;
644 else if (config_theme_window_list_icon_size > 96)
645 config_theme_window_list_icon_size = 96;
646 }
647
648 n = obt_xml_find_node(node, "font");
649 while (n) {
650 xmlNodePtr fnode;
651 RrFont **font;
652 gchar *name = g_strdup(RrDefaultFontFamily);
653 gint size = RrDefaultFontSize;
654 RrFontWeight weight = RrDefaultFontWeight;
655 RrFontSlant slant = RrDefaultFontSlant;
656
657 if (obt_xml_attr_contains(n, "place", "ActiveWindow"))
658 font = &config_font_activewindow;
659 else if (obt_xml_attr_contains(n, "place", "InactiveWindow"))
660 font = &config_font_inactivewindow;
661 else if (obt_xml_attr_contains(n, "place", "MenuHeader"))
662 font = &config_font_menutitle;
663 else if (obt_xml_attr_contains(n, "place", "MenuItem"))
664 font = &config_font_menuitem;
665 else if (obt_xml_attr_contains(n, "place", "ActiveOnScreenDisplay"))
666 font = &config_font_activeosd;
667 else if (obt_xml_attr_contains(n, "place", "OnScreenDisplay"))
668 font = &config_font_activeosd;
669 else if (obt_xml_attr_contains(n, "place","InactiveOnScreenDisplay"))
670 font = &config_font_inactiveosd;
671 else
672 goto next_font;
673
674 if ((fnode = obt_xml_find_node(n->children, "name"))) {
675 g_free(name);
676 name = obt_xml_node_string(fnode);
677 }
678 if ((fnode = obt_xml_find_node(n->children, "size"))) {
679 int s = obt_xml_node_int(fnode);
680 if (s > 0) size = s;
681 }
682 if ((fnode = obt_xml_find_node(n->children, "weight"))) {
683 gchar *w = obt_xml_node_string(fnode);
684 if (!g_ascii_strcasecmp(w, "Bold"))
685 weight = RR_FONTWEIGHT_BOLD;
686 g_free(w);
687 }
688 if ((fnode = obt_xml_find_node(n->children, "slant"))) {
689 gchar *s = obt_xml_node_string(fnode);
690 if (!g_ascii_strcasecmp(s, "Italic"))
691 slant = RR_FONTSLANT_ITALIC;
692 if (!g_ascii_strcasecmp(s, "Oblique"))
693 slant = RR_FONTSLANT_OBLIQUE;
694 g_free(s);
695 }
696
697 *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
698 g_free(name);
699 next_font:
700 n = obt_xml_find_node(n->next, "font");
701 }
702 }
703
704 static void parse_desktops(xmlNodePtr node, gpointer d)
705 {
706 xmlNodePtr n;
707
708 node = node->children;
709
710 if ((n = obt_xml_find_node(node, "number"))) {
711 gint d = obt_xml_node_int(n);
712 if (d > 0)
713 config_desktops_num = (unsigned) d;
714 }
715 if ((n = obt_xml_find_node(node, "firstdesk"))) {
716 gint d = obt_xml_node_int(n);
717 if (d > 0)
718 config_screen_firstdesk = (unsigned) d;
719 }
720 if ((n = obt_xml_find_node(node, "names"))) {
721 GSList *it;
722 xmlNodePtr nname;
723
724 for (it = config_desktops_names; it; it = it->next)
725 g_free(it->data);
726 g_slist_free(config_desktops_names);
727 config_desktops_names = NULL;
728
729 nname = obt_xml_find_node(n->children, "name");
730 while (nname) {
731 config_desktops_names =
732 g_slist_append(config_desktops_names,
733 obt_xml_node_string(nname));
734 nname = obt_xml_find_node(nname->next, "name");
735 }
736 }
737 if ((n = obt_xml_find_node(node, "popupTime")))
738 config_desktop_popup_time = obt_xml_node_int(n);
739 }
740
741 static void parse_resize(xmlNodePtr node, gpointer d)
742 {
743 xmlNodePtr n;
744
745 node = node->children;
746
747 if ((n = obt_xml_find_node(node, "drawContents")))
748 config_resize_redraw = obt_xml_node_bool(n);
749 if ((n = obt_xml_find_node(node, "popupShow"))) {
750 config_resize_popup_show = obt_xml_node_int(n);
751 if (obt_xml_node_contains(n, "Always"))
752 config_resize_popup_show = 2;
753 else if (obt_xml_node_contains(n, "Never"))
754 config_resize_popup_show = 0;
755 else if (obt_xml_node_contains(n, "Nonpixel"))
756 config_resize_popup_show = 1;
757 }
758 if ((n = obt_xml_find_node(node, "popupPosition"))) {
759 if (obt_xml_node_contains(n, "Top"))
760 config_resize_popup_pos = OB_RESIZE_POS_TOP;
761 else if (obt_xml_node_contains(n, "Center"))
762 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
763 else if (obt_xml_node_contains(n, "Fixed")) {
764 config_resize_popup_pos = OB_RESIZE_POS_FIXED;
765
766 if ((n = obt_xml_find_node(node, "popupFixedPosition"))) {
767 xmlNodePtr n2;
768
769 if ((n2 = obt_xml_find_node(n->children, "x")))
770 config_parse_gravity_coord(n2,
771 &config_resize_popup_fixed.x);
772 if ((n2 = obt_xml_find_node(n->children, "y")))
773 config_parse_gravity_coord(n2,
774 &config_resize_popup_fixed.y);
775
776 config_resize_popup_fixed.x.pos =
777 MAX(config_resize_popup_fixed.x.pos, 0);
778 config_resize_popup_fixed.y.pos =
779 MAX(config_resize_popup_fixed.y.pos, 0);
780 }
781 }
782 }
783 }
784
785 static void parse_dock(xmlNodePtr node, gpointer d)
786 {
787 xmlNodePtr n;
788
789 node = node->children;
790
791 if ((n = obt_xml_find_node(node, "position"))) {
792 if (obt_xml_node_contains(n, "TopLeft"))
793 config_dock_floating = FALSE,
794 config_dock_pos = OB_DIRECTION_NORTHWEST;
795 else if (obt_xml_node_contains(n, "Top"))
796 config_dock_floating = FALSE,
797 config_dock_pos = OB_DIRECTION_NORTH;
798 else if (obt_xml_node_contains(n, "TopRight"))
799 config_dock_floating = FALSE,
800 config_dock_pos = OB_DIRECTION_NORTHEAST;
801 else if (obt_xml_node_contains(n, "Right"))
802 config_dock_floating = FALSE,
803 config_dock_pos = OB_DIRECTION_EAST;
804 else if (obt_xml_node_contains(n, "BottomRight"))
805 config_dock_floating = FALSE,
806 config_dock_pos = OB_DIRECTION_SOUTHEAST;
807 else if (obt_xml_node_contains(n, "Bottom"))
808 config_dock_floating = FALSE,
809 config_dock_pos = OB_DIRECTION_SOUTH;
810 else if (obt_xml_node_contains(n, "BottomLeft"))
811 config_dock_floating = FALSE,
812 config_dock_pos = OB_DIRECTION_SOUTHWEST;
813 else if (obt_xml_node_contains(n, "Left"))
814 config_dock_floating = FALSE,
815 config_dock_pos = OB_DIRECTION_WEST;
816 else if (obt_xml_node_contains(n, "Floating"))
817 config_dock_floating = TRUE;
818 }
819 if (config_dock_floating) {
820 if ((n = obt_xml_find_node(node, "floatingX")))
821 config_dock_x = obt_xml_node_int(n);
822 if ((n = obt_xml_find_node(node, "floatingY")))
823 config_dock_y = obt_xml_node_int(n);
824 } else {
825 if ((n = obt_xml_find_node(node, "noStrut")))
826 config_dock_nostrut = obt_xml_node_bool(n);
827 }
828 if ((n = obt_xml_find_node(node, "stacking"))) {
829 if (obt_xml_node_contains(n, "normal"))
830 config_dock_layer = OB_STACKING_LAYER_NORMAL;
831 else if (obt_xml_node_contains(n, "below"))
832 config_dock_layer = OB_STACKING_LAYER_BELOW;
833 else if (obt_xml_node_contains(n, "above"))
834 config_dock_layer = OB_STACKING_LAYER_ABOVE;
835 }
836 if ((n = obt_xml_find_node(node, "direction"))) {
837 if (obt_xml_node_contains(n, "horizontal"))
838 config_dock_orient = OB_ORIENTATION_HORZ;
839 else if (obt_xml_node_contains(n, "vertical"))
840 config_dock_orient = OB_ORIENTATION_VERT;
841 }
842 if ((n = obt_xml_find_node(node, "autoHide")))
843 config_dock_hide = obt_xml_node_bool(n);
844 if ((n = obt_xml_find_node(node, "hideDelay")))
845 config_dock_hide_delay = obt_xml_node_int(n);
846 if ((n = obt_xml_find_node(node, "showDelay")))
847 config_dock_show_delay = obt_xml_node_int(n);
848 if ((n = obt_xml_find_node(node, "moveButton"))) {
849 gchar *str = obt_xml_node_string(n);
850 guint b, s;
851 if (translate_button(str, &s, &b)) {
852 config_dock_app_move_button = b;
853 config_dock_app_move_modifiers = s;
854 } else {
855 g_message(_("Invalid button \"%s\" specified in config file"), str);
856 }
857 g_free(str);
858 }
859 }
860
861 static void parse_menu(xmlNodePtr node, gpointer d)
862 {
863 xmlNodePtr n;
864 node = node->children;
865
866 if ((n = obt_xml_find_node(node, "hideDelay")))
867 config_menu_hide_delay = obt_xml_node_int(n);
868 if ((n = obt_xml_find_node(node, "middle")))
869 config_menu_middle = obt_xml_node_bool(n);
870 if ((n = obt_xml_find_node(node, "submenuShowDelay")))
871 config_submenu_show_delay = obt_xml_node_int(n);
872 if ((n = obt_xml_find_node(node, "submenuHideDelay")))
873 config_submenu_hide_delay = obt_xml_node_int(n);
874 if ((n = obt_xml_find_node(node, "manageDesktops")))
875 config_menu_manage_desktops = obt_xml_node_bool(n);
876 if ((n = obt_xml_find_node(node, "showIcons"))) {
877 config_menu_show_icons = obt_xml_node_bool(n);
878 #ifndef USE_IMLIB2
879 if (config_menu_show_icons)
880 g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
881 #endif
882 }
883
884 while ((node = obt_xml_find_node(node, "file"))) {
885 gchar *c = obt_xml_node_string(node);
886 config_menu_files = g_slist_append(config_menu_files,
887 obt_paths_expand_tilde(c));
888 g_free(c);
889 node = node->next;
890 }
891 }
892
893 static void parse_resistance(xmlNodePtr node, gpointer d)
894 {
895 xmlNodePtr n;
896
897 node = node->children;
898 if ((n = obt_xml_find_node(node, "strength")))
899 config_resist_win = obt_xml_node_int(n);
900 if ((n = obt_xml_find_node(node, "screen_edge_strength")))
901 config_resist_edge = obt_xml_node_int(n);
902 }
903
904 typedef struct
905 {
906 const gchar *key;
907 const gchar *actname;
908 } ObDefKeyBind;
909
910 static void bind_default_keyboard(void)
911 {
912 ObDefKeyBind *it;
913 ObDefKeyBind binds[] = {
914 { "A-Tab", "NextWindow" },
915 { "S-A-Tab", "PreviousWindow" },
916 { "A-F4", "Close" },
917 { NULL, NULL }
918 };
919 for (it = binds; it->key; ++it) {
920 GList *l = g_list_append(NULL, g_strdup(it->key));
921 keyboard_bind(l, actions_parse_string(it->actname));
922 }
923 }
924
925 typedef struct
926 {
927 const gchar *button;
928 const gchar *context;
929 const ObMouseAction mact;
930 const gchar *actname;
931 } ObDefMouseBind;
932
933 static void bind_default_mouse(void)
934 {
935 ObDefMouseBind *it;
936 ObDefMouseBind binds[] = {
937 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
938 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
939 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
940 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
941 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
942 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
943 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
944 { "Left", "Bottom", OB_MOUSE_ACTION_PRESS, "Focus" },
945 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
946 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
947 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
948 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
949 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
950 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
951 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
952 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
953 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
954 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
955 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
956 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
957 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
958 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
959 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
960 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
961 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
962 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
963 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
964 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
965 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
966 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
967 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
968 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
969 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
970 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
971 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
972 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
973 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
974 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
975 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
976 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
977 { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
978 { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
979 { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
980 { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
981 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
982 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
983 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
984 { NULL, NULL, 0, NULL }
985 };
986
987 for (it = binds; it->button; ++it)
988 mouse_bind(it->button, frame_context_from_string(it->context),
989 it->mact, actions_parse_string(it->actname));
990 }
991
992 void config_startup(ObtXmlInst *i)
993 {
994 config_focus_new = TRUE;
995 config_focus_follow = FALSE;
996 config_focus_delay = 0;
997 config_focus_raise = FALSE;
998 config_focus_last = TRUE;
999 config_focus_under_mouse = FALSE;
1000 config_unfocus_leave = FALSE;
1001
1002 obt_xml_register(i, "focus", parse_focus, NULL);
1003
1004 config_place_policy = OB_PLACE_POLICY_SMART;
1005 config_place_center = TRUE;
1006 config_place_monitor = OB_PLACE_MONITOR_ANY;
1007
1008 config_primary_monitor_index = 1;
1009 config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
1010
1011 obt_xml_register(i, "placement", parse_placement, NULL);
1012
1013 STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1014
1015 obt_xml_register(i, "margins", parse_margins, NULL);
1016
1017 config_theme = NULL;
1018
1019 config_animate_iconify = TRUE;
1020 config_title_layout = g_strdup("NLIMC");
1021 config_theme_keepborder = TRUE;
1022 config_theme_window_list_icon_size = 36;
1023
1024 config_font_activewindow = NULL;
1025 config_font_inactivewindow = NULL;
1026 config_font_menuitem = NULL;
1027 config_font_menutitle = NULL;
1028 config_font_activeosd = NULL;
1029 config_font_inactiveosd = NULL;
1030
1031 obt_xml_register(i, "theme", parse_theme, NULL);
1032
1033 config_desktops_num = 4;
1034 config_screen_firstdesk = 1;
1035 config_desktops_names = NULL;
1036 config_desktop_popup_time = 875;
1037
1038 obt_xml_register(i, "desktops", parse_desktops, NULL);
1039
1040 config_resize_redraw = TRUE;
1041 config_resize_popup_show = 1; /* nonpixel increments */
1042 config_resize_popup_pos = OB_RESIZE_POS_CENTER;
1043 GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
1044 GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
1045
1046 obt_xml_register(i, "resize", parse_resize, NULL);
1047
1048 config_dock_layer = OB_STACKING_LAYER_ABOVE;
1049 config_dock_pos = OB_DIRECTION_NORTHEAST;
1050 config_dock_floating = FALSE;
1051 config_dock_nostrut = FALSE;
1052 config_dock_x = 0;
1053 config_dock_y = 0;
1054 config_dock_orient = OB_ORIENTATION_VERT;
1055 config_dock_hide = FALSE;
1056 config_dock_hide_delay = 300;
1057 config_dock_show_delay = 300;
1058 config_dock_app_move_button = 2; /* middle */
1059 config_dock_app_move_modifiers = 0;
1060
1061 obt_xml_register(i, "dock", parse_dock, NULL);
1062
1063 translate_key("C-g", &config_keyboard_reset_state,
1064 &config_keyboard_reset_keycode);
1065
1066 bind_default_keyboard();
1067
1068 obt_xml_register(i, "keyboard", parse_keyboard, NULL);
1069
1070 config_mouse_threshold = 8;
1071 config_mouse_dclicktime = 200;
1072 config_mouse_screenedgetime = 400;
1073 config_mouse_screenedgewarp = FALSE;
1074
1075 bind_default_mouse();
1076
1077 obt_xml_register(i, "mouse", parse_mouse, NULL);
1078
1079 config_resist_win = 10;
1080 config_resist_edge = 20;
1081
1082 obt_xml_register(i, "resistance", parse_resistance, NULL);
1083
1084 config_menu_hide_delay = 250;
1085 config_menu_middle = FALSE;
1086 config_submenu_show_delay = 100;
1087 config_submenu_hide_delay = 400;
1088 config_menu_manage_desktops = TRUE;
1089 config_menu_files = NULL;
1090 config_menu_show_icons = TRUE;
1091
1092 obt_xml_register(i, "menu", parse_menu, NULL);
1093
1094 config_per_app_settings = NULL;
1095
1096 obt_xml_register(i, "applications", parse_per_app_settings, NULL);
1097 }
1098
1099 void config_shutdown(void)
1100 {
1101 GSList *it;
1102
1103 g_free(config_theme);
1104
1105 g_free(config_title_layout);
1106
1107 RrFontClose(config_font_activewindow);
1108 RrFontClose(config_font_inactivewindow);
1109 RrFontClose(config_font_menuitem);
1110 RrFontClose(config_font_menutitle);
1111 RrFontClose(config_font_activeosd);
1112 RrFontClose(config_font_inactiveosd);
1113
1114 for (it = config_desktops_names; it; it = g_slist_next(it))
1115 g_free(it->data);
1116 g_slist_free(config_desktops_names);
1117
1118 for (it = config_menu_files; it; it = g_slist_next(it))
1119 g_free(it->data);
1120 g_slist_free(config_menu_files);
1121
1122 for (it = config_per_app_settings; it; it = g_slist_next(it)) {
1123 ObAppSettings *itd = (ObAppSettings *)it->data;
1124 if (itd->name) g_pattern_spec_free(itd->name);
1125 if (itd->role) g_pattern_spec_free(itd->role);
1126 if (itd->title) g_pattern_spec_free(itd->title);
1127 if (itd->class) g_pattern_spec_free(itd->class);
1128 g_slice_free(ObAppSettings, it->data);
1129 }
1130 g_slist_free(config_per_app_settings);
1131 }
This page took 0.07946 seconds and 5 git commands to generate.