summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntónio Fernandes <antoniof@gnome.org>2021-08-05 19:11:59 +0100
committerAntónio Fernandes <antoniojpfernandes@gmail.com>2021-12-22 01:38:47 +0000
commit48c083e909a13a85f16e1c776ec225b73a0fadea (patch)
tree487d0124b038408b62f21353e542c6b5e7712882
parent87b93eb803586b7c4c45316bc19722d1b4e9859c (diff)
downloadnautilus-48c083e909a13a85f16e1c776ec225b73a0fadea.tar.gz
floating-bar: Use GdkEventControllerMotion
The ::event signal won't exist in GTK4. Based on Ernestas Kulik's earlier port.
-rw-r--r--src/nautilus-floating-bar.c100
1 files changed, 60 insertions, 40 deletions
diff --git a/src/nautilus-floating-bar.c b/src/nautilus-floating-bar.c
index 4d166d4d8..8f6393cf8 100644
--- a/src/nautilus-floating-bar.c
+++ b/src/nautilus-floating-bar.c
@@ -43,6 +43,9 @@ struct _NautilusFloatingBar
gboolean show_stop;
gboolean is_interactive;
guint hover_timeout_id;
+
+ GtkEventController *motion_controller;
+ double pointer_y_in_parent_coordinates;
};
enum
@@ -81,6 +84,7 @@ nautilus_floating_bar_finalize (GObject *obj)
nautilus_floating_bar_remove_hover_timeout (self);
g_free (self->primary_label);
g_free (self->details_label);
+ g_clear_object (&self->motion_controller);
G_OBJECT_CLASS (nautilus_floating_bar_parent_class)->finalize (obj);
}
@@ -200,9 +204,7 @@ nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self)
typedef struct
{
- GtkWidget *overlay;
- GtkWidget *floating_bar;
- GdkDevice *device;
+ NautilusFloatingBar *floating_bar;
gint y_down_limit;
gint y_upper_limit;
} CheckPointerData;
@@ -217,92 +219,107 @@ 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);
+ NautilusFloatingBar *self = data->floating_bar;
+ double pointer_y = self->pointer_y_in_parent_coordinates;
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)->hover_timeout_id = 0;
+ gtk_widget_show (GTK_WIDGET (self));
+ self->hover_timeout_id = 0;
return G_SOURCE_REMOVE;
}
else
{
- gtk_widget_hide (data->floating_bar);
+ gtk_widget_hide (GTK_WIDGET (self));
}
return G_SOURCE_CONTINUE;
}
-static gboolean
-overlay_event_cb (GtkWidget *parent,
- GdkEvent *event,
- gpointer user_data)
+static void
+on_event_controller_motion_enter (GtkEventControllerMotion *controller,
+ double x,
+ double y,
+ gpointer user_data)
{
NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (user_data);
- GtkWidget *widget = user_data;
CheckPointerData *data;
gint y_pos;
- if (gdk_event_get_event_type (event) != GDK_ENTER_NOTIFY)
- {
- return GDK_EVENT_PROPAGATE;
- }
+ self->pointer_y_in_parent_coordinates = y;
- if (self->hover_timeout_id != 0)
+ if (self->is_interactive || !gtk_widget_is_visible (GTK_WIDGET (self)))
{
- g_source_remove (self->hover_timeout_id);
+ return;
}
- if (gdk_event_get_window (event) != gtk_widget_get_window (widget))
+ gdk_window_get_position (gtk_widget_get_window (GTK_WIDGET (self)), NULL, &y_pos);
+ if (y < y_pos)
{
- return GDK_EVENT_PROPAGATE;
+ return;
}
- if (self->is_interactive)
+ if (self->hover_timeout_id != 0)
{
- return GDK_EVENT_PROPAGATE;
+ g_source_remove (self->hover_timeout_id);
}
- 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 (event);
+ data->floating_bar = self;
data->y_down_limit = y_pos;
- data->y_upper_limit = y_pos + gtk_widget_get_allocated_height (widget);
+ data->y_upper_limit = y_pos + gtk_widget_get_allocated_height (GTK_WIDGET (self));
self->hover_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, HOVER_HIDE_TIMEOUT_INTERVAL,
check_pointer_timeout, data,
check_pointer_data_free);
- g_source_set_name_by_id (self->hover_timeout_id, "[nautilus-floating-bar] overlay_event_cb");
+ g_source_set_name_by_id (self->hover_timeout_id, "[nautilus-floating-bar] on_event_controller_motion_enter");
+}
+
+static void
+on_event_controller_motion_leave (GtkEventControllerMotion *controller,
+ gpointer user_data)
+{
+ NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (user_data);
- return GDK_EVENT_STOP;
+ self->pointer_y_in_parent_coordinates = -1;
+}
+
+static void
+on_event_controller_motion_motion (GtkEventControllerMotion *controller,
+ double x,
+ double y,
+ gpointer user_data)
+{
+ NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (user_data);
+
+ self->pointer_y_in_parent_coordinates = y;
}
static void
nautilus_floating_bar_parent_set (GtkWidget *widget,
GtkWidget *old_parent)
{
+ NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
GtkWidget *parent;
parent = gtk_widget_get_parent (widget);
- if (old_parent != NULL)
- {
- g_signal_handlers_disconnect_by_func (old_parent,
- overlay_event_cb, widget);
- }
+ g_clear_object (&self->motion_controller);
if (parent != NULL)
{
- g_signal_connect (parent, "event",
- G_CALLBACK (overlay_event_cb), widget);
+ self->motion_controller = gtk_event_controller_motion_new (parent);
+
+ gtk_event_controller_set_propagation_phase (self->motion_controller,
+ GTK_PHASE_CAPTURE);
+ g_signal_connect (self->motion_controller, "enter",
+ G_CALLBACK (on_event_controller_motion_enter), self);
+ g_signal_connect (self->motion_controller, "leave",
+ G_CALLBACK (on_event_controller_motion_leave), self);
+ g_signal_connect (self->motion_controller, "motion",
+ G_CALLBACK (on_event_controller_motion_motion), self);
}
}
@@ -467,6 +484,9 @@ nautilus_floating_bar_init (NautilusFloatingBar *self)
context = gtk_widget_get_style_context (GTK_WIDGET (self));
gtk_style_context_add_class (context, "floating-bar");
+
+ self->motion_controller = NULL;
+ self->pointer_y_in_parent_coordinates = -1;
}
static void