[libdazzle] panel: add rudimentary support for needs-attention



commit 2a76d51ded395eb16a5c6d75e210e5504d6d9c15
Author: Christian Hergert <chergert redhat com>
Date:   Mon May 6 13:18:21 2019 -0700

    panel: add rudimentary support for needs-attention
    
    This allows us to use needs-attention child-property of GtkStack
    and propagate it to the DzlTab widget so it can be styled
    appropriately by the application theme.

 src/panel/dzl-dock-item.c  | 28 ++++++++++++++++++++++++++++
 src/panel/dzl-dock-item.h  |  3 +++
 src/panel/dzl-dock-stack.c | 31 ++++++++++++++++++++++++++++++-
 src/panel/dzl-tab-strip.c  | 39 ++++++++++++++++++++++++++++++++++++++-
 4 files changed, 99 insertions(+), 2 deletions(-)
---
diff --git a/src/panel/dzl-dock-item.c b/src/panel/dzl-dock-item.c
index 53aca01..bcc09c5 100644
--- a/src/panel/dzl-dock-item.c
+++ b/src/panel/dzl-dock-item.c
@@ -34,6 +34,7 @@ G_DEFINE_INTERFACE (DzlDockItem, dzl_dock_item, GTK_TYPE_WIDGET)
 
 enum {
   MANAGER_SET,
+  NEEDS_ATTENTION,
   PRESENTED,
   N_SIGNALS
 };
@@ -166,6 +167,17 @@ dzl_dock_item_default_init (DzlDockItemInterface *iface)
                               G_TYPE_FROM_INTERFACE (iface),
                               g_cclosure_marshal_VOID__OBJECTv);
 
+  signals [NEEDS_ATTENTION] =
+    g_signal_new ("needs-attention",
+                  G_TYPE_FROM_INTERFACE (iface),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (DzlDockItemInterface, needs_attention),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+  g_signal_set_va_marshaller (signals [NEEDS_ATTENTION],
+                              G_TYPE_FROM_INTERFACE (iface),
+                              g_cclosure_marshal_VOID__VOIDv);
+
   signals [PRESENTED] =
     g_signal_new ("presented",
                   G_TYPE_FROM_INTERFACE (iface),
@@ -736,3 +748,19 @@ dzl_dock_item_ref_gicon (DzlDockItem *self)
 
   return NULL;
 }
+
+/**
+ * dzl_dock_item_needs_attention:
+ * @self: a #DzlDockItem
+ *
+ * Emits the "needs-attention" signal.
+ *
+ * Since: 3.34
+ */
+void
+dzl_dock_item_needs_attention (DzlDockItem *self)
+{
+  g_return_if_fail (DZL_IS_DOCK_ITEM (self));
+
+  g_signal_emit (self, signals [NEEDS_ATTENTION], 0);
+}
diff --git a/src/panel/dzl-dock-item.h b/src/panel/dzl-dock-item.h
index 9a95af8..0446e8f 100644
--- a/src/panel/dzl-dock-item.h
+++ b/src/panel/dzl-dock-item.h
@@ -59,6 +59,7 @@ struct _DzlDockItemInterface
                                          DzlDockItem     *child);
   void            (*presented)          (DzlDockItem     *self);
   GIcon          *(*ref_gicon)          (DzlDockItem     *self);
+  void            (*needs_attention)    (DzlDockItem     *self);
 };
 
 DZL_AVAILABLE_IN_ALL
@@ -108,6 +109,8 @@ DZL_AVAILABLE_IN_3_30
 void            dzl_dock_item_emit_presented    (DzlDockItem     *self);
 DZL_AVAILABLE_IN_3_34
 GIcon          *dzl_dock_item_ref_gicon         (DzlDockItem     *self);
+DZL_AVAILABLE_IN_3_34
+void            dzl_dock_item_needs_attention   (DzlDockItem     *self);
 G_GNUC_INTERNAL
 void            _dzl_dock_item_printf           (DzlDockItem     *self);
 
diff --git a/src/panel/dzl-dock-stack.c b/src/panel/dzl-dock-stack.c
index 62a0b0d..9fa797e 100644
--- a/src/panel/dzl-dock-stack.c
+++ b/src/panel/dzl-dock-stack.c
@@ -53,6 +53,21 @@ enum {
 
 static GParamSpec *properties [N_PROPS];
 
+static void
+dzl_dock_stack_item_needs_attention_cb (DzlDockStack *self,
+                                        DzlDockItem  *item)
+{
+  DzlDockStackPrivate *priv = dzl_dock_stack_get_instance_private (self);
+
+  g_assert (DZL_IS_DOCK_STACK (self));
+  g_assert (DZL_IS_DOCK_ITEM (item));
+
+  if (GTK_WIDGET (item) != gtk_stack_get_visible_child (priv->stack))
+    gtk_container_child_set (GTK_CONTAINER (priv->stack), GTK_WIDGET (item),
+                             "needs-attention", TRUE,
+                             NULL);
+}
+
 static void
 dzl_dock_stack_add (GtkContainer *container,
                     GtkWidget    *widget)
@@ -68,6 +83,11 @@ dzl_dock_stack_add (GtkContainer *container,
     {
       title = dzl_dock_item_get_title (DZL_DOCK_ITEM (widget));
       icon_name = dzl_dock_item_get_icon_name (DZL_DOCK_ITEM (widget));
+      g_signal_connect_object (widget,
+                               "needs-attention",
+                               G_CALLBACK (dzl_dock_stack_item_needs_attention_cb),
+                               self,
+                               G_CONNECT_SWAPPED);
     }
 
   gtk_container_add_with_properties (GTK_CONTAINER (priv->stack), widget,
@@ -111,7 +131,12 @@ dzl_dock_stack_notify_visible_child_cb (DzlDockStack *self,
     return;
 
   if ((visible_child = gtk_stack_get_visible_child (stack)) && DZL_IS_DOCK_ITEM (visible_child))
-    dzl_dock_item_emit_presented (DZL_DOCK_ITEM (visible_child));
+    {
+      gtk_container_child_set (GTK_CONTAINER (stack), visible_child,
+                               "needs-attention", FALSE,
+                               NULL);
+      dzl_dock_item_emit_presented (DZL_DOCK_ITEM (visible_child));
+    }
 }
 
 static void
@@ -436,6 +461,10 @@ dzl_dock_stack_release (DzlDockItem *item,
   g_assert (DZL_IS_DOCK_STACK (self));
   g_assert (DZL_IS_DOCK_ITEM (child));
 
+  g_signal_handlers_disconnect_by_func (child,
+                                        G_CALLBACK (dzl_dock_stack_item_needs_attention_cb),
+                                        self);
+
   gtk_container_remove (GTK_CONTAINER (priv->stack), GTK_WIDGET (child));
 }
 
diff --git a/src/panel/dzl-tab-strip.c b/src/panel/dzl-tab-strip.c
index 9a7f476..75a7ff7 100644
--- a/src/panel/dzl-tab-strip.c
+++ b/src/panel/dzl-tab-strip.c
@@ -25,6 +25,7 @@
 #include "panel/dzl-dock-widget.h"
 #include "panel/dzl-tab.h"
 #include "panel/dzl-tab-strip.h"
+#include "util/dzl-gtk.h"
 #include "util/dzl-macros.h"
 
 typedef struct
@@ -447,6 +448,28 @@ dzl_tab_strip_gicon_changed (DzlDockItem *item,
     dzl_tab_set_gicon (tab, icon);
 }
 
+static void
+dzl_tab_strip_child_needs_attention (DzlTab     *tab,
+                                     GParamSpec *pspec,
+                                     GtkWidget  *child)
+{
+  GtkWidget *parent;
+  gboolean needs_attention;
+
+  g_assert (DZL_IS_TAB (tab));
+  g_assert (GTK_IS_WIDGET (child));
+
+  parent = gtk_widget_get_parent (child);
+  gtk_container_child_get (GTK_CONTAINER (parent), child,
+                           "needs-attention", &needs_attention,
+                           NULL);
+
+  if (needs_attention)
+    dzl_gtk_widget_add_style_class (GTK_WIDGET (tab), "needs-attention");
+  else
+    dzl_gtk_widget_remove_style_class (GTK_WIDGET (tab), "needs-attention");
+}
+
 static void
 dzl_tab_strip_stack_add (DzlTabStrip *self,
                          GtkWidget   *widget,
@@ -454,8 +477,9 @@ dzl_tab_strip_stack_add (DzlTabStrip *self,
 {
   DzlTabStripPrivate *priv = dzl_tab_strip_get_instance_private (self);
   g_autoptr(GVariant) target = g_variant_ref_sink (g_variant_new_int32 (0));
-  DzlTab *tab;
+  gboolean needs_attention = FALSE;
   gboolean can_close = FALSE;
+  DzlTab *tab;
 
   g_assert (DZL_IS_TAB_STRIP (self));
   g_assert (GTK_IS_WIDGET (widget));
@@ -475,12 +499,25 @@ dzl_tab_strip_stack_add (DzlTabStrip *self,
 
   g_object_set_data (G_OBJECT (widget), "DZL_TAB", tab);
 
+  gtk_container_child_get (GTK_CONTAINER (stack), widget,
+                           "needs-attention", &needs_attention,
+                           NULL);
+
+  if (needs_attention)
+    dzl_gtk_widget_add_style_class (GTK_WIDGET (tab), "needs-attention");
+
   g_signal_connect_object (tab,
                            "clicked",
                            G_CALLBACK (dzl_tab_strip_tab_clicked),
                            self,
                            G_CONNECT_SWAPPED | G_CONNECT_AFTER);
 
+  g_signal_connect_object (widget,
+                           "child-notify::needs-attention",
+                           G_CALLBACK (dzl_tab_strip_child_needs_attention),
+                           tab,
+                           G_CONNECT_SWAPPED);
+
   g_signal_connect_object (widget,
                            "child-notify::position",
                            G_CALLBACK (dzl_tab_strip_child_position_changed),


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