network-manager-applet r1000 - in trunk: . src



Author: dcbw
Date: Sun Nov  2 22:51:04 2008
New Revision: 1000
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=1000&view=rev

Log:
2008-11-02  Dan Williams  <dcbw redhat com>

	* src/applet.c
	  src/applet.h
		- (find_active_device): return the active connection object instead of
			just the active connection's specific object
		- (applet_settings_new_secrets_requested_cb): pass the active connection
			to the device subclasses

	* src/applet-device-wired.c
	  src/applet-device-wifi.c
	  src/applet-device-gsm.c
	  src/applet-device-cdma.c
		- Attach any secrets dialogs to the active connection object, such that
			when the active connection object goes away the dialog also gets
			closed



Modified:
   trunk/ChangeLog
   trunk/src/applet-device-cdma.c
   trunk/src/applet-device-gsm.c
   trunk/src/applet-device-wifi.c
   trunk/src/applet-device-wired.c
   trunk/src/applet.c
   trunk/src/applet.h

Modified: trunk/src/applet-device-cdma.c
==============================================================================
--- trunk/src/applet-device-cdma.c	(original)
+++ trunk/src/applet-device-cdma.c	Sun Nov  2 22:51:04 2008
@@ -356,12 +356,26 @@
 	DBusGMethodInvocation *context;
 	NMApplet *applet;
 	NMConnection *connection;
-	GtkWidget *ok_button;
+	NMActiveConnection *active_connection;
+	GtkWidget *dialog;
 	GtkEntry *secret_entry;
 	char *secret_name;
 } NMCdmaInfo;
 
 static void
+destroy_cdma_dialog (gpointer user_data, GObject *finalized)
+{
+	NMCdmaInfo *info = user_data;
+
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+
+	g_object_unref (info->connection);
+	g_free (info->secret_name);
+	g_free (info);
+}
+
+static void
 get_cdma_secrets_cb (GtkDialog *dialog,
                      gint response,
                      gpointer user_data)
@@ -373,6 +387,11 @@
 	GHashTable *secrets;
 	GError *err = NULL;
 
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_cdma_dialog, info);
+
 	if (response != GTK_RESPONSE_OK) {
 		g_set_error (&err, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): canceled",
@@ -421,45 +440,30 @@
 		g_error_free (err);
 	}
 
-	gtk_widget_hide (GTK_WIDGET (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-
 	nm_connection_clear_secrets (info->connection);
-	g_object_unref (info->connection);
-	g_free (info->secret_name);
-	g_free (info);
+	destroy_cdma_dialog (info, NULL);
 }
 
-
-static void
+static GtkWidget *
 ask_for_password (NMDevice *device,
                   NMConnection *connection,
-                  DBusGMethodInvocation *context,
-                  NMApplet *applet)
+                  GtkEntry **out_secret_entry)
 {
 	GtkDialog *dialog;
 	GtkWidget *w;
 	GtkBox *box;
 	char *dev_str;
-	NMCdmaInfo *info;
 	NMSettingConnection *s_con;
 	char *tmp;
 	const char *id;
 
-	info = g_new (NMCdmaInfo, 1);
-	info->context = context;
-	info->applet = applet;
-	info->connection = g_object_ref (connection);
-	info->secret_name = g_strdup (NM_SETTING_CDMA_PASSWORD);
-
 	dialog = GTK_DIALOG (gtk_dialog_new ());
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 	gtk_window_set_title (GTK_WINDOW (dialog), _("Mobile broadband network password"));
 
 	w = gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
 	w = gtk_dialog_add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
-	info->ok_button = w;
-	gtk_window_set_default (GTK_WINDOW (dialog), info->ok_button);
+	gtk_window_set_default (GTK_WINDOW (dialog), w);
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
 	id = nm_setting_connection_get_id (s_con);
@@ -485,31 +489,28 @@
 	gtk_box_pack_start (box, gtk_label_new (_("Password:")), FALSE, FALSE, 0);
 
 	w = gtk_entry_new ();
-	info->secret_entry = GTK_ENTRY (w);
+	*out_secret_entry = GTK_ENTRY (w);
 	gtk_entry_set_activates_default (GTK_ENTRY (w), TRUE);
 	gtk_box_pack_start (box, w, FALSE, FALSE, 0);
 
 	gtk_widget_show_all (dialog->vbox);
-
-	g_signal_connect (dialog, "response",
-				   G_CALLBACK (get_cdma_secrets_cb),
-				   info);
-
-	gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
-	gtk_widget_realize (GTK_WIDGET (dialog));
-	gtk_window_present (GTK_WINDOW (dialog));
+	return GTK_WIDGET (dialog);
 }
 
 static gboolean
 cdma_get_secrets (NMDevice *device,
                  NMConnection *connection,
-                 const char *specific_object,
+                 NMActiveConnection *active_connection,
                  const char *setting_name,
                  const char **hints,
                  DBusGMethodInvocation *context,
                  NMApplet *applet,
                  GError **error)
 {
+	NMCdmaInfo *info;
+	GtkWidget *widget;
+	GtkEntry *secret_entry = NULL;
+
 	if (!hints || !g_strv_length ((char **) hints)) {
 		g_set_error (error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): missing secrets hints.",
@@ -518,7 +519,7 @@
 	}
 
 	if (!strcmp (hints[0], NM_SETTING_CDMA_PASSWORD))
-		ask_for_password (device, connection, context, applet);
+		widget = ask_for_password (device, connection, &secret_entry);
 	else {
 		g_set_error (error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): unknown secrets hint '%s'.",
@@ -526,6 +527,33 @@
 		return FALSE;
 	}
 
+	if (!widget || !secret_entry) {
+		g_set_error (error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d (%s): error asking for CDMA secrets.",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
+
+	info = g_new (NMCdmaInfo, 1);
+	info->context = context;
+	info->applet = applet;
+	info->active_connection = active_connection;
+	info->connection = g_object_ref (connection);
+	info->secret_name = g_strdup (hints[0]);
+	info->dialog = widget;
+	info->secret_entry = secret_entry;
+
+	g_signal_connect (widget, "response", G_CALLBACK (get_cdma_secrets_cb), info);
+
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_cdma_dialog, info);
+
+	gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ALWAYS);
+	gtk_widget_realize (GTK_WIDGET (widget));
+	gtk_window_present (GTK_WINDOW (widget));
+
 	return TRUE;
 }
 

Modified: trunk/src/applet-device-gsm.c
==============================================================================
--- trunk/src/applet-device-gsm.c	(original)
+++ trunk/src/applet-device-gsm.c	Sun Nov  2 22:51:04 2008
@@ -355,16 +355,18 @@
 typedef struct {
 	DBusGMethodInvocation *context;
 	NMApplet *applet;
+	NMActiveConnection *active_connection;
+	GtkWidget *dialog;
 	NMConnection *connection;
-	GtkWidget *ok_button;
 	GtkEntry *secret_entry;
 	char *secret_name;
 } NMGsmInfo;
 
+
 static void
 pin_entry_changed (GtkEditable *editable, gpointer user_data)
 {
-	NMGsmInfo *info = (NMGsmInfo *) user_data;
+	GtkWidget *ok_button = GTK_WIDGET (user_data);
 	const char *s;
 	int i;
 	gboolean valid = FALSE;
@@ -380,7 +382,20 @@
 		}
 	}
 
-	gtk_widget_set_sensitive (info->ok_button, valid);
+	gtk_widget_set_sensitive (ok_button, valid);
+}
+
+static void
+destroy_gsm_dialog (gpointer user_data, GObject *finalized)
+{
+	NMGsmInfo *info = user_data;
+
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+
+	g_object_unref (info->connection);
+	g_free (info->secret_name);
+	g_free (info);
 }
 
 static void
@@ -395,6 +410,11 @@
 	GHashTable *secrets;
 	GError *err = NULL;
 
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_gsm_dialog, info);
+
 	if (response != GTK_RESPONSE_OK) {
 		g_set_error (&err, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): canceled",
@@ -442,33 +462,20 @@
 		g_error_free (err);
 	}
 
-	gtk_widget_hide (GTK_WIDGET (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-
 	nm_connection_clear_secrets (info->connection);
-	g_object_unref (info->connection);
-	g_free (info->secret_name);
-	g_free (info);
+	destroy_gsm_dialog (info, NULL);
 }
 
-static void
+static GtkWidget *
 ask_for_pin_puk (NMDevice *device,
                  NMConnection *connection,
                  const char *secret_name,
-                 DBusGMethodInvocation *context,
-                 NMApplet *applet)
+                 GtkEntry **out_secret_entry)
 {
 	GtkDialog *dialog;
-	GtkWidget *w;
+	GtkWidget *w, *ok_button;
 	GtkBox *box;
 	char *dev_str;
-	NMGsmInfo *info;
-
-	info = g_new (NMGsmInfo, 1);
-	info->context = context;
-	info->applet = applet;
-	info->connection = g_object_ref (connection);
-	info->secret_name = g_strdup (secret_name);
 
 	dialog = GTK_DIALOG (gtk_dialog_new ());
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
@@ -480,10 +487,9 @@
 	else
 		g_assert_not_reached ();
 
-	w = gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-	w = gtk_dialog_add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
-	info->ok_button = w;
-	gtk_window_set_default (GTK_WINDOW (dialog), info->ok_button);
+	ok_button = gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+	ok_button = gtk_dialog_add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
+	gtk_window_set_default (GTK_WINDOW (dialog), ok_button);
 
 	if (!strcmp (secret_name, NM_SETTING_GSM_PIN))
 		w = gtk_label_new (_("PIN code is needed for the mobile broadband device"));
@@ -507,54 +513,38 @@
 	gtk_box_pack_start (box, gtk_label_new ("PIN:"), FALSE, FALSE, 0);
 
 	w = gtk_entry_new ();
-	info->secret_entry = GTK_ENTRY (w);
+	*out_secret_entry = GTK_ENTRY (w);
 	gtk_entry_set_max_length (GTK_ENTRY (w), 4);
 	gtk_entry_set_width_chars (GTK_ENTRY (w), 4);
 	gtk_entry_set_activates_default (GTK_ENTRY (w), TRUE);
 	gtk_box_pack_start (box, w, FALSE, FALSE, 0);
-	g_signal_connect (w, "changed", G_CALLBACK (pin_entry_changed), info);
-	pin_entry_changed (GTK_EDITABLE (w), info);
+	g_signal_connect (w, "changed", G_CALLBACK (pin_entry_changed), ok_button);
+	pin_entry_changed (GTK_EDITABLE (w), ok_button);
 
 	gtk_widget_show_all (dialog->vbox);
-
-	g_signal_connect (dialog, "response",
-				   G_CALLBACK (get_gsm_secrets_cb),
-				   info);
-
-	gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
-	gtk_widget_realize (GTK_WIDGET (dialog));
-	gtk_window_present (GTK_WINDOW (dialog));
+	return GTK_WIDGET (dialog);
 }
 
-static void
+static GtkWidget *
 ask_for_password (NMDevice *device,
                   NMConnection *connection,
-                  DBusGMethodInvocation *context,
-                  NMApplet *applet)
+                  GtkEntry **out_secret_entry)
 {
 	GtkDialog *dialog;
 	GtkWidget *w;
 	GtkBox *box;
 	char *dev_str;
-	NMGsmInfo *info;
 	NMSettingConnection *s_con;
 	char *tmp;
 	const char *id;
 
-	info = g_new (NMGsmInfo, 1);
-	info->context = context;
-	info->applet = applet;
-	info->connection = g_object_ref (connection);
-	info->secret_name = g_strdup (NM_SETTING_GSM_PASSWORD);
-
 	dialog = GTK_DIALOG (gtk_dialog_new ());
 	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 	gtk_window_set_title (GTK_WINDOW (dialog), _("Mobile broadband network password"));
 
 	w = gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
 	w = gtk_dialog_add_button (dialog, GTK_STOCK_OK, GTK_RESPONSE_OK);
-	info->ok_button = w;
-	gtk_window_set_default (GTK_WINDOW (dialog), info->ok_button);
+	gtk_window_set_default (GTK_WINDOW (dialog), w);
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
 	id = nm_setting_connection_get_id (s_con);
@@ -580,31 +570,28 @@
 	gtk_box_pack_start (box, gtk_label_new (_("Password:")), FALSE, FALSE, 0);
 
 	w = gtk_entry_new ();
-	info->secret_entry = GTK_ENTRY (w);
+	*out_secret_entry = GTK_ENTRY (w);
 	gtk_entry_set_activates_default (GTK_ENTRY (w), TRUE);
 	gtk_box_pack_start (box, w, FALSE, FALSE, 0);
 
 	gtk_widget_show_all (dialog->vbox);
-
-	g_signal_connect (dialog, "response",
-				   G_CALLBACK (get_gsm_secrets_cb),
-				   info);
-
-	gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
-	gtk_widget_realize (GTK_WIDGET (dialog));
-	gtk_window_present (GTK_WINDOW (dialog));
+	return GTK_WIDGET (dialog);
 }
 
 static gboolean
 gsm_get_secrets (NMDevice *device,
                  NMConnection *connection,
-                 const char *specific_object,
+                 NMActiveConnection *active_connection,
                  const char *setting_name,
                  const char **hints,
                  DBusGMethodInvocation *context,
                  NMApplet *applet,
                  GError **error)
 {
+	NMGsmInfo *info;
+	GtkWidget *widget;
+	GtkEntry *secret_entry = NULL;
+
 	if (!hints || !g_strv_length ((char **) hints)) {
 		g_set_error (error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): missing secrets hints.",
@@ -614,9 +601,9 @@
 
 	if (   !strcmp (hints[0], NM_SETTING_GSM_PIN)
 	    || !strcmp (hints[0], NM_SETTING_GSM_PUK))
-		ask_for_pin_puk (device, connection, hints[0], context, applet);
+		widget = ask_for_pin_puk (device, connection, hints[0], &secret_entry);
 	else if (!strcmp (hints[0], NM_SETTING_GSM_PASSWORD))
-		ask_for_password (device, connection, context, applet);
+		widget = ask_for_password (device, connection, &secret_entry);
 	else {
 		g_set_error (error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): unknown secrets hint '%s'.",
@@ -624,6 +611,33 @@
 		return FALSE;
 	}
 
+	if (!widget || !secret_entry) {
+		g_set_error (error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d (%s): error asking for GSM secrets.",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
+
+	info = g_new (NMGsmInfo, 1);
+	info->context = context;
+	info->applet = applet;
+	info->active_connection = active_connection;
+	info->connection = g_object_ref (connection);
+	info->secret_name = g_strdup (hints[0]);
+	info->dialog = widget;
+	info->secret_entry = secret_entry;
+
+	g_signal_connect (widget, "response", G_CALLBACK (get_gsm_secrets_cb), info);
+
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_gsm_dialog, info);
+
+	gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ALWAYS);
+	gtk_widget_realize (GTK_WIDGET (widget));
+	gtk_window_present (GTK_WINDOW (widget));
+
 	return TRUE;
 }
 

Modified: trunk/src/applet-device-wifi.c
==============================================================================
--- trunk/src/applet-device-wifi.c	(original)
+++ trunk/src/applet-device-wifi.c	Sun Nov  2 22:51:04 2008
@@ -1314,6 +1314,7 @@
 		nag_dialog = nma_wireless_dialog_nag_user (dialog);
 		if (nag_dialog) {
 			gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog));
+			gtk_window_set_destroy_with_parent (GTK_WINDOW (nag_dialog), TRUE);
 			g_signal_connect (nag_dialog, "response",
 			                  G_CALLBACK (nag_dialog_response_cb),
 			                  dialog);
@@ -1470,39 +1471,45 @@
 	return secrets ? TRUE : FALSE;
 }
 
+typedef struct {
+	NMApplet *applet;
+	NMActiveConnection *active_connection;
+	GtkWidget *dialog;
+	GtkWidget *nag_dialog;
+	DBusGMethodInvocation *context;
+	char *setting_name;
+} NMWifiInfo;
+
+static void
+destroy_wifi_dialog (gpointer user_data, GObject *finalized)
+{
+	NMWifiInfo *info = user_data;
+
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+	g_free (info->setting_name);
+	g_free (info);
+}
+
 static void
 get_secrets_dialog_response_cb (GtkDialog *foo,
                                 gint response,
                                 gpointer user_data)
 {
-	NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (foo);
-	NMApplet *applet = NM_APPLET (user_data);
-	DBusGMethodInvocation *context;
+	NMWifiInfo *info = user_data;
+	NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (info->dialog);
 	NMAGConfConnection *gconf_connection;
 	NMConnection *connection = NULL;
 	NMSettingWirelessSecurity *s_wireless_sec;
 	NMDevice *device = NULL;
 	GHashTable *settings = NULL;
-	const char *setting_name, *key_mgmt, *auth_alg;
+	const char *key_mgmt, *auth_alg;
 	GError *error = NULL;
 
-	context = g_object_get_data (G_OBJECT (dialog), "dbus-context");
-	setting_name = g_object_get_data (G_OBJECT (dialog), "setting-name");
-	if (!context || !setting_name) {
-		g_set_error (&error, NM_SETTINGS_ERROR, 1,
-		             "%s.%d (%s): couldn't get dialog data",
-		             __FILE__, __LINE__, __func__);
-		goto done;
-	}
-
-	if (response != GTK_RESPONSE_OK) {
-		g_set_error (&error, NM_SETTINGS_ERROR, 1,
-		             "%s.%d (%s): canceled",
-		             __FILE__, __LINE__, __func__);
-		goto done;
-	}
-
-	if (!nma_wireless_dialog_get_nag_ignored (dialog)) {
+	/* Handle the nag dialog specially; don't want to clear the NMActiveConnection
+	 * destroy handler yet if the main dialog isn't going away.
+	 */
+	if ((response == GTK_RESPONSE_OK) && !nma_wireless_dialog_get_nag_ignored (dialog)) {
 		GtkWidget *widget;
 
 		/* Nag the user about certificates or whatever.  Only destroy the dialog
@@ -1511,6 +1518,7 @@
 		widget = nma_wireless_dialog_nag_user (dialog);
 		if (widget) {
 			gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (dialog));
+			gtk_window_set_destroy_with_parent (GTK_WINDOW (widget), TRUE);
 			g_signal_connect (widget, "response",
 			                  G_CALLBACK (nag_dialog_response_cb),
 			                  dialog);
@@ -1518,6 +1526,18 @@
 		}
 	}
 
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_wifi_dialog, info);
+
+	if (response != GTK_RESPONSE_OK) {
+		g_set_error (&error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d (%s): canceled",
+		             __FILE__, __LINE__, __func__);
+		goto done;
+	}
+
 	connection = nma_wireless_dialog_get_connection (dialog, &device, NULL);
 	if (!connection) {
 		g_set_error (&error, NM_SETTINGS_ERROR, 1,
@@ -1580,13 +1600,13 @@
 	if (!add_one_setting (settings, connection, NM_SETTING (s_wireless_sec), &error))
 		goto done;
 
-	dbus_g_method_return (context, settings);
+	dbus_g_method_return (info->context, settings);
 
 	/* Save the connection back to GConf _after_ hashing it, because
 	 * saving to GConf might trigger the GConf change notifiers, resulting
 	 * in the connection being read back in from GConf which clears secrets.
 	 */
-	gconf_connection = nma_gconf_settings_get_by_connection (applet->gconf_settings, connection);
+	gconf_connection = nma_gconf_settings_get_by_connection (info->applet->gconf_settings, connection);
 	if (gconf_connection)
 		nma_gconf_connection_save (gconf_connection);
 
@@ -1596,52 +1616,73 @@
 
 	if (error) {
 		g_warning ("%s", error->message);
-		dbus_g_method_return_error (context, error);
+		dbus_g_method_return_error (info->context, error);
 		g_error_free (error);
 	}
 
 	if (connection)
 		nm_connection_clear_secrets (connection);
 
-	gtk_widget_hide (GTK_WIDGET (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
+	destroy_wifi_dialog (info, NULL);
 }
 
 static gboolean
 wireless_get_secrets (NMDevice *device,
                       NMConnection *connection,
-                      const char *specific_object,
+                      NMActiveConnection *active_connection,
                       const char *setting_name,
                       const char **hints,
                       DBusGMethodInvocation *context,
                       NMApplet *applet,
                       GError **error)
 {
+	NMWifiInfo *info;
 	NMAccessPoint *ap;
-	GtkWidget *dialog;
+	const char *specific_object;
 
-	g_assert (specific_object);
-	ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), specific_object);
+	if (!setting_name || !active_connection) {
+		g_set_error (error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d (%s): setting name and active connection object required",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
 
-	dialog = nma_wireless_dialog_new (applet, connection, device, ap);
-	if (!dialog) {
+	specific_object = nm_active_connection_get_specific_object (active_connection);
+	if (!specific_object) {
+		g_set_error (error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d (%s): could not determine AP for specific object",
+		             __FILE__, __LINE__, __func__);
+		return FALSE;
+	}
+
+	info = g_malloc0 (sizeof (NMWifiInfo));
+
+	ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), specific_object);
+	info->dialog = nma_wireless_dialog_new (applet, connection, device, ap);
+	if (!info->dialog) {
 		g_set_error (error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): couldn't display secrets UI",
 		             __FILE__, __LINE__, __func__);
+		g_free (info);
 		return FALSE;
 	}
 
-	g_object_set_data (G_OBJECT (dialog), "dbus-context", context);
-	g_object_set_data_full (G_OBJECT (dialog),
-	                        "setting-name", g_strdup (setting_name),
-	                        (GDestroyNotify) g_free);
+	info->applet = applet;
+	info->active_connection = active_connection;
+	info->context = context;
+	info->setting_name = g_strdup (setting_name);
 
-	g_signal_connect (dialog, "response",
+	g_signal_connect (info->dialog, "response",
 	                  G_CALLBACK (get_secrets_dialog_response_cb),
-	                  applet);
+	                  info);
 
-	gtk_widget_realize (dialog);
-	gtk_window_present (GTK_WINDOW (dialog));
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_wifi_dialog, info);
+
+	gtk_widget_realize (info->dialog);
+	gtk_window_present (GTK_WINDOW (info->dialog));
 
 	return TRUE;
 }

Modified: trunk/src/applet-device-wired.c
==============================================================================
--- trunk/src/applet-device-wired.c	(original)
+++ trunk/src/applet-device-wired.c	Sun Nov  2 22:51:04 2008
@@ -308,7 +308,6 @@
 /* PPPoE */
 
 typedef struct {
-	GladeXML *xml;
 	GtkEntry *username_entry;
 	GtkEntry *service_entry;
 	GtkEntry *password_entry;
@@ -317,6 +316,9 @@
 	NMApplet *applet;
 	NMConnection *connection;
 	DBusGMethodInvocation *context;
+
+	GtkWidget *dialog;
+	NMActiveConnection *active_connection;
 } NMPppoeInfo;
 
 static void
@@ -399,12 +401,15 @@
 }
 
 static NMPppoeInfo *
-pppoe_info_new (GladeXML *xml)
+pppoe_info_new (GladeXML *xml,
+                NMApplet *applet,
+                DBusGMethodInvocation *context,
+                NMConnection *connection,
+                NMActiveConnection *active_connection)
 {
 	NMPppoeInfo *info;
 
 	info = g_new0 (NMPppoeInfo, 1);
-	info->xml = xml;
 	
 	info->username_entry = GTK_ENTRY (glade_xml_get_widget (xml, "dsl_username"));
 	g_signal_connect (info->username_entry, "changed", G_CALLBACK (pppoe_verify), info);
@@ -414,6 +419,11 @@
 	info->password_entry = GTK_ENTRY (glade_xml_get_widget (xml, "dsl_password"));
 	g_signal_connect (info->password_entry, "changed", G_CALLBACK (pppoe_verify), info);
 
+	info->applet = applet;
+	info->context = context;
+	info->connection = g_object_ref (connection);
+	info->active_connection = active_connection;
+
 	return info;
 }
 
@@ -422,13 +432,24 @@
 {
 	NMPppoeInfo *info = (NMPppoeInfo *) data;
 
-	g_object_unref (info->connection);
-	g_object_unref (info->xml);
-	
+	g_object_unref (info->connection);	
 	g_free (info);
 }
 
 static void
+destroy_pppoe_dialog (gpointer data, GObject *finalized)
+{
+	NMPppoeInfo *info = data;
+
+	/* When the active connection object is destroyed, try to destroy the
+	 * dialog too, if it's still around.
+	 */
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+	pppoe_info_destroy (info, NULL);
+}
+
+static void
 get_pppoe_secrets_cb (GtkDialog *dialog,
 					  gint response,
 					  gpointer user_data)
@@ -440,6 +461,11 @@
 	GHashTable *secrets;
 	GError *err = NULL;
 
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_pppoe_dialog, info);
+
 	if (response != GTK_RESPONSE_OK) {
 		g_set_error (&err, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): canceled",
@@ -484,34 +510,30 @@
 	}
 
 	nm_connection_clear_secrets (info->connection);
-	gtk_widget_hide (GTK_WIDGET (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
+	destroy_pppoe_dialog (info, NULL);
 }
 
 static void
 show_password_toggled (GtkToggleButton *button, gpointer user_data)
 {
 	NMPppoeInfo *info = (NMPppoeInfo *) user_data;
-	GtkWidget *entry;
 
-	entry = glade_xml_get_widget (info->xml, "dsl_password");
 	if (gtk_toggle_button_get_active (button))
-		gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE);
+		gtk_entry_set_visibility (GTK_ENTRY (info->password_entry), TRUE);
 	else
-		gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
+		gtk_entry_set_visibility (GTK_ENTRY (info->password_entry), FALSE);
 }
 
 static gboolean
 pppoe_get_secrets (NMDevice *device,
 				   NMConnection *connection,
-				   const char *specific_object,
+				   NMActiveConnection *active_connection,
 				   const char *setting_name,
 				   DBusGMethodInvocation *context,
 				   NMApplet *applet,
 				   GError **error)
 {
 	GladeXML *xml;
-	GtkWidget *dialog;
 	NMPppoeInfo *info;
 	GtkWidget *w;
 
@@ -523,50 +545,67 @@
 		return FALSE;
 	}
 
-	info = pppoe_info_new (xml);
-	info->applet = applet;
-	info->context = context;
-	info->connection = g_object_ref (connection);
+	info = pppoe_info_new (xml, applet, context, connection, active_connection);
 
 	/* Create the dialog */
-	dialog = gtk_dialog_new ();
-	gtk_window_set_title (GTK_WINDOW (dialog), _("DSL authentication"));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+	info->dialog = gtk_dialog_new ();
+	gtk_window_set_title (GTK_WINDOW (info->dialog), _("DSL authentication"));
+	gtk_window_set_modal (GTK_WINDOW (info->dialog), TRUE);
 
-	w = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
-	w = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);
+	w = gtk_dialog_add_button (GTK_DIALOG (info->dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+	w = gtk_dialog_add_button (GTK_DIALOG (info->dialog), GTK_STOCK_OK, GTK_RESPONSE_OK);
 	info->ok_button = w;
 
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (info->dialog)->vbox),
 	                    glade_xml_get_widget (xml, "DslPage"),
 	                    TRUE, TRUE, 0);
 
 	pppoe_update_ui (connection, info);
-	g_object_weak_ref (G_OBJECT (dialog), pppoe_info_destroy, info);
 
 	w = glade_xml_get_widget (xml, "dsl_show_password");
 	g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (show_password_toggled), info);
 
-	g_signal_connect (dialog, "response",
+	g_signal_connect (info->dialog, "response",
 	                  G_CALLBACK (get_pppoe_secrets_cb),
 	                  info);
 
-	gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
-	gtk_widget_realize (dialog);
-	gtk_window_present (GTK_WINDOW (dialog));
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_pppoe_dialog, info);
+
+	gtk_window_set_position (GTK_WINDOW (info->dialog), GTK_WIN_POS_CENTER_ALWAYS);
+	gtk_widget_realize (info->dialog);
+	gtk_window_present (GTK_WINDOW (info->dialog));
 
 	return TRUE;
 }
 
 /* 802.1x */
 
+typedef struct {
+	NMApplet *applet;
+	NMActiveConnection *active_connection;
+	GtkWidget *dialog;
+	DBusGMethodInvocation *context;
+} NM8021xInfo;
+
+static void
+destroy_8021x_dialog (gpointer user_data, GObject *finalized)
+{
+	NM8021xInfo *info = user_data;
+
+	gtk_widget_hide (info->dialog);
+	gtk_widget_destroy (info->dialog);
+	g_free (info);
+}
+
 static void
 get_8021x_secrets_cb (GtkDialog *dialog,
 					  gint response,
 					  gpointer user_data)
 {
-	NMApplet *applet = NM_APPLET (user_data);
-	DBusGMethodInvocation *context;
+	NM8021xInfo *info = user_data;
 	NMAGConfConnection *gconf_connection;
 	NMConnection *connection = NULL;
 	NMSetting *setting;
@@ -574,13 +613,10 @@
 	GHashTable *secrets;
 	GError *err = NULL;
 
-	context = g_object_get_data (G_OBJECT (dialog), "dbus-context");
-	if (!context) {
-		g_set_error (&err, NM_SETTINGS_ERROR, 1,
-		             "%s.%d (%s): couldn't get dialog data",
-		             __FILE__, __LINE__, __func__);
-		goto done;
-	}
+	/* Got a user response, clear the NMActiveConnection destroy handler for
+	 * this dialog since this function will now take over dialog destruction.
+	 */
+	g_object_weak_unref (G_OBJECT (info->active_connection), destroy_8021x_dialog, info);
 
 	if (response != GTK_RESPONSE_OK) {
 		g_set_error (&err, NM_SETTINGS_ERROR, 1,
@@ -589,7 +625,7 @@
 		goto done;
 	}
 
-	connection = nma_wired_dialog_get_connection (GTK_WIDGET (dialog));
+	connection = nma_wired_dialog_get_connection (info->dialog);
 	if (!connection) {
 		g_set_error (&err, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): couldn't get connection from wired dialog.",
@@ -624,43 +660,41 @@
 										   g_free, (GDestroyNotify) g_hash_table_destroy);
 
 	g_hash_table_insert (settings_hash, g_strdup (nm_setting_get_name (setting)), secrets);
-	dbus_g_method_return (context, settings_hash);
+	dbus_g_method_return (info->context, settings_hash);
 	g_hash_table_destroy (settings_hash);
 
 	/* Save the connection back to GConf _after_ hashing it, because
 	 * saving to GConf might trigger the GConf change notifiers, resulting
 	 * in the connection being read back in from GConf which clears secrets.
 	 */
-	gconf_connection = nma_gconf_settings_get_by_connection (applet->gconf_settings, connection);
+	gconf_connection = nma_gconf_settings_get_by_connection (info->applet->gconf_settings, connection);
 	if (gconf_connection)
 		nma_gconf_connection_save (gconf_connection);
 
 done:
 	if (err) {
 		g_warning ("%s", err->message);
-
-		if (context)
-			dbus_g_method_return_error (context, err);
-
+		dbus_g_method_return_error (info->context, err);
 		g_error_free (err);
 	}
 
 	if (connection)
 		nm_connection_clear_secrets (connection);
-	gtk_widget_hide (GTK_WIDGET (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
+
+	destroy_8021x_dialog (info, NULL);
 }
 
 static gboolean
 nm_8021x_get_secrets (NMDevice *device,
 					  NMConnection *connection,
-					  const char *specific_object,
+					  NMActiveConnection *active_connection,
 					  const char *setting_name,
 					  DBusGMethodInvocation *context,
 					  NMApplet *applet,
 					  GError **error)
 {
 	GtkWidget *dialog;
+	NM8021xInfo *info;
 
 	dialog = nma_wired_dialog_new (applet->glade_file,
 								   applet->nm_client,
@@ -673,14 +707,18 @@
 		return FALSE;
 	}
 
-	g_object_set_data (G_OBJECT (dialog), "dbus-context", context);
-	g_object_set_data_full (G_OBJECT (dialog),
-	                        "setting-name", g_strdup (setting_name),
-	                        (GDestroyNotify) g_free);
-
-	g_signal_connect (dialog, "response",
-	                  G_CALLBACK (get_8021x_secrets_cb),
-	                  applet);
+	info = g_malloc0 (sizeof (NM8021xInfo));
+	info->context = context;
+	info->applet = applet;
+	info->active_connection = active_connection;
+	info->dialog = dialog;
+
+	g_signal_connect (dialog, "response", G_CALLBACK (get_8021x_secrets_cb), info);
+
+	/* Attach a destroy notifier to the NMActiveConnection so we can destroy
+	 * the dialog when the active connection goes away.
+	 */
+	g_object_weak_ref (G_OBJECT (active_connection), destroy_8021x_dialog, info);
 
 	gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS);
 	gtk_widget_realize (dialog);
@@ -692,7 +730,7 @@
 static gboolean
 wired_get_secrets (NMDevice *device,
 				   NMConnection *connection,
-				   const char *specific_object,
+				   NMActiveConnection *active_connection,
 				   const char *setting_name,
 				   const char **hints,
 				   DBusGMethodInvocation *context,
@@ -713,9 +751,9 @@
 
 	connection_type = nm_setting_connection_get_connection_type (s_con);
 	if (!strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)) {
-		success = nm_8021x_get_secrets (device, connection, specific_object, setting_name, context, applet, error);
+		success = nm_8021x_get_secrets (device, connection, active_connection, setting_name, context, applet, error);
 	} else if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
-		success = pppoe_get_secrets (device, connection, specific_object, setting_name, context, applet, error);
+		success = pppoe_get_secrets (device, connection, active_connection, setting_name, context, applet, error);
 
 	return success;
 }

Modified: trunk/src/applet.c
==============================================================================
--- trunk/src/applet.c	(original)
+++ trunk/src/applet.c	Sun Nov  2 22:51:04 2008
@@ -1787,13 +1787,15 @@
 static NMDevice *
 find_active_device (NMAGConfConnection *exported,
                     NMApplet *applet,
-                    const char **out_specific_object)
+                    NMActiveConnection **out_active_connection)
 {
 	const GPtrArray *active_connections;
 	int i;
 
 	g_return_val_if_fail (exported != NULL, NULL);
 	g_return_val_if_fail (applet != NULL, NULL);
+	g_return_val_if_fail (out_active_connection != NULL, NULL);
+	g_return_val_if_fail (*out_active_connection == NULL, NULL);
 
 	/* Look through the active connection list trying to find the D-Bus
 	 * object path of applet_connection.
@@ -1804,7 +1806,6 @@
 		NMConnection *connection;
 		const char *service_name;
 		const char *connection_path;
-		const char *specific_object;
 		const GPtrArray *devices;
 
 		active = NM_ACTIVE_CONNECTION (g_ptr_array_index (active_connections, i));
@@ -1813,12 +1814,12 @@
 			continue;
 
 		connection_path = nm_active_connection_get_connection (active);
-		specific_object = nm_active_connection_get_specific_object (active);
 
 		connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (exported));
 		if (!strcmp (connection_path, nm_connection_get_path (connection))) {
 			devices = nm_active_connection_get_devices (active);
-			*out_specific_object = specific_object;
+			if (devices)
+				*out_active_connection = active;
 			return devices ? NM_DEVICE (g_ptr_array_index (devices, 0)) : NULL;
 		}
 	}
@@ -1836,12 +1837,12 @@
                                           gpointer user_data)
 {
 	NMApplet *applet = NM_APPLET (user_data);
+	NMActiveConnection *active_connection = NULL;
 	NMConnection *connection;
 	NMSettingConnection *s_con;
 	NMDevice *device;
 	NMADeviceClass *dclass;
 	GError *error = NULL;
-	const char *specific_object = NULL;
 
 	connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (exported));
 	g_return_if_fail (connection != NULL);
@@ -1856,8 +1857,8 @@
 	}
 
 	/* Find the active device for this connection */
-	device = find_active_device (exported, applet, &specific_object);
-	if (!device) {
+	device = find_active_device (exported, applet, &active_connection);
+	if (!device || !active_connection) {
 		g_set_error (&error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d (%s): couldn't find details for connection",
 		             __FILE__, __LINE__, __func__);
@@ -1880,7 +1881,7 @@
 	}
 
 	/* Let the device class handle secrets */
-	if (!dclass->get_secrets (device, connection, specific_object, setting_name,
+	if (!dclass->get_secrets (device, connection, active_connection, setting_name,
 	                          hints, context, applet, &error))
 		goto error;
 

Modified: trunk/src/applet.h
==============================================================================
--- trunk/src/applet.h	(original)
+++ trunk/src/applet.h	Sun Nov  2 22:51:04 2008
@@ -175,7 +175,7 @@
 
 	gboolean       (*get_secrets)          (NMDevice *device,
 	                                        NMConnection *connection,
-	                                        const char *specific_object,
+	                                        NMActiveConnection *active_connection,
 	                                        const char *setting_name,
 	                                        const char **hints,
 	                                        DBusGMethodInvocation *context,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]