2 * Copyright (C) 2006-2007 Imendio AB
3 * Copyright (C) 2007-2008 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Martyn Russell <martyn@imendio.com>
21 * Xavier Claessens <xclaesse@gmail.com>
31 #include "libempathy/empathy-utils.h"
32 #include "empathy-geometry.h"
34 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
35 #include <libempathy/empathy-debug.h>
37 #define GEOMETRY_DIR_CREATE_MODE (S_IRUSR | S_IWUSR | S_IXUSR)
38 #define GEOMETRY_FILE_CREATE_MODE (S_IRUSR | S_IWUSR)
40 #define GEOMETRY_KEY_FILENAME "geometry.ini"
41 #define GEOMETRY_FORMAT "%d,%d,%d,%d"
42 #define GEOMETRY_GROUP_NAME "geometry"
43 #define GEOMETRY_MAXIMIZED_GROUP_NAME "maximized"
45 static guint store_id = 0;
48 geometry_real_store (GKeyFile *key_file)
55 content = g_key_file_to_data (key_file, &length, &error);
58 DEBUG ("Error: %s", error->message);
63 filename = g_build_filename (g_get_user_config_dir (),
64 PACKAGE_NAME, GEOMETRY_KEY_FILENAME, NULL);
66 if (!g_file_set_contents (filename, content, length, &error))
68 DEBUG ("Error: %s", error->message);
77 geometry_store_cb (gpointer key_file)
79 geometry_real_store (key_file);
86 geometry_schedule_store (GKeyFile *key_file)
89 g_source_remove (store_id);
91 store_id = g_timeout_add_seconds (1, geometry_store_cb, key_file);
95 geometry_get_key_file (void)
97 static GKeyFile *key_file = NULL;
101 if (key_file != NULL)
104 dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
105 if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
107 DEBUG ("Creating directory:'%s'", dir);
108 g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
111 filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
114 key_file = g_key_file_new ();
115 g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
122 empathy_geometry_save (GtkWindow *window,
126 GdkWindow *gdk_window;
127 GdkWindowState window_state;
132 g_return_if_fail (GTK_IS_WINDOW (window));
133 g_return_if_fail (!EMP_STR_EMPTY (name));
135 /* escape the name so that unwanted characters such as # are removed */
136 escaped_name = g_uri_escape_string (name, NULL, TRUE);
138 /* Get window geometry */
139 gtk_window_get_position (window, &x, &y);
140 gtk_window_get_size (window, &w, &h);
141 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
142 window_state = gdk_window_get_state (gdk_window);
143 maximized = (window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
145 key_file = geometry_get_key_file ();
147 /* Save window size only if not maximized */
152 str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
153 g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, str);
157 g_key_file_set_boolean (key_file, GEOMETRY_MAXIMIZED_GROUP_NAME,
158 escaped_name, maximized);
160 geometry_schedule_store (key_file);
164 empathy_geometry_load (GtkWindow *window,
172 g_return_if_fail (GTK_IS_WINDOW (window));
173 g_return_if_fail (!EMP_STR_EMPTY (name));
175 /* escape the name so that unwanted characters such as # are removed */
176 escaped_name = g_uri_escape_string (name, NULL, TRUE);
178 key_file = geometry_get_key_file ();
180 /* restore window size and position */
181 str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name,
187 sscanf (str, GEOMETRY_FORMAT, &x, &y, &w, &h);
188 gtk_window_move (window, x, y);
189 gtk_window_resize (window, w, h);
192 /* restore window maximized state */
193 maximized = g_key_file_get_boolean (key_file,
194 GEOMETRY_MAXIMIZED_GROUP_NAME,
198 gtk_window_maximize (window);
200 gtk_window_unmaximize (window);
203 g_free (escaped_name);
207 geometry_configure_event_cb (GtkWindow *window,
208 GdkEventConfigure *event,
211 empathy_geometry_save (window, name);
216 geometry_window_state_event_cb (GtkWindow *window,
217 GdkEventWindowState *event,
220 if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0)
221 empathy_geometry_save (window, name);
227 empathy_geometry_bind (GtkWindow *window,
230 g_return_if_fail (GTK_IS_WINDOW (window));
231 g_return_if_fail (!EMP_STR_EMPTY (name));
233 /* First load initial geometry */
234 empathy_geometry_load (window, name);
236 /* Track geometry changes */
237 g_signal_connect_data (window, "configure-event",
238 G_CALLBACK (geometry_configure_event_cb), g_strdup (name),
239 (GClosureNotify) g_free, 0);
240 g_signal_connect_data (window, "window-state-event",
241 G_CALLBACK (geometry_window_state_event_cb), g_strdup (name),
242 (GClosureNotify) g_free, 0);
246 empathy_geometry_unbind (GtkWindow *window)
248 g_signal_handlers_disconnect_matched (window,
249 G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
250 geometry_configure_event_cb, NULL);
251 g_signal_handlers_disconnect_matched (window,
252 G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
253 geometry_window_state_event_cb, NULL);