aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonny Lamb <jonnylamb@gnome.org>2011-05-17 16:36:33 +0800
committerJonny Lamb <jonnylamb@gnome.org>2011-05-17 16:36:33 +0800
commit2950825a4452bc984c0dd356c5bf17c3a674c451 (patch)
treec562a901727f1548105acf75884f350d9dfd7192
parent38e5925b90ca5864907aaef09cbaa4c963b1be98 (diff)
parent9e1914959b7e26e82ca4042ad5f7f042cb5a34a2 (diff)
downloadgsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar.gz
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar.bz2
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar.lz
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar.xz
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.tar.zst
gsoc2013-empathy-2950825a4452bc984c0dd356c5bf17c3a674c451.zip
Merge branch 'ack'
-rw-r--r--libempathy-gtk/empathy-chat-view.c11
-rw-r--r--libempathy-gtk/empathy-chat-view.h4
-rw-r--r--libempathy-gtk/empathy-chat.c43
-rw-r--r--libempathy-gtk/empathy-theme-adium.c163
-rw-r--r--libempathy/empathy-message.c55
-rw-r--r--libempathy/empathy-message.h4
-rw-r--r--libempathy/empathy-tp-chat.c113
-rw-r--r--src/empathy-chat-window.c9
8 files changed, 296 insertions, 106 deletions
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c
index 097215cfd..43d89dd78 100644
--- a/libempathy-gtk/empathy-chat-view.c
+++ b/libempathy-gtk/empathy-chat-view.c
@@ -212,3 +212,14 @@ empathy_chat_view_focus_toggled (EmpathyChatView *view,
}
}
+void
+empathy_chat_view_message_acknowledged (EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ if (EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->message_acknowledged) {
+ EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->message_acknowledged (view, message);
+ }
+}
+
diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h
index 1af0721a3..73245c422 100644
--- a/libempathy-gtk/empathy-chat-view.h
+++ b/libempathy-gtk/empathy-chat-view.h
@@ -70,6 +70,8 @@ struct _EmpathyChatViewIface {
void (*copy_clipboard) (EmpathyChatView *view);
void (*focus_toggled) (EmpathyChatView *view,
gboolean has_focus);
+ void (*message_acknowledged) (EmpathyChatView *view,
+ EmpathyMessage *message);
};
GType empathy_chat_view_get_type (void) G_GNUC_CONST;
@@ -101,6 +103,8 @@ void empathy_chat_view_highlight (EmpathyChatView *view,
void empathy_chat_view_copy_clipboard (EmpathyChatView *view);
void empathy_chat_view_focus_toggled (EmpathyChatView *view,
gboolean has_focus);
+void empathy_chat_view_message_acknowledged (EmpathyChatView *view,
+ EmpathyMessage *message);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 034cd9ea7..e76998065 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -174,6 +174,7 @@ enum {
PROP_SHOW_CONTACTS,
PROP_SMS_CHANNEL,
PROP_N_MESSAGES_SENDING,
+ PROP_NB_UNREAD_MESSAGES,
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -220,6 +221,10 @@ chat_get_property (GObject *object,
g_value_set_uint (value,
empathy_chat_get_n_messages_sending (chat));
break;
+ case PROP_NB_UNREAD_MESSAGES:
+ g_value_set_uint (value,
+ empathy_chat_get_nb_unread_messages (chat));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -1326,7 +1331,11 @@ chat_message_received (EmpathyChat *chat,
TP_CHANNEL_CHAT_STATE_ACTIVE,
chat);
- priv->unread_messages++;
+ if (empathy_message_is_incoming (message)) {
+ priv->unread_messages++;
+ g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+ }
+
g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending);
}
@@ -1339,6 +1348,20 @@ chat_message_received_cb (EmpathyTpChat *tp_chat,
}
static void
+chat_message_acknowledged_cb (EmpathyTpChat *tp_chat,
+ EmpathyMessage *message,
+ EmpathyChat *chat)
+{
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+
+ empathy_chat_view_message_acknowledged (chat->view,
+ message);
+
+ priv->unread_messages--;
+ g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+}
+
+static void
chat_send_error_cb (EmpathyTpChat *tp_chat,
const gchar *message_body,
TpChannelTextSendError error_code,
@@ -2927,6 +2950,8 @@ chat_finalize (GObject *object)
g_signal_handlers_disconnect_by_func (priv->tp_chat,
chat_message_received_cb, chat);
g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_message_acknowledged_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
chat_send_error_cb, chat);
g_signal_handlers_disconnect_by_func (priv->tp_chat,
chat_state_changed_cb, chat);
@@ -3062,6 +3087,14 @@ empathy_chat_class_init (EmpathyChatClass *klass)
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class,
+ PROP_NB_UNREAD_MESSAGES,
+ g_param_spec_uint ("nb-unread-messages",
+ "Num Unread Messages",
+ "The number of unread messages",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
signals[COMPOSING] =
g_signal_new ("composing",
G_OBJECT_CLASS_TYPE (object_class),
@@ -3630,6 +3663,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat,
g_signal_connect (tp_chat, "message-received",
G_CALLBACK (chat_message_received_cb),
chat);
+ g_signal_connect (tp_chat, "message_acknowledged",
+ G_CALLBACK (chat_message_acknowledged_cb),
+ chat);
g_signal_connect (tp_chat, "send-error",
G_CALLBACK (chat_send_error_cb),
chat);
@@ -3957,12 +3993,9 @@ empathy_chat_messages_read (EmpathyChat *self)
if (priv->retrieving_backlogs)
return;
- if (priv->tp_chat != NULL ) {
+ if (priv->tp_chat != NULL) {
empathy_tp_chat_acknowledge_all_messages (priv->tp_chat);
}
- priv->unread_messages = 0;
-
- empathy_chat_view_focus_toggled (self->view, TRUE);
}
/* Return TRUE if on of the contacts in this chat is composing */
diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c
index 06410c528..b62b017c9 100644
--- a/libempathy-gtk/empathy-theme-adium.c
+++ b/libempathy-gtk/empathy-theme-adium.c
@@ -61,6 +61,9 @@ typedef struct {
guint pages_loading;
/* Queue of GValue* containing an EmpathyMessage or string */
GQueue message_queue;
+ /* Queue of owned gchar* of message token to remove unread
+ * marker for when we lose focus. */
+ GQueue acked_messages;
GtkWidget *inspector_window;
GSettings *gsettings_chat;
gboolean has_focus;
@@ -569,32 +572,10 @@ theme_adium_append_event_escaped (EmpathyChatView *view,
}
static void
-theme_adium_remove_focus_marks (EmpathyThemeAdium *theme)
+theme_adium_remove_focus_marks (EmpathyThemeAdium *theme,
+ WebKitDOMNodeList *nodes)
{
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
- WebKitDOMDocument *dom;
- WebKitDOMNodeList *nodes;
guint i;
- GError *error = NULL;
-
- if (!priv->has_unread_message)
- return;
-
- priv->has_unread_message = FALSE;
-
- dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (theme));
- if (dom == NULL) {
- return;
- }
-
- /* Get all nodes with focus class */
- nodes = webkit_dom_document_query_selector_all (dom, ".focus", &error);
- if (nodes == NULL) {
- DEBUG ("Error getting focus nodes: %s",
- error ? error->message : "No error");
- g_clear_error (&error);
- return;
- }
/* Remove focus and firstFocus class */
for (i = 0; i < webkit_dom_node_list_get_length (nodes); i++) {
@@ -632,12 +613,43 @@ theme_adium_remove_focus_marks (EmpathyThemeAdium *theme)
}
static void
+theme_adium_remove_all_focus_marks (EmpathyThemeAdium *theme)
+{
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+ WebKitDOMDocument *dom;
+ WebKitDOMNodeList *nodes;
+ GError *error = NULL;
+
+ if (!priv->has_unread_message)
+ return;
+
+ priv->has_unread_message = FALSE;
+
+ dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (theme));
+ if (dom == NULL) {
+ return;
+ }
+
+ /* Get all nodes with focus class */
+ nodes = webkit_dom_document_query_selector_all (dom, ".focus", &error);
+ if (nodes == NULL) {
+ DEBUG ("Error getting focus nodes: %s",
+ error ? error->message : "No error");
+ g_clear_error (&error);
+ return;
+ }
+
+ theme_adium_remove_focus_marks (theme, nodes);
+}
+
+static void
theme_adium_append_message (EmpathyChatView *view,
EmpathyMessage *msg)
{
EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view);
EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
EmpathyContact *sender;
+ TpMessage *tp_msg;
TpAccount *account;
gchar *body_escaped;
const gchar *body;
@@ -759,6 +771,20 @@ theme_adium_append_message (EmpathyChatView *view,
* %status% - See %status% in theme_adium_append_html ()
*/
+ /* This is slightly a hack, but it's the only way to add
+ * arbitrary data to messages in the HTML. We add another
+ * class called "x-empathy-message-id-*" to the message. This
+ * way, we can remove the unread marker for this specific
+ * message later. */
+ tp_msg = empathy_message_get_tp_message (msg);
+ if (tp_msg != NULL) {
+ gchar *tmp = tp_escape_as_identifier (
+ tp_message_get_token (tp_msg));
+ g_string_append_printf (message_classes,
+ " x-empathy-message-id-%s", tmp);
+ g_free (tmp);
+ }
+
/* Define javascript function to use */
if (consecutive) {
func = priv->allow_scrolling ? "appendNextMessage" : "appendNextMessageNoScroll";
@@ -777,7 +803,7 @@ theme_adium_append_message (EmpathyChatView *view,
}
/* remove all the unread marks when we are sending a message */
- theme_adium_remove_focus_marks (theme);
+ theme_adium_remove_all_focus_marks (theme);
} else {
/* in */
if (is_backlog) {
@@ -927,16 +953,93 @@ theme_adium_copy_clipboard (EmpathyChatView *view)
}
static void
+theme_adium_remove_mark_from_message (EmpathyThemeAdium *self,
+ const gchar *token)
+{
+ WebKitDOMDocument *dom;
+ WebKitDOMNodeList *nodes;
+ gchar *class, *tmp;
+ GError *error = NULL;
+
+ dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (self));
+ if (dom == NULL) {
+ return;
+ }
+
+ tmp = tp_escape_as_identifier (token);
+ class = g_strdup_printf (".x-empathy-message-id-%s", tmp);
+ g_free (tmp);
+
+ /* Get all nodes with focus class */
+ nodes = webkit_dom_document_query_selector_all (dom, class, &error);
+ g_free (class);
+
+ if (nodes == NULL) {
+ DEBUG ("Error getting focus nodes: %s",
+ error ? error->message : "No error");
+ g_clear_error (&error);
+ return;
+ }
+
+ theme_adium_remove_focus_marks (self, nodes);
+}
+
+static void
+theme_adium_remove_acked_message_unread_mark_foreach (gpointer data,
+ gpointer user_data)
+{
+ EmpathyThemeAdium *self = user_data;
+ gchar *token = data;
+
+ theme_adium_remove_mark_from_message (self, token);
+ g_free (token);
+}
+
+static void
theme_adium_focus_toggled (EmpathyChatView *view,
gboolean has_focus)
{
- EmpathyThemeAdium *self = (EmpathyThemeAdium *) view;
EmpathyThemeAdiumPriv *priv = GET_PRIV (view);
priv->has_focus = has_focus;
if (!priv->has_focus) {
- theme_adium_remove_focus_marks (self);
+ /* We've lost focus, so let's make sure all the acked
+ * messages have lost their unread marker. */
+ g_queue_foreach (&priv->acked_messages,
+ theme_adium_remove_acked_message_unread_mark_foreach,
+ view);
+ g_queue_clear (&priv->acked_messages);
+
+ priv->has_unread_message = FALSE;
+ }
+}
+
+static void
+theme_adium_message_acknowledged (EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ EmpathyThemeAdium *self = (EmpathyThemeAdium *) view;
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (view);
+ TpMessage *tp_msg;
+
+ tp_msg = empathy_message_get_tp_message (message);
+
+ if (tp_msg == NULL) {
+ return;
}
+
+ /* We only want to actually remove the unread marker if the
+ * view doesn't have focus. If we did it all the time we would
+ * never see the unread markers, ever! So, we'll queue these
+ * up, and when we lose focus, we'll remove the markers. */
+ if (priv->has_focus) {
+ g_queue_push_tail (&priv->acked_messages,
+ g_strdup (tp_message_get_token (tp_msg)));
+ return;
+ }
+
+ theme_adium_remove_mark_from_message (self,
+ tp_message_get_token (tp_msg));
}
static void
@@ -1059,6 +1162,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface)
iface->highlight = theme_adium_highlight;
iface->copy_clipboard = theme_adium_copy_clipboard;
iface->focus_toggled = theme_adium_focus_toggled;
+ iface->message_acknowledged = theme_adium_message_acknowledged;
}
static void
@@ -1124,6 +1228,11 @@ theme_adium_dispose (GObject *object)
priv->inspector_window = NULL;
}
+ if (priv->acked_messages.length > 0) {
+ g_queue_foreach (&priv->acked_messages, (GFunc) g_free, NULL);
+ g_queue_clear (&priv->acked_messages);
+ }
+
G_OBJECT_CLASS (empathy_theme_adium_parent_class)->dispose (object);
}
diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c
index 076a10053..25ec498ce 100644
--- a/libempathy/empathy-message.c
+++ b/libempathy/empathy-message.c
@@ -40,6 +40,7 @@
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyMessage)
typedef struct {
+ TpMessage *tp_message;
TpChannelTextMessageType type;
EmpathyContact *sender;
EmpathyContact *receiver;
@@ -73,6 +74,7 @@ enum {
PROP_IS_BACKLOG,
PROP_INCOMING,
PROP_FLAGS,
+ PROP_TP_MESSAGE,
};
static void
@@ -153,6 +155,15 @@ empathy_message_class_init (EmpathyMessageClass *class)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_TP_MESSAGE,
+ g_param_spec_object ("tp-message",
+ "TpMessage",
+ "The TpMessage of this message",
+ TP_TYPE_MESSAGE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_CONSTRUCT_ONLY));
+
g_type_class_add_private (object_class, sizeof (EmpathyMessagePriv));
}
@@ -181,6 +192,10 @@ empathy_message_finalize (GObject *object)
g_object_unref (priv->receiver);
}
+ if (priv->tp_message) {
+ g_object_unref (priv->tp_message);
+ }
+
g_free (priv->body);
G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object);
@@ -221,6 +236,9 @@ message_get_property (GObject *object,
case PROP_FLAGS:
g_value_set_uint (value, priv->flags);
break;
+ case PROP_TP_MESSAGE:
+ g_value_set_object (value, priv->tp_message);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -267,6 +285,9 @@ message_set_property (GObject *object,
case PROP_FLAGS:
priv->flags = g_value_get_uint (value);
break;
+ case PROP_TP_MESSAGE:
+ priv->tp_message = g_value_dup_object (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -342,6 +363,18 @@ empathy_message_from_tpl_log_event (TplEvent *logevent)
return retval;
}
+TpMessage *
+empathy_message_get_tp_message (EmpathyMessage *message)
+{
+ EmpathyMessagePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
+
+ priv = GET_PRIV (message);
+
+ return priv->tp_message;
+}
+
TpChannelTextMessageType
empathy_message_get_tptype (EmpathyMessage *message)
{
@@ -563,16 +596,6 @@ empathy_message_type_to_str (TpChannelTextMessageType type)
}
}
-guint
-empathy_message_get_id (EmpathyMessage *message)
-{
- EmpathyMessagePriv *priv = GET_PRIV (message);
-
- g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), 0);
-
- return priv->id;
-}
-
gboolean
empathy_message_is_incoming (EmpathyMessage *message)
{
@@ -618,10 +641,8 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg,
gboolean incoming)
{
EmpathyMessage *message;
- EmpathyMessagePriv *priv;
gchar *body;
TpChannelTextMessageFlags flags;
- guint id;
g_return_val_if_fail (TP_IS_MESSAGE (tp_msg), NULL);
@@ -634,17 +655,9 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg,
"flags", flags,
"is-backlog", flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK,
"incoming", incoming,
+ "tp-message", tp_msg,
NULL);
- priv = GET_PRIV (message);
-
- /* FIXME: this is pretty low level, ideally we shouldn't have to use the
- * ID directly but we don't use TpTextChannel's ack API everywhere yet. */
- id = tp_asv_get_uint32 (tp_message_peek (tp_msg, 0),
- "pending-message-id", NULL);
-
- priv->id = id;
-
g_free (body);
return message;
}
diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h
index 7508cb08e..b20ceca16 100644
--- a/libempathy/empathy-message.h
+++ b/libempathy/empathy-message.h
@@ -59,6 +59,8 @@ EmpathyMessage * empathy_message_from_tpl_log_event (TplEvent
EmpathyMessage * empathy_message_new_from_tp_message (TpMessage *tp_msg,
gboolean incoming);
+TpMessage * empathy_message_get_tp_message (EmpathyMessage *message);
+
TpChannelTextMessageType empathy_message_get_tptype (EmpathyMessage *message);
EmpathyContact * empathy_message_get_sender (EmpathyMessage *message);
void empathy_message_set_sender (EmpathyMessage *message,
@@ -75,8 +77,6 @@ gboolean empathy_message_should_highlight (EmpathyMessage
TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str);
const gchar * empathy_message_type_to_str (TpChannelTextMessageType type);
-guint empathy_message_get_id (EmpathyMessage *message);
-
gboolean empathy_message_equal (EmpathyMessage *message1, EmpathyMessage *message2);
TpChannelTextMessageFlags empathy_message_get_flags (EmpathyMessage *message);
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 8e6672eee..0541943b9 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -84,6 +84,7 @@ enum {
CHAT_STATE_CHANGED,
PROPERTY_CHANGED,
DESTROY,
+ MESSAGE_ACKNOWLEDGED,
LAST_SIGNAL
};
@@ -93,8 +94,6 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyTpChat, empathy_tp_chat, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
tp_chat_iface_init));
-static void acknowledge_messages (EmpathyTpChat *chat, GArray *ids);
-
static void
tp_chat_set_delivery_status (EmpathyTpChat *self,
const gchar *token,
@@ -453,6 +452,39 @@ message_received_cb (TpTextChannel *channel,
handle_incoming_message (chat, message, FALSE);
}
+static gboolean
+find_pending_message_func (gconstpointer a,
+ gconstpointer b)
+{
+ EmpathyMessage *msg = (EmpathyMessage *) a;
+ TpMessage *message = (TpMessage *) b;
+
+ if (empathy_message_get_tp_message (msg) == message)
+ return 0;
+
+ return -1;
+}
+
+static void
+pending_message_removed_cb (TpTextChannel *channel,
+ TpMessage *message,
+ EmpathyTpChat *chat)
+{
+ EmpathyTpChatPriv *priv = GET_PRIV (chat);
+ GList *m;
+
+ m = g_queue_find_custom (priv->pending_messages_queue, message,
+ find_pending_message_func);
+
+ if (m == NULL)
+ return;
+
+ g_signal_emit (chat, signals[MESSAGE_ACKNOWLEDGED], 0, m->data);
+
+ g_object_unref (m->data);
+ g_queue_delete_link (priv->pending_messages_queue, m);
+}
+
static void
message_sent_cb (TpTextChannel *channel,
TpMessage *message,
@@ -911,6 +943,8 @@ check_almost_ready (EmpathyTpChat *chat)
tp_g_signal_connect_object (priv->channel, "message-received",
G_CALLBACK (message_received_cb), chat, 0);
+ tp_g_signal_connect_object (priv->channel, "pending-message-removed",
+ G_CALLBACK (pending_message_removed_cb), chat, 0);
list_pending_messages (chat);
@@ -1632,6 +1666,16 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass)
G_TYPE_NONE,
0);
+ signals[MESSAGE_ACKNOWLEDGED] =
+ g_signal_new ("message-acknowledged",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1, EMPATHY_TYPE_MESSAGE);
+
g_type_class_add_private (object_class, sizeof (EmpathyTpChatPriv));
}
@@ -1793,84 +1837,51 @@ empathy_tp_chat_get_pending_messages (EmpathyTpChat *chat)
return priv->pending_messages_queue->head;
}
-static void
-acknowledge_messages (EmpathyTpChat *chat, GArray *ids) {
- EmpathyTpChatPriv *priv = GET_PRIV (chat);
-
- tp_cli_channel_type_text_call_acknowledge_pending_messages (
- priv->channel, -1, ids, tp_chat_async_cb,
- "acknowledging received message", NULL, G_OBJECT (chat));
-}
-
void
empathy_tp_chat_acknowledge_message (EmpathyTpChat *chat,
EmpathyMessage *message) {
EmpathyTpChatPriv *priv = GET_PRIV (chat);
- GArray *message_ids;
- GList *m;
- guint id;
+ TpMessage *tp_msg;
g_return_if_fail (EMPATHY_IS_TP_CHAT (chat));
g_return_if_fail (priv->ready);
if (!empathy_message_is_incoming (message))
- goto out;
-
- message_ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
-
- id = empathy_message_get_id (message);
- g_array_append_val (message_ids, id);
- acknowledge_messages (chat, message_ids);
- g_array_free (message_ids, TRUE);
+ return;
-out:
- m = g_queue_find (priv->pending_messages_queue, message);
- g_assert (m != NULL);
- g_queue_delete_link (priv->pending_messages_queue, m);
- g_object_unref (message);
+ tp_msg = empathy_message_get_tp_message (message);
+ tp_text_channel_ack_message_async (TP_TEXT_CHANNEL (priv->channel),
+ tp_msg, NULL, NULL);
}
void
empathy_tp_chat_acknowledge_messages (EmpathyTpChat *chat,
const GSList *messages) {
EmpathyTpChatPriv *priv = GET_PRIV (chat);
- /* Copy messages as the messges list (probably is) our own */
- GSList *msgs = g_slist_copy ((GSList *) messages);
- GSList *l;
- guint length;
- GArray *message_ids;
+ const GSList *l;
+ GList *messages_to_ack = NULL;
g_return_if_fail (EMPATHY_IS_TP_CHAT (chat));
g_return_if_fail (priv->ready);
- length = g_slist_length ((GSList *) messages);
-
- if (length == 0)
+ if (messages == NULL)
return;
- message_ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), length);
-
- for (l = msgs; l != NULL; l = g_slist_next (l)) {
- GList *m;
-
+ for (l = messages; l != NULL; l = g_slist_next (l)) {
EmpathyMessage *message = EMPATHY_MESSAGE (l->data);
- m = g_queue_find (priv->pending_messages_queue, message);
- g_assert (m != NULL);
- g_queue_delete_link (priv->pending_messages_queue, m);
-
if (empathy_message_is_incoming (message)) {
- guint id = empathy_message_get_id (message);
- g_array_append_val (message_ids, id);
+ TpMessage *tp_msg = empathy_message_get_tp_message (message);
+ messages_to_ack = g_list_append (messages_to_ack, tp_msg);
}
- g_object_unref (message);
}
- if (message_ids->len > 0)
- acknowledge_messages (chat, message_ids);
+ if (messages_to_ack != NULL) {
+ tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (priv->channel),
+ messages_to_ack, NULL, NULL);
+ }
- g_array_free (message_ids, TRUE);
- g_slist_free (msgs);
+ g_list_free (messages_to_ack);
}
void
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index e9298ddbf..d8a75cb0c 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -794,6 +794,7 @@ chat_window_update_chat_tab (EmpathyChat *chat)
static void
chat_window_chat_notify_cb (EmpathyChat *chat)
{
+ EmpathyChatWindow *window;
EmpathyContact *old_remote_contact;
EmpathyContact *remote_contact = NULL;
@@ -820,6 +821,11 @@ chat_window_chat_notify_cb (EmpathyChat *chat)
}
chat_window_update_chat_tab (chat);
+
+ window = chat_window_find_chat (chat);
+ if (window != NULL) {
+ chat_window_update (window, FALSE);
+ }
}
static void
@@ -2326,6 +2332,9 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
g_signal_connect (chat, "notify::n-messages-sending",
G_CALLBACK (chat_window_chat_notify_cb),
NULL);
+ g_signal_connect (chat, "notify::nb-unread-messages",
+ G_CALLBACK (chat_window_chat_notify_cb),
+ NULL);
chat_window_chat_notify_cb (chat);
gtk_notebook_append_page_menu (GTK_NOTEBOOK (priv->notebook), child, label, popup_label);