aboutsummaryrefslogtreecommitdiffstats
path: root/src/empathy.c
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@src.gnome.org>2008-03-09 00:18:53 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2008-03-09 00:18:53 +0800
commit02a7ab821520e0f33474e10415c488cdc44bb59d (patch)
tree59582912a27c7ff4eba0224762ad577cdfdb787c /src/empathy.c
parentfa4c1507e3e605dd000e7b92be06aae73498d8ee (diff)
downloadgsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar.gz
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar.bz2
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar.lz
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar.xz
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.tar.zst
gsoc2013-empathy-02a7ab821520e0f33474e10415c488cdc44bb59d.zip
Do not run multiple instances of empathy. Fixes bug #501805 (Marco Barisione).
svn path=/trunk/; revision=711
Diffstat (limited to 'src/empathy.c')
-rw-r--r--src/empathy.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/empathy.c b/src/empathy.c
index e16aaf165..863d307f2 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -23,10 +23,12 @@
#include <config.h>
#include <stdlib.h>
+#include <errno.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
#include <libebook/e-book.h>
#include <libgnomevfs/gnome-vfs.h>
@@ -45,8 +47,12 @@
#include <libempathy-gtk/empathy-main-window.h>
#include <libempathy-gtk/empathy-status-icon.h>
+#include "bacon-message-connection.h"
+
#define DEBUG_DOMAIN "EmpathyMain"
+static BaconMessageConnection *connection = NULL;
+
static void
service_ended_cb (MissionControl *mc,
gpointer user_data)
@@ -184,9 +190,87 @@ create_salut_account (void)
g_object_unref (book);
}
+/* The code that handles single-instance and startup notification is
+ * copied from gedit.
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ */
+static void
+on_bacon_message_received (const char *message,
+ gpointer data)
+{
+ GtkWidget *window = data;
+ guint32 startup_timestamp;
+
+ g_return_if_fail (message != NULL);
+
+ empathy_debug (DEBUG_DOMAIN,
+ "Other instance launched, presenting the main window "
+ "(message is '%s')", message);
+
+ startup_timestamp = atoi (message);
+
+ /* Set the proper interaction time on the window.
+ * Fall back to roundtripping to the X server when we
+ * don't have the timestamp, e.g. when launched from
+ * terminal. We also need to make sure that the window
+ * has been realized otherwise it will not work. lame. */
+ if (startup_timestamp == 0) {
+ /* Work if launched from the terminal */
+ empathy_debug (DEBUG_DOMAIN, "Using X server timestamp as a fallback");
+
+ if (!GTK_WIDGET_REALIZED (window)) {
+ gtk_widget_realize (GTK_WIDGET (window));
+ }
+
+ startup_timestamp = gdk_x11_get_server_time (window->window);
+ }
+
+ gtk_window_present_with_time (GTK_WINDOW (window), startup_timestamp);
+}
+
+static guint32
+get_startup_timestamp ()
+{
+ const gchar *startup_id_env;
+ gchar *startup_id = NULL;
+ gchar *time_str;
+ gchar *end;
+ gulong retval = 0;
+
+ /* we don't unset the env, since startup-notification
+ * may still need it */
+ startup_id_env = g_getenv ("DESKTOP_STARTUP_ID");
+ if (startup_id_env == NULL) {
+ goto out;
+ }
+
+ startup_id = g_strdup (startup_id_env);
+
+ time_str = g_strrstr (startup_id, "_TIME");
+ if (time_str == NULL) {
+ goto out;
+ }
+
+ errno = 0;
+
+ /* Skip past the "_TIME" part */
+ time_str += 5;
+
+ retval = strtoul (time_str, &end, 0);
+ if (end == time_str || errno != 0)
+ retval = 0;
+
+ out:
+ g_free (startup_id);
+
+ return (retval > 0) ? retval : 0;
+}
+
int
main (int argc, char *argv[])
{
+ guint32 startup_timestamp;
EmpathyStatusIcon *icon;
GtkWidget *window;
MissionControl *mc;
@@ -201,6 +285,8 @@ main (int argc, char *argv[])
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
+ startup_timestamp = get_startup_timestamp ();
+
if (!gtk_init_with_args (&argc, &argv,
_("- Empathy Instant Messenger"),
NULL, GETTEXT_PACKAGE, &error)) {
@@ -215,6 +301,31 @@ main (int argc, char *argv[])
PKGDATADIR G_DIR_SEPARATOR_S "icons");
gnome_vfs_init ();
+ /* Setting up the bacon connection */
+ connection = bacon_message_connection_new ("empathy");
+ if (connection != NULL) {
+ if (!bacon_message_connection_get_is_server (connection)) {
+ gchar *message;
+
+ empathy_debug (DEBUG_DOMAIN, "Activating existing instance");
+
+ message = g_strdup_printf ("%" G_GUINT32_FORMAT,
+ startup_timestamp);
+ bacon_message_connection_send (connection, message);
+
+ /* We never popup a window, so tell startup-notification
+ * that we are done. */
+ gdk_notify_startup_complete ();
+
+ g_free (message);
+ bacon_message_connection_free (connection);
+
+ return EXIT_SUCCESS;
+ }
+ } else {
+ g_warning ("Cannot create the 'empathy' bacon connection.");
+ }
+
/* Setting up MC */
monitor = mc_account_monitor_new ();
mc = empathy_mission_control_new ();
@@ -243,6 +354,13 @@ main (int argc, char *argv[])
window = empathy_main_window_show ();
icon = empathy_status_icon_new (GTK_WINDOW (window));
+ if (connection) {
+ /* We se the callback here because we need window */
+ bacon_message_connection_set_callback (connection,
+ on_bacon_message_received,
+ window);
+ }
+
gtk_main ();
empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);