[nautilus/gnome-3-20] nautilus-floating-bar: hide on hover



commit 16382ad12374ba7399a0281653d115c7bbb05eb1
Author: Carlos Soriano <csoriano gnome org>
Date:   Wed Jan 14 23:17:42 2015 +0500

    nautilus-floating-bar: hide on hover
    
    Due to the floating bar being in an overlay, it can obscure the content
    under it.
    
    We were planning to remove it and use an action bar. But it's taking
    long, so in the meantime we can improve this situations hiding the
    floating bar when hovered.
    
    On the way I improved the handling of the spinner, which was failing
    to be shown on certain situations.
    
    Patch based on Nelson Benitez, thanks!
    
    https://bugzilla.gnome.org/show_bug.cgi?id=651293

 src/nautilus-files-view.c   |    1 +
 src/nautilus-floating-bar.c |  109 ++++++++++++++++++++++++++++++-------------
 src/nautilus-floating-bar.h |    2 +
 3 files changed, 79 insertions(+), 33 deletions(-)
---
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index fd4f2f5..be8c31b 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -446,6 +446,7 @@ real_floating_bar_set_short_status (NautilusFilesView *view,
 
         if ((primary_status == NULL && detail_status == NULL) || disable_chrome) {
                 gtk_widget_hide (view->details->floating_bar);
+                nautilus_floating_bar_remove_hover_timeout (NAUTILUS_FLOATING_BAR 
(view->details->floating_bar));
                 return;
         }
 
diff --git a/src/nautilus-floating-bar.c b/src/nautilus-floating-bar.c
index 0595ddb..778b25d 100644
--- a/src/nautilus-floating-bar.c
+++ b/src/nautilus-floating-bar.c
@@ -27,6 +27,8 @@
 
 #include "nautilus-floating-bar.h"
 
+#define HOVER_HIDE_TIMEOUT_INTERVAL 100
+
 struct _NautilusFloatingBarDetails {
        gchar *primary_label;
        gchar *details_label;
@@ -36,6 +38,7 @@ struct _NautilusFloatingBarDetails {
        GtkWidget *spinner;
        gboolean show_spinner;
        gboolean is_interactive;
+       guint hover_timeout_id;
 };
 
 enum {
@@ -73,6 +76,7 @@ nautilus_floating_bar_finalize (GObject *obj)
 {
        NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (obj);
 
+        nautilus_floating_bar_remove_hover_timeout (self);
        g_free (self->priv->primary_label);
        g_free (self->priv->details_label);
 
@@ -146,30 +150,92 @@ update_labels (NautilusFloatingBar *self)
        gtk_widget_set_visible (self->priv->details_label_widget, details_visible);
 }
 
+void
+nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self)
+{
+       if (self->priv->hover_timeout_id != 0) {
+               g_source_remove (self->priv->hover_timeout_id);
+               self->priv->hover_timeout_id = 0;
+       }
+}
+
+typedef struct {
+       GtkWidget *overlay;
+       GtkWidget *floating_bar;
+       GdkDevice *device;
+       gint y_down_limit;
+       gint y_upper_limit;
+} CheckPointerData;
+
+static void
+check_pointer_data_free (gpointer data)
+{
+       g_slice_free (CheckPointerData, data);
+}
+
+static gboolean
+check_pointer_timeout (gpointer user_data)
+{
+  CheckPointerData *data = user_data;
+  gint pointer_y = -1;
+
+  gdk_window_get_device_position (gtk_widget_get_window (data->overlay), data->device,
+                                  NULL, &pointer_y, NULL);
+
+  if (pointer_y == -1 || pointer_y < data->y_down_limit || pointer_y > data->y_upper_limit) {
+       gtk_widget_show (data->floating_bar);
+       NAUTILUS_FLOATING_BAR (data->floating_bar)->priv->hover_timeout_id = 0;
+
+       return G_SOURCE_REMOVE;
+
+  } else {
+       gtk_widget_hide (data->floating_bar);
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
 static gboolean
 overlay_enter_notify_cb (GtkWidget        *parent,
                         GdkEventCrossing *event,
                         gpointer          user_data)
 {
        GtkWidget *widget = user_data;
+       CheckPointerData *data;
+       GtkAllocation alloc_parent;
+       gint y_pos;
+
+       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+
+       if (self->priv->hover_timeout_id != 0) {
+               g_source_remove (self->priv->hover_timeout_id);
+       }
 
        if (event->window != gtk_widget_get_window (widget)) {
-               return FALSE;
+               return GDK_EVENT_PROPAGATE;
        }
 
        if (NAUTILUS_FLOATING_BAR (widget)->priv->is_interactive) {
-               return FALSE;
+               return GDK_EVENT_PROPAGATE;
        }
 
-       if (gtk_widget_get_halign (widget) == GTK_ALIGN_START) {
-               gtk_widget_set_halign (widget, GTK_ALIGN_END);
-       } else {
-               gtk_widget_set_halign (widget, GTK_ALIGN_START);
-       }
+       gtk_widget_get_allocation (parent, &alloc_parent);
+       gdk_window_get_position (gtk_widget_get_window (widget), NULL, &y_pos);
+
+       data = g_slice_new (CheckPointerData);
+       data->overlay = parent;
+       data->floating_bar = widget;
+       data->device = gdk_event_get_device ((GdkEvent *) event);
+       data->y_down_limit = y_pos;
+       data->y_upper_limit = alloc_parent.height;
+
+       self->priv->hover_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, HOVER_HIDE_TIMEOUT_INTERVAL,
+                                                           check_pointer_timeout, data,
+                                                           check_pointer_data_free);
 
-       gtk_widget_queue_resize (widget);
+       g_source_set_name_by_id (self->priv->hover_timeout_id, "[nautilus-floating-bar] 
overlay_enter_notify_cb");
 
-       return FALSE;
+       return GDK_EVENT_STOP;
 }
 
 static void
@@ -192,28 +258,6 @@ nautilus_floating_bar_parent_set (GtkWidget *widget,
 }
 
 static void
-nautilus_floating_bar_show (GtkWidget *widget)
-{
-       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
-
-       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->show (widget);
-
-       if (self->priv->show_spinner) {
-               gtk_spinner_start (GTK_SPINNER (self->priv->spinner));
-       }
-}
-
-static void
-nautilus_floating_bar_hide (GtkWidget *widget)
-{
-       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
-
-       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->hide (widget);
-
-       gtk_spinner_stop (GTK_SPINNER (self->priv->spinner));
-}
-
-static void
 get_padding_and_border (GtkWidget *widget,
                         GtkBorder *border)
 {
@@ -317,6 +361,7 @@ nautilus_floating_bar_constructed (GObject *obj)
        w = gtk_spinner_new ();
        gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
        gtk_widget_set_visible (w, self->priv->show_spinner);
+        gtk_spinner_start (GTK_SPINNER (w));
        self->priv->spinner = w;
 
        gtk_widget_set_size_request (w, 16, 16);
@@ -373,8 +418,6 @@ nautilus_floating_bar_class_init (NautilusFloatingBarClass *klass)
        wclass->get_preferred_width_for_height = nautilus_floating_bar_get_preferred_width_for_height;
        wclass->get_preferred_height = nautilus_floating_bar_get_preferred_height;
        wclass->get_preferred_height_for_width = nautilus_floating_bar_get_preferred_height_for_width;
-       wclass->show = nautilus_floating_bar_show;
-       wclass->hide = nautilus_floating_bar_hide;
        wclass->parent_set = nautilus_floating_bar_parent_set;
 
        properties[PROP_PRIMARY_LABEL] =
diff --git a/src/nautilus-floating-bar.h b/src/nautilus-floating-bar.h
index 59fd1ab..adb1d4d 100644
--- a/src/nautilus-floating-bar.h
+++ b/src/nautilus-floating-bar.h
@@ -75,5 +75,7 @@ void        nautilus_floating_bar_add_action       (NautilusFloatingBar *self,
                                                    gint action_id);
 void        nautilus_floating_bar_cleanup_actions  (NautilusFloatingBar *self);
 
+void        nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self);
+
 #endif /* __NAUTILUS_FLOATING_BAR_H__ */
 


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