[gtk/wip/exalm/consumes-motion: 5/6] dragsource: Use double coordinates for checking drag threshold
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/exalm/consumes-motion: 5/6] dragsource: Use double coordinates for checking drag threshold
- Date: Fri, 25 Dec 2020 21:23:52 +0000 (UTC)
commit 7b893660a43121a51b6bf6ad1ac52317803a46ba
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Fri Dec 25 22:57:48 2020 +0500
dragsource: Use double coordinates for checking drag threshold
If multiple nested widgets have drag sources on them, both using bubble
phase, we need to reliably pick the inner one. Both of them will try to
start dragging, and we need to make sure there are no situations where the
outer widget starts drag earlier and cancels the inner one.
Currently, this can easily happen via integer rounding: start and current
coordinates passed into gtk_drag_check_threshold() are initially doubles
(other than in GtkNotebook and GtkIconView), and are casted to ints. Then
those rounded values are used to calculate deltas to compare to the drag
threshold, losing quite a lot of precision along the way, and often
resulting in the outer widget getting larger deltas.
To avoid it, just don't round it. Introduce a variant of the function that
operates on doubles: gtk_drag_check_threshold_double() and use it instead
of the original everywhere.
Fix coordinates in GtkEntry along the way: it was passing offsets as
current oordinates.
gtk/gtkcolumnview.c | 4 ++--
gtk/gtkdragsource.c | 21 +++++++++++++++++++--
gtk/gtkentry.c | 4 ++--
gtk/gtkgesturelongpress.c | 4 ++--
gtk/gtkiconview.c | 10 +++++-----
gtk/gtkiconviewprivate.h | 4 ++--
gtk/gtkimcontextwayland.c | 9 +++++----
gtk/gtklabel.c | 4 ++--
gtk/gtklistbase.c | 4 ++--
gtk/gtknotebook.c | 17 ++++++++++-------
gtk/gtkplacessidebar.c | 4 ++--
gtk/gtkscrolledwindow.c | 6 +++---
gtk/gtktext.c | 6 ++----
gtk/gtktextview.c | 5 +++--
gtk/gtktreeview.c | 4 ++--
gtk/gtktreeviewcolumn.c | 4 ++--
16 files changed, 65 insertions(+), 45 deletions(-)
---
diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c
index f00bede003..2e835d366a 100644
--- a/gtk/gtkcolumnview.c
+++ b/gtk/gtkcolumnview.c
@@ -39,7 +39,7 @@
#include "gtkadjustment.h"
#include "gtkgesturedrag.h"
#include "gtkeventcontrollermotion.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkeventcontrollerkey.h"
#include "gtkgestureclick.h"
@@ -1128,7 +1128,7 @@ header_drag_update (GtkGestureDrag *gesture,
if (!self->in_column_resize && !self->in_column_reorder)
{
- if (gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, 0))
+ if (gtk_drag_check_threshold_double (GTK_WIDGET (self), 0, 0, offset_x, 0))
{
GtkColumnViewColumn *column;
GtkWidget *header;
diff --git a/gtk/gtkdragsource.c b/gtk/gtkdragsource.c
index 98b96c7594..47f0ba179d 100644
--- a/gtk/gtkdragsource.c
+++ b/gtk/gtkdragsource.c
@@ -24,7 +24,7 @@
#include "config.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkgesturedrag.h"
#include "gtkgesturesingleprivate.h"
@@ -292,7 +292,7 @@ gtk_drag_source_update (GtkGesture *gesture,
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
- if (gtk_drag_check_threshold (widget, source->start_x, source->start_y, x, y))
+ if (gtk_drag_check_threshold_double (widget, source->start_x, source->start_y, x, y))
{
gtk_drag_source_drag_begin (source);
}
@@ -796,3 +796,20 @@ gtk_drag_check_threshold (GtkWidget *widget,
return (ABS (current_x - start_x) > drag_threshold ||
ABS (current_y - start_y) > drag_threshold);
}
+
+gboolean
+gtk_drag_check_threshold_double (GtkWidget *widget,
+ double start_x,
+ double start_y,
+ double current_x,
+ double current_y)
+{
+ int drag_threshold;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ drag_threshold = gtk_settings_get_dnd_drag_threshold (gtk_widget_get_settings (widget));
+
+ return (ABS (current_x - start_x) > drag_threshold ||
+ ABS (current_y - start_y) > drag_threshold);
+}
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index acb2774481..df3d62089c 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -66,7 +66,7 @@
#include "gtkwindow.h"
#include "gtknative.h"
#include "gtkgestureclick.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkwidgetpaintable.h"
@@ -1601,7 +1601,7 @@ icon_drag_update_cb (GtkGestureDrag *gesture,
icon_info = priv->icons[pos];
if (icon_info->content != NULL &&
- gtk_drag_check_threshold (icon_info->widget, start_x, start_y, x, y))
+ gtk_drag_check_threshold_double (icon_info->widget, 0, 0, x, y))
{
GdkPaintable *paintable;
GdkSurface *surface;
diff --git a/gtk/gtkgesturelongpress.c b/gtk/gtkgesturelongpress.c
index df01077ab4..446829856e 100644
--- a/gtk/gtkgesturelongpress.c
+++ b/gtk/gtkgesturelongpress.c
@@ -37,7 +37,7 @@
#include "gtkgesturelongpressprivate.h"
#include "gtkgestureprivate.h"
#include "gtkmarshalers.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
@@ -159,7 +159,7 @@ gtk_gesture_long_press_update (GtkGesture *gesture,
priv = gtk_gesture_long_press_get_instance_private (GTK_GESTURE_LONG_PRESS (gesture));
gtk_gesture_get_point (gesture, sequence, &x, &y);
- if (gtk_drag_check_threshold (widget, priv->initial_x, priv->initial_y, x, y))
+ if (gtk_drag_check_threshold_double (widget, priv->initial_x, priv->initial_y, x, y))
{
if (priv->timeout_id)
{
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index 5d24c1f0bf..cce12cc45d 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -26,7 +26,7 @@
#include "gtkcellrenderer.h"
#include "gtkcellrendererpixbuf.h"
#include "gtkcellrenderertext.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkentry.h"
#include "gtkintl.h"
#include "gtkmain.h"
@@ -5884,10 +5884,10 @@ gtk_icon_view_maybe_begin_drag (GtkIconView *icon_view,
if (icon_view->priv->pressed_button < 0)
goto out;
- if (!gtk_drag_check_threshold (GTK_WIDGET (icon_view),
- icon_view->priv->press_start_x,
- icon_view->priv->press_start_y,
- x, y))
+ if (!gtk_drag_check_threshold_double (GTK_WIDGET (icon_view),
+ icon_view->priv->press_start_x,
+ icon_view->priv->press_start_y,
+ x, y))
goto out;
model = gtk_icon_view_get_model (icon_view);
diff --git a/gtk/gtkiconviewprivate.h b/gtk/gtkiconviewprivate.h
index ef785bad04..b5fa1358d1 100644
--- a/gtk/gtkiconviewprivate.h
+++ b/gtk/gtkiconviewprivate.h
@@ -133,8 +133,8 @@ struct _GtkIconViewPrivate
/* Drag-and-drop. */
GdkModifierType start_button_mask;
int pressed_button;
- int press_start_x;
- int press_start_y;
+ double press_start_x;
+ double press_start_y;
GdkContentFormats *source_formats;
GtkDropTargetAsync *dest;
diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c
index ad89d83a07..77264087eb 100644
--- a/gtk/gtkimcontextwayland.c
+++ b/gtk/gtkimcontextwayland.c
@@ -21,6 +21,7 @@
#include <string.h>
#include <wayland-client-protocol.h>
+#include "gtk/gtkdragsourceprivate.h"
#include "gtk/gtkimcontextwayland.h"
#include "gtk/gtkintl.h"
#include "gtk/gtkimmoduleprivate.h"
@@ -524,10 +525,10 @@ released_cb (GtkGestureClick *gesture,
if (global->focused &&
n_press == 1 &&
(hints & GTK_INPUT_HINT_INHIBIT_OSK) == 0 &&
- !gtk_drag_check_threshold (context->widget,
- context->press_x,
- context->press_y,
- x, y))
+ !gtk_drag_check_threshold_double (context->widget,
+ context->press_x,
+ context->press_y,
+ x, y))
{
zwp_text_input_v3_enable (global->text_input);
g_signal_emit_by_name (global->current, "retrieve-surrounding", &result);
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 19b0386c05..ab20e0bd84 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -54,7 +54,7 @@
#include "gtkwindow.h"
#include "gtkpopovermenu.h"
#include "gtknative.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkcsscolorvalueprivate.h"
@@ -4138,7 +4138,7 @@ gtk_label_drag_gesture_update (GtkGestureDrag *gesture,
if (info->in_drag)
{
- if (gtk_drag_check_threshold (widget, info->drag_start_x, info->drag_start_y, x, y))
+ if (gtk_drag_check_threshold_double (widget, info->drag_start_x, info->drag_start_y, x, y))
{
GdkDrag *drag;
GdkSurface *surface;
diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c
index ed4f84ad2a..6c4078a66a 100644
--- a/gtk/gtklistbase.c
+++ b/gtk/gtklistbase.c
@@ -23,7 +23,7 @@
#include "gtkadjustment.h"
#include "gtkbitset.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdropcontrollermotion.h"
#include "gtkgesturedrag.h"
#include "gtkgizmoprivate.h"
@@ -1710,7 +1710,7 @@ gtk_list_base_drag_update (GtkGestureDrag *gesture,
if (!priv->rubberband)
{
- if (!gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, offset_y))
+ if (!gtk_drag_check_threshold_double (GTK_WIDGET (self), 0, 0, offset_x, offset_y))
return;
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index bad99cdddc..47fe9224fd 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -51,7 +51,7 @@
#include "gtkstack.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkwidgetpaintable.h"
#include "gtknative.h"
@@ -249,14 +249,14 @@ struct _GtkNotebook
GList *first_tab; /* The first tab visible (for scrolling notebooks) */
GList *focus_tab;
- int drag_begin_x;
- int drag_begin_y;
+ double drag_begin_x;
+ double drag_begin_y;
int drag_offset_x;
int drag_offset_y;
int drag_surface_x;
int drag_surface_y;
- int mouse_x;
- int mouse_y;
+ double mouse_x;
+ double mouse_y;
int pressed_button;
GQuark group;
@@ -2935,8 +2935,11 @@ gtk_notebook_motion (GtkEventController *controller,
if (page->reorderable &&
(notebook->operation == DRAG_OPERATION_REORDER ||
- gtk_drag_check_threshold (widget, notebook->drag_begin_x, notebook->drag_begin_y,
- notebook->mouse_x, notebook->mouse_y)))
+ gtk_drag_check_threshold_double (widget,
+ notebook->drag_begin_x,
+ notebook->drag_begin_y,
+ notebook->mouse_x,
+ notebook->mouse_y)))
{
GtkNotebookPointerPosition pointer_position = get_pointer_position (notebook);
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 41df790cc6..7c055296d3 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -60,7 +60,7 @@
#include "gtkgestureclick.h"
#include "gtkgesturedrag.h"
#include "gtknative.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
/*< private >
@@ -3451,7 +3451,7 @@ on_row_dragged (GtkGestureDrag *gesture,
return;
}
- if (gtk_drag_check_threshold (GTK_WIDGET (row), 0, 0, x, y))
+ if (gtk_drag_check_threshold_double (GTK_WIDGET (row), 0, 0, x, y))
{
double start_x, start_y;
double drag_x, drag_y;
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index d27d05c432..c780c6fc8d 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -29,7 +29,7 @@
#include "gtkadjustment.h"
#include "gtkadjustmentprivate.h"
#include "gtkbuildable.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkeventcontrollerprivate.h"
@@ -953,8 +953,8 @@ scrolled_window_drag_update_cb (GtkScrolledWindow *scrolled_window,
GtkAdjustment *vadjustment;
double dx, dy;
- if (!gtk_drag_check_threshold (GTK_WIDGET (scrolled_window),
- 0, 0, offset_x, offset_y))
+ if (!gtk_drag_check_threshold_double (GTK_WIDGET (scrolled_window),
+ 0, 0, offset_x, offset_y))
return;
gtk_scrolled_window_invalidate_overshoot (scrolled_window);
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index c39e007d61..6d10722e6b 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -29,7 +29,7 @@
#include "gtkbutton.h"
#include "gtkdebug.h"
#include "gtkdragicon.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdroptarget.h"
#include "gtkeditable.h"
#include "gtkemojichooser.h"
@@ -2941,9 +2941,7 @@ gtk_text_drag_gesture_update (GtkGestureDrag *gesture,
if (priv->in_drag)
{
if (gtk_text_get_display_mode (self) == DISPLAY_NORMAL &&
- gtk_drag_check_threshold (widget,
- priv->drag_start_x, priv->drag_start_y,
- x, y))
+ gtk_drag_check_threshold_double (widget, 0, 0, offset_x, offset_y))
{
int *ranges;
int n_ranges;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 5a4ad33e2a..765d67aea6 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -32,6 +32,7 @@
#include "gtkadjustmentprivate.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkdebug.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdropcontrollermotion.h"
#include "gtkintl.h"
#include "gtkmain.h"
@@ -7232,7 +7233,7 @@ gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
/* If no data is attached, the initial press happened within the current
* text selection, check for drag and drop to be initiated.
*/
- if (gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y, x, y))
+ if (gtk_drag_check_threshold_double (GTK_WIDGET (text_view), 0, 0, offset_x, offset_y))
{
if (!is_touchscreen)
{
@@ -7366,7 +7367,7 @@ gtk_text_view_drag_gesture_end (GtkGestureDrag *gesture,
gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN;
if ((is_touchscreen || clicked_in_selection) &&
- !gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y, x, y))
+ !gtk_drag_check_threshold_double (GTK_WIDGET (text_view), 0, 0, offset_x, offset_y))
{
GtkTextIter iter;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 82d5fd97d8..39292db8ae 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -29,7 +29,7 @@
#include "gtkcssnumbervalueprivate.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkdragicon.h"
#include "gtkdroptargetasync.h"
#include "gtkentryprivate.h"
@@ -7046,7 +7046,7 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view)
gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (priv->drag_gesture),
&offset_x, &offset_y);
- if (!gtk_drag_check_threshold (widget, 0, 0, offset_x, offset_y))
+ if (!gtk_drag_check_threshold_double (widget, 0, 0, offset_x, offset_y))
goto out;
model = gtk_tree_view_get_model (tree_view);
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index e321bed4b6..638c9707da 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -24,7 +24,7 @@
#include "gtkcellareabox.h"
#include "gtkcellareacontext.h"
#include "gtkcelllayout.h"
-#include "gtkdragsource.h"
+#include "gtkdragsourceprivate.h"
#include "gtkframe.h"
#include "gtkimage.h"
#include "gtkintl.h"
@@ -1076,7 +1076,7 @@ column_button_drag_update (GtkGestureDrag *gesture,
{
GtkTreeViewColumnPrivate *priv = column->priv;
- if (gtk_drag_check_threshold (priv->button, 0, 0, offset_x, offset_y))
+ if (gtk_drag_check_threshold_double (priv->button, 0, 0, offset_x, offset_y))
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
_gtk_tree_view_column_start_drag (GTK_TREE_VIEW (priv->tree_view), column,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]