[gtk+] popover: Hide/ungrab on button release



commit 7b4ef9932038a31961517669367d043d71a8acf5
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jan 28 14:05:08 2014 +0100

    popover: Hide/ungrab on button release
    
    If the grab is released during button press, the button release is
    just then sent to the widget below the pointer. Depending on the
    widget implementation, this could already trigger actions if the
    widget does not perform any kind of button state tracking. It is
    safer to ungrab on button release so no extra actions are possibly
    triggered, and the behavior is uniform across widgets.
    
    But the opposite situation may also happen, that a popover is
    shown/grabbed on a button press event, so it'd get the sole button
    release event after being shown, so prepare for that case by making
    popover ignore single button release events with no preceding button
    press.
    
    Fixes issues seen in
    https://bugzilla.gnome.org/show_bug.cgi?id=723031#c2

 gtk/gtkpopover.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index d0323b0..f635e6b 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -84,6 +84,7 @@ struct _GtkPopoverPrivate
   guint final_position     : 2;
   guint current_position   : 2;
   guint modal              : 1;
+  guint button_pressed     : 1;
 };
 
 static GQuark quark_widget_popovers = 0;
@@ -283,6 +284,7 @@ gtk_popover_unmap (GtkWidget *widget)
   GtkPopoverPrivate *priv;
 
   priv = GTK_POPOVER (widget)->priv;
+  priv->button_pressed = FALSE;
 
   if (priv->modal)
     gtk_popover_apply_modality (GTK_POPOVER (widget), FALSE);
@@ -1015,10 +1017,30 @@ static gboolean
 gtk_popover_button_press (GtkWidget      *widget,
                           GdkEventButton *event)
 {
+  GtkPopoverPrivate *priv;
+
+  if (event->type != GDK_BUTTON_PRESS)
+    return GDK_EVENT_PROPAGATE;
+
+  priv = gtk_popover_get_instance_private (GTK_POPOVER (widget));
+  priv->button_pressed = TRUE;
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+gtk_popover_button_release (GtkWidget      *widget,
+                           GdkEventButton *event)
+{
+  GtkPopoverPrivate *priv;
   GtkWidget *child;
 
+  priv = gtk_popover_get_instance_private (GTK_POPOVER (widget));
   child = gtk_bin_get_child (GTK_BIN (widget));
 
+  if (!priv->button_pressed)
+    return GDK_EVENT_PROPAGATE;
+
   if (child && event->window == gtk_widget_get_window (widget))
     {
       GtkAllocation child_alloc;
@@ -1111,6 +1133,7 @@ gtk_popover_class_init (GtkPopoverClass *klass)
   widget_class->size_allocate = gtk_popover_size_allocate;
   widget_class->draw = gtk_popover_draw;
   widget_class->button_press_event = gtk_popover_button_press;
+  widget_class->button_release_event = gtk_popover_button_release;
   widget_class->key_press_event = gtk_popover_key_press;
   widget_class->grab_focus = gtk_popover_grab_focus;
   widget_class->focus = gtk_popover_focus;


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