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