diff options
-rw-r--r-- | src/nautilus-files-view.c | 1 | ||||
-rw-r--r-- | src/nautilus-floating-bar.c | 109 | ||||
-rw-r--r-- | 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 ac84b7333..bf8fc5f83 100644 --- a/src/nautilus-files-view.c +++ b/src/nautilus-files-view.c @@ -445,6 +445,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 5ab1527cd..97c223a7d 100644 --- a/src/nautilus-floating-bar.c +++ b/src/nautilus-floating-bar.c @@ -26,6 +26,8 @@ #include "nautilus-floating-bar.h" +#define HOVER_HIDE_TIMEOUT_INTERVAL 100 + struct _NautilusFloatingBarDetails { gchar *primary_label; gchar *details_label; @@ -35,6 +37,7 @@ struct _NautilusFloatingBarDetails { GtkWidget *spinner; gboolean show_spinner; gboolean is_interactive; + guint hover_timeout_id; }; enum { @@ -72,6 +75,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); @@ -145,30 +149,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 @@ -191,28 +257,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) { @@ -316,6 +360,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); @@ -372,8 +417,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 f0b08a97a..ebe8e14d5 100644 --- a/src/nautilus-floating-bar.h +++ b/src/nautilus-floating-bar.h @@ -74,5 +74,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__ */ |