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