rename behavior tab to windows.
[dana/obconf.git] / src / mouse.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    mouse.c for ObConf, the configuration tool for Openbox
4    Copyright (c) 2007        Dana Jansens
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "main.h"
20 #include "tree.h"
21 #include "gettext.h"
22 #include <openbox/parse.h>
23
24 static gboolean   mapping = FALSE;
25 static xmlNodePtr saved_custom = NULL;
26
27 #define TITLEBAR_MAXIMIZE 0
28 #define TITLEBAR_SHADE    1
29 #define TITLEBAR_CUSTOM   2
30
31 static gint read_doubleclick_action();
32 static void write_doubleclick_action(gint a);
33 static void on_titlebar_doubleclick_custom_activate(GtkMenuItem *w,
34                                                     gpointer data);
35
36 void mouse_setup_tab()
37 {
38     GtkWidget *w, *w1, *w2;
39     GtkSizeGroup *group;
40     gint a;
41
42     mapping = TRUE;
43
44     w1    = get_widget("doubleclick_time");
45     w2    = get_widget("drag_threshold");
46     group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
47     gtk_size_group_add_widget(group, w1);
48     gtk_size_group_add_widget(group, w2);
49
50     w1    = get_widget("doubleclick_time_label");
51     w2    = get_widget("drag_threshold_label");
52     group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
53     gtk_size_group_add_widget(group, w1);
54     gtk_size_group_add_widget(group, w2);
55
56     w = get_widget("doubleclick_time");
57     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
58                               tree_get_int("mouse/doubleClickTime", 200));
59
60     w = get_widget("drag_threshold");
61     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
62                               tree_get_int("mouse/dragThreshold", 3));
63
64     w = get_widget("titlebar_doubleclick");
65     a = read_doubleclick_action();
66     if (a == TITLEBAR_CUSTOM) {
67         GtkWidget *i = gtk_menu_item_new_with_label(_("Custom actions"));
68         g_signal_connect(i, "activate",
69                          G_CALLBACK (on_titlebar_doubleclick_custom_activate),
70                          NULL);
71         gtk_menu_shell_append
72             (GTK_MENU_SHELL
73              (gtk_option_menu_get_menu
74               (GTK_OPTION_MENU(w))), i);
75     }
76     gtk_option_menu_set_history(GTK_OPTION_MENU(w), a);
77
78     mapping = FALSE;
79 }
80
81 void on_titlebar_doubleclick_maximize_activate(GtkMenuItem *w, gpointer data)
82 {
83     if (mapping) return;
84
85     write_doubleclick_action(TITLEBAR_MAXIMIZE);
86 }
87
88 void on_titlebar_doubleclick_shade_activate(GtkMenuItem *w, gpointer data)
89 {
90     if (mapping) return;
91
92     write_doubleclick_action(TITLEBAR_SHADE);
93 }
94
95 static void on_titlebar_doubleclick_custom_activate(GtkMenuItem *w,
96                                                     gpointer data)
97 {
98     if (mapping) return;
99
100     write_doubleclick_action(TITLEBAR_CUSTOM);
101 }
102
103 void on_doubleclick_time_value_changed(GtkSpinButton *w, gpointer data)
104 {
105     if (mapping) return;
106
107     tree_set_int("mouse/doubleClickTime",
108                  gtk_spin_button_get_value_as_int(w));
109 }
110
111 void on_drag_threshold_value_changed(GtkSpinButton *w, gpointer data)
112 {
113     if (mapping) return;
114
115     tree_set_int("mouse/dragThreshold",
116                  gtk_spin_button_get_value_as_int(w));
117 }
118
119 static gint read_doubleclick_action()
120 {
121     xmlNodePtr n, top, c;
122     gint max = 0, shade = 0, other = 0;
123
124     top = tree_get_node("mouse/context:name=Titlebar"
125                         "/mousebind:button=Left:action=DoubleClick", NULL);
126     n = top->children;
127
128     /* save the current state */
129     saved_custom = xmlCopyNode(top, 1);
130
131     /* remove the namespace from all the nodes under saved_custom..
132        without recursion! */
133     c = saved_custom;
134     while (c) {
135         xmlSetNs(c, NULL);
136         if (c->children)
137             c = c->children;
138         else if (c->next)
139             c = c->next;
140         while (c->parent && !c->parent->next)
141             c = c->parent;
142         if (!c->parent)
143             c = NULL;
144     }
145
146     while (n) {
147         if (!xmlStrcmp(n->name, (const xmlChar*)"action")) {
148             if (parse_attr_contains("ToggleMaximizeFull", n, "name"))
149                 ++max;
150             else if (parse_attr_contains("ToggleShade", n, "name"))
151                 ++shade;
152             else
153                 ++other;
154             
155         }
156         n = n->next;
157     }
158
159     if (max == 1 && shade == 0 && other == 0)
160         return TITLEBAR_MAXIMIZE;
161     if (max == 0 && shade == 1 && other == 0)
162         return TITLEBAR_SHADE;
163
164     return TITLEBAR_CUSTOM;
165 }
166
167 static void write_doubleclick_action(gint a)
168 {
169     xmlNodePtr n;
170
171     n = tree_get_node("mouse/context:name=Titlebar"
172                       "/mousebind:button=Left:action=DoubleClick", NULL);
173
174     /* remove all children */
175     while (n->children) {
176         xmlUnlinkNode(n->children);
177         xmlFreeNode(n->children);
178     }
179
180     if (a == TITLEBAR_MAXIMIZE) {
181         n = xmlNewChild(n, NULL, "action", NULL);
182         xmlSetProp(n, "name", "ToggleMaximizeFull");
183     } else if (a == TITLEBAR_SHADE) {
184         n = xmlNewChild(n, NULL, "action", NULL);
185         xmlSetProp(n, "name", "ToggleShade");
186     } else {
187         xmlNodePtr c = saved_custom->children;
188         while (c) {
189             xmlAddChild(n, xmlCopyNode(c, 1));
190             c = c->next;
191         }
192     }
193
194     tree_apply();
195 }