Index: libgossip/gossip-protocol.c
===================================================================
RCS file: /cvs/gnome/gossip/libgossip/gossip-protocol.c,v
retrieving revision 1.27
diff -u -p -r1.27 gossip-protocol.c
--- libgossip/gossip-protocol.c	29 Jun 2006 14:12:55 -0000	1.27
+++ libgossip/gossip-protocol.c	3 Sep 2006 23:07:17 -0000
@@ -105,9 +105,9 @@ gossip_protocol_class_init (GossipProtoc
 			      G_SIGNAL_RUN_LAST,
 			      0,
 			      NULL, NULL,
-			      libgossip_marshal_VOID__OBJECT,
+			      libgossip_marshal_VOID__OBJECT_INT,
 			      G_TYPE_NONE, 
-			      1, GOSSIP_TYPE_ACCOUNT);
+			      2, GOSSIP_TYPE_ACCOUNT, G_TYPE_INT);
 
 	signals[NEW_MESSAGE] = 
 		g_signal_new ("new-message",
Index: libgossip/gossip-session.c
===================================================================
RCS file: /cvs/gnome/gossip/libgossip/gossip-session.c,v
retrieving revision 1.71
diff -u -p -r1.71 gossip-session.c
--- libgossip/gossip-session.c	26 Jul 2006 13:53:15 -0000	1.71
+++ libgossip/gossip-session.c	3 Sep 2006 23:07:18 -0000
@@ -86,6 +86,7 @@ static void            session_protocol_
 								  GossipSession        *session);
 static void            session_protocol_logged_out               (GossipProtocol       *protocol,
 								  GossipAccount        *account,
+								  gint                  reason,
 								  GossipSession        *session);
 static void            session_protocol_new_message              (GossipProtocol       *protocol,
 								  GossipMessage        *message,
@@ -224,9 +225,9 @@ gossip_session_class_init (GossipSession
 			      G_SIGNAL_RUN_LAST,
 			      0,
 			      NULL, NULL,
-			      libgossip_marshal_VOID__OBJECT_OBJECT,
+			      libgossip_marshal_VOID__OBJECT_OBJECT_INT,
 			      G_TYPE_NONE, 
-			      2, GOSSIP_TYPE_ACCOUNT, GOSSIP_TYPE_PROTOCOL);
+			      3, GOSSIP_TYPE_ACCOUNT, GOSSIP_TYPE_PROTOCOL, G_TYPE_INT);
 
 	signals[PROTOCOL_DISCONNECTING] = 
 		g_signal_new ("protocol-disconnecting",
@@ -454,6 +455,7 @@ session_protocol_logged_in (GossipProtoc
 static void
 session_protocol_logged_out (GossipProtocol *protocol, 
 			     GossipAccount  *account,
+			     gint            reason,
 			     GossipSession  *session) 
 {
 	GossipSessionPriv *priv;
@@ -483,8 +485,9 @@ session_protocol_logged_out (GossipProto
 		priv->connecting_counter--;
 	}
 
-	g_signal_emit (session, signals[PROTOCOL_DISCONNECTED], 0, account, protocol);
-	
+	g_signal_emit (session, signals[PROTOCOL_DISCONNECTED], 0,
+		       account, protocol, reason);
+
 	if (priv->connected_counter == 0) {
 		/* Last connected protocol was disconnected */
 		g_signal_emit (session, signals[DISCONNECTED], 0);
Index: libgossip/gossip-session.h
===================================================================
RCS file: /cvs/gnome/gossip/libgossip/gossip-session.h,v
retrieving revision 1.30
diff -u -p -r1.30 gossip-session.h
--- libgossip/gossip-session.h	26 Jul 2006 13:53:15 -0000	1.30
+++ libgossip/gossip-session.h	3 Sep 2006 23:07:18 -0000
@@ -34,6 +34,11 @@
 #include "gossip-protocol.h"
 #include "gossip-vcard.h"
 
+typedef enum {
+	GOSSIP_DISCONNECT_ASKED,
+	GOSSIP_DISCONNECT_ERROR
+} GossipDisconnectReason;
+
 #define GOSSIP_TYPE_SESSION         (gossip_session_get_type ())
 #define GOSSIP_SESSION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_SESSION, GossipSession))
 #define GOSSIP_SESSION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GOSSIP_TYPE_SESSION, GossipSessionClass))
Index: libgossip/libgossip-marshal.list
===================================================================
RCS file: /cvs/gnome/gossip/libgossip/libgossip-marshal.list,v
retrieving revision 1.7
diff -u -p -r1.7 libgossip-marshal.list
--- libgossip/libgossip-marshal.list	2 Jun 2006 18:32:51 -0000	1.7
+++ libgossip/libgossip-marshal.list	3 Sep 2006 23:07:18 -0000
@@ -8,5 +8,6 @@ VOID:OBJECT,OBJECT
 VOID:OBJECT,OBJECT,POINTER
 VOID:OBJECT,BOOLEAN
 VOID:OBJECT,POINTER
+VOID:OBJECT,INT
 VOID:OBJECT,OBJECT,INT
 STRING:OBJECT
Index: protocols/jabber/gossip-jabber-chatrooms.c
===================================================================
RCS file: /cvs/gnome/gossip/protocols/jabber/gossip-jabber-chatrooms.c,v
retrieving revision 1.50
diff -u -p -r1.50 gossip-jabber-chatrooms.c
--- protocols/jabber/gossip-jabber-chatrooms.c	18 Jul 2006 17:15:25 -0000	1.50
+++ protocols/jabber/gossip-jabber-chatrooms.c	3 Sep 2006 23:07:19 -0000
@@ -67,6 +67,7 @@ typedef struct {
 
 static void             jabber_chatrooms_logged_out_cb         (GossipProtocol         *jabber,
 								GossipAccount          *account,
+								gint                    reason,
 								GossipJabberChatrooms  *chatrooms);
 static JabberChatroom * jabber_chatrooms_chatroom_new          (GossipJabberChatrooms  *chatrooms,
 								GossipChatroom         *chatroom);
@@ -175,6 +176,7 @@ gossip_jabber_chatrooms_finalize (Gossip
 static void
 jabber_chatrooms_logged_out_cb (GossipProtocol        *jabber,
 				GossipAccount         *account,
+				gint                   reason,
 				GossipJabberChatrooms *chatrooms)
 {
 	GList *rooms;
Index: protocols/jabber/gossip-jabber.c
===================================================================
RCS file: /cvs/gnome/gossip/protocols/jabber/gossip-jabber.c,v
retrieving revision 1.104
diff -u -p -r1.104 gossip-jabber.c
--- protocols/jabber/gossip-jabber.c	24 Aug 2006 23:57:03 -0000	1.104
+++ protocols/jabber/gossip-jabber.c	3 Sep 2006 23:07:23 -0000
@@ -30,6 +30,7 @@
 #include <libgossip/gossip-vcard.h>
 #include <libgossip/gossip-chatroom-provider.h>
 #include <libgossip/gossip-ft-provider.h>
+#include <libgossip/gossip-session.h>
 
 #include "gossip-jid.h"
 #include "gossip-jabber-chatrooms.h"
@@ -67,7 +68,10 @@
  * the user has stopped composing.
  */
 #define COMPOSING_TIMEOUT          45
- 
+
+/* How many rand char should be happend to the resource */
+#define N_RAND_CHAR                6
+
 struct _GossipJabberPriv {
 	LmConnection          *connection;
 	
@@ -738,6 +742,9 @@ jabber_connection_open_cb (LmConnection 
 	gchar            *id;
 	const gchar      *resource;
 	gchar            *password = NULL;
+	gchar            *resource_rand;
+	gchar             rand_str[N_RAND_CHAR + 1];
+	gint              i;
 	
 	priv = GET_PRIV (jabber);
 
@@ -798,13 +805,25 @@ jabber_connection_open_cb (LmConnection 
 		return;
 	}
 
+	/* appens a random string to the resource to avoid conflicts */
+	for (i = 0; i < N_RAND_CHAR; i++) {
+		if (g_random_boolean()) {
+			rand_str[i] = g_random_int_range('A', 'Z' + 1);
+		} else {
+			rand_str[i] = g_random_int_range('0', '9' + 1);
+		}
+	}
+	rand_str[N_RAND_CHAR] = '\0';
+	resource_rand = g_strdup_printf ("%s.%s", resource, rand_str);
+
 	lm_connection_authenticate (priv->connection,
 				    id,
 				    password, 
-				    resource,
+				    resource_rand,
 				    (LmResultFunction) jabber_connection_auth_cb,
 				    jabber, NULL, NULL);
 
+	g_free (resource_rand);
 	g_free (id);
 	g_free (password);
 }
@@ -885,7 +904,8 @@ jabber_disconnect_cb (LmConnection      
 		      LmDisconnectReason  reason,
 		      GossipJabber       *jabber)
 {
-	GossipJabberPriv *priv;
+	GossipJabberPriv       *priv;
+	GossipDisconnectReason  gossip_reason;
 
 	priv = GET_PRIV (jabber);
 
@@ -900,8 +920,22 @@ jabber_disconnect_cb (LmConnection      
 					     (GHRFunc) jabber_logout_contact_foreach,
 					     jabber);
 	}
-
-	g_signal_emit_by_name (jabber, "logged-out", priv->account);
+	
+	switch (reason) {
+	case LM_DISCONNECT_REASON_OK:
+		gossip_reason = GOSSIP_DISCONNECT_ASKED;
+		break;
+	case LM_DISCONNECT_REASON_PING_TIME_OUT:
+	case LM_DISCONNECT_REASON_HUP:
+	case LM_DISCONNECT_REASON_ERROR:
+	case LM_DISCONNECT_REASON_UNKNOWN:
+		gossip_reason = GOSSIP_DISCONNECT_ERROR;
+		break;
+	default:
+		g_assert_not_reached();
+	}
+	
+	g_signal_emit_by_name (jabber, "logged-out", priv->account, gossip_reason);
 }
 
 static LmSSLResponse 
Index: src/gossip-account-button.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-account-button.c,v
retrieving revision 1.24
diff -u -p -r1.24 gossip-account-button.c
--- src/gossip-account-button.c	5 Jul 2006 21:58:10 -0000	1.24
+++ src/gossip-account-button.c	3 Sep 2006 23:07:24 -0000
@@ -89,6 +89,7 @@ static void       account_button_protoco
 static void       account_button_protocol_disconnected_cb  (GossipSession       *session,
 							    GossipAccount       *account,
 							    GossipProtocol      *protocol,
+							    gint                 reason,
 							    GossipAccountButton *account_button);
 static void       account_button_protocol_error_cb         (GossipSession       *session,
 							    GossipProtocol      *protocol,
@@ -583,6 +584,7 @@ static void
 account_button_protocol_disconnected_cb (GossipSession       *session,
 					 GossipAccount       *account,
 					 GossipProtocol      *protocol,
+					 gint                 reason,
 					 GossipAccountButton *account_button)
 {
 	GossipAccountButtonPriv *priv;
Index: src/gossip-account-chooser.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-account-chooser.c,v
retrieving revision 1.6
diff -u -p -r1.6 gossip-account-chooser.c
--- src/gossip-account-chooser.c	25 Mar 2006 20:41:40 -0000	1.6
+++ src/gossip-account-chooser.c	3 Sep 2006 23:07:24 -0000
@@ -83,6 +83,7 @@ static void     account_chooser_protocol
 static void     account_chooser_protocol_disconnected_cb (GossipSession         *session,
 							  GossipAccount         *account,
 							  GossipProtocol        *protocol,
+							  gint                   reason,
 							  GossipAccountChooser  *account_chooser);
 static gboolean account_chooser_set_account_foreach      (GtkTreeModel          *model,
 							  GtkTreePath           *path,
@@ -406,6 +407,7 @@ static void
 account_chooser_protocol_disconnected_cb (GossipSession        *session,
 					  GossipAccount        *account,
 					  GossipProtocol       *protocol,
+					  gint                  reason,
 					  GossipAccountChooser *account_chooser)
 {
 	GtkComboBox           *combobox;
Index: src/gossip-accounts-dialog.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-accounts-dialog.c,v
retrieving revision 1.40
diff -u -p -r1.40 gossip-accounts-dialog.c
--- src/gossip-accounts-dialog.c	26 Jul 2006 13:39:22 -0000	1.40
+++ src/gossip-accounts-dialog.c	3 Sep 2006 23:07:26 -0000
@@ -123,6 +123,7 @@ static void           accounts_dialog_pr
 static void           accounts_dialog_protocol_disconnected_cb  (GossipSession         *session,
 								 GossipAccount         *account,
 								 GossipProtocol        *protocol,
+								 gint                   reason,
 								 GossipAccountsDialog  *dialog);
 static void           accounts_dialog_entry_changed_cb          (GtkWidget             *widget,
 								 GossipAccountsDialog  *dialog);
@@ -1203,6 +1204,7 @@ static void
 accounts_dialog_protocol_disconnected_cb (GossipSession        *session,
 					  GossipAccount        *account,
 					  GossipProtocol       *protocol,
+					  gint                  reason,
 					  GossipAccountsDialog *dialog)
 {
 	GtkTreeView      *view;
Index: src/gossip-app.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-app.c,v
retrieving revision 1.279
diff -u -p -r1.279 gossip-app.c
--- src/gossip-app.c	3 Sep 2006 21:28:15 -0000	1.279
+++ src/gossip-app.c	3 Sep 2006 23:07:29 -0000
@@ -117,6 +117,9 @@
 /* Accels (menu shortcuts) can be configured and saved */
 #define ACCELS_FILENAME "accels.txt"
 
+/* Delay for retry to connect when disconnected (seconds) */
+#define RETRY_CONNECT_TIMEOUT 10
+
 struct _GossipAppPriv {
 	GossipSession         *session;
 
@@ -178,6 +181,7 @@ struct _GossipAppPriv {
 	
 	/* Misc */
 	guint                  size_timeout_id;
+	guint                  retry_connect_id;
 };
 
 static void            gossip_app_class_init                  (GossipAppClass           *klass);
@@ -260,9 +264,11 @@ static void            app_session_proto
 							       GossipAccount            *account,
 							       GossipProtocol           *protocol,
 							       gpointer                  user_data);
+static gboolean        app_retry_connect_cb                   (gpointer                  data);
 static void            app_session_protocol_disconnected_cb   (GossipSession            *session,
 							       GossipAccount            *account,
 							       GossipProtocol           *protocol,
+							       gint                      reason,
 							       gpointer                  user_data);
 static void            app_session_protocol_error_cb          (GossipSession            *session,
 							       GossipProtocol           *protocol,
@@ -388,6 +394,10 @@ app_finalize (GObject *object)
 		g_source_remove (priv->size_timeout_id);
 	}
 
+	if (priv->retry_connect_id) {
+		g_source_remove (priv->retry_connect_id);
+	}
+
 	if (priv->tray_flash_timeout_id) {
 		g_source_remove (priv->tray_flash_timeout_id);
 	}
@@ -1470,16 +1480,31 @@ app_session_protocol_connected_cb (Gossi
 				 gossip_status_presets_get_default_status());
 
 	app_presence_updated ();
+	
+	if (priv->retry_connect_id) {
+		g_source_remove (priv->retry_connect_id);
+		priv->retry_connect_id = 0;
+	}
+}
+
+static gboolean
+app_retry_connect_cb (gpointer data)
+{
+	gossip_app_connect (NULL, TRUE);
+	return TRUE;
 }
 
 static void
 app_session_protocol_disconnected_cb (GossipSession  *session,
 				      GossipAccount  *account,
 				      GossipProtocol *protocol,
+				      gint            reason,
 				      gpointer        user_data)
 {
 	GossipAppPriv *priv;
 	gboolean       connecting;
+	gboolean       should_reconnect;
+	gboolean       nm_connected;
 
 	priv = GET_PRIV (app);
 
@@ -1498,6 +1523,23 @@ app_session_protocol_disconnected_cb (Go
  	app_connection_items_update ();
 	app_favorite_chatroom_menu_update ();
 	app_presence_updated ();
+
+	should_reconnect = reason != GOSSIP_DISCONNECT_ASKED;
+
+#ifdef HAVE_DBUS
+	/* If NM says we are offline that's useless to retry to connect,
+	 * NM will tell us when network is up again. */
+	if (gossip_dbus_nm_get_state (&nm_connected)) {
+		should_reconnect &= nm_connected;
+	}
+#endif
+
+	if (should_reconnect) {
+		/* unexpected disconnection, try to reconnect */
+		priv->retry_connect_id = g_timeout_add (RETRY_CONNECT_TIMEOUT * 1000,
+							app_retry_connect_cb,
+							NULL);
+	}
 }
 
 static void
Index: src/gossip-ft-window.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-ft-window.c,v
retrieving revision 1.13
diff -u -p -r1.13 gossip-ft-window.c
--- src/gossip-ft-window.c	27 Jul 2006 08:20:50 -0000	1.13
+++ src/gossip-ft-window.c	3 Sep 2006 23:07:30 -0000
@@ -54,6 +54,7 @@ static void ft_window_protocol_connected
 static void ft_window_protocol_disconnected_cb (GossipSession      *session,
 						GossipAccount      *account,
 						GossipProtocol     *protocol,
+						gint                reason,
 						gpointer            user_data);
 static void ft_window_request_cb               (GossipProtocol     *protocol,
 						GossipFT           *ft,
@@ -130,6 +131,7 @@ static void
 ft_window_protocol_disconnected_cb (GossipSession  *session,
 				    GossipAccount  *account,
 				    GossipProtocol *protocol,
+				    gint            reason,
 				    gpointer        user_data)
 {
  	g_signal_handlers_disconnect_by_func (protocol, 
Index: src/gossip-group-chat.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-group-chat.c,v
retrieving revision 1.76
diff -u -p -r1.76 gossip-group-chat.c
--- src/gossip-group-chat.c	16 Aug 2006 15:26:53 -0000	1.76
+++ src/gossip-group-chat.c	3 Sep 2006 23:07:31 -0000
@@ -97,6 +97,7 @@ static void            group_chat_protoc
 static void            group_chat_protocol_disconnected_cb    (GossipSession                *session,
 							       GossipAccount                *account,
 							       GossipProtocol               *protocol,
+							       gint                          reason,
 							       GossipGroupChat              *chat);
 static gboolean        group_chat_key_press_event_cb          (GtkWidget                    *widget,
 							       GdkEventKey                  *event,
@@ -362,6 +363,7 @@ static void
 group_chat_protocol_disconnected_cb (GossipSession   *session,
 				     GossipAccount   *account,
 				     GossipProtocol  *protocol,
+				     gint             reason,
 				     GossipGroupChat *chat)
 {
 	GossipGroupChatPriv *priv;
Index: src/gossip-notify.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-notify.c,v
retrieving revision 1.36
diff -u -p -r1.36 gossip-notify.c
--- src/gossip-notify.c	24 Aug 2006 23:57:02 -0000	1.36
+++ src/gossip-notify.c	3 Sep 2006 23:07:32 -0000
@@ -70,6 +70,7 @@ static void                notify_protoc
 static void                notify_protocol_disconnected_cb        (GossipSession      *session,
 								   GossipAccount      *account,
 								   GossipProtocol     *protocol,
+								   gint                reason,
 								   gpointer            user_data);
 static void                notify_contact_presence_updated_cb     (GossipSession      *session,
 								   GossipContact      *contact,
@@ -507,6 +508,7 @@ static void
 notify_protocol_disconnected_cb (GossipSession  *session,
 				 GossipAccount  *account,
 				 GossipProtocol *protocol,
+				 gint            reason,
 				 gpointer        user_data)
 {
 	g_hash_table_remove (account_states, account);
Index: src/gossip-private-chat.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-private-chat.c,v
retrieving revision 1.56
diff -u -p -r1.56 gossip-private-chat.c
--- src/gossip-private-chat.c	29 Jul 2006 12:15:59 -0000	1.56
+++ src/gossip-private-chat.c	3 Sep 2006 23:07:33 -0000
@@ -94,6 +94,7 @@ static void           private_chat_proto
 static void           private_chat_protocol_disconnected_cb     (GossipSession          *session,
 								 GossipAccount          *account,
 								 GossipProtocol         *protocol,
+								 gint                    reason,
 								 GossipPrivateChat      *chat);
 static void           private_chat_composing_cb                 (GossipSession          *session,
 								 GossipContact          *contact,
@@ -545,6 +546,7 @@ static void
 private_chat_protocol_disconnected_cb (GossipSession     *session,
 				       GossipAccount     *account,
 				       GossipProtocol    *protocol,
+				       gint               reason,
 				       GossipPrivateChat *chat)
 {
 	GossipPrivateChatPriv *priv;
Index: src/gossip-sound.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-sound.c,v
retrieving revision 1.26
diff -u -p -r1.26 gossip-sound.c
--- src/gossip-sound.c	21 Jul 2006 22:40:30 -0000	1.26
+++ src/gossip-sound.c	3 Sep 2006 23:07:34 -0000
@@ -97,6 +97,7 @@ static void
 sound_protocol_disconnected_cb (GossipSession  *session,
 				GossipAccount  *account,
 				GossipProtocol *protocol,
+				gint            reason,
 				gpointer        user_data)
 {
 	g_hash_table_remove (account_states, account);
Index: src/gossip-subscription-dialog.c
===================================================================
RCS file: /cvs/gnome/gossip/src/gossip-subscription-dialog.c,v
retrieving revision 1.17
diff -u -p -r1.17 gossip-subscription-dialog.c
--- src/gossip-subscription-dialog.c	3 Sep 2006 19:11:34 -0000	1.17
+++ src/gossip-subscription-dialog.c	3 Sep 2006 23:07:34 -0000
@@ -60,6 +60,7 @@ static void subscription_dialog_protocol
 static void subscription_dialog_protocol_disconnected_cb (GossipSession            *session,
 							  GossipAccount            *account,
 							  GossipProtocol           *protocol,
+							  gint                      reason,
 							  gpointer                  user_data);
 static void subscription_dialog_request_cb               (GossipProtocol           *protocol,
 							  GossipContact            *contact,
@@ -135,6 +136,7 @@ static void
 subscription_dialog_protocol_disconnected_cb (GossipSession  *session,
 					      GossipAccount  *account,
 					      GossipProtocol *protocol,
+					      gint            reason,
 					      gpointer        user_data)
 {
  	g_signal_handlers_disconnect_by_func (protocol, 
