aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-chat.c6
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c3
-rw-r--r--libempathy-gtk/empathy-contact-menu.c3
-rw-r--r--libempathy-gtk/empathy-new-message-dialog.c3
-rw-r--r--libempathy-gtk/empathy-ui-utils.c24
-rw-r--r--libempathy-gtk/empathy-ui-utils.h4
-rw-r--r--libempathy/empathy-call-handler.c5
-rw-r--r--libempathy/empathy-call-handler.h3
-rw-r--r--libempathy/empathy-dispatch-operation.c46
-rw-r--r--libempathy/empathy-dispatch-operation.h14
-rw-r--r--libempathy/empathy-dispatcher.c36
-rw-r--r--libempathy/empathy-dispatcher.h22
-rw-r--r--libempathy/empathy-ft-handler.c3
-rw-r--r--libempathy/empathy-tp-chat.c2
-rw-r--r--src/empathy-call-window.c3
-rw-r--r--src/empathy-chat-manager.c5
-rw-r--r--src/empathy-chat-window.c48
-rw-r--r--src/empathy-chat-window.h3
-rw-r--r--src/empathy-event-manager.c19
-rw-r--r--src/empathy-main-window.c3
-rw-r--r--src/empathy-new-chatroom-dialog.c3
-rw-r--r--src/empathy.c9
-rw-r--r--tests/interactive/empetit.c3
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);
}