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