summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2015-01-14 23:17:42 +0500
committerCarlos Soriano <csoriano@gnome.org>2016-07-13 11:22:49 +0200
commite66d3ca6d7816b3f28d3487df1a29e26b923fd9b (patch)
tree6568bc53a26e9c0bb11164be8b6447b212053c3a
parentf0a16b15f2c9ec753deefd03146a69bb2d6b0d28 (diff)
downloadnautilus-e66d3ca6d7816b3f28d3487df1a29e26b923fd9b.tar.gz
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
-rw-r--r--src/nautilus-files-view.c1
-rw-r--r--src/nautilus-floating-bar.c109
-rw-r--r--src/nautilus-floating-bar.h2
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__ */