~bcurtiswx/ubuntu/precise/empathy/3.4.2.1-0ubuntu1

« back to all changes in this revision

Viewing changes to libempathy-gtk/empathy-geometry.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2009-11-16 23:40:52 UTC
  • mfrom: (1.1.39 upstream)
  • mto: (6.3.7 experimental)
  • mto: This revision was merged to the branch mainline in revision 80.
  • Revision ID: james.westby@ubuntu.com-20091116234052-7hhwrpeln4mwdyw7
Tags: upstream-2.29.2
ImportĀ upstreamĀ versionĀ 2.29.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
1
/*
3
2
 * Copyright (C) 2006-2007 Imendio AB
4
3
 * Copyright (C) 2007-2008 Collabora Ltd.
29
28
#include <glib.h>
30
29
#include <gdk/gdk.h>
31
30
 
 
31
#include "libempathy/empathy-utils.h"
32
32
#include "empathy-geometry.h"
33
33
 
34
34
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
37
37
#define GEOMETRY_DIR_CREATE_MODE  (S_IRUSR | S_IWUSR | S_IXUSR)
38
38
#define GEOMETRY_FILE_CREATE_MODE (S_IRUSR | S_IWUSR)
39
39
 
40
 
#define GEOMETRY_KEY_FILENAME     "geometry.ini"
41
 
#define GEOMETRY_FORMAT           "%d,%d,%d,%d"
42
 
#define GEOMETRY_GROUP_NAME       "geometry"
43
 
 
44
 
static gchar *geometry_get_filename (void);
45
 
 
46
 
static gchar *
47
 
geometry_get_filename (void)
48
 
{
49
 
        gchar *dir;
50
 
        gchar *filename;
51
 
 
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);
56
 
        }
57
 
 
58
 
        filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
59
 
        g_free (dir);
60
 
 
61
 
        return filename;
62
 
}
63
 
 
64
 
void
65
 
empathy_geometry_save (const gchar *name,
66
 
                      gint         x,
67
 
                      gint         y,
68
 
                      gint         w,
69
 
                      gint         h)
70
 
{
71
 
        GError      *error = NULL;
72
 
        GKeyFile    *key_file;
73
 
        gchar       *filename;
74
 
        GdkScreen   *screen;
75
 
        gint         max_width;
76
 
        gint         max_height;
77
 
        gchar       *content;
78
 
        gsize        length;
79
 
        gchar       *str;
80
 
        gchar       *escaped_name;
81
 
 
82
 
        /* escape the name so that unwanted characters such as # are removed */
83
 
        escaped_name = g_uri_escape_string (name, NULL, TRUE);
84
 
 
85
 
        DEBUG ("Saving window geometry: name:%s x:%d, y:%d, w:%d, h:%d\n",
86
 
                escaped_name, x, y, w, h);
87
 
 
88
 
        screen = gdk_screen_get_default ();
89
 
        max_width = gdk_screen_get_width (screen);
90
 
        max_height = gdk_screen_get_height (screen);
91
 
 
92
 
        w = CLAMP (w, 100, max_width);
93
 
        h = CLAMP (h, 100, max_height);
94
 
 
95
 
        x = CLAMP (x, 0, max_width - w);
96
 
        y = CLAMP (y, 0, max_height - h);
97
 
 
98
 
        str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
99
 
 
100
 
        key_file = g_key_file_new ();
101
 
 
102
 
        filename = geometry_get_filename ();
103
 
 
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);
106
 
 
107
 
        g_free (str);
108
 
 
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);
114
 
        }
115
 
 
116
 
        g_free (content);
117
 
        g_free (filename);
118
 
        g_free (escaped_name);
119
 
        g_key_file_free (key_file);
120
 
}
121
 
 
122
 
void
123
 
empathy_geometry_load (const gchar *name,
124
 
                      gint        *x,
125
 
                      gint        *y,
126
 
                      gint        *w,
127
 
                      gint        *h)
128
 
{
129
 
        GKeyFile    *key_file;
130
 
        gchar       *filename;
131
 
        gchar       *str = NULL;
132
 
        gchar       *escaped_name;
133
 
 
134
 
        /* escape the name so that unwanted characters such as # are removed */
135
 
        escaped_name = g_uri_escape_string (name, NULL, TRUE);
136
 
 
137
 
        if (x) {
138
 
                *x = -1;
139
 
        }
140
 
 
141
 
        if (y) {
142
 
                *y = -1;
143
 
        }
144
 
 
145
 
        if (w) {
146
 
                *w = -1;
147
 
        }
148
 
 
149
 
        if (h) {
150
 
                *h = -1;
151
 
        }
152
 
 
153
 
        key_file = g_key_file_new ();
154
 
 
155
 
        filename = geometry_get_filename ();
156
 
 
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);
159
 
        }
160
 
 
161
 
        if (str) {
162
 
                gint tmp_x, tmp_y, tmp_w, tmp_h;
163
 
 
164
 
                sscanf (str, GEOMETRY_FORMAT, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
165
 
 
166
 
                if (x) {
167
 
                        *x = tmp_x;
168
 
                }
169
 
 
170
 
                if (y) {
171
 
                        *y = tmp_y;
172
 
                }
173
 
 
174
 
                if (w) {
175
 
                        *w = tmp_w;
176
 
                }
177
 
 
178
 
                if (h) {
179
 
                        *h = tmp_h;
180
 
                }
181
 
 
182
 
                g_free (str);
183
 
        }
184
 
 
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);
187
 
 
188
 
        g_free (filename);
189
 
        g_free (escaped_name);
190
 
        g_key_file_free (key_file);
191
 
}
192
 
 
 
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"
 
44
 
 
45
static guint store_id = 0;
 
46
 
 
47
static void
 
48
geometry_real_store (GKeyFile *key_file)
 
49
{
 
50
  gchar *filename;
 
51
  gchar *content;
 
52
  gsize length;
 
53
  GError *error = NULL;
 
54
 
 
55
  content = g_key_file_to_data (key_file, &length, &error);
 
56
  if (error != NULL)
 
57
    {
 
58
      DEBUG ("Error: %s", error->message);
 
59
      g_error_free (error);
 
60
      return;
 
61
    }
 
62
 
 
63
  filename = g_build_filename (g_get_user_config_dir (),
 
64
    PACKAGE_NAME, GEOMETRY_KEY_FILENAME, NULL);
 
65
 
 
66
  if (!g_file_set_contents (filename, content, length, &error))
 
67
    {
 
68
      DEBUG ("Error: %s", error->message);
 
69
      g_error_free (error);
 
70
    }
 
71
 
 
72
  g_free (content);
 
73
  g_free (filename);
 
74
}
 
75
 
 
76
static gboolean
 
77
geometry_store_cb (gpointer key_file)
 
78
{
 
79
  geometry_real_store (key_file);
 
80
  store_id = 0;
 
81
 
 
82
  return FALSE;
 
83
}
 
84
 
 
85
static void
 
86
geometry_schedule_store (GKeyFile *key_file)
 
87
{
 
88
  if (store_id != 0)
 
89
    g_source_remove (store_id);
 
90
 
 
91
  store_id = g_timeout_add_seconds (1, geometry_store_cb, key_file);
 
92
}
 
93
 
 
94
static GKeyFile *
 
95
geometry_get_key_file (void)
 
96
{
 
97
  static GKeyFile *key_file = NULL;
 
98
  gchar *dir;
 
99
  gchar *filename;
 
100
 
 
101
  if (key_file != NULL)
 
102
    return key_file;
 
103
 
 
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))
 
106
    {
 
107
      DEBUG ("Creating directory:'%s'", dir);
 
108
      g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
 
109
    }
 
110
 
 
111
  filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
 
112
  g_free (dir);
 
113
 
 
114
  key_file = g_key_file_new ();
 
115
  g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
 
116
  g_free (filename);
 
117
 
 
118
  return key_file;
 
119
}
 
120
 
 
121
void
 
122
empathy_geometry_save (GtkWindow *window,
 
123
    const gchar *name)
 
124
{
 
125
  GKeyFile *key_file;
 
126
  GdkWindow *gdk_window;
 
127
  GdkWindowState window_state;
 
128
  gchar *escaped_name;
 
129
  gint x, y, w, h;
 
130
  gboolean maximized;
 
131
 
 
132
  g_return_if_fail (GTK_IS_WINDOW (window));
 
133
  g_return_if_fail (!EMP_STR_EMPTY (name));
 
134
 
 
135
  /* escape the name so that unwanted characters such as # are removed */
 
136
  escaped_name = g_uri_escape_string (name, NULL, TRUE);
 
137
 
 
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;
 
144
 
 
145
  key_file = geometry_get_key_file ();
 
146
 
 
147
  /* Save window size only if not maximized */
 
148
  if (!maximized)
 
149
    {
 
150
      gchar *str;
 
151
 
 
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);
 
154
      g_free (str);
 
155
    }
 
156
 
 
157
  g_key_file_set_boolean (key_file, GEOMETRY_MAXIMIZED_GROUP_NAME,
 
158
        escaped_name, maximized);
 
159
 
 
160
  geometry_schedule_store (key_file);
 
161
}
 
162
 
 
163
void
 
164
empathy_geometry_load (GtkWindow *window,
 
165
    const gchar *name)
 
166
{
 
167
  GKeyFile *key_file;
 
168
  gchar    *escaped_name;
 
169
  gchar    *str;
 
170
  gboolean  maximized;
 
171
 
 
172
  g_return_if_fail (GTK_IS_WINDOW (window));
 
173
  g_return_if_fail (!EMP_STR_EMPTY (name));
 
174
 
 
175
  /* escape the name so that unwanted characters such as # are removed */
 
176
  escaped_name = g_uri_escape_string (name, NULL, TRUE);
 
177
 
 
178
  key_file = geometry_get_key_file ();
 
179
 
 
180
  /* restore window size and position */
 
181
  str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name,
 
182
      NULL);
 
183
  if (str)
 
184
    {
 
185
      gint x, y, w, h;
 
186
 
 
187
      sscanf (str, GEOMETRY_FORMAT, &x, &y, &w, &h);
 
188
      gtk_window_move (window, x, y);
 
189
      gtk_window_resize (window, w, h);
 
190
    }
 
191
 
 
192
  /* restore window maximized state */
 
193
  maximized = g_key_file_get_boolean (key_file,
 
194
      GEOMETRY_MAXIMIZED_GROUP_NAME,
 
195
      escaped_name, NULL);
 
196
 
 
197
  if (maximized)
 
198
    gtk_window_maximize (window);
 
199
  else
 
200
    gtk_window_unmaximize (window);
 
201
 
 
202
  g_free (str);
 
203
  g_free (escaped_name);
 
204
}
 
205
 
 
206
static gboolean
 
207
geometry_configure_event_cb (GtkWindow *window,
 
208
    GdkEventConfigure *event,
 
209
    gchar *name)
 
210
{
 
211
  empathy_geometry_save (window, name);
 
212
  return FALSE;
 
213
}
 
214
 
 
215
static gboolean
 
216
geometry_window_state_event_cb (GtkWindow *window,
 
217
    GdkEventWindowState *event,
 
218
    gchar *name)
 
219
{
 
220
  if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0)
 
221
    empathy_geometry_save (window, name);
 
222
 
 
223
  return FALSE;
 
224
}
 
225
 
 
226
void
 
227
empathy_geometry_bind (GtkWindow *window,
 
228
    const gchar *name)
 
229
{
 
230
  g_return_if_fail (GTK_IS_WINDOW (window));
 
231
  g_return_if_fail (!EMP_STR_EMPTY (name));
 
232
 
 
233
  /* First load initial geometry */
 
234
  empathy_geometry_load (window, name);
 
235
 
 
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);
 
243
}
 
244
 
 
245
void
 
246
empathy_geometry_unbind (GtkWindow *window)
 
247
{
 
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);
 
254
}