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