diff options
-rw-r--r-- | libempathy-gtk/empathy-chat-view.c | 11 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-view.h | 4 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 16 | ||||
-rw-r--r-- | libempathy-gtk/empathy-theme-adium.c | 93 |
4 files changed, 118 insertions, 6 deletions
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index ada669885..097215cfd 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -201,3 +201,14 @@ empathy_chat_view_copy_clipboard (EmpathyChatView *view) } } +void +empathy_chat_view_focus_toggled (EmpathyChatView *view, + gboolean has_focus) +{ + g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); + + if (EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->focus_toggled) { + EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->focus_toggled (view, has_focus); + } +} + diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h index 96365a618..1af0721a3 100644 --- a/libempathy-gtk/empathy-chat-view.h +++ b/libempathy-gtk/empathy-chat-view.h @@ -68,6 +68,8 @@ struct _EmpathyChatViewIface { const gchar *text, gboolean match_case); void (*copy_clipboard) (EmpathyChatView *view); + void (*focus_toggled) (EmpathyChatView *view, + gboolean has_focus); }; GType empathy_chat_view_get_type (void) G_GNUC_CONST; @@ -97,6 +99,8 @@ void empathy_chat_view_highlight (EmpathyChatView *view, const gchar *text, gboolean match_case); void empathy_chat_view_copy_clipboard (EmpathyChatView *view); +void empathy_chat_view_focus_toggled (EmpathyChatView *view, + gboolean has_focus); G_END_DECLS diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 53c4677fc..c146941b3 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1753,6 +1753,14 @@ chat_input_realize_cb (GtkWidget *widget, } static void +chat_input_has_focus_notify_cb (GtkWidget *widget, + GParamSpec *pspec, + EmpathyChat *chat) +{ + empathy_chat_view_focus_toggled (chat->view, gtk_widget_has_focus (widget)); +} + +static void chat_insert_smiley_activate_cb (EmpathySmileyManager *manager, EmpathySmiley *smiley, gpointer user_data) @@ -2710,7 +2718,9 @@ chat_create_ui (EmpathyChat *chat) /* Add input GtkTextView */ chat->input_text_view = empathy_input_text_view_new (); - + g_signal_connect (chat->input_text_view, "notify::has-focus", + G_CALLBACK (chat_input_has_focus_notify_cb), + chat); g_signal_connect (chat->input_text_view, "key-press-event", G_CALLBACK (chat_input_key_press_event_cb), chat); @@ -3789,9 +3799,11 @@ empathy_chat_messages_read (EmpathyChat *self) return; if (priv->tp_chat != NULL ) { - empathy_tp_chat_acknowledge_all_messages (priv->tp_chat); + 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 a90095e3e..2ab3383b3 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -62,6 +62,8 @@ typedef struct { GList *message_queue; GtkWidget *inspector_window; GSettings *gsettings_chat; + gboolean has_focus; + gboolean has_unread_message; } EmpathyThemeAdiumPriv; struct _EmpathyAdiumData { @@ -303,8 +305,10 @@ escape_and_append_len (GString *string, const gchar *str, gint len) } } +/* If *str starts with match, returns TRUE and move pointer to the end */ static gboolean -theme_adium_match (const gchar **str, const gchar *match) +theme_adium_match (const gchar **str, + const gchar *match) { gint len; @@ -317,8 +321,10 @@ theme_adium_match (const gchar **str, const gchar *match) return FALSE; } +/* Like theme_adium_match() but also return the X part if match is like %foo{X}% */ static gboolean -theme_adium_match_with_format (const gchar **str, const gchar *match, +theme_adium_match_with_format (const gchar **str, + const gchar *match, gchar **format) { const gchar *cur = *str; @@ -503,6 +509,63 @@ theme_adium_append_event_escaped (EmpathyChatView *view, } static void +theme_adium_remove_focus_marks (EmpathyThemeAdium *theme) +{ + WebKitDOMDocument *dom; + WebKitDOMNodeList *nodes; + guint i; + GError *error = NULL; + + 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++) { + WebKitDOMNode *node = webkit_dom_node_list_item (nodes, i); + WebKitDOMHTMLElement *element = WEBKIT_DOM_HTML_ELEMENT (node); + gchar *class_name; + gchar **classes, **iter; + GString *new_class_name; + gboolean first = TRUE; + + if (element == NULL) { + continue; + } + + class_name = webkit_dom_html_element_get_class_name (element); + classes = g_strsplit (class_name, " ", -1); + new_class_name = g_string_sized_new (strlen (class_name)); + for (iter = classes; *iter != NULL; iter++) { + if (tp_strdiff (*iter, "focus") && + tp_strdiff (*iter, "firstFocus")) { + if (!first) { + g_string_append_c (new_class_name, ' '); + } + g_string_append (new_class_name, *iter); + first = FALSE; + } + } + + webkit_dom_html_element_set_class_name (element, new_class_name->str); + + g_free (class_name); + g_strfreev (classes); + g_string_free (new_class_name, TRUE); + } +} + +static void theme_adium_append_message (EmpathyChatView *view, EmpathyMessage *msg) { @@ -591,6 +654,17 @@ theme_adium_append_message (EmpathyChatView *view, /* Define message classes */ message_classes = g_string_new ("message"); + if (!priv->has_focus && !is_backlog) { + if (!priv->has_unread_message) { + /* This is the first message we receive since we lost + * focus; remove previous unread marks. */ + theme_adium_remove_focus_marks (theme); + + g_string_append (message_classes, " firstFocus"); + priv->has_unread_message = TRUE; + } + g_string_append (message_classes, " focus"); + } if (is_backlog) { g_string_append (message_classes, " history"); } @@ -608,8 +682,6 @@ theme_adium_append_message (EmpathyChatView *view, * mention - the incoming message (in groupchat) matches your username * or one of the mention keywords specified in Adium's * advanced prefs. - * focus - the message was received while focus was lost - * firstFocus - the first message received while focus was lost * status - the message is a status change * event - the message is a notification of something happening * (for example, encryption being turned on) @@ -816,6 +888,18 @@ theme_adium_copy_clipboard (EmpathyChatView *view) } static void +theme_adium_focus_toggled (EmpathyChatView *view, + gboolean has_focus) +{ + EmpathyThemeAdiumPriv *priv = GET_PRIV (view); + + priv->has_focus = has_focus; + if (priv->has_focus) { + priv->has_unread_message = FALSE; + } +} + +static void theme_adium_context_menu_selection_done_cb (GtkMenuShell *menu, gpointer user_data) { WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data); @@ -934,6 +1018,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface) iface->find_abilities = theme_adium_find_abilities; iface->highlight = theme_adium_highlight; iface->copy_clipboard = theme_adium_copy_clipboard; + iface->focus_toggled = theme_adium_focus_toggled; } static void |