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