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