diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2010-09-22 15:20:31 +0200 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2010-09-29 12:52:10 +0200 |
commit | 1a69c8b6c2aa0ce113cd132eb7ead8058e9ddacb (patch) | |
tree | 749cef2ba60c7a9016b113353679d7e2e214ec4e | |
parent | a59a1e8874cdf7c0e1bc323543820f9a36167933 (diff) |
geometry: add suport for binding a window more than once
-rw-r--r-- | libempathy-gtk/empathy-geometry.c | 105 | ||||
-rw-r--r-- | libempathy-gtk/empathy-geometry.h | 3 |
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 |