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