diff options
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 6 | ||||
-rw-r--r-- | libempathy-gtk/empathy-contact-list-view.c | 3 | ||||
-rw-r--r-- | libempathy-gtk/empathy-contact-menu.c | 3 | ||||
-rw-r--r-- | libempathy-gtk/empathy-new-message-dialog.c | 3 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.c | 24 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.h | 4 | ||||
-rw-r--r-- | libempathy/empathy-call-handler.c | 5 | ||||
-rw-r--r-- | libempathy/empathy-call-handler.h | 3 | ||||
-rw-r--r-- | libempathy/empathy-dispatch-operation.c | 46 | ||||
-rw-r--r-- | libempathy/empathy-dispatch-operation.h | 14 | ||||
-rw-r--r-- | libempathy/empathy-dispatcher.c | 36 | ||||
-rw-r--r-- | libempathy/empathy-dispatcher.h | 22 | ||||
-rw-r--r-- | libempathy/empathy-ft-handler.c | 3 | ||||
-rw-r--r-- | libempathy/empathy-tp-chat.c | 2 | ||||
-rw-r--r-- | src/empathy-call-window.c | 3 | ||||
-rw-r--r-- | src/empathy-chat-manager.c | 5 | ||||
-rw-r--r-- | src/empathy-chat-window.c | 48 | ||||
-rw-r--r-- | src/empathy-chat-window.h | 3 | ||||
-rw-r--r-- | src/empathy-event-manager.c | 19 | ||||
-rw-r--r-- | src/empathy-main-window.c | 3 | ||||
-rw-r--r-- | src/empathy-new-chatroom-dialog.c | 3 | ||||
-rw-r--r-- | src/empathy.c | 9 | ||||
-rw-r--r-- | tests/interactive/empetit.c | 3 |
23 files changed, 207 insertions, 63 deletions
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index b06329a67..57cf62632 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -262,13 +262,13 @@ reconnected_connection_ready_cb (TpConnection *connection, switch (priv->handle_type) { case TP_HANDLE_TYPE_CONTACT: empathy_dispatcher_chat_with_contact_id ( - connection, priv->id, + connection, priv->id, EMPATHY_DISPATCHER_NON_USER_ACTION, chat_connect_channel_reconnected, chat); break; case TP_HANDLE_TYPE_ROOM: empathy_dispatcher_join_muc (connection, - priv->id, + priv->id, EMPATHY_DISPATCHER_NON_USER_ACTION, chat_connect_channel_reconnected, chat); break; @@ -743,6 +743,7 @@ chat_command_join (EmpathyChat *chat, connection = empathy_tp_chat_get_connection (priv->tp_chat); empathy_dispatcher_join_muc (connection, rooms[i], + gtk_get_current_event_time (), chat_command_join_cb, chat); } @@ -767,6 +768,7 @@ chat_command_msg_internal (EmpathyChat *chat, data->message = g_strdup (message); connection = empathy_tp_chat_get_connection (priv->tp_chat); empathy_dispatcher_chat_with_contact_id (connection, contact_id, + gtk_get_current_event_time (), chat_command_msg_cb, data); } diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c index 15df212ce..ae84e3e15 100644 --- a/libempathy-gtk/empathy-contact-list-view.c +++ b/libempathy-gtk/empathy-contact-list-view.c @@ -804,7 +804,8 @@ contact_list_view_row_activated (GtkTreeView *view, if (contact) { DEBUG ("Starting a chat"); - empathy_dispatcher_chat_with_contact (contact, NULL, NULL); + empathy_dispatcher_chat_with_contact (contact, + gtk_get_current_event_time (), NULL, NULL); g_object_unref (contact); } } diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c index fbcd8dc8a..e160f5e20 100644 --- a/libempathy-gtk/empathy-contact-menu.c +++ b/libempathy-gtk/empathy-contact-menu.c @@ -222,7 +222,8 @@ static void empathy_contact_chat_menu_item_activated (GtkMenuItem *item, EmpathyContact *contact) { - empathy_dispatcher_chat_with_contact (contact, NULL, NULL); + empathy_dispatcher_chat_with_contact (contact, gtk_get_current_event_time (), + NULL, NULL); } GtkWidget * diff --git a/libempathy-gtk/empathy-new-message-dialog.c b/libempathy-gtk/empathy-new-message-dialog.c index 338da2760..509438575 100644 --- a/libempathy-gtk/empathy-new-message-dialog.c +++ b/libempathy-gtk/empathy-new-message-dialog.c @@ -70,7 +70,8 @@ empathy_new_message_dialog_response (GtkDialog *dialog, int response_id) if (EMP_STR_EMPTY (contact_id) || connection == NULL) goto out; - empathy_dispatcher_chat_with_contact_id (connection, contact_id, NULL, NULL); + empathy_dispatcher_chat_with_contact_id (connection, contact_id, + gtk_get_current_event_time (), NULL, NULL); out: gtk_widget_destroy (GTK_WIDGET (dialog)); diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index 3f37ea2db..2f06ae902 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -1392,10 +1392,10 @@ empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon) /* Takes care of moving the window to the current workspace. */ void -empathy_window_present (GtkWindow *window) +empathy_window_present_with_time (GtkWindow *window, + guint32 timestamp) { GdkWindow *gdk_window; - guint32 timestamp; g_return_if_fail (GTK_IS_WINDOW (window)); @@ -1417,25 +1417,17 @@ empathy_window_present (GtkWindow *window) gtk_widget_hide (GTK_WIDGET (window)); } - timestamp = gtk_get_current_event_time (); - if (timestamp == 0 && gdk_window != NULL) { - GdkEventMask mask; - - /* According to the documentation of gdk_x11_get_server_time - * GDK_PROPERTY_CHANGE_MASK needs to be set in its events otherwise a hang - * can occur. Be sure to at least temporarily set this mask */ - mask = gdk_window_get_events (gdk_window); - gdk_window_set_events (gdk_window, - mask | GDK_PROPERTY_CHANGE_MASK); - timestamp = gdk_x11_get_server_time (gdk_window); - gdk_window_set_events (gdk_window, mask); - } - gtk_window_present_with_time (window, timestamp); gtk_window_set_skip_taskbar_hint (window, FALSE); gtk_window_deiconify (window); } +void +empathy_window_present (GtkWindow *window) +{ + empathy_window_present_with_time (window, GDK_CURRENT_TIME); +} + GtkWindow * empathy_get_toplevel_window (GtkWidget *widget) { diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h index 8834cb4c9..6dab13789 100644 --- a/libempathy-gtk/empathy-ui-utils.h +++ b/libempathy-gtk/empathy-ui-utils.h @@ -104,7 +104,9 @@ gboolean empathy_text_iter_backward_search (const GtkTextIter*iter, const GtkTextIter*limit); /* Windows */ gboolean empathy_window_get_is_visible (GtkWindow *window); -void empathy_window_present (GtkWindow *window); +void empathy_window_present (GtkWindow *window); +void empathy_window_present_with_time (GtkWindow *window, + guint32 timestamp); void empathy_window_iconify (GtkWindow *window, GtkStatusIcon *status_icon); GtkWindow * empathy_get_toplevel_window (GtkWidget *widget); diff --git a/libempathy/empathy-call-handler.c b/libempathy/empathy-call-handler.c index a49baed44..ec8b055c2 100644 --- a/libempathy/empathy-call-handler.c +++ b/libempathy/empathy-call-handler.c @@ -487,7 +487,8 @@ empathy_call_handler_request_cb (EmpathyDispatchOperation *operation, } void -empathy_call_handler_start_call (EmpathyCallHandler *handler) +empathy_call_handler_start_call (EmpathyCallHandler *handler, + gint64 timestamp) { EmpathyCallHandlerPriv *priv = GET_PRIV (handler); @@ -536,7 +537,7 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler) g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value); empathy_dispatcher_create_channel (dispatcher, connection, - request, empathy_call_handler_request_cb, handler); + request, timestamp, empathy_call_handler_request_cb, handler); g_object_unref (dispatcher); } diff --git a/libempathy/empathy-call-handler.h b/libempathy/empathy-call-handler.h index 1f67fe56b..f0be11ba5 100644 --- a/libempathy/empathy-call-handler.h +++ b/libempathy/empathy-call-handler.h @@ -70,7 +70,8 @@ EmpathyCallHandler * empathy_call_handler_new_for_contact_with_streams ( EmpathyCallHandler * empathy_call_handler_new_for_channel ( EmpathyTpCall *call); -void empathy_call_handler_start_call (EmpathyCallHandler *handler); +void empathy_call_handler_start_call (EmpathyCallHandler *handler, + gint64 timestamp); void empathy_call_handler_stop_call (EmpathyCallHandler *handler); gboolean empathy_call_handler_has_initial_video (EmpathyCallHandler *handler); diff --git a/libempathy/empathy-dispatch-operation.c b/libempathy/empathy-dispatch-operation.c index 6120f8e05..08013889e 100644 --- a/libempathy/empathy-dispatch-operation.c +++ b/libempathy/empathy-dispatch-operation.c @@ -70,6 +70,7 @@ enum { PROP_CONTACT, PROP_INCOMING, PROP_STATUS, + PROP_USER_ACTION_TIME, }; /* private structure */ @@ -85,6 +86,7 @@ struct _EmpathyDispatchOperationPriv EmpathyContact *contact; EmpathyDispatchOperationState status; gboolean incoming; + gint64 user_action_time; gboolean approved; gulong invalidated_handler; gulong ready_handler; @@ -132,6 +134,10 @@ empathy_dispatch_operation_set_property (GObject *object, case PROP_INCOMING: priv->incoming = g_value_get_boolean (value); break; + + case PROP_USER_ACTION_TIME: + priv->user_action_time = g_value_get_int64 (value); + break; } } @@ -162,6 +168,9 @@ empathy_dispatch_operation_get_property (GObject *object, case PROP_STATUS: g_value_set_enum (value, priv->status); break; + case PROP_USER_ACTION_TIME: + g_value_set_int64 (value, priv->user_action_time); + break; } } @@ -357,6 +366,13 @@ empathy_dispatch_operation_class_init ( EMPATHY_TYPE_DISPATCH_OPERATION_STATE, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_STATUS, param_spec); + + param_spec = g_param_spec_int64 ("user-action-time", + "user action time", "The user action time of the operation", + G_MININT64, G_MAXINT64, 0, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_USER_ACTION_TIME, + param_spec); } void @@ -492,8 +508,11 @@ out: } EmpathyDispatchOperation * -empathy_dispatch_operation_new (TpConnection *connection, TpChannel *channel, - EmpathyContact *contact, gboolean incoming) +empathy_dispatch_operation_new (TpConnection *connection, + TpChannel *channel, + EmpathyContact *contact, + gboolean incoming, + gint64 user_action_time) { g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (channel != NULL, NULL); @@ -503,6 +522,7 @@ empathy_dispatch_operation_new (TpConnection *connection, TpChannel *channel, "channel", channel, "contact", contact, "incoming", incoming, + "user-action-time", user_action_time, NULL); } @@ -681,3 +701,25 @@ empathy_dispatch_operation_is_incoming (EmpathyDispatchOperation *operation) return priv->incoming; } + +void +empathy_dispatch_operation_set_user_action_time ( + EmpathyDispatchOperation *self, + gint64 user_action_time) +{ + EmpathyDispatchOperationPriv *priv = GET_PRIV (self); + + priv->user_action_time = user_action_time; +} + +gint64 +empathy_dispatch_operation_get_user_action_time (EmpathyDispatchOperation *self) +{ + EmpathyDispatchOperationPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_DISPATCH_OPERATION (self), FALSE); + + priv = GET_PRIV (self); + + return priv->user_action_time; +} diff --git a/libempathy/empathy-dispatch-operation.h b/libempathy/empathy-dispatch-operation.h index 148adec90..f199be521 100644 --- a/libempathy/empathy-dispatch-operation.h +++ b/libempathy/empathy-dispatch-operation.h @@ -76,11 +76,14 @@ GType empathy_dispatch_operation_get_type (void); EmpathyDispatchOperation *empathy_dispatch_operation_new ( TpConnection *connection, TpChannel *channel, EmpathyContact *contact, - gboolean incoming); + gboolean incoming, + gint64 user_action_time); EmpathyDispatchOperation *empathy_dispatch_operation_new_with_wrapper ( TpConnection *connection, TpChannel *channel, EmpathyContact *contact, - gboolean incoming, GObject *channel_wrapper); + gboolean incoming, + gint64 user_action_time, + GObject *channel_wrapper); /* Start the dispatching process, goes to the APPROVING state for incoming * channels and DISPATCHING for outgoing ones */ @@ -115,6 +118,13 @@ EmpathyDispatchOperationState empathy_dispatch_operation_get_status ( gboolean empathy_dispatch_operation_is_incoming ( EmpathyDispatchOperation *operation); +void empathy_dispatch_operation_set_user_action_time ( + EmpathyDispatchOperation *self, + gint64 user_action_time); + +gint64 empathy_dispatch_operation_get_user_action_time ( + EmpathyDispatchOperation *self); + G_END_DECLS #endif /* #ifndef __EMPATHY_DISPATCH_OPERATION_H__*/ diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c index 027a9601f..2141b0b15 100644 --- a/libempathy/empathy-dispatcher.c +++ b/libempathy/empathy-dispatcher.c @@ -141,6 +141,7 @@ typedef struct /* Properties to pass to the channel when requesting it */ GHashTable *request; + gint64 timestamp; EmpathyDispatcherRequestCb *cb; gpointer user_data; gpointer *request_data; @@ -218,6 +219,7 @@ new_dispatcher_request_data (EmpathyDispatcher *self, guint handle_type, guint handle, GHashTable *request, + gint64 timestamp, EmpathyContact *contact, EmpathyDispatcherRequestCb *cb, gpointer user_data) @@ -233,6 +235,7 @@ new_dispatcher_request_data (EmpathyDispatcher *self, result->handle_type = handle_type; result->handle = handle; result->request = request; + result->timestamp = timestamp; if (contact != NULL) result->contact = g_object_ref (contact); @@ -570,7 +573,8 @@ dispatcher_connection_new_channel (EmpathyDispatcher *self, guint handle, GHashTable *properties, gboolean incoming, - const GPtrArray *requests_satisfied) + const GPtrArray *requests_satisfied, + gint64 timestamp) { EmpathyDispatcherPriv *priv = GET_PRIV (self); TpChannel *channel; @@ -627,7 +631,7 @@ dispatcher_connection_new_channel (EmpathyDispatcher *self, priv->channels = g_list_prepend (priv->channels, channel); operation = empathy_dispatch_operation_new (connection, channel, NULL, - incoming); + incoming, timestamp); g_object_unref (channel); @@ -688,7 +692,8 @@ dispatcher_connection_new_channel_with_properties ( TpConnection *connection, const gchar *object_path, GHashTable *properties, - const GPtrArray *requests_satisfied) + const GPtrArray *requests_satisfied, + gint64 timestamp) { const gchar *channel_type; guint handle_type; @@ -732,7 +737,7 @@ dispatcher_connection_new_channel_with_properties ( dispatcher_connection_new_channel (self, connection, object_path, channel_type, handle_type, handle, properties, !requested, - requests_satisfied); + requests_satisfied, timestamp); } static void @@ -1298,6 +1303,7 @@ dispatcher_request_channel (DispatcherRequestData *request_data) void empathy_dispatcher_chat_with_contact (EmpathyContact *contact, + gint64 timestamp, EmpathyDispatcherRequestCb *callback, gpointer user_data) { @@ -1329,7 +1335,8 @@ empathy_dispatcher_chat_with_contact (EmpathyContact *contact, /* The contact handle might not be known yet */ request_data = new_dispatcher_request_data (self, connection, TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_CONTACT, - empathy_contact_get_handle (contact), NULL, contact, callback, user_data); + empathy_contact_get_handle (contact), NULL, timestamp, contact, + callback, user_data); request_data->should_ensure = TRUE; connection_data->outstanding_requests = g_list_prepend @@ -1346,6 +1353,7 @@ typedef struct EmpathyDispatcher *dispatcher; EmpathyDispatcherRequestCb *callback; gpointer user_data; + gint64 timestamp; } ChatWithContactIdData; static void @@ -1368,8 +1376,8 @@ dispatcher_chat_with_contact_id_cb (EmpathyTpContactFactory *factory, } else { - empathy_dispatcher_chat_with_contact (contact, data->callback, - data->user_data); + empathy_dispatcher_chat_with_contact (contact, data->timestamp, + data->callback, data->user_data); } g_object_unref (data->dispatcher); @@ -1379,6 +1387,7 @@ dispatcher_chat_with_contact_id_cb (EmpathyTpContactFactory *factory, void empathy_dispatcher_chat_with_contact_id (TpConnection *connection, const gchar *contact_id, + gint64 timestamp, EmpathyDispatcherRequestCb *callback, gpointer user_data) { @@ -1395,6 +1404,7 @@ empathy_dispatcher_chat_with_contact_id (TpConnection *connection, data->dispatcher = self; data->callback = callback; data->user_data = user_data; + data->timestamp = timestamp; empathy_tp_contact_factory_get_from_id (factory, contact_id, dispatcher_chat_with_contact_id_cb, data, NULL, NULL); @@ -1437,6 +1447,7 @@ dispatcher_request_handles_cb (TpConnection *connection, void empathy_dispatcher_join_muc (TpConnection *connection, const gchar *roomname, + gint64 timestamp, EmpathyDispatcherRequestCb *callback, gpointer user_data) { @@ -1458,7 +1469,7 @@ empathy_dispatcher_join_muc (TpConnection *connection, /* Don't know the room handle yet */ request_data = new_dispatcher_request_data (self, connection, - TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_ROOM, 0, NULL, + TP_IFACE_CHANNEL_TYPE_TEXT, TP_HANDLE_TYPE_ROOM, 0, NULL, timestamp, NULL, callback, user_data); request_data->should_ensure = TRUE; @@ -1619,7 +1630,7 @@ empathy_dispatcher_call_create_or_ensure_channel ( call = tp_cli_channel_dispatcher_call_ensure_channel ( priv->channel_dispatcher, -1, tp_proxy_get_object_path (TP_PROXY (account)), - request_data->request, 0, handler, + request_data->request, request_data->timestamp, handler, dispatcher_create_channel_cb, request_data, NULL, NULL); } else @@ -1627,7 +1638,7 @@ empathy_dispatcher_call_create_or_ensure_channel ( call = tp_cli_channel_dispatcher_call_create_channel ( priv->channel_dispatcher, -1, tp_proxy_get_object_path (TP_PROXY (account)), - request_data->request, 0, handler, + request_data->request, request_data->timestamp, handler, dispatcher_create_channel_cb, request_data, NULL, G_OBJECT (dispatcher)); } @@ -1653,6 +1664,7 @@ void empathy_dispatcher_create_channel (EmpathyDispatcher *self, TpConnection *connection, GHashTable *request, + gint64 timestamp, EmpathyDispatcherRequestCb *callback, gpointer user_data) { @@ -1681,7 +1693,7 @@ empathy_dispatcher_create_channel (EmpathyDispatcher *self, handle = tp_asv_get_uint32 (request, TP_IFACE_CHANNEL ".TargetHandle", NULL); request_data = new_dispatcher_request_data (self, connection, - channel_type, handle_type, handle, request, + channel_type, handle_type, handle, request, timestamp, NULL, callback, user_data); connection_data->outstanding_requests = g_list_prepend @@ -2068,7 +2080,7 @@ empathy_dispatcher_handle_channels (EmpathyHandler *handler, properties = g_value_get_boxed (g_value_array_get_nth (arr, 1)); dispatcher_connection_new_channel_with_properties (self, - connection, object_path, properties, requests_satisfied); + connection, object_path, properties, requests_satisfied, timestamp); } return TRUE; diff --git a/libempathy/empathy-dispatcher.h b/libempathy/empathy-dispatcher.h index 6176ea088..d1dec072c 100644 --- a/libempathy/empathy-dispatcher.h +++ b/libempathy/empathy-dispatcher.h @@ -40,6 +40,9 @@ G_BEGIN_DECLS #define EMPATHY_IS_DISPATCHER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_DISPATCHER)) #define EMPATHY_DISPATCHER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_DISPATCHER, EmpathyDispatcherClass)) +#define EMPATHY_DISPATCHER_NON_USER_ACTION (G_GINT64_CONSTANT (0)) +#define EMPATHY_DISPATCHER_CURRENT_TIME G_MAXINT64 + typedef struct _EmpathyDispatcher EmpathyDispatcher; typedef struct _EmpathyDispatcherClass EmpathyDispatcherClass; @@ -65,15 +68,22 @@ typedef void (EmpathyDispatcherFindChannelClassCb) ( GType empathy_dispatcher_get_type (void) G_GNUC_CONST; void empathy_dispatcher_create_channel (EmpathyDispatcher *dispatcher, - TpConnection *connection, GHashTable *request, - EmpathyDispatcherRequestCb *callback, gpointer user_data); + TpConnection *connection, + GHashTable *request, + gint64 timestamp, + EmpathyDispatcherRequestCb *callback, + gpointer user_data); /* Requesting 1 to 1 text channels */ void empathy_dispatcher_chat_with_contact_id (TpConnection *connection, - const gchar *contact_id, EmpathyDispatcherRequestCb *callback, + const gchar *contact_id, + gint64 timestamp, + EmpathyDispatcherRequestCb *callback, gpointer user_data); void empathy_dispatcher_chat_with_contact (EmpathyContact *contact, - EmpathyDispatcherRequestCb *callback, gpointer user_data); + gint64 timestamp, + EmpathyDispatcherRequestCb *callback, + gpointer user_data); /* Request a file channel to a specific contact */ void empathy_dispatcher_send_file_to_contact (EmpathyContact *contact, @@ -83,7 +93,9 @@ void empathy_dispatcher_send_file_to_contact (EmpathyContact *contact, /* Request a muc channel */ void empathy_dispatcher_join_muc (TpConnection *connection, - const gchar *roomname, EmpathyDispatcherRequestCb *callback, + const gchar *roomname, + gint64 timestamp, + EmpathyDispatcherRequestCb *callback, gpointer user_data); void empathy_dispatcher_find_requestable_channel_classes_async diff --git a/libempathy/empathy-ft-handler.c b/libempathy/empathy-ft-handler.c index ff3f9322a..bbc99f61a 100644 --- a/libempathy/empathy-ft-handler.c +++ b/libempathy/empathy-ft-handler.c @@ -757,7 +757,8 @@ ft_handler_push_to_dispatcher (EmpathyFTHandler *handler) /* I want to own a reference to the request, and destroy it later */ empathy_dispatcher_create_channel (priv->dispatcher, connection, - g_hash_table_ref (priv->request), ft_handler_create_channel_cb, handler); + g_hash_table_ref (priv->request), EMPATHY_DISPATCHER_NON_USER_ACTION, + ft_handler_create_channel_cb, handler); } static void diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index 835827410..cad014df3 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -160,7 +160,7 @@ tp_chat_add (EmpathyContactList *list, * valid. * props now belongs to EmpathyDispatcher, don't free it */ empathy_dispatcher_create_channel (dispatcher, connection, - props, NULL, NULL); + props, EMPATHY_DISPATCHER_NON_USER_ACTION, NULL, NULL); g_object_unref (dispatcher); } else { diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index 943e2cd0f..153da4689 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -2387,7 +2387,8 @@ start_call (EmpathyCallWindow *self) EmpathyCallWindowPriv *priv = GET_PRIV (self); priv->call_started = TRUE; - empathy_call_handler_start_call (priv->handler); + empathy_call_handler_start_call (priv->handler, + gtk_get_current_event_time ()); if (empathy_call_handler_has_initial_video (priv->handler)) { diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index 01506f52e..97d210c84 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -199,10 +199,11 @@ connection_ready_cb (TpConnection *connection, if (error == NULL) { if (data->room) - empathy_dispatcher_join_muc (connection, data->id, NULL, NULL); + empathy_dispatcher_join_muc (connection, data->id, + EMPATHY_DISPATCHER_NON_USER_ACTION, NULL, NULL); else empathy_dispatcher_chat_with_contact_id (connection, data->id, - NULL, NULL); + EMPATHY_DISPATCHER_NON_USER_ACTION, NULL, NULL); g_signal_emit (self, signals[CHATS_CHANGED], 0, g_queue_get_length (priv->queue)); diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 6e80bb458..d47e942f5 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -32,6 +32,7 @@ #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> +#include <gdk/gdkx.h> #include <glib/gi18n.h> #include <libnotify/notification.h> @@ -62,6 +63,13 @@ #define DEBUG_FLAG EMPATHY_DEBUG_CHAT #include <libempathy/empathy-debug.h> +/* Macro to compare guint32 X timestamps, while accounting for wrapping around + */ +#define X_EARLIER_OR_EQL(t1, t2) \ + ((t1 <= t2 && ((t2 - t1) < G_MAXUINT32/2)) \ + || (t1 >= t2 && (t1 - t2) > (G_MAXUINT32/2)) \ + ) + #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChatWindow) typedef struct { EmpathyChat *current_chat; @@ -99,6 +107,9 @@ typedef struct { GtkAction *menu_tabs_left; GtkAction *menu_tabs_right; GtkAction *menu_tabs_detach; + + /* Last user action time we acted upon to show a tab */ + guint32 x_user_action_time; } EmpathyChatWindowPriv; static GList *chat_windows = NULL; @@ -1682,7 +1693,7 @@ chat_window_drag_data_received (GtkWidget *widget, if (connection) { empathy_dispatcher_chat_with_contact_id ( - connection, contact_id, NULL, NULL); + connection, contact_id, gtk_get_current_event_time (), NULL, NULL); } g_strfreev (strv); @@ -1704,7 +1715,8 @@ chat_window_drag_data_received (GtkWidget *widget, } /* Added to take care of any outstanding chat events */ - empathy_chat_window_present_chat (chat); + empathy_chat_window_present_chat (chat, + EMPATHY_DISPATCHER_NON_USER_ACTION); /* We should return TRUE to remove the data when doing * GDK_ACTION_MOVE, but we don't here otherwise it has @@ -2267,10 +2279,12 @@ empathy_chat_window_find_chat (TpAccount *account, } void -empathy_chat_window_present_chat (EmpathyChat *chat) +empathy_chat_window_present_chat (EmpathyChat *chat, + gint64 timestamp) { EmpathyChatWindow *window; EmpathyChatWindowPriv *priv; + guint32 x_timestamp; g_return_if_fail (EMPATHY_IS_CHAT (chat)); @@ -2281,16 +2295,40 @@ empathy_chat_window_present_chat (EmpathyChat *chat) window = empathy_chat_window_get_default (empathy_chat_is_room (chat)); if (!window) { window = empathy_chat_window_new (); + gtk_widget_show_all (GET_PRIV (window)->dialog); } empathy_chat_window_add_chat (window, chat); } + /* Don't force the window to show itself when it wasn't + * an action by the user + */ + if (timestamp == EMPATHY_DISPATCHER_NON_USER_ACTION) + return; + priv = GET_PRIV (window); + + if (timestamp == EMPATHY_DISPATCHER_CURRENT_TIME) { + x_timestamp = GDK_CURRENT_TIME; + } else { + x_timestamp = CLAMP (timestamp, 0, G_MAXUINT32); + /* Don't present or switch tab if the action was earlier than the + * last actions X time, accounting for overflow and the first ever + * presentation */ + + if (priv->x_user_action_time != 0 + && X_EARLIER_OR_EQL (x_timestamp, priv->x_user_action_time)) + return; + + priv->x_user_action_time = x_timestamp; + } + empathy_chat_window_switch_to_chat (window, chat); - empathy_window_present (GTK_WINDOW (priv->dialog)); + empathy_window_present_with_time (GTK_WINDOW (priv->dialog), + x_timestamp); - gtk_widget_grab_focus (chat->input_text_view); + gtk_widget_grab_focus (chat->input_text_view); } void diff --git a/src/empathy-chat-window.h b/src/empathy-chat-window.h index 93ffcc53a..4cbd2094a 100644 --- a/src/empathy-chat-window.h +++ b/src/empathy-chat-window.h @@ -72,7 +72,8 @@ void empathy_chat_window_switch_to_chat (EmpathyChatWindow *window gboolean empathy_chat_window_has_focus (EmpathyChatWindow *window); EmpathyChat * empathy_chat_window_find_chat (TpAccount *account, const gchar *id); -void empathy_chat_window_present_chat (EmpathyChat *chat); +void empathy_chat_window_present_chat (EmpathyChat *chat, + gint64 timestamp); void empathy_chat_window_get_nb_chats (EmpathyChatWindow *window, guint *nb_rooms, diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c index c4ab4ad78..841883d06 100644 --- a/src/empathy-event-manager.c +++ b/src/empathy-event-manager.c @@ -228,6 +228,12 @@ event_manager_add (EmpathyEventManager *manager, static void event_channel_process_func (EventPriv *event) { + gint64 timestamp = gtk_get_current_event_time (); + if (timestamp == GDK_CURRENT_TIME) + timestamp = EMPATHY_DISPATCHER_CURRENT_TIME; + + empathy_dispatch_operation_set_user_action_time (event->approval->operation, + timestamp); empathy_dispatch_operation_approve (event->approval->operation); } @@ -235,6 +241,12 @@ static void event_text_channel_process_func (EventPriv *event) { EmpathyTpChat *tp_chat; + gint64 timestamp = gtk_get_current_event_time (); + if (timestamp == GDK_CURRENT_TIME) + timestamp = EMPATHY_DISPATCHER_CURRENT_TIME; + + empathy_dispatch_operation_set_user_action_time (event->approval->operation, + timestamp); if (event->approval->handler != 0) { @@ -527,6 +539,7 @@ invite_dialog_response_cb (GtkDialog *dialog, TpChannel *channel; TpHandle self_handle; GArray *members; + gint64 timestamp; gtk_widget_destroy (GTK_WIDGET (approval->dialog)); approval->dialog = NULL; @@ -556,6 +569,12 @@ invite_dialog_response_cb (GtkDialog *dialog, tp_cli_channel_interface_group_call_add_members (channel, -1, members, "", NULL, NULL, NULL, NULL); + timestamp = gtk_get_current_event_time (); + if (timestamp == GDK_CURRENT_TIME) + timestamp = EMPATHY_DISPATCHER_CURRENT_TIME; + + empathy_dispatch_operation_set_user_action_time (approval->operation, + timestamp); empathy_dispatch_operation_approve (approval->operation); g_array_free (members, TRUE); diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c index 51d0ec9ef..6826ee534 100644 --- a/src/empathy-main-window.c +++ b/src/empathy-main-window.c @@ -908,7 +908,8 @@ main_window_favorite_chatroom_join (EmpathyChatroom *chatroom) if (connection != NULL) { DEBUG ("Requesting channel for '%s'", room); - empathy_dispatcher_join_muc (connection, room, NULL, NULL); + empathy_dispatcher_join_muc (connection, room, + gtk_get_current_event_time (), NULL, NULL); } } diff --git a/src/empathy-new-chatroom-dialog.c b/src/empathy-new-chatroom-dialog.c index 7c330b22c..50b5f5d82 100644 --- a/src/empathy-new-chatroom-dialog.c +++ b/src/empathy-new-chatroom-dialog.c @@ -732,7 +732,8 @@ new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog) } DEBUG ("Requesting channel for '%s'", room_name); - empathy_dispatcher_join_muc (connection, room_name, NULL, NULL); + empathy_dispatcher_join_muc (connection, room_name, + gtk_get_current_event_time (), NULL, NULL); g_free (room_name); } diff --git a/src/empathy.c b/src/empathy.c index 637778d47..5dcf035e3 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -133,7 +133,8 @@ dispatch_cb (EmpathyDispatcher *dispatcher, * (a GtkNotebook) when we'll call empathy_chat_window_present_chat */ } - empathy_chat_window_present_chat (chat); + empathy_chat_window_present_chat (chat, + empathy_dispatch_operation_get_user_action_time (operation)); empathy_dispatch_operation_claim (operation); } @@ -481,7 +482,8 @@ account_status_changed_cb (TpAccount *account, return; empathy_dispatcher_join_muc (conn, - empathy_chatroom_get_room (room), NULL, NULL); + empathy_chatroom_get_room (room), EMPATHY_DISPATCHER_NON_USER_ACTION, + NULL, NULL); } static void @@ -529,7 +531,8 @@ account_manager_chatroom_ready_cb (GObject *source_object, else { empathy_dispatcher_join_muc (conn, - empathy_chatroom_get_room (room), NULL, NULL); + empathy_chatroom_get_room (room), + EMPATHY_DISPATCHER_NON_USER_ACTION, NULL, NULL); } } diff --git a/tests/interactive/empetit.c b/tests/interactive/empetit.c index e2eb61f66..7bcaf03ee 100644 --- a/tests/interactive/empetit.c +++ b/tests/interactive/empetit.c @@ -42,7 +42,8 @@ clicked_cb (GtkButton *button, if (!contact) return; - empathy_dispatcher_chat_with_contact (contact, chat_cb, NULL); + empathy_dispatcher_chat_with_contact (contact, gtk_get_current_event_time (), + chat_cb, NULL); g_object_unref (contact); } |