aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.c16
-rw-r--r--libempathy-gtk/empathy-theme-adium.c93
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