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