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