diff options
author | Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk> | 2011-07-08 19:46:33 +0800 |
---|---|---|
committer | Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk> | 2011-09-08 19:26:25 +0800 |
commit | d5136f90339362d53d780700808dc055fc0a7121 (patch) | |
tree | 32ec6c397399c8d22bee88ffd1f1474cbbc1ceff | |
parent | 44731ebba06458462f5c26fed8fd0abab30e7450 (diff) | |
download | gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar.gz gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar.bz2 gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar.lz gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar.xz gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.tar.zst gsoc2013-empathy-d5136f90339362d53d780700808dc055fc0a7121.zip |
Reuse Call windows when possible
If we have a call window opened for a contact and we get an
incoming call from the same person, use the existing window
instead of creating another one.
Based on a patch from Jonathan Tellier.
https://bugzilla.gnome.org/show_bug.cgi?id=580794
-rw-r--r-- | src/empathy-call-window.c | 47 | ||||
-rw-r--r-- | src/empathy-call-window.h | 6 | ||||
-rw-r--r-- | src/empathy-call.c | 43 |
3 files changed, 78 insertions, 18 deletions
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index ccec9f628..af06b6251 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -293,6 +293,8 @@ static gboolean empathy_call_window_video_output_motion_notify ( static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window, guint button); +static void empathy_call_window_connect_handler (EmpathyCallWindow *self); + static void empathy_call_window_dialpad_cb (GtkToggleToolButton *button, EmpathyCallWindow *window); @@ -2199,6 +2201,20 @@ empathy_call_window_new (EmpathyCallHandler *handler) g_object_new (EMPATHY_TYPE_CALL_WINDOW, "handler", handler, NULL)); } +void +empathy_call_window_present (EmpathyCallWindow *self, + EmpathyCallHandler *handler) +{ + g_return_if_fail (EMPATHY_IS_CALL_HANDLER (handler)); + + tp_clear_object (&self->priv->handler); + self->priv->handler = g_object_ref (handler); + empathy_call_window_connect_handler (self); + + empathy_window_present (GTK_WINDOW (self)); + empathy_call_window_restart_call (self); +} + static void empathy_call_window_conference_added_cb (EmpathyCallHandler *handler, GstElement *conference, gpointer user_data) @@ -3272,9 +3288,9 @@ call_handler_notify_call_cb (EmpathyCallHandler *handler, } static void -empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) +empathy_call_window_connect_handler (EmpathyCallWindow *self) { - EmpathyCallWindowPriv *priv = GET_PRIV (window); + EmpathyCallWindowPriv *priv = GET_PRIV (self); TpyCallChannel *call; gint width; @@ -3283,24 +3299,24 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) gtk_widget_set_size_request (priv->hangup_button, width * 2, -1); g_signal_connect (priv->handler, "state-changed", - G_CALLBACK (empathy_call_window_state_changed_cb), window); + G_CALLBACK (empathy_call_window_state_changed_cb), self); g_signal_connect (priv->handler, "conference-added", - G_CALLBACK (empathy_call_window_conference_added_cb), window); + G_CALLBACK (empathy_call_window_conference_added_cb), self); g_signal_connect (priv->handler, "conference-removed", - G_CALLBACK (empathy_call_window_conference_removed_cb), window); + G_CALLBACK (empathy_call_window_conference_removed_cb), self); g_signal_connect (priv->handler, "closed", - G_CALLBACK (empathy_call_window_channel_closed_cb), window); + G_CALLBACK (empathy_call_window_channel_closed_cb), self); g_signal_connect (priv->handler, "src-pad-added", - G_CALLBACK (empathy_call_window_src_added_cb), window); + G_CALLBACK (empathy_call_window_src_added_cb), self); g_signal_connect (priv->handler, "sink-pad-added", - G_CALLBACK (empathy_call_window_sink_added_cb), window); + G_CALLBACK (empathy_call_window_sink_added_cb), self); g_signal_connect (priv->handler, "sink-pad-removed", - G_CALLBACK (empathy_call_window_sink_removed_cb), window); + G_CALLBACK (empathy_call_window_sink_removed_cb), self); g_object_get (priv->handler, "call-channel", &call, NULL); if (call != NULL) { - call_handler_notify_call_cb (priv->handler, NULL, window); + call_handler_notify_call_cb (priv->handler, NULL, self); g_object_unref (call); } else @@ -3308,10 +3324,17 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) /* call-channel doesn't exist yet, we'll connect signals once it has been * set */ g_signal_connect (priv->handler, "notify::call-channel", - G_CALLBACK (call_handler_notify_call_cb), window); + G_CALLBACK (call_handler_notify_call_cb), self); } +} + +static void +empathy_call_window_realized_cb (GtkWidget *widget, + EmpathyCallWindow *self) +{ + empathy_call_window_connect_handler (self); - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); + gst_element_set_state (self->priv->pipeline, GST_STATE_PAUSED); } static gboolean diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h index eebb55f69..81cf170ae 100644 --- a/src/empathy-call-window.h +++ b/src/empathy-call-window.h @@ -63,6 +63,12 @@ GType empathy_call_window_get_type (void); EmpathyCallWindowClass)) EmpathyCallWindow *empathy_call_window_new (EmpathyCallHandler *handler); +void empathy_call_window_present (EmpathyCallWindow *window, + EmpathyCallHandler *handler); +void empathy_call_window_start_ringing (EmpathyCallWindow *self, + TpyCallChannel *channel, + TpChannelDispatchOperation *dispatch_operation, + TpAddDispatchOperationContext *context); GtkUIManager *empathy_call_window_get_ui_manager (EmpathyCallWindow *window); diff --git a/src/empathy-call.c b/src/empathy-call.c index 1f60217db..a5e463ba3 100644 --- a/src/empathy-call.c +++ b/src/empathy-call.c @@ -34,6 +34,8 @@ #include <telepathy-yell/telepathy-yell.h> +#include <libempathy/empathy-client-factory.h> + #include <libempathy-gtk/empathy-ui-utils.h> #include "empathy-call-window.h" @@ -55,6 +57,19 @@ static gboolean use_timer = TRUE; static EmpathyCallFactory *call_factory = NULL; +/* An EmpathyContact -> EmpathyCallWindow hash table for all existing + * Call windows. We own a ref on the EmpathyContacts. */ +static GHashTable *call_windows; + +static void +call_window_destroyed_cb (GtkWidget *window, + EmpathyContact *contact) +{ + g_hash_table_remove (call_windows, contact); + + g_application_release (G_APPLICATION (app)); +} + static void new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler, @@ -62,17 +77,29 @@ new_call_handler_cb (EmpathyCallFactory *factory, gpointer user_data) { EmpathyCallWindow *window; + EmpathyContact *contact; - DEBUG ("Create a new call window"); + DEBUG ("Show the call window"); - window = empathy_call_window_new (handler); + g_object_get (handler, "target-contact", &contact, NULL); - g_application_hold (G_APPLICATION (app)); + window = g_hash_table_lookup (call_windows, contact); + + if (window != NULL) + { + empathy_call_window_present (window, handler); + } + else + { + window = empathy_call_window_new (handler); - g_signal_connect_swapped (window, "destroy", - G_CALLBACK (g_application_release), app); + g_hash_table_insert (call_windows, g_object_ref (contact), window); + g_application_hold (G_APPLICATION (app)); + g_signal_connect (window, "destroy", + G_CALLBACK (call_window_destroyed_cb), contact); - gtk_widget_show (GTK_WIDGET (window)); + gtk_widget_show (GTK_WIDGET (window)); + } } static void @@ -172,6 +199,9 @@ main (int argc, use_timer = FALSE; } + call_windows = g_hash_table_new_full (g_direct_hash, g_direct_equal, + g_object_unref, NULL); + /* the inactivity timeout can only be set while the application is held */ g_application_hold (G_APPLICATION (app)); g_application_set_inactivity_timeout (G_APPLICATION (app), TIMEOUT * 1000); @@ -179,6 +209,7 @@ main (int argc, retval = g_application_run (G_APPLICATION (app), argc, argv); + g_hash_table_unref (call_windows); g_object_unref (app); tp_clear_object (&call_factory); |