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
parent f0a16b15
......@@ -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;
}
......
......@@ -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
......@@ -190,28 +256,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] =
......
......@@ -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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment