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