1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 config.c for the Openbox window manager
4 Copyright (c) 2004 Mikael Magnusson
5 Copyright (c) 2003 Ben Jansens
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "translate.h"
25 #include "per_app_settings.h"
26 #include "parser/parse.h"
29 gboolean config_focus_new;
30 gboolean config_focus_follow;
31 guint config_focus_delay;
32 gboolean config_focus_raise;
33 gboolean config_focus_last;
35 ObPlacePolicy config_place_policy;
38 gboolean config_theme_keepborder;
39 gboolean config_theme_hidedisabled;
41 gchar *config_title_layout;
43 gint config_desktops_num;
44 GSList *config_desktops_names;
45 gint config_screen_firstdesk;
47 gboolean config_resize_redraw;
48 gboolean config_resize_four_corners;
49 gint config_resize_popup_show;
50 gint config_resize_popup_pos;
52 ObStackingLayer config_dock_layer;
53 gboolean config_dock_floating;
54 gboolean config_dock_nostrut;
55 ObDirection config_dock_pos;
58 ObOrientation config_dock_orient;
59 gboolean config_dock_hide;
60 guint config_dock_hide_delay;
61 guint config_dock_show_delay;
62 guint config_dock_app_move_button;
63 guint config_dock_app_move_modifiers;
65 guint config_keyboard_reset_keycode;
66 guint config_keyboard_reset_state;
68 gint config_mouse_threshold;
69 gint config_mouse_dclicktime;
71 gboolean config_menu_warppointer;
72 gboolean config_menu_xorstyle;
73 guint config_menu_hide_delay;
74 guint config_submenu_show_delay;
75 gboolean config_menu_client_list_icons;
77 GSList *config_menu_files;
79 gint config_resist_win;
80 gint config_resist_edge;
82 gboolean config_resist_layers_below;
84 GSList *config_per_app_settings;
88 <application name="aterm">
91 <application name="Rhythmbox">
102 /* Manages settings for individual applications.
103 Some notes: head is the screen number in a multi monitor
104 (Xinerama) setup (starting from 0) or mouse, meaning the
105 head the pointer is on. Default: mouse.
106 If decor is false and shade is true, the decor will be
107 set to true (otherwise we will have an invisible window).
108 Layer can be three values, above (Always on top), below
109 (Always on bottom) and everything else (normal behaviour).
110 Positions can be an integer value or center, which will
111 center the window in the specified axis. Position is relative
112 from head, so <position><x>center</x></position><head>1</head>
113 will center the window on the second head.
115 static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
116 xmlNodePtr node, gpointer d)
118 xmlNodePtr app = parse_find_node("application", node->children);
123 if (parse_attr_string("name", app, &name)) {
125 ObAppSetting *setting = g_new0(ObAppSetting, 1);
126 setting->name = name;
128 setting->decor = TRUE;
129 if ((n = parse_find_node("decor", app->children)))
130 setting->decor = parse_bool(doc, n);
132 if ((n = parse_find_node("shade", app->children)))
133 setting->shade = parse_bool(doc, n);
135 setting->position.x = setting->position.y = -1;
136 if ((n = parse_find_node("position", app->children))) {
137 if ((c = parse_find_node("x", n->children))) {
138 if (!strcmp(parse_string(doc, c), "center")) {
139 setting->center_x = TRUE;
142 setting->position.x = parse_int(doc, c);
145 if ((c = parse_find_node("y", n->children))) {
146 if (!strcmp(parse_string(doc, c), "center")) {
147 setting->center_y = TRUE;
150 setting->position.y = parse_int(doc, c);
154 if ((n = parse_find_node("focus", app->children)))
155 setting->focus = parse_bool(doc, n);
157 if ((n = parse_find_node("desktop", app->children)))
158 setting->desktop = parse_int(doc, n);
160 setting->desktop = -1;
162 if ((n = parse_find_node("head", app->children))) {
163 if (!strcmp(parse_string(doc, n), "mouse"))
166 setting->head = parse_int(doc, n);
169 if ((n = parse_find_node("layer", app->children))) {
170 if (!strcmp(parse_string(doc, n), "above"))
172 else if (!strcmp(parse_string(doc, n), "below"))
178 config_per_app_settings = g_slist_append(config_per_app_settings,
182 app = parse_find_node("application", app->next);
189 <action name="ChangeDesktop">
196 static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
204 if ((n = parse_find_node("chainQuitKey", node))) {
205 key = parse_string(doc, n);
206 translate_key(key, &config_keyboard_reset_state,
207 &config_keyboard_reset_keycode);
211 n = parse_find_node("keybind", node);
213 if (parse_attr_string("key", n, &key)) {
214 keylist = g_list_append(keylist, key);
216 parse_key(i, doc, n->children, keylist);
218 it = g_list_last(keylist);
220 keylist = g_list_delete_link(keylist, it);
222 n = parse_find_node("keybind", n->next);
225 nact = parse_find_node("action", node);
227 if ((action = action_parse(i, doc, nact,
228 OB_USER_ACTION_KEYBOARD_KEY)))
229 keyboard_bind(keylist, action);
230 nact = parse_find_node("action", nact->next);
235 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
238 keyboard_unbind_all();
240 parse_key(i, doc, node->children, NULL);
245 <context name="Titlebar">
246 <mousebind button="Left" action="Press">
247 <action name="Raise"></action>
253 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
256 xmlNodePtr n, nbut, nact;
265 node = node->children;
267 if ((n = parse_find_node("dragThreshold", node)))
268 config_mouse_threshold = parse_int(doc, n);
269 if ((n = parse_find_node("doubleClickTime", node)))
270 config_mouse_dclicktime = parse_int(doc, n);
272 n = parse_find_node("context", node);
274 if (!parse_attr_string("name", n, &contextstr))
276 nbut = parse_find_node("mousebind", n->children);
278 if (!parse_attr_string("button", nbut, &buttonstr))
280 if (parse_attr_contains("press", nbut, "action")) {
281 uact = OB_USER_ACTION_MOUSE_PRESS;
282 mact = OB_MOUSE_ACTION_PRESS;
283 } else if (parse_attr_contains("release", nbut, "action")) {
284 uact = OB_USER_ACTION_MOUSE_RELEASE;
285 mact = OB_MOUSE_ACTION_RELEASE;
286 } else if (parse_attr_contains("click", nbut, "action")) {
287 uact = OB_USER_ACTION_MOUSE_CLICK;
288 mact = OB_MOUSE_ACTION_CLICK;
289 } else if (parse_attr_contains("doubleclick", nbut,"action")) {
290 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
291 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
292 } else if (parse_attr_contains("drag", nbut, "action")) {
293 uact = OB_USER_ACTION_MOUSE_MOTION;
294 mact = OB_MOUSE_ACTION_MOTION;
297 nact = parse_find_node("action", nbut->children);
299 if ((action = action_parse(i, doc, nact, uact)))
300 mouse_bind(buttonstr, contextstr, mact, action);
301 nact = parse_find_node("action", nact->next);
305 nbut = parse_find_node("mousebind", nbut->next);
309 n = parse_find_node("context", n->next);
313 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
318 node = node->children;
320 if ((n = parse_find_node("focusNew", node)))
321 config_focus_new = parse_bool(doc, n);
322 if ((n = parse_find_node("followMouse", node)))
323 config_focus_follow = parse_bool(doc, n);
324 if ((n = parse_find_node("focusDelay", node)))
325 config_focus_delay = parse_int(doc, n) * 1000;
326 if ((n = parse_find_node("raiseOnFocus", node)))
327 config_focus_raise = parse_bool(doc, n);
328 if ((n = parse_find_node("focusLast", node)))
329 config_focus_last = parse_bool(doc, n);
332 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
337 node = node->children;
339 if ((n = parse_find_node("policy", node)))
340 if (parse_contains("UnderMouse", doc, n))
341 config_place_policy = OB_PLACE_POLICY_MOUSE;
344 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
349 node = node->children;
351 if ((n = parse_find_node("name", node))) {
354 g_free(config_theme);
355 c = parse_string(doc, n);
356 config_theme = parse_expand_tilde(c);
359 if ((n = parse_find_node("titleLayout", node))) {
360 g_free(config_title_layout);
361 config_title_layout = parse_string(doc, n);
363 if ((n = parse_find_node("keepBorder", node)))
364 config_theme_keepborder = parse_bool(doc, n);
365 if ((n = parse_find_node("hideDisabled", node)))
366 config_theme_hidedisabled = parse_bool(doc, n);
369 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
374 node = node->children;
376 if ((n = parse_find_node("number", node))) {
377 gint d = parse_int(doc, n);
379 config_desktops_num = d;
381 if ((n = parse_find_node("firstdesk", node))) {
382 gint d = parse_int(doc, n);
384 config_screen_firstdesk = d;
386 if ((n = parse_find_node("names", node))) {
390 for (it = config_desktops_names; it; it = it->next)
392 g_slist_free(config_desktops_names);
393 config_desktops_names = NULL;
395 nname = parse_find_node("name", n->children);
397 config_desktops_names = g_slist_append(config_desktops_names,
398 parse_string(doc, nname));
399 nname = parse_find_node("name", nname->next);
404 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
409 node = node->children;
411 if ((n = parse_find_node("drawContents", node)))
412 config_resize_redraw = parse_bool(doc, n);
413 if ((n = parse_find_node("fourCorner", node)))
414 config_resize_four_corners = parse_bool(doc, n);
415 if ((n = parse_find_node("popupShow", node))) {
416 config_resize_popup_show = parse_int(doc, n);
417 if (parse_contains("Always", doc, n))
418 config_resize_popup_show = 2;
419 else if (parse_contains("Never", doc, n))
420 config_resize_popup_show = 0;
421 else if (parse_contains("Nonpixel", doc, n))
422 config_resize_popup_show = 1;
424 if ((n = parse_find_node("popupPosition", node))) {
425 config_resize_popup_pos = parse_int(doc, n);
426 if (parse_contains("Top", doc, n))
427 config_resize_popup_pos = 1;
428 else if (parse_contains("Center", doc, n))
429 config_resize_popup_pos = 0;
433 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
438 node = node->children;
440 if ((n = parse_find_node("position", node))) {
441 if (parse_contains("TopLeft", doc, n))
442 config_dock_floating = FALSE,
443 config_dock_pos = OB_DIRECTION_NORTHWEST;
444 else if (parse_contains("Top", doc, n))
445 config_dock_floating = FALSE,
446 config_dock_pos = OB_DIRECTION_NORTH;
447 else if (parse_contains("TopRight", doc, n))
448 config_dock_floating = FALSE,
449 config_dock_pos = OB_DIRECTION_NORTHEAST;
450 else if (parse_contains("Right", doc, n))
451 config_dock_floating = FALSE,
452 config_dock_pos = OB_DIRECTION_EAST;
453 else if (parse_contains("BottomRight", doc, n))
454 config_dock_floating = FALSE,
455 config_dock_pos = OB_DIRECTION_SOUTHEAST;
456 else if (parse_contains("Bottom", doc, n))
457 config_dock_floating = FALSE,
458 config_dock_pos = OB_DIRECTION_SOUTH;
459 else if (parse_contains("BottomLeft", doc, n))
460 config_dock_floating = FALSE,
461 config_dock_pos = OB_DIRECTION_SOUTHWEST;
462 else if (parse_contains("Left", doc, n))
463 config_dock_floating = FALSE,
464 config_dock_pos = OB_DIRECTION_WEST;
465 else if (parse_contains("Floating", doc, n))
466 config_dock_floating = TRUE;
468 if (config_dock_floating) {
469 if ((n = parse_find_node("floatingX", node)))
470 config_dock_x = parse_int(doc, n);
471 if ((n = parse_find_node("floatingY", node)))
472 config_dock_y = parse_int(doc, n);
474 if ((n = parse_find_node("noStrut", node)))
475 config_dock_nostrut = parse_bool(doc, n);
477 if ((n = parse_find_node("stacking", node))) {
478 if (parse_contains("top", doc, n))
479 config_dock_layer = OB_STACKING_LAYER_ABOVE;
480 else if (parse_contains("normal", doc, n))
481 config_dock_layer = OB_STACKING_LAYER_NORMAL;
482 else if (parse_contains("bottom", doc, n))
483 config_dock_layer = OB_STACKING_LAYER_BELOW;
485 if ((n = parse_find_node("direction", node))) {
486 if (parse_contains("horizontal", doc, n))
487 config_dock_orient = OB_ORIENTATION_HORZ;
488 else if (parse_contains("vertical", doc, n))
489 config_dock_orient = OB_ORIENTATION_VERT;
491 if ((n = parse_find_node("autoHide", node)))
492 config_dock_hide = parse_bool(doc, n);
493 if ((n = parse_find_node("hideDelay", node)))
494 config_dock_hide_delay = parse_int(doc, n) * 1000;
495 if ((n = parse_find_node("showDelay", node)))
496 config_dock_show_delay = parse_int(doc, n) * 1000;
497 if ((n = parse_find_node("moveButton", node))) {
498 gchar *str = parse_string(doc, n);
500 if (translate_button(str, &s, &b)) {
501 config_dock_app_move_button = b;
502 config_dock_app_move_modifiers = s;
504 g_warning("invalid button '%s'", str);
510 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
514 for (node = node->children; node; node = node->next) {
515 if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
518 c = parse_string(doc, node);
519 config_menu_files = g_slist_append(config_menu_files,
520 parse_expand_tilde(c));
523 if ((n = parse_find_node("warpPointer", node)))
524 config_menu_warppointer = parse_bool(doc, n);
525 if ((n = parse_find_node("xorStyle", node)))
526 config_menu_xorstyle = parse_bool(doc, n);
527 if ((n = parse_find_node("hideDelay", node)))
528 config_menu_hide_delay = parse_int(doc, n);
529 if ((n = parse_find_node("submenuShowDelay", node)))
530 config_submenu_show_delay = parse_int(doc, n);
531 if ((n = parse_find_node("desktopMenuIcons", node)))
532 config_menu_client_list_icons = parse_bool(doc, n);
536 static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
541 node = node->children;
542 if ((n = parse_find_node("strength", node)))
543 config_resist_win = parse_int(doc, n);
544 if ((n = parse_find_node("screen_edge_strength", node)))
545 config_resist_edge = parse_int(doc, n);
546 if ((n = parse_find_node("edges_hit_layers_below", node)))
547 config_resist_layers_below = parse_bool(doc, n);
553 const gchar *actname;
556 static void bind_default_keyboard()
559 ObDefKeyBind binds[] = {
560 { "A-Tab", "NextWindow" },
561 { "S-A-Tab", "PreviousWindow" },
566 for (it = binds; it->key; ++it) {
567 GList *l = g_list_append(NULL, g_strdup(it->key));
568 keyboard_bind(l, action_from_string(it->actname,
569 OB_USER_ACTION_KEYBOARD_KEY));
576 const gchar *context;
577 const ObMouseAction mact;
578 const gchar *actname;
581 static void bind_default_mouse()
584 ObDefMouseBind binds[] = {
585 { "Left", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
586 { "Middle", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
587 { "Right", "Client", OB_MOUSE_ACTION_PRESS, "Focus" },
588 { "Left", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
589 { "Middle", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
590 { "Right", "Desktop", OB_MOUSE_ACTION_PRESS, "Focus" },
591 { "Left", "Titlebar", OB_MOUSE_ACTION_PRESS, "Focus" },
592 { "Left", "Handle", OB_MOUSE_ACTION_PRESS, "Focus" },
593 { "Left", "BLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
594 { "Left", "BRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
595 { "Left", "TLCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
596 { "Left", "TRCorner", OB_MOUSE_ACTION_PRESS, "Focus" },
597 { "Left", "Close", OB_MOUSE_ACTION_PRESS, "Focus" },
598 { "Left", "Maximize", OB_MOUSE_ACTION_PRESS, "Focus" },
599 { "Left", "Iconify", OB_MOUSE_ACTION_PRESS, "Focus" },
600 { "Left", "Icon", OB_MOUSE_ACTION_PRESS, "Focus" },
601 { "Left", "AllDesktops", OB_MOUSE_ACTION_PRESS, "Focus" },
602 { "Left", "Shade", OB_MOUSE_ACTION_PRESS, "Focus" },
603 { "Left", "Client", OB_MOUSE_ACTION_CLICK, "Raise" },
604 { "Left", "Titlebar", OB_MOUSE_ACTION_CLICK, "Raise" },
605 { "Middle", "Titlebar", OB_MOUSE_ACTION_CLICK, "Lower" },
606 { "Left", "Handle", OB_MOUSE_ACTION_CLICK, "Raise" },
607 { "Left", "BLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
608 { "Left", "BRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
609 { "Left", "TLCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
610 { "Left", "TRCorner", OB_MOUSE_ACTION_CLICK, "Raise" },
611 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Raise" },
612 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "Raise" },
613 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Raise" },
614 { "Left", "Icon", OB_MOUSE_ACTION_CLICK, "Raise" },
615 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
616 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
617 { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
618 { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
619 { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
620 { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
621 { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
622 { "Left", "TLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
623 { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
624 { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
625 { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
626 { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
627 { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
628 { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
629 { NULL, NULL, 0, NULL }
632 for (it = binds; it->button; ++it) {
635 case OB_MOUSE_ACTION_PRESS:
636 uact = OB_USER_ACTION_MOUSE_PRESS; break;
637 case OB_MOUSE_ACTION_RELEASE:
638 uact = OB_USER_ACTION_MOUSE_RELEASE; break;
639 case OB_MOUSE_ACTION_CLICK:
640 uact = OB_USER_ACTION_MOUSE_CLICK; break;
641 case OB_MOUSE_ACTION_DOUBLE_CLICK:
642 uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK; break;
643 case OB_MOUSE_ACTION_MOTION:
644 uact = OB_USER_ACTION_MOUSE_MOTION; break;
645 case OB_NUM_MOUSE_ACTIONS:
646 g_assert_not_reached();
648 mouse_bind(it->button, it->context, it->mact,
649 action_from_string(it->actname, uact));
653 void config_startup(ObParseInst *i)
655 config_focus_new = TRUE;
656 config_focus_follow = FALSE;
657 config_focus_delay = 0;
658 config_focus_raise = FALSE;
659 config_focus_last = FALSE;
661 parse_register(i, "focus", parse_focus, NULL);
663 config_place_policy = OB_PLACE_POLICY_SMART;
665 parse_register(i, "placement", parse_placement, NULL);
669 config_title_layout = g_strdup("NLIMC");
670 config_theme_keepborder = TRUE;
671 config_theme_hidedisabled = FALSE;
673 parse_register(i, "theme", parse_theme, NULL);
675 config_desktops_num = 4;
676 config_screen_firstdesk = 1;
677 config_desktops_names = NULL;
679 parse_register(i, "desktops", parse_desktops, NULL);
681 config_resize_redraw = TRUE;
682 config_resize_four_corners = FALSE;
683 config_resize_popup_show = 1; /* nonpixel increments */
684 config_resize_popup_pos = 0; /* center of client */
686 parse_register(i, "resize", parse_resize, NULL);
688 config_dock_layer = OB_STACKING_LAYER_ABOVE;
689 config_dock_pos = OB_DIRECTION_NORTHEAST;
690 config_dock_floating = FALSE;
691 config_dock_nostrut = FALSE;
694 config_dock_orient = OB_ORIENTATION_VERT;
695 config_dock_hide = FALSE;
696 config_dock_hide_delay = 300;
697 config_dock_show_delay = 300;
698 config_dock_app_move_button = 2; /* middle */
699 config_dock_app_move_modifiers = 0;
701 parse_register(i, "dock", parse_dock, NULL);
703 translate_key("C-g", &config_keyboard_reset_state,
704 &config_keyboard_reset_keycode);
706 bind_default_keyboard();
708 parse_register(i, "keyboard", parse_keyboard, NULL);
710 config_mouse_threshold = 3;
711 config_mouse_dclicktime = 200;
713 bind_default_mouse();
715 parse_register(i, "mouse", parse_mouse, NULL);
717 config_resist_win = 10;
718 config_resist_edge = 20;
719 config_resist_layers_below = FALSE;
721 parse_register(i, "resistance", parse_resistance, NULL);
723 config_menu_warppointer = TRUE;
724 config_menu_xorstyle = TRUE;
725 config_menu_hide_delay = 250;
726 config_submenu_show_delay = 0;
727 config_menu_client_list_icons = TRUE;
728 config_menu_files = NULL;
730 parse_register(i, "menu", parse_menu, NULL);
732 config_per_app_settings = NULL;
734 parse_register(i, "applications", parse_per_app_settings, NULL);
737 void config_shutdown()
741 g_free(config_theme);
743 g_free(config_title_layout);
745 for (it = config_desktops_names; it; it = g_slist_next(it))
747 g_slist_free(config_desktops_names);
749 for (it = config_menu_files; it; it = g_slist_next(it))
751 g_slist_free(config_menu_files);
753 for (it = config_per_app_settings; it; it = g_slist_next(it))
755 g_slist_free(config_per_app_settings);