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