]> git.0d.be Git - empathy.git/commitdiff
Use focus feature of adium themes
authorXavier Claessens <xclaesse@gmail.com>
Tue, 26 Apr 2011 09:52:33 +0000 (11:52 +0200)
committerXavier Claessens <xclaesse@gmail.com>
Wed, 27 Apr 2011 11:51:13 +0000 (13:51 +0200)
libempathy-gtk/empathy-chat-view.c
libempathy-gtk/empathy-chat-view.h
libempathy-gtk/empathy-chat.c
libempathy-gtk/empathy-theme-adium.c

index ada66988522a6bd2f92dc4ab168c6b9d2d0483c7..097215cfdfd615e9800b6b352191dd5c038fd89c 100644 (file)
@@ -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);
+       }
+}
+
index 96365a618d1615f8bf4034aedbe1d59bee5ee9d3..1af0721a3c3cfe7fe03fc741839af0c325e4945c 100644 (file)
@@ -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
 
index 53c4677fc6410e74415aca4c633d64d9c7b98b54..c146941b3b9157f7bc3a23d5929363f194f085fe 100644 (file)
@@ -1752,6 +1752,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,
@@ -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 */
index a90095e3ece4480accd2499e72189f5f19d753c6..2ab3383b3842d4c0e1dbab632f1d8eac7f37bd78 100644 (file)
@@ -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;
@@ -502,6 +508,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)
@@ -815,6 +887,18 @@ theme_adium_copy_clipboard (EmpathyChatView *view)
        webkit_web_view_copy_clipboard (WEBKIT_WEB_VIEW (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)
 {
@@ -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