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