From a1046a13da52e0b4ad4a552d27a535be2a604f5c Mon Sep 17 00:00:00 2001 From: likai Date: Wed, 7 Aug 2024 22:01:15 +0800 Subject: [PATCH] gesture: set widget x and y if coordinate translation between widgets fails Bug Description: In a GTK+ application with a menu bar, clicking the menu item displays a dialog. However, when the user opens this dialog and drags the parent window's menu bar with the cursor, the dialog gets moved. Issue: When _gtk_gesture_update_point calls the _update_widget_coordinates function, the local variables x and y are not explicitly initialized, leading to arbitrary values. For instance, in my case, x was 32767 and y was -145750164 . These values are used in the subsequent call to gtk_widget_translate_coordinates. In gtk_widget_translate_coordinates, if ancestor is NULL, the function returns FALSE, and dest_x and dest_y are not updated. The incorrect values of x and y cause data->widget_x and data->widget_y to be incorrect, ultimately leading to abnormal x and y values in the gtk_gesture_drag_update function. To avoid this, we should set x and y to values clearly outside the widget. Signed-off-by: Li Kai --- gtk/gtkgesture.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/gtk/gtkgesture.c b/gtk/gtkgesture.c index 48cf9ba4de..bfc8ce08a5 100644 --- a/gtk/gtkgesture.c +++ b/gtk/gtkgesture.c @@ -125,6 +125,7 @@ #include "gtkmain.h" #include "gtkintl.h" #include "gtkmarshalers.h" +#include typedef struct _GtkGesturePrivate GtkGesturePrivate; typedef struct _PointData PointData; @@ -472,7 +473,7 @@ _update_widget_coordinates (GtkGesture *gesture, GtkWidget *event_widget, *widget; GtkAllocation allocation; gdouble event_x, event_y; - gint wx, wy, x, y; + gint x, y; event_widget = gtk_get_event_widget (data->event); @@ -486,6 +487,7 @@ _update_widget_coordinates (GtkGesture *gesture, while (window && window != event_widget_window) { + gint wx, wy; gdk_window_get_position (window, &wx, &wy); event_x += wx; event_y += wy; @@ -502,13 +504,20 @@ _update_widget_coordinates (GtkGesture *gesture, event_y -= allocation.y; } - gtk_widget_translate_coordinates (event_widget, widget, - event_x, event_y, &x, &y); - /* gtk_widget_translate() loses the fractional part so we need to - * add it back to not lose accuracy */ - data->widget_x = x + (event_x - (int)event_x); - data->widget_y = y + (event_y - (int)event_y); - + if (gtk_widget_translate_coordinates (event_widget, widget, + event_x, event_y, &x, &y)) + { + /* gtk_widget_translate() loses the fractional part so we need to + * add it back to not lose accuracy */ + data->widget_x = x + (event_x - (int)event_x); + data->widget_y = y + (event_y - (int)event_y); + } + else + { + /* Mark the coordinates well outside the widget, to + * signal that the translation has failed */ + data->widget_x = data->widget_y = NAN; + } } static GtkEventSequenceState