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