eventcontrollermotion: translate event to widget coordinates
When creating the motion controller, we know the widget that is of interest based on gtk_event_controller_motion_new(). However, not all incoming events are guaranteed to be of the GdkWindow associated to that widget. They may also be for a descendant. Therefore, it is useful to translate those coordinates into the target widget coordinate space as that is likely what they care about.
This commit is contained in:
@ -58,18 +58,49 @@ static guint signals[N_SIGNALS] = { 0 };
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GtkEventControllerMotion, gtk_event_controller_motion, GTK_TYPE_EVENT_CONTROLLER)
|
G_DEFINE_TYPE (GtkEventControllerMotion, gtk_event_controller_motion, GTK_TYPE_EVENT_CONTROLLER)
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_coords (GtkWidget *widget,
|
||||||
|
const GdkEvent *event,
|
||||||
|
double *x,
|
||||||
|
double *y)
|
||||||
|
{
|
||||||
|
GdkWindow *window, *ancestor;
|
||||||
|
GtkAllocation alloc;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &alloc);
|
||||||
|
gdk_event_get_coords (event, x, y);
|
||||||
|
|
||||||
|
ancestor = gtk_widget_get_window (widget);
|
||||||
|
window = gdk_event_get_window (event);
|
||||||
|
|
||||||
|
while (window && ancestor && (window != ancestor))
|
||||||
|
{
|
||||||
|
gdk_window_coords_to_parent (window, *x, *y, x, y);
|
||||||
|
window = gdk_window_get_parent (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_has_window (widget))
|
||||||
|
{
|
||||||
|
*x -= alloc.x;
|
||||||
|
*y -= alloc.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_event_controller_motion_handle_event (GtkEventController *controller,
|
gtk_event_controller_motion_handle_event (GtkEventController *controller,
|
||||||
const GdkEvent *event)
|
const GdkEvent *event)
|
||||||
{
|
{
|
||||||
GtkEventControllerClass *parent_class;
|
GtkEventControllerClass *parent_class;
|
||||||
|
GtkWidget *widget;
|
||||||
GdkEventType type;
|
GdkEventType type;
|
||||||
|
|
||||||
|
widget = gtk_event_controller_get_widget (controller);
|
||||||
|
|
||||||
type = gdk_event_get_event_type (event);
|
type = gdk_event_get_event_type (event);
|
||||||
if (type == GDK_ENTER_NOTIFY)
|
if (type == GDK_ENTER_NOTIFY)
|
||||||
{
|
{
|
||||||
double x, y;
|
double x, y;
|
||||||
gdk_event_get_coords (event, &x, &y);
|
get_coords (widget, event, &x, &y);
|
||||||
g_signal_emit (controller, signals[ENTER], 0, x, y);
|
g_signal_emit (controller, signals[ENTER], 0, x, y);
|
||||||
}
|
}
|
||||||
else if (type == GDK_LEAVE_NOTIFY)
|
else if (type == GDK_LEAVE_NOTIFY)
|
||||||
@ -79,7 +110,7 @@ gtk_event_controller_motion_handle_event (GtkEventController *controller,
|
|||||||
else if (type == GDK_MOTION_NOTIFY)
|
else if (type == GDK_MOTION_NOTIFY)
|
||||||
{
|
{
|
||||||
double x, y;
|
double x, y;
|
||||||
gdk_event_get_coords (event, &x, &y);
|
get_coords (widget, event, &x, &y);
|
||||||
g_signal_emit (controller, signals[MOTION], 0, x, y);
|
g_signal_emit (controller, signals[MOTION], 0, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user