[epiphany] Replace current notebook tab label widget with an own widget



commit 02fd8a2685cf3f4e91ce80b1f82e58c605f82ca9
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Sun Mar 24 14:52:34 2019 +0100

    Replace current notebook tab label widget with an own widget
    
    Introducing EphyTabLabel widget which handels everything within notebook tab label. This builds the
    starting point for upcoming changes.

 src/ephy-notebook.c                  | 208 +++----------------------------
 src/ephy-tab-label.c                 | 232 +++++++++++++++++++++++++++++++++++
 src/ephy-tab-label.h                 |  36 ++++++
 src/meson.build                      |   1 +
 src/resources/epiphany.gresource.xml |   1 +
 src/resources/gtk/tab-label.ui       |  89 ++++++++++++++
 6 files changed, 375 insertions(+), 192 deletions(-)
---
diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c
index 90aa30b2a..fa1c0c0fe 100644
--- a/src/ephy-notebook.c
+++ b/src/ephy-notebook.c
@@ -33,6 +33,7 @@
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
 #include "ephy-shell.h"
+#include "ephy-tab-label.h"
 #include "ephy-window.h"
 
 #include <glib/gi18n.h>
@@ -560,7 +561,6 @@ get_nth_tab_label_text (GtkNotebook *notebook,
 {
   GtkWidget *page;
   GtkWidget *tab_label;
-  GtkWidget *label;
 
   g_assert (n >= 0);
 
@@ -568,12 +568,9 @@ get_nth_tab_label_text (GtkNotebook *notebook,
   g_assert (page != NULL);
 
   tab_label = gtk_notebook_get_tab_label (notebook, page);
-  g_assert (GTK_IS_BOX (tab_label));
+  g_assert (EPHY_IS_TAB_LABEL (tab_label));
 
-  label = g_object_get_data (G_OBJECT (tab_label), "label");
-  g_assert (GTK_IS_LABEL (label));
-
-  return gtk_label_get_text (GTK_LABEL (label));
+  return ephy_tab_label_get_text (tab_label);
 }
 
 static char *
@@ -634,52 +631,6 @@ ephy_notebook_rebuild_tab_menu (EphyNotebook *notebook)
   g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_uint32 ((guint32)current_page));
 }
 
-static void
-sync_load_status (EphyWebView *view, GParamSpec *pspec, GtkWidget *proxy)
-{
-  GtkWidget *spinner, *icon;
-  EphyEmbed *embed;
-
-  spinner = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "spinner"));
-  icon = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "icon"));
-  g_assert (spinner != NULL && icon != NULL);
-
-  embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (view);
-  if (ephy_web_view_is_loading (view) && !ephy_embed_has_load_pending (embed)) {
-    gtk_widget_hide (icon);
-    gtk_widget_show (spinner);
-    gtk_spinner_start (GTK_SPINNER (spinner));
-  } else {
-    gtk_spinner_stop (GTK_SPINNER (spinner));
-    gtk_widget_hide (spinner);
-    gtk_widget_show (icon);
-  }
-}
-
-static void
-load_changed_cb (EphyWebView *view, WebKitLoadEvent load_event, GtkWidget *proxy)
-{
-  sync_load_status (view, NULL, proxy);
-}
-
-static void
-sync_icon (EphyWebView *view,
-           GParamSpec  *pspec,
-           GtkImage    *icon)
-{
-  gtk_image_set_from_pixbuf (icon, ephy_web_view_get_icon (view));
-}
-
-static void
-sync_label (EphyEmbed *embed, GParamSpec *pspec, GtkWidget *label)
-{
-  const char *title;
-
-  title = ephy_embed_get_title (embed);
-  gtk_label_set_text (GTK_LABEL (label), title);
-  gtk_widget_set_tooltip_text (label, title);
-}
-
 static void
 rebuild_tab_menu_cb (EphyEmbed    *embed,
                      GParamSpec   *pspec,
@@ -688,14 +639,6 @@ rebuild_tab_menu_cb (EphyEmbed    *embed,
   ephy_notebook_rebuild_tab_menu (notebook);
 }
 
-static void
-sync_is_playing_audio (WebKitWebView *view,
-                       GParamSpec    *pspec,
-                       GtkWidget     *speaker_icon)
-{
-  gtk_widget_set_visible (speaker_icon, webkit_web_view_is_playing_audio (view));
-}
-
 static void
 close_button_clicked_cb (GtkWidget *widget, GtkWidget *tab)
 {
@@ -705,133 +648,35 @@ close_button_clicked_cb (GtkWidget *widget, GtkWidget *tab)
   g_signal_emit (notebook, signals[TAB_CLOSE_REQUEST], 0, tab);
 }
 
-static void
-tab_label_style_set_cb (GtkWidget *hbox,
-                        GtkStyle  *previous_style,
-                        gpointer   user_data)
-{
-  PangoFontMetrics *metrics;
-  PangoContext *context;
-  GtkStyleContext *style;
-  PangoFontDescription *font_desc;
-  GtkWidget *button;
-  int char_width, h, w;
-
-  context = gtk_widget_get_pango_context (hbox);
-  style = gtk_widget_get_style_context (hbox);
-  gtk_style_context_get (style, gtk_style_context_get_state (style),
-                         "font", &font_desc, NULL);
-  metrics = pango_context_get_metrics (context,
-                                       font_desc,
-                                       pango_context_get_language (context));
-  pango_font_description_free (font_desc);
-  char_width = pango_font_metrics_get_approximate_digit_width (metrics);
-  pango_font_metrics_unref (metrics);
-
-  gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
-
-  gtk_widget_set_size_request (hbox, TAB_WIDTH_N_CHARS * PANGO_PIXELS (char_width) + 2 * w, -1);
-
-  button = g_object_get_data (G_OBJECT (hbox), "close-button");
-  gtk_widget_set_size_request (button, w + 2, h + 2);
-}
-
 static GtkWidget *
 build_tab_label (EphyNotebook *nb, EphyEmbed *embed)
 {
-  GtkWidget *hbox, *label, *close_button, *image, *spinner, *icon, *speaker_icon;
-  GtkWidget *box;
+  GtkWidget *tab_label;
   EphyWebView *view;
-  GtkPositionType type = ephy_settings_get_tabs_bar_position ();
 
-  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
-  gtk_widget_show (box);
-
-  /* set hbox spacing and label padding (see below) so that there's an
-   * equal amount of space around the label */
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-  gtk_widget_show (hbox);
-  box_set_halign (hbox, type);
-  gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 0);
-
-  /* setup load feedback */
-  spinner = gtk_spinner_new ();
-  gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
-
-  /* setup site icon, empty by default */
-  icon = gtk_image_new ();
-  gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-  /* don't show the icon */
-
-  /* setup label */
-  label = gtk_label_new (NULL);
-  gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
-  gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
-  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-  gtk_widget_show (label);
-
-  /* setup speaker icon */
-  speaker_icon = gtk_image_new_from_icon_name ("audio-volume-high-symbolic",
-                                               GTK_ICON_SIZE_MENU);
-  gtk_box_pack_start (GTK_BOX (hbox), speaker_icon, FALSE, FALSE, 0);
-
-  /* setup close button */
-  close_button = gtk_button_new ();
-  gtk_button_set_relief (GTK_BUTTON (close_button),
-                         GTK_RELIEF_NONE);
-  /* don't allow focus on the close button */
-  gtk_widget_set_focus_on_click (close_button, FALSE);
-
-  gtk_widget_set_name (close_button, "ephy-tab-close-button");
-
-  image = gtk_image_new_from_icon_name ("window-close-symbolic",
-                                        GTK_ICON_SIZE_MENU);
-  gtk_widget_set_tooltip_text (close_button, _("Close tab"));
-  g_signal_connect (close_button, "clicked",
-                    G_CALLBACK (close_button_clicked_cb), embed);
-
-  gtk_container_add (GTK_CONTAINER (close_button), image);
-  gtk_widget_show (image);
-
-  gtk_box_pack_start (GTK_BOX (box), close_button, FALSE, FALSE, 0);
-  gtk_widget_show (close_button);
-
-  /* Set minimal size */
-  g_signal_connect (box, "style-set",
-                    G_CALLBACK (tab_label_style_set_cb), NULL);
+  tab_label = ephy_tab_label_new ();
+  g_signal_connect (tab_label, "close-clicked", G_CALLBACK (close_button_clicked_cb), embed);
 
   /* Set up drag-and-drop target */
-  g_signal_connect (box, "drag-data-received",
+  g_signal_connect (tab_label, "drag-data-received",
                     G_CALLBACK (notebook_drag_data_received_cb), embed);
-  gtk_drag_dest_set (box, GTK_DEST_DEFAULT_ALL,
+  gtk_drag_dest_set (tab_label, GTK_DEST_DEFAULT_ALL,
                      url_drag_types, G_N_ELEMENTS (url_drag_types),
                      GDK_ACTION_MOVE | GDK_ACTION_COPY);
-  gtk_drag_dest_add_text_targets (box);
-
-  g_object_set_data (G_OBJECT (box), "label", label);
-  g_object_set_data (G_OBJECT (box), "spinner", spinner);
-  g_object_set_data (G_OBJECT (box), "icon", icon);
-  g_object_set_data (G_OBJECT (box), "close-button", close_button);
-  g_object_set_data (G_OBJECT (box), "speaker-icon", speaker_icon);
+  gtk_drag_dest_add_text_targets (tab_label);
 
   /* Hook the label up to the tab properties */
   view = ephy_embed_get_web_view (embed);
-  sync_icon (view, NULL, GTK_IMAGE (icon));
-  sync_label (embed, NULL, label);
-  sync_load_status (view, NULL, box);
-  sync_is_playing_audio (WEBKIT_WEB_VIEW (view), NULL, speaker_icon);
 
-  g_signal_connect_object (view, "notify::icon",
-                           G_CALLBACK (sync_icon), icon, 0);
-  g_signal_connect_object (embed, "notify::title",
-                           G_CALLBACK (sync_label), label, 0);
   g_signal_connect_object (embed, "notify::title",
                            G_CALLBACK (rebuild_tab_menu_cb), nb, 0);
-  g_signal_connect_object (view, "load-changed",
-                           G_CALLBACK (load_changed_cb), box, 0);
-  g_signal_connect_object (view, "notify::is-playing-audio",
-                           G_CALLBACK (sync_is_playing_audio), speaker_icon, 0);
-  return box;
+
+  g_object_bind_property (view, "title", tab_label, "label-text", G_BINDING_DEFAULT);
+  g_object_bind_property (view, "icon", tab_label, "icon-buf", G_BINDING_DEFAULT);
+  g_object_bind_property (view, "is-loading", tab_label, "spinning", G_BINDING_DEFAULT);
+  g_object_bind_property (view, "is-playing-audio", tab_label, "audio", G_BINDING_DEFAULT);
+
+  return tab_label;
 }
 
 void
@@ -945,9 +790,7 @@ ephy_notebook_remove (GtkContainer *container,
 {
   GtkNotebook *gnotebook = GTK_NOTEBOOK (container);
   EphyNotebook *notebook = EPHY_NOTEBOOK (container);
-  GtkWidget *tab_label, *tab_label_label, *tab_label_icon, *tab_label_speaker_icon;
   int position, curr;
-  EphyWebView *view;
 
   if (!EPHY_IS_EMBED (tab_widget))
     return;
@@ -962,25 +805,6 @@ ephy_notebook_remove (GtkContainer *container,
     smart_tab_switching_on_closure (notebook, tab_widget);
   }
 
-  /* Prepare tab label for destruction */
-  tab_label = gtk_notebook_get_tab_label (gnotebook, tab_widget);
-  tab_label_icon = g_object_get_data (G_OBJECT (tab_label), "icon");
-  tab_label_label = g_object_get_data (G_OBJECT (tab_label), "label");
-  tab_label_speaker_icon = g_object_get_data (G_OBJECT (tab_label), "speaker-icon");
-
-  view = ephy_embed_get_web_view (EPHY_EMBED (tab_widget));
-
-  g_signal_handlers_disconnect_by_func
-    (view, G_CALLBACK (sync_icon), tab_label_icon);
-  g_signal_handlers_disconnect_by_func
-    (tab_widget, G_CALLBACK (sync_label), tab_label_label);
-  g_signal_handlers_disconnect_by_func
-    (tab_widget, G_CALLBACK (sync_label), notebook);
-  g_signal_handlers_disconnect_by_func
-    (view, G_CALLBACK (sync_load_status), tab_label);
-  g_signal_handlers_disconnect_by_func
-    (view, G_CALLBACK (sync_is_playing_audio), tab_label_speaker_icon);
-
   GTK_CONTAINER_CLASS (ephy_notebook_parent_class)->remove (container, tab_widget);
 
   update_tabs_visibility (notebook, FALSE);
diff --git a/src/ephy-tab-label.c b/src/ephy-tab-label.c
new file mode 100644
index 000000000..0820f7bce
--- /dev/null
+++ b/src/ephy-tab-label.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Jan-Michael Brummer
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ephy-embed.h"
+#include "ephy-tab-label.h"
+
+#define TAB_WIDTH_N_CHARS 15
+
+struct _EphyTabLabel {
+  GtkBox parent_instance;
+
+  GtkWidget *spinner;
+  GtkWidget *icon;
+  GtkWidget *label;
+  GtkWidget *close_button;
+  GtkWidget *audio_button;
+};
+
+enum {
+  CLOSE_CLICKED,
+  LAST_SIGNAL
+};
+
+enum {
+  PROP_0,
+  PROP_LABEL_TEXT,
+  PROP_ICON_BUF,
+  PROP_SPINNING,
+  PROP_AUDIO,
+  LAST_PROP
+};
+
+static GParamSpec *obj_properties[LAST_PROP];
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EphyTabLabel, ephy_tab_label, GTK_TYPE_BOX)
+
+static void
+ephy_tab_label_set_spinning (EphyTabLabel *tab_label,
+                             gboolean      is_spinning)
+{
+  g_object_set (tab_label->spinner, "active", is_spinning, NULL);
+  g_object_set (tab_label->icon, "visible", !is_spinning, NULL);
+  g_object_set (tab_label->spinner, "visible", is_spinning, NULL);
+}
+
+static void
+ephy_tab_label_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  EphyTabLabel *self = EPHY_TAB_LABEL (object);
+
+  switch (prop_id) {
+  case PROP_LABEL_TEXT:
+    gtk_label_set_text (GTK_LABEL (self->label), g_value_get_string((value)));
+    gtk_widget_set_tooltip_text (GTK_WIDGET (self), g_value_get_string((value)));
+    break;
+  case PROP_ICON_BUF:
+    gtk_image_set_from_pixbuf (GTK_IMAGE (self->icon), g_value_get_object(value));
+    break;
+  case PROP_SPINNING:
+    ephy_tab_label_set_spinning (self, g_value_get_boolean(value));
+    break;
+  case PROP_AUDIO:
+    gtk_widget_set_visible (self->audio_button, g_value_get_boolean(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+ephy_tab_label_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  EphyTabLabel *self = EPHY_TAB_LABEL (object);
+  gboolean spinning = FALSE;
+
+  switch (prop_id) {
+  case PROP_LABEL_TEXT:
+    g_value_set_string (value, gtk_label_get_text (GTK_LABEL (self->label)));
+    break;
+  case PROP_ICON_BUF:
+    g_value_set_object (value, gtk_image_get_pixbuf (GTK_IMAGE (self->icon)));
+    break;
+  case PROP_SPINNING:
+    g_object_get (self->spinner, "active", &spinning, NULL);
+    g_value_set_boolean (value, spinning);
+    break;
+  case PROP_AUDIO:
+    g_value_set_boolean (value, gtk_widget_get_visible (self->audio_button));
+    break;
+  default:
+   G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+   break;
+  }
+}
+
+static void
+ephy_tab_label_init (EphyTabLabel *self)
+{
+   gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+static void
+close_button_clicked_cb (GtkWidget     *widget,
+                         EphyTabLabel  *tab_label)
+{
+  g_signal_emit (tab_label, signals[CLOSE_CLICKED], 0, NULL);
+}
+
+static void
+style_updated_cb (GtkWidget *widget,
+                  gpointer   user_data)
+{
+  PangoFontMetrics *metrics;
+  PangoContext *context;
+  GtkStyleContext *style;
+  PangoFontDescription *font_desc;
+  EphyTabLabel *self = EPHY_TAB_LABEL (widget);
+  int char_width, h, w;
+
+  context = gtk_widget_get_pango_context (widget);
+  style = gtk_widget_get_style_context (widget);
+  gtk_style_context_get (style, gtk_style_context_get_state (style), "font", &font_desc, NULL);
+  metrics = pango_context_get_metrics (context, font_desc, pango_context_get_language (context));
+  pango_font_description_free (font_desc);
+  char_width = pango_font_metrics_get_approximate_digit_width (metrics);
+  pango_font_metrics_unref (metrics);
+
+  gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
+
+  gtk_widget_set_size_request (widget, TAB_WIDTH_N_CHARS * PANGO_PIXELS (char_width) + 2 * w, -1);
+
+  gtk_widget_set_size_request (self->close_button, w + 2, h + 2);
+}
+
+static void
+ephy_tab_label_class_init (EphyTabLabelClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->set_property = ephy_tab_label_set_property;
+  object_class->get_property = ephy_tab_label_get_property;
+
+  obj_properties[PROP_LABEL_TEXT] = g_param_spec_string ("label-text",
+                                                         "Label Text",
+                                                         "The displayed text",
+                                                         "",
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT);
+
+  obj_properties[PROP_ICON_BUF] = g_param_spec_object ("icon-buf",
+                                                       "Icon Buffer",
+                                                       "Buffer of the icon to be displayed",
+                                                       GDK_TYPE_PIXBUF,
+                                                       G_PARAM_READWRITE |
+                                                       G_PARAM_CONSTRUCT);
+  obj_properties[PROP_SPINNING] = g_param_spec_boolean ("spinning",
+                                                        "Spinning",
+                                                        "Is the spinner spinning",
+                                                        FALSE,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT);
+  obj_properties[PROP_AUDIO] = g_param_spec_boolean ("audio",
+                                                     "Audio",
+                                                     "Is audio playing",
+                                                     FALSE,
+                                                     G_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT);
+  g_object_class_install_properties (object_class, LAST_PROP, obj_properties);
+
+  signals[CLOSE_CLICKED] = g_signal_new ("close-clicked",
+                                         EPHY_TYPE_TAB_LABEL,
+                                         G_SIGNAL_RUN_LAST,
+                                         0,
+                                         NULL, NULL,
+                                         NULL,
+                                         G_TYPE_NONE,
+                                         0);
+
+  /* Bind class to template */
+  gtk_widget_class_set_template_from_resource (widget_class,  "/org/gnome/epiphany/gtk/tab-label.ui");
+
+  gtk_widget_class_bind_template_child (widget_class, EphyTabLabel, spinner);
+  gtk_widget_class_bind_template_child (widget_class, EphyTabLabel, icon);
+  gtk_widget_class_bind_template_child (widget_class, EphyTabLabel, label);
+  gtk_widget_class_bind_template_child (widget_class, EphyTabLabel, audio_button);
+  gtk_widget_class_bind_template_child (widget_class, EphyTabLabel, close_button);
+
+  gtk_widget_class_bind_template_callback (widget_class, close_button_clicked_cb);
+  gtk_widget_class_bind_template_callback (widget_class, style_updated_cb);
+}
+
+GtkWidget *
+ephy_tab_label_new (void)
+{
+  return g_object_new (EPHY_TYPE_TAB_LABEL, "homogeneous", FALSE, NULL);
+}
+
+const gchar *
+ephy_tab_label_get_text (GtkWidget *widget)
+{
+  EphyTabLabel *self = EPHY_TAB_LABEL (widget);
+
+  return gtk_label_get_text (GTK_LABEL (self->label));
+}
diff --git a/src/ephy-tab-label.h b/src/ephy-tab-label.h
new file mode 100644
index 000000000..86cb7f63b
--- /dev/null
+++ b/src/ephy-tab-label.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ *  Copyright © 2019 Jan-Michael Brummer
+ *
+ *  This file is part of Epiphany.
+ *
+ *  Epiphany is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Epiphany is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Epiphany.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ephy-window.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_TAB_LABEL (ephy_tab_label_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyTabLabel, ephy_tab_label, EPHY, TAB_LABEL, GtkBox);
+
+GtkWidget   *ephy_tab_label_new      (void);
+const gchar *ephy_tab_label_get_text (GtkWidget *self);
+
+G_END_DECLS
diff --git a/src/meson.build b/src/meson.build
index 40cb73a04..899aacd58 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -40,6 +40,7 @@ libephymain_sources = [
   'ephy-session.c',
   'ephy-shell.c',
   'ephy-suggestion-model.c',
+  'ephy-tab-label.c',
   'ephy-window.c',
   'passwords-dialog.c',
   'popup-commands.c',
diff --git a/src/resources/epiphany.gresource.xml b/src/resources/epiphany.gresource.xml
index e26159f15..091d16a1f 100644
--- a/src/resources/epiphany.gresource.xml
+++ b/src/resources/epiphany.gresource.xml
@@ -32,6 +32,7 @@
     <file preprocess="xml-stripblanks" compressed="true">gtk/search-engine-dialog.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">gtk/synced-tabs-dialog.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">gtk/shortcuts-dialog.ui</file>
+    <file preprocess="xml-stripblanks" compressed="true">gtk/tab-label.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">gtk/webapp-additional-urls-dialog.ui</file>
     <file compressed="true">readability.js</file>
     <file compressed="true">reader.css</file>
diff --git a/src/resources/gtk/tab-label.ui b/src/resources/gtk/tab-label.ui
new file mode 100644
index 000000000..27c719b30
--- /dev/null
+++ b/src/resources/gtk/tab-label.ui
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkImage" id="audio_button_image">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">audio-volume-high-symbolic</property>
+  </object>
+  <object class="GtkImage" id="close_button_image">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">window-close-symbolic</property>
+  </object>
+  <template class="EphyTabLabel" parent="GtkBox">
+    <property name="can_focus">False</property>
+    <property name="spacing">6</property>
+    <signal name="style-updated" handler="style_updated_cb" swapped="no"/>
+    <child>
+      <object class="GtkImage" id="icon">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkSpinner" id="spinner">
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="center">
+      <object class="GtkLabel" id="label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="ellipsize">end</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkButton" id="close_button">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="focus_on_click">False</property>
+        <property name="receives_default">False</property>
+        <property name="tooltip_text" translatable="yes">Close Document</property>
+        <property name="image">close_button_image</property>
+        <property name="relief">none</property>
+        <signal name="clicked" handler="close_button_clicked_cb" object="EphyTabLabel" swapped="no"/>
+        <style>
+          <class name="small-button"/>
+          <class name="flat"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="pack_type">end</property>
+        <property name="position">3</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkButton" id="audio_button">
+        <property name="can_focus">True</property>
+        <property name="receives_default">True</property>
+        <property name="image">audio_button_image</property>
+        <property name="relief">none</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="pack_type">end</property>
+        <property name="position">5</property>
+      </packing>
+    </child>
+  </template>
+</interface>


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