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