[gtk/wip/carlosg/for-master: 1/3] gtkpopover: Add cascade-popdown property/functions




commit 024d832d943b2abf4f0dac634d21e2781a5107d9
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Oct 13 14:26:41 2020 +0200

    gtkpopover: Add cascade-popdown property/functions
    
    And honor it in gtk_popover_popdown(). By default, a GtkPopover
    pops down automatically if a child popover was closed, if this
    property is FALSE, the popover will remain opened.

 docs/reference/gtk/gtk4-sections.txt |  2 +
 gtk/gtkpopover.c                     | 82 ++++++++++++++++++++++++++++++++++++
 gtk/gtkpopover.h                     |  5 +++
 gtk/gtkwidget.c                      |  3 ++
 4 files changed, 92 insertions(+)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 71ffac0806..bf33adde32 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -6150,6 +6150,8 @@ gtk_popover_get_has_arrow
 gtk_popover_set_offset
 gtk_popover_get_offset
 gtk_popover_set_default_widget
+gtk_popover_set_cascade_popdown
+gtk_popover_get_cascade_popdown
 <SUBSECTION Standard>
 GTK_TYPE_POPOVER
 GTK_IS_POPOVER
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index fd3567d8e2..c6fa5851d1 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -149,6 +149,7 @@ typedef struct {
   gboolean has_arrow;
   gboolean mnemonics_visible;
   gboolean disable_auto_mnemonics;
+  gboolean cascade_popdown;
 
   int x_offset;
   int y_offset;
@@ -181,6 +182,7 @@ enum {
   PROP_HAS_ARROW,
   PROP_MNEMONICS_VISIBLE,
   PROP_CHILD,
+  PROP_CASCADE_POPDOWN,
   NUM_PROPERTIES
 };
 
@@ -852,6 +854,7 @@ gtk_popover_init (GtkPopover *popover)
   priv->final_position = GTK_POS_BOTTOM;
   priv->autohide = TRUE;
   priv->has_arrow = TRUE;
+  priv->cascade_popdown = TRUE;
 
   controller = gtk_event_controller_key_new ();
   g_signal_connect_swapped (controller, "key-pressed", G_CALLBACK (gtk_popover_key_pressed), popover);
@@ -1479,6 +1482,10 @@ gtk_popover_set_property (GObject      *object,
       gtk_popover_set_child (popover, g_value_get_object (value));
       break;
 
+    case PROP_CASCADE_POPDOWN:
+      gtk_popover_set_cascade_popdown (popover, g_value_get_boolean (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1524,6 +1531,10 @@ gtk_popover_get_property (GObject      *object,
       g_value_set_object (value, gtk_popover_get_child (popover));
       break;
 
+    case PROP_CASCADE_POPDOWN:
+      g_value_set_boolean (value, priv->cascade_popdown);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1674,6 +1685,13 @@ gtk_popover_class_init (GtkPopoverClass *klass)
                            GTK_TYPE_WIDGET,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
 
+  properties[PROP_CASCADE_POPDOWN] =
+      g_param_spec_boolean ("cascade-popdown",
+                            P_("Cascade popdown"),
+                            P_("Wether the popover pops down after a child popover"),
+                            TRUE,
+                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
 
   signals[CLOSED] =
@@ -2047,6 +2065,31 @@ gtk_popover_popup (GtkPopover *popover)
   gtk_widget_show (GTK_WIDGET (popover));
 }
 
+static void
+cascade_popdown (GtkPopover *popover)
+{
+  GtkWidget *parent;
+
+  /* Do not trigger cascade close from non-modal popovers */
+  if (!gtk_popover_get_autohide (popover))
+    return;
+
+  parent = gtk_widget_get_parent (GTK_WIDGET (popover));
+
+  while (parent)
+    {
+      if (GTK_IS_POPOVER (parent))
+        {
+          if (gtk_popover_get_cascade_popdown (GTK_POPOVER (parent)))
+            gtk_widget_hide (parent);
+          else
+            break;
+        }
+
+      parent = gtk_widget_get_parent (parent);
+    }
+}
+
 /**
  * gtk_popover_popdown:
  * @popover: a #GtkPopover
@@ -2061,6 +2104,8 @@ gtk_popover_popdown (GtkPopover *popover)
   g_return_if_fail (GTK_IS_POPOVER (popover));
 
   gtk_widget_hide (GTK_WIDGET (popover));
+
+  cascade_popdown (popover);
 }
 
 GtkWidget *
@@ -2223,3 +2268,40 @@ gtk_popover_get_offset (GtkPopover *popover,
   if (y_offset)
     *y_offset = priv->y_offset;
 }
+
+/**
+ * gtk_popover_set_cascade_popdown:
+ * @popover: A #GtkPopover
+ * @cascade_popdown: #TRUE if the popover should follow a child closing
+ *
+ * If @cascade_popdown is #TRUE, the popover will be closed when a child
+ * modal popover is closed. If #FALSE, @popover will stay visible.
+ **/
+void
+gtk_popover_set_cascade_popdown (GtkPopover *popover,
+                                 gboolean    cascade_popdown)
+{
+  GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+  if (priv->cascade_popdown != !!cascade_popdown)
+    {
+      priv->cascade_popdown = !!cascade_popdown;
+      g_object_notify (G_OBJECT (popover), "cascade-popdown");
+    }
+}
+
+/**
+ * gtk_popover_get_cascade_popdown:
+ * @popover: a #GtkPopover
+ *
+ * Returns whether the popover will close after a modal child is closed.
+ *
+ * Returns: #TRUE if @popover will close after a modal child.
+ **/
+gboolean
+gtk_popover_get_cascade_popdown (GtkPopover *popover)
+{
+  GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+  return priv->cascade_popdown;
+}
diff --git a/gtk/gtkpopover.h b/gtk/gtkpopover.h
index a27fdf431a..9cb1208761 100644
--- a/gtk/gtkpopover.h
+++ b/gtk/gtkpopover.h
@@ -111,6 +111,11 @@ GDK_AVAILABLE_IN_ALL
 void            gtk_popover_get_offset (GtkPopover *popover,
                                         int        *x_offset,
                                         int        *y_offset);
+GDK_AVAILABLE_IN_ALL
+void            gtk_popover_set_cascade_popdown (GtkPopover *popover,
+                                                 gboolean    cascade_popdown);
+GDK_AVAILABLE_IN_ALL
+gboolean        gtk_popover_get_cascade_popdown (GtkPopover *popover);
 
 GDK_AVAILABLE_IN_ALL
 void gtk_popover_set_default_widget (GtkPopover *popover,
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 2ea7fb9c3a..45228b508f 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -809,6 +809,9 @@ _gtk_widget_grab_notify (GtkWidget *widget,
 
       gtk_event_controller_reset (controller);
     }
+
+  if (GTK_IS_NATIVE (widget))
+    gtk_widget_hide (widget);
 }
 
 static void


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