37
37
#define GEOMETRY_DIR_CREATE_MODE (S_IRUSR | S_IWUSR | S_IXUSR)
38
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"
44
static gchar *geometry_get_filename (void);
47
geometry_get_filename (void)
52
dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
53
if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
54
DEBUG ("Creating directory:'%s'", dir);
55
g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
58
filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
65
empathy_geometry_save (const gchar *name,
82
/* escape the name so that unwanted characters such as # are removed */
83
escaped_name = g_uri_escape_string (name, NULL, TRUE);
85
DEBUG ("Saving window geometry: name:%s x:%d, y:%d, w:%d, h:%d\n",
86
escaped_name, x, y, w, h);
88
screen = gdk_screen_get_default ();
89
max_width = gdk_screen_get_width (screen);
90
max_height = gdk_screen_get_height (screen);
92
w = CLAMP (w, 100, max_width);
93
h = CLAMP (h, 100, max_height);
95
x = CLAMP (x, 0, max_width - w);
96
y = CLAMP (y, 0, max_height - h);
98
str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
100
key_file = g_key_file_new ();
102
filename = geometry_get_filename ();
104
g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
105
g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, str);
109
content = g_key_file_to_data (key_file, &length, NULL);
110
if (!g_file_set_contents (filename, content, length, &error)) {
111
g_warning ("Couldn't save window geometry, error:%d->'%s'",
112
error->code, error->message);
113
g_error_free (error);
118
g_free (escaped_name);
119
g_key_file_free (key_file);
123
empathy_geometry_load (const gchar *name,
134
/* escape the name so that unwanted characters such as # are removed */
135
escaped_name = g_uri_escape_string (name, NULL, TRUE);
153
key_file = g_key_file_new ();
155
filename = geometry_get_filename ();
157
if (g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) {
158
str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, NULL);
162
gint tmp_x, tmp_y, tmp_w, tmp_h;
164
sscanf (str, GEOMETRY_FORMAT, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
185
DEBUG ("Loading window geometry: x:%d, y:%d, w:%d, h:%d\n",
186
x ? *x : -1, y ? *y : -1, w ? *w : -1, h ? *h : -1);
189
g_free (escaped_name);
190
g_key_file_free (key_file);
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);