[empathy] Use focus feature of adium themes



commit 5360a078c1b0d1e80a031fab38b865144447080d
Author: Xavier Claessens <xclaesse gmail com>
Date:   Tue Apr 26 11:52:33 2011 +0200

    Use focus feature of adium themes

 libempathy-gtk/empathy-chat-view.c   |   11 ++++
 libempathy-gtk/empathy-chat-view.h   |    4 ++
 libempathy-gtk/empathy-chat.c        |   16 +++++-
 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 ada6698..097215c 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 96365a6..1af0721 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 53c4677..c146941 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 a90095e..2ab3383 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]