]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-geometry.c
local-xmpp-assistant-widget: increase row-spacing
[empathy.git] / libempathy-gtk / empathy-geometry.c
index 79730d650c3af4e9de5cd7a9afbbcbb2107f6f4a..986015452967ee5715aa1218de05f30144dc259f 100644 (file)
@@ -127,31 +127,23 @@ geometry_get_key_file (void)
 }
 
 void
-empathy_geometry_save (GtkWindow *window,
-    const gchar *name)
+empathy_geometry_save_values (GtkWindow *window,
+    gint x,
+    gint y,
+    gint w,
+    gint h,
+    gboolean maximized)
 {
   GKeyFile *key_file;
-  GdkWindow *gdk_window;
-  GdkWindowState window_state;
-  gchar *escaped_name;
-  gint x, y, w, h;
-  gboolean maximized;
-
-  g_return_if_fail (GTK_IS_WINDOW (window));
-  g_return_if_fail (!EMP_STR_EMPTY (name));
-
-  if (!gtk_widget_get_visible (GTK_WIDGET (window)))
-    return;
+  gchar *position_str = NULL;
+  GHashTable *names;
+  GHashTableIter iter;
+  const gchar *name;
 
-  /* escape the name so that unwanted characters such as # are removed */
-  escaped_name = g_uri_escape_string (name, NULL, TRUE);
+  names = g_object_get_data (G_OBJECT (window), GEOMETRY_NAME_KEY);
 
-  /* Get window geometry */
-  gtk_window_get_position (window, &x, &y);
-  gtk_window_get_size (window, &w, &h);
-  gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
-  window_state = gdk_window_get_state (gdk_window);
-  maximized = (window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (names != NULL);
 
   /* Don't save off-screen positioning */
   if (!EMPATHY_RECT_IS_ON_SCREEN (x, y, w, h))
@@ -162,21 +154,57 @@ 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 (position_str);
 }
 
-void
+static void
+empathy_geometry_save (GtkWindow *window)
+{
+  GdkWindow *gdk_window;
+  GdkWindowState window_state;
+  gboolean maximized;
+  gint x, y, w, h;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (!gtk_widget_get_visible (GTK_WIDGET (window)))
+    return;
+
+  /* Get window geometry */
+  gtk_window_get_position (window, &x, &y);
+  gtk_window_get_size (window, &w, &h);
+
+  gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+  window_state = gdk_window_get_state (gdk_window);
+  maximized = (window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
+
+  empathy_geometry_save_values (window, x, y, w, h, maximized);
+}
+
+static void
 empathy_geometry_load (GtkWindow *window,
     const gchar *name)
 {
@@ -223,10 +251,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;
 }
@@ -238,10 +263,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;
@@ -251,10 +273,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);
 }
 
@@ -262,23 +293,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);
@@ -289,8 +334,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,