summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-09-22 15:20:31 +0200
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-09-29 12:52:10 +0200
commit1a69c8b6c2aa0ce113cd132eb7ead8058e9ddacb (patch)
tree749cef2ba60c7a9016b113353679d7e2e214ec4e
parenta59a1e8874cdf7c0e1bc323543820f9a36167933 (diff)
geometry: add suport for binding a window more than once
-rw-r--r--libempathy-gtk/empathy-geometry.c105
-rw-r--r--libempathy-gtk/empathy-geometry.h3
2 files changed, 75 insertions, 33 deletions
diff --git a/libempathy-gtk/empathy-geometry.c b/libempathy-gtk/empathy-geometry.c
index fe24b61b..b549b8ba 100644
--- a/libempathy-gtk/empathy-geometry.c
+++ b/libempathy-gtk/empathy-geometry.c
@@ -127,25 +127,26 @@ geometry_get_key_file (void)
}
static void
-empathy_geometry_save (GtkWindow *window,
- const gchar *name)
+empathy_geometry_save (GtkWindow *window)
{
GKeyFile *key_file;
GdkWindow *gdk_window;
GdkWindowState window_state;
- gchar *escaped_name;
gint x, y, w, h;
gboolean maximized;
+ gchar *position_str = NULL;
+ GHashTable *names;
+ GHashTableIter iter;
+ const gchar *name;
+
+ names = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
g_return_if_fail (GTK_IS_WINDOW (window));
- g_return_if_fail (!EMP_STR_EMPTY (name));
+ g_return_if_fail (names != NULL);
if (!gtk_widget_get_visible (GTK_WIDGET (window)))
return;
- /* escape the name so that unwanted characters such as # are removed */
- escaped_name = g_uri_escape_string (name, NULL, TRUE);
-
/* Get window geometry */
gtk_window_get_position (window, &x, &y);
gtk_window_get_size (window, &w, &h);
@@ -162,19 +163,30 @@ empathy_geometry_save (GtkWindow *window,
/* Save window size only if not maximized */
if (!maximized)
{
- gchar *str;
+ position_str = g_strdup_printf (GEOMETRY_POSITION_FORMAT, x, y, w, h);
+ }
+
+ g_hash_table_iter_init (&iter, names);
+ while (g_hash_table_iter_next (&iter, (gpointer) &name, NULL))
+ {
+ gchar *escaped_name;
- str = g_strdup_printf (GEOMETRY_POSITION_FORMAT, x, y, w, h);
- g_key_file_set_string (key_file, GEOMETRY_POSITION_GROUP,
- escaped_name, str);
- g_free (str);
+ /* escape the name so that unwanted characters such as # are removed */
+ escaped_name = g_uri_escape_string (name, NULL, TRUE);
+
+ g_key_file_set_boolean (key_file, GEOMETRY_MAXIMIZED_GROUP,
+ escaped_name, maximized);
+
+ if (position_str != NULL)
+ g_key_file_set_string (key_file, GEOMETRY_POSITION_GROUP,
+ escaped_name, position_str);
+
+ g_free (escaped_name);
}
- g_key_file_set_boolean (key_file, GEOMETRY_MAXIMIZED_GROUP,
- escaped_name, maximized);
geometry_schedule_store (key_file);
- g_free (escaped_name);
+ g_free (position_str);
}
static void
@@ -224,10 +236,7 @@ geometry_configure_event_cb (GtkWindow *window,
GdkEventConfigure *event,
gpointer user_data)
{
- gchar *name;
-
- name = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
- empathy_geometry_save (window, name);
+ empathy_geometry_save (window);
return FALSE;
}
@@ -239,10 +248,7 @@ geometry_window_state_event_cb (GtkWindow *window,
{
if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0)
{
- gchar *name;
-
- name = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
- empathy_geometry_save (window, name);
+ empathy_geometry_save (window);
}
return FALSE;
@@ -252,10 +258,19 @@ static void
geometry_map_cb (GtkWindow *window,
gpointer user_data)
{
- gchar *name;
+ GHashTable *names;
+ GHashTableIter iter;
+ const gchar *name;
/* The WM will replace this window, restore its last position */
- name = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
+ names = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
+
+ g_assert (names != NULL);
+
+ /* Use the first name we get in the hash table */
+ g_hash_table_iter_init (&iter, names);
+ g_assert (g_hash_table_iter_next (&iter, (gpointer) &name, NULL));
+
empathy_geometry_load (window, name);
}
@@ -263,23 +278,37 @@ void
empathy_geometry_bind (GtkWindow *window,
const gchar *name)
{
- gchar *str;
+ GHashTable *names;
+ gboolean connect_sigs = FALSE;
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (!EMP_STR_EMPTY (name));
/* Check if this window is already bound */
- str = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
- if (str != NULL)
- return;
+ names = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
+ if (names == NULL)
+ {
+ connect_sigs = TRUE;
+ names = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ g_object_set_data_full (G_OBJECT (window), GEOMETRY_NAME_KEY, names,
+ (GDestroyNotify) g_hash_table_unref);
+ }
+ else if (g_hash_table_lookup (names, name) != NULL)
+ {
+ return;
+ }
/* Store the geometry name in the window's data */
- str = g_strdup (name);
- g_object_set_data_full (G_OBJECT (window), GEOMETRY_NAME_KEY, str, g_free);
+ g_hash_table_insert (names, g_strdup (name), GUINT_TO_POINTER (TRUE));
/* Load initial geometry */
empathy_geometry_load (window, name);
+ if (!connect_sigs)
+ return;
+
/* Track geometry changes */
g_signal_connect (window, "configure-event",
G_CALLBACK (geometry_configure_event_cb), NULL);
@@ -290,8 +319,20 @@ empathy_geometry_bind (GtkWindow *window,
}
void
-empathy_geometry_unbind (GtkWindow *window)
+empathy_geometry_unbind (GtkWindow *window,
+ const gchar *name)
{
+ GHashTable *names;
+
+ names = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
+ if (names == NULL)
+ return;
+
+ g_hash_table_remove (names, name);
+
+ if (g_hash_table_size (names) > 0)
+ return;
+
g_signal_handlers_disconnect_by_func (window,
geometry_configure_event_cb, NULL);
g_signal_handlers_disconnect_by_func (window,
diff --git a/libempathy-gtk/empathy-geometry.h b/libempathy-gtk/empathy-geometry.h
index 17c067de..80ea92eb 100644
--- a/libempathy-gtk/empathy-geometry.h
+++ b/libempathy-gtk/empathy-geometry.h
@@ -32,7 +32,8 @@ G_BEGIN_DECLS
void empathy_geometry_bind (GtkWindow *window,
const gchar *name);
-void empathy_geometry_unbind (GtkWindow *window);
+void empathy_geometry_unbind (GtkWindow *window,
+ const gchar *name);
G_END_DECLS