[Xfce4-commits] <xfce4-panel:master> Panel: Don't remove windows using the destroy signal.

Nick Schermer noreply at xfce.org
Fri Dec 30 20:10:02 CET 2011


Updating branch refs/heads/master
         to bbf484ea71dfd1b97a8716739c698ed2bb9348ac (commit)
       from c9fed3f4a8f15324b0d08cbb5a13dfa5234f5dfa (commit)

commit bbf484ea71dfd1b97a8716739c698ed2bb9348ac
Author: Nick Schermer <nick at xfce.org>
Date:   Fri Dec 30 20:07:59 2011 +0100

    Panel: Don't remove windows using the destroy signal.
    
    This can lead to problems if the window is destroyed
    when the signal still connected: the configuration is
    lost. Do this explicitly in a function, so this problem
    never occurs.

 panel/panel-application.c        |  117 +++++++++++++++++--------------------
 panel/panel-application.h        |    3 +
 panel/panel-preferences-dialog.c |   13 +---
 3 files changed, 61 insertions(+), 72 deletions(-)

diff --git a/panel/panel-application.c b/panel/panel-application.c
index c064a6d..6b8d2dd 100644
--- a/panel/panel-application.c
+++ b/panel/panel-application.c
@@ -68,8 +68,6 @@ static gboolean  panel_application_plugin_insert      (PanelApplication       *a
                                                        gint                    unique_id,
                                                        gchar                 **arguments,
                                                        gint                    position);
-static void      panel_application_window_destroyed   (GtkWidget              *window,
-                                                       PanelApplication       *application);
 static void      panel_application_dialog_destroyed   (GtkWindow              *dialog,
                                                        PanelApplication       *application);
 static void      panel_application_drag_data_received (PanelWindow            *window,
@@ -233,7 +231,6 @@ static void
 panel_application_finalize (GObject *object)
 {
   PanelApplication *application = PANEL_APPLICATION (object);
-  GSList           *li;
 
   panel_return_if_fail (application->dialogs == NULL);
 
@@ -243,13 +240,8 @@ panel_application_finalize (GObject *object)
     g_source_remove (application->wait_for_wm_timeout_id);
 #endif
 
-  /* free all windows */
-  for (li = application->windows; li != NULL; li = li->next)
-    {
-      g_signal_handlers_disconnect_by_func (G_OBJECT (li->data),
-          G_CALLBACK (panel_application_window_destroyed), application);
-      gtk_widget_destroy (GTK_WIDGET (li->data));
-    }
+  /* destroy all panels */
+  g_slist_foreach (application->windows, (GFunc) gtk_widget_destroy, NULL);
   g_slist_free (application->windows);
 
   g_object_unref (G_OBJECT (application->factory));
@@ -794,55 +786,6 @@ panel_application_plugin_insert (PanelApplication  *application,
 
 
 static void
-panel_application_window_destroyed (GtkWidget        *window,
-                                    PanelApplication *application)
-{
-  gchar     *property;
-  GtkWidget *itembar;
-  gint       panel_id;
-
-  panel_return_if_fail (PANEL_IS_WINDOW (window));
-  panel_return_if_fail (PANEL_IS_APPLICATION (application));
-  panel_return_if_fail (g_slist_find (application->windows, window) != NULL);
-
-  /* leave if the application or window is locked */
-  if (panel_application_get_locked (application)
-      || panel_window_get_locked (PANEL_WINDOW (window)))
-    return;
-
-  panel_id = panel_window_get_id (PANEL_WINDOW (window));
-  panel_debug (PANEL_DEBUG_APPLICATION,
-               "removing configuration and plugins of panel %d",
-               panel_id);
-
-  /* remove from the internal list */
-  application->windows = g_slist_remove (application->windows, window);
-
-  /* disconnect bindings from this panel */
-  panel_properties_unbind (G_OBJECT (window));
-
-  /* remove all the plugins from the itembar */
-  itembar = gtk_bin_get_child (GTK_BIN (window));
-  gtk_container_foreach (GTK_CONTAINER (itembar),
-      panel_application_plugin_remove, NULL);
-
-  /* remove the panel settings */
-  property = g_strdup_printf ("/panels/panel-%d", panel_id);
-  xfconf_channel_reset_property (application->xfconf, property, TRUE);
-  g_free (property);
-
-  /* save updated panel ids */
-  panel_application_save (application, SAVE_PANEL_IDS);
-
-  /* quit if there are no windows */
-  /* TODO, allow removing all windows and ask user what to do */
-  if (application->windows == NULL)
-    gtk_main_quit ();
-}
-
-
-
-static void
 panel_application_windows_block_autohide (PanelApplication *application,
                                           gboolean          blocked)
 {
@@ -1504,10 +1447,6 @@ panel_application_new_window (PanelApplication *application,
   /* create panel window */
   window = panel_window_new (screen, panel_id);
 
-  /* monitor window destruction */
-  g_signal_connect (G_OBJECT (window), "destroy",
-      G_CALLBACK (panel_application_window_destroyed), application);
-
   /* add the window to internal list */
   application->windows = g_slist_append (application->windows, window);
 
@@ -1566,6 +1505,58 @@ panel_application_new_window (PanelApplication *application,
 
 
 
+void
+panel_application_remove_window (PanelApplication *application,
+                                 PanelWindow      *window)
+{
+  gchar     *property;
+  GtkWidget *itembar;
+  gint       panel_id;
+
+  panel_return_if_fail (PANEL_IS_WINDOW (window));
+  panel_return_if_fail (PANEL_IS_APPLICATION (application));
+  panel_return_if_fail (g_slist_find (application->windows, window) != NULL);
+
+  /* leave if the application or window is locked */
+  if (panel_application_get_locked (application)
+      || panel_window_get_locked (PANEL_WINDOW (window)))
+    return;
+
+  panel_id = panel_window_get_id (PANEL_WINDOW (window));
+  panel_debug (PANEL_DEBUG_APPLICATION,
+               "removing configuration and plugins of panel %d",
+               panel_id);
+
+  /* remove from the internal list */
+  application->windows = g_slist_remove (application->windows, window);
+
+  /* disconnect bindings from this panel */
+  panel_properties_unbind (G_OBJECT (window));
+
+  /* set all the plugins on this panel the remove signal */
+  itembar = gtk_bin_get_child (GTK_BIN (window));
+  gtk_container_foreach (GTK_CONTAINER (itembar),
+      panel_application_plugin_remove, NULL);
+
+  /* destroy */
+  gtk_widget_destroy (GTK_WIDGET (window));
+
+  /* remove the panel settings */
+  property = g_strdup_printf ("/panels/panel-%d", panel_id);
+  xfconf_channel_reset_property (application->xfconf, property, TRUE);
+  g_free (property);
+
+  /* save changed panel ids */
+  panel_application_save (application, SAVE_PANEL_IDS);
+
+  /* quit if there are no windows */
+  /* TODO, allow removing all windows and ask user what to do */
+  if (application->windows == NULL)
+    gtk_main_quit ();
+}
+
+
+
 GSList *
 panel_application_get_windows (PanelApplication *application)
 {
diff --git a/panel/panel-application.h b/panel/panel-application.h
index 3dcf1b6..36f4504 100644
--- a/panel/panel-application.h
+++ b/panel/panel-application.h
@@ -68,6 +68,9 @@ PanelWindow      *panel_application_new_window        (PanelApplication  *applic
                                                        gint               id,
                                                        gboolean           new_window);
 
+void              panel_application_remove_window     (PanelApplication  *application,
+                                                       PanelWindow       *window);
+
 GSList           *panel_application_get_windows       (PanelApplication  *application);
 
 PanelWindow      *panel_application_get_window        (PanelApplication  *application,
diff --git a/panel/panel-preferences-dialog.c b/panel/panel-preferences-dialog.c
index 8f9c1d2..3a0119f 100644
--- a/panel/panel-preferences-dialog.c
+++ b/panel/panel-preferences-dialog.c
@@ -843,7 +843,6 @@ panel_preferences_dialog_panel_remove (GtkWidget              *widget,
                                        PanelPreferencesDialog *dialog)
 {
   gint       idx;
-  GObject   *combo;
   GtkWidget *toplevel;
   GSList    *windows;
   gint       n_windows;
@@ -866,17 +865,13 @@ panel_preferences_dialog_panel_remove (GtkWidget              *widget,
       idx = g_slist_index (windows, dialog->active);
       n_windows = g_slist_length (windows) - 2;
 
-      /* destroy the panel */
-      gtk_widget_destroy (GTK_WIDGET (dialog->active));
+      /* remove the panel, plugins and configuration */
+      panel_application_remove_window (dialog->application,
+                                       dialog->active);
       dialog->active = NULL;
 
       /* rebuild the selector */
-      panel_preferences_dialog_panel_combobox_rebuild (dialog, -1);
-
-      /* select window after this window */
-      combo = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-combobox");
-      panel_return_if_fail (GTK_IS_WIDGET (combo));
-      gtk_combo_box_set_active (GTK_COMBO_BOX (combo), CLAMP (idx, 0, n_windows));
+      panel_preferences_dialog_panel_combobox_rebuild (dialog, CLAMP (idx, 0, n_windows));
     }
 }
 


More information about the Xfce4-commits mailing list