move mouse focus options to mouse tab
[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 static void enable_stuff();
36
37 void mouse_setup_tab()
38 {
39     GtkWidget *w, *w1, *w2;
40     GtkSizeGroup *group;
41     gint a;
42
43     mapping = TRUE;
44
45     w1    = get_widget("doubleclick_time");
46     w2    = get_widget("drag_threshold");
47     group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
48     gtk_size_group_add_widget(group, w1);
49     gtk_size_group_add_widget(group, w2);
50
51     w1    = get_widget("doubleclick_time_label");
52     w2    = get_widget("drag_threshold_label");
53     group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
54     gtk_size_group_add_widget(group, w1);
55     gtk_size_group_add_widget(group, w2);
56
57     w = get_widget("focus_mouse");
58     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
59                                  tree_get_bool("focus/followMouse", FALSE));
60
61     w = get_widget("focus_delay");
62     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
63                               tree_get_int("focus/focusDelay", 0));
64
65     w = get_widget("focus_raise");
66     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
67                                  tree_get_bool("focus/raiseOnFocus", FALSE));
68
69     w = get_widget("focus_last");
70     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
71                                  tree_get_bool("focus/focusLast", FALSE));
72
73     w = get_widget("doubleclick_time");
74     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
75                               tree_get_int("mouse/doubleClickTime", 200));
76
77     w = get_widget("drag_threshold");
78     gtk_spin_button_set_value(GTK_SPIN_BUTTON(w),
79                               tree_get_int("mouse/dragThreshold", 8));
80
81     w = get_widget("titlebar_doubleclick");
82     a = read_doubleclick_action();
83     if (a == TITLEBAR_CUSTOM) {
84         GtkWidget *i = gtk_menu_item_new_with_label(_("Custom actions"));
85         g_signal_connect(i, "activate",
86                          G_CALLBACK (on_titlebar_doubleclick_custom_activate),
87                          NULL);
88         gtk_menu_shell_append
89             (GTK_MENU_SHELL
90              (gtk_option_menu_get_menu
91               (GTK_OPTION_MENU(w))), i);
92     }
93     gtk_option_menu_set_history(GTK_OPTION_MENU(w), a);
94
95     enable_stuff();
96
97     mapping = FALSE;
98 }
99
100 static void enable_stuff()
101 {
102     GtkWidget *w;
103     gboolean b;
104
105     w = get_widget("focus_mouse");
106     b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
107
108     w = get_widget("focus_delay");
109     gtk_widget_set_sensitive(w, b);
110     w = get_widget("focus_delay_label");
111     gtk_widget_set_sensitive(w, b);
112     w = get_widget("focus_delay_label_units");
113     gtk_widget_set_sensitive(w, b);
114     w = get_widget("focus_raise");
115     gtk_widget_set_sensitive(w, b);
116     w = get_widget("focus_last");
117     gtk_widget_set_sensitive(w, b);
118 }
119
120 void on_focus_mouse_toggled(GtkToggleButton *w, gpointer data)
121 {
122     gboolean b;
123
124     if (mapping) return;
125
126     b = gtk_toggle_button_get_active(w);
127     tree_set_bool("focus/followMouse", b);
128
129     enable_stuff();
130 }
131
132 void on_focus_delay_value_changed(GtkSpinButton *w, gpointer data)
133 {
134     if (mapping) return;
135
136     tree_set_int("focus/focusDelay", gtk_spin_button_get_value_as_int(w));
137 }
138
139 void on_focus_raise_toggled(GtkToggleButton *w, gpointer data)
140 {
141     if (mapping) return;
142
143     tree_set_bool("focus/raiseOnFocus", gtk_toggle_button_get_active(w));
144 }
145
146 void on_focus_last_toggled(GtkToggleButton *w, gpointer data)
147 {
148     if (mapping) return;
149
150     tree_set_bool("focus/focusLast", gtk_toggle_button_get_active(w));
151 }
152
153 void on_titlebar_doubleclick_maximize_activate(GtkMenuItem *w, gpointer data)
154 {
155     if (mapping) return;
156
157     write_doubleclick_action(TITLEBAR_MAXIMIZE);
158 }
159
160 void on_titlebar_doubleclick_shade_activate(GtkMenuItem *w, gpointer data)
161 {
162     if (mapping) return;
163
164     write_doubleclick_action(TITLEBAR_SHADE);
165 }
166
167 static void on_titlebar_doubleclick_custom_activate(GtkMenuItem *w,
168                                                     gpointer data)
169 {
170     if (mapping) return;
171
172     write_doubleclick_action(TITLEBAR_CUSTOM);
173 }
174
175 void on_doubleclick_time_value_changed(GtkSpinButton *w, gpointer data)
176 {
177     if (mapping) return;
178
179     tree_set_int("mouse/doubleClickTime",
180                  gtk_spin_button_get_value_as_int(w));
181 }
182
183 void on_drag_threshold_value_changed(GtkSpinButton *w, gpointer data)
184 {
185     if (mapping) return;
186
187     tree_set_int("mouse/dragThreshold",
188                  gtk_spin_button_get_value_as_int(w));
189 }
190
191 static gint read_doubleclick_action()
192 {
193     xmlNodePtr n, top, c;
194     gint max = 0, shade = 0, other = 0;
195
196     top = tree_get_node("mouse/context:name=Titlebar"
197                         "/mousebind:button=Left:action=DoubleClick", NULL);
198     n = top->children;
199
200     /* save the current state */
201     saved_custom = xmlCopyNode(top, 1);
202
203     /* remove the namespace from all the nodes under saved_custom..
204        without recursion! */
205     c = saved_custom;
206     while (c) {
207         xmlSetNs(c, NULL);
208         if (c->children)
209             c = c->children;
210         else if (c->next)
211             c = c->next;
212         while (c->parent && !c->parent->next)
213             c = c->parent;
214         if (!c->parent)
215             c = NULL;
216     }
217
218     while (n) {
219         if (!xmlStrcmp(n->name, (const xmlChar*)"action")) {
220             if (parse_attr_contains("ToggleMaximizeFull", n, "name"))
221                 ++max;
222             else if (parse_attr_contains("ToggleShade", n, "name"))
223                 ++shade;
224             else
225                 ++other;
226             
227         }
228         n = n->next;
229     }
230
231     if (max == 1 && shade == 0 && other == 0)
232         return TITLEBAR_MAXIMIZE;
233     if (max == 0 && shade == 1 && other == 0)
234         return TITLEBAR_SHADE;
235
236     return TITLEBAR_CUSTOM;
237 }
238
239 static void write_doubleclick_action(gint a)
240 {
241     xmlNodePtr n;
242
243     n = tree_get_node("mouse/context:name=Titlebar"
244                       "/mousebind:button=Left:action=DoubleClick", NULL);
245
246     /* remove all children */
247     while (n->children) {
248         xmlUnlinkNode(n->children);
249         xmlFreeNode(n->children);
250     }
251
252     if (a == TITLEBAR_MAXIMIZE) {
253         n = xmlNewChild(n, NULL, "action", NULL);
254         xmlSetProp(n, "name", "ToggleMaximizeFull");
255     } else if (a == TITLEBAR_SHADE) {
256         n = xmlNewChild(n, NULL, "action", NULL);
257         xmlSetProp(n, "name", "ToggleShade");
258     } else {
259         xmlNodePtr c = saved_custom->children;
260         while (c) {
261             xmlAddChild(n, xmlCopyNode(c, 1));
262             c = c->next;
263         }
264     }
265
266     tree_apply();
267 }