Pass translated coordinates outside the event

We want to make events readonly, so stop translating
their coordinates and instead pass the translated
coordinates separately, when propagating events.
This commit is contained in:
Matthias Clasen 2020-02-13 00:08:49 -05:00
parent cd2b58574d
commit dd251d85c4
16 changed files with 93 additions and 104 deletions

View File

@ -117,7 +117,9 @@ static gboolean gtk_drop_target_accept (GtkDropTarget *dest,
GdkDrop *drop);
static gboolean gtk_drop_target_handle_event (GtkEventController *controller,
const GdkEvent *event);
const GdkEvent *event,
double x,
double y);
static gboolean gtk_drop_target_filter_event (GtkEventController *controller,
const GdkEvent *event);
static void gtk_drop_target_set_widget (GtkEventController *controller,
@ -755,11 +757,12 @@ gtk_drop_set_current_dest (GdkDrop *drop,
static gboolean
gtk_drop_target_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkDropTarget *dest = GTK_DROP_TARGET (controller);
GdkDrop *drop;
double x, y;
GtkDropStatus status;
gboolean found = FALSE;
@ -769,8 +772,6 @@ gtk_drop_target_handle_event (GtkEventController *controller,
if (status == GTK_DROP_STATUS_DENIED)
return FALSE;
gdk_event_get_coords (event, &x, &y);
switch ((int)gdk_event_get_event_type (event))
{
case GDK_DRAG_MOTION:

View File

@ -120,7 +120,9 @@ gtk_event_controller_filter_event_default (GtkEventController *self,
static gboolean
gtk_event_controller_handle_event_default (GtkEventController *self,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
return FALSE;
}
@ -269,6 +271,8 @@ gtk_event_controller_init (GtkEventController *controller)
* gtk_event_controller_handle_event:
* @controller: a #GtkEventController
* @event: a #GdkEvent
* @x: event position in widget coordinates, or 0 if not a pointer event
* @y: event position in widget coordinates, or 0 if not a pointer event
*
* Feeds an event into @controller, so it can be interpreted
* and the controller actions triggered.
@ -278,7 +282,9 @@ gtk_event_controller_init (GtkEventController *controller)
**/
gboolean
gtk_event_controller_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkEventControllerClass *controller_class;
gboolean retval = FALSE;
@ -294,7 +300,7 @@ gtk_event_controller_handle_event (GtkEventController *controller,
if (controller_class->handle_event)
{
g_object_ref (controller);
retval = controller_class->handle_event (controller, event);
retval = controller_class->handle_event (controller, event, x, y);
g_object_unref (controller);
}

View File

@ -48,7 +48,9 @@ GtkWidget * gtk_event_controller_get_widget (GtkEventController *controller
GDK_AVAILABLE_IN_ALL
gboolean gtk_event_controller_handle_event (GtkEventController *controller,
const GdkEvent *event);
const GdkEvent *event,
double x,
double y);
GDK_AVAILABLE_IN_ALL
void gtk_event_controller_reset (GtkEventController *controller);

View File

@ -147,7 +147,9 @@ update_focus (GtkEventControllerKey *key,
static gboolean
gtk_event_controller_key_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkEventControllerKey *key = GTK_EVENT_CONTROLLER_KEY (controller);
GdkEventType event_type = gdk_event_get_event_type (event);
@ -506,13 +508,13 @@ gtk_event_controller_key_forward (GtkEventControllerKey *controller,
if (!gtk_widget_get_realized (widget))
gtk_widget_realize (widget);
if (gtk_widget_run_controllers (widget, controller->current_event,
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
GTK_PHASE_CAPTURE))
return TRUE;
if (gtk_widget_run_controllers (widget, controller->current_event,
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
GTK_PHASE_TARGET))
return TRUE;
if (gtk_widget_run_controllers (widget, controller->current_event,
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
GTK_PHASE_BUBBLE))
return TRUE;

View File

@ -59,7 +59,9 @@ G_DEFINE_TYPE (GtkEventControllerLegacy, gtk_event_controller_legacy,
static gboolean
gtk_event_controller_legacy_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
gboolean handled;

View File

@ -117,7 +117,9 @@ update_pointer_focus (GtkEventControllerMotion *motion,
static gboolean
gtk_event_controller_motion_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkEventControllerMotion *motion = GTK_EVENT_CONTROLLER_MOTION (controller);
GtkEventControllerClass *parent_class;
@ -126,11 +128,9 @@ gtk_event_controller_motion_handle_event (GtkEventController *controller,
type = gdk_event_get_event_type (event);
if (type == GDK_ENTER_NOTIFY)
{
double x, y;
GdkCrossingMode mode;
GdkNotifyType detail;
gdk_event_get_coords (event, &x, &y);
gdk_event_get_crossing_mode (event, &mode);
gdk_event_get_crossing_detail (event, &detail);
@ -160,16 +160,12 @@ gtk_event_controller_motion_handle_event (GtkEventController *controller,
}
else if (type == GDK_MOTION_NOTIFY)
{
double x, y;
gdk_event_get_coords (event, &x, &y);
g_signal_emit (controller, signals[MOTION], 0, x, y);
}
parent_class = GTK_EVENT_CONTROLLER_CLASS (gtk_event_controller_motion_parent_class);
return parent_class->handle_event (controller, event);
return parent_class->handle_event (controller, event, x, y);
}
static void

View File

@ -35,7 +35,9 @@ struct _GtkEventControllerClass
GtkWidget *widget);
void (* unset_widget) (GtkEventController *controller);
gboolean (* handle_event) (GtkEventController *controller,
const GdkEvent *event);
const GdkEvent *event,
double x,
double y);
void (* reset) (GtkEventController *controller);
/*<private>*/

View File

@ -238,7 +238,9 @@ gtk_event_controller_scroll_get_property (GObject *object,
static gboolean
gtk_event_controller_scroll_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkEventControllerScroll *scroll = GTK_EVENT_CONTROLLER_SCROLL (controller);
GdkScrollDirection direction = GDK_SCROLL_SMOOTH;

View File

@ -414,36 +414,6 @@ _update_touchpad_deltas (PointData *data)
}
}
static void
_get_event_coordinates (PointData *data,
gdouble *x,
gdouble *y)
{
gdouble event_x, event_y;
g_assert (data->event != NULL);
gdk_event_get_coords (data->event, &event_x, &event_y);
event_x += data->accum_dx;
event_y += data->accum_dy;
if (x)
*x = event_x;
if (y)
*y = event_y;
}
static void
_update_widget_coordinates (GtkGesture *gesture,
PointData *data)
{
gdouble event_x, event_y;
_get_event_coordinates (data, &event_x, &event_y);
data->widget_x = event_x;
data->widget_y = event_y;
}
static GtkEventSequenceState
gtk_gesture_get_group_state (GtkGesture *gesture,
GdkEventSequence *sequence)
@ -470,6 +440,8 @@ gtk_gesture_get_group_state (GtkGesture *gesture,
static gboolean
_gtk_gesture_update_point (GtkGesture *gesture,
const GdkEvent *event,
double x,
double y,
gboolean add)
{
GdkEventSequence *sequence;
@ -534,7 +506,8 @@ _gtk_gesture_update_point (GtkGesture *gesture,
data->event = gdk_event_ref ((GdkEvent *)event);
_update_touchpad_deltas (data);
_update_widget_coordinates (gesture, data);
data->widget_x = x + data->accum_dx;
data->widget_y = y + data->accum_dy;
/* Deny the sequence right away if the expected
* number of points is exceeded, so this sequence
@ -627,7 +600,9 @@ gtk_gesture_filter_event (GtkEventController *controller,
static gboolean
gtk_gesture_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkGesture *gesture = GTK_GESTURE (controller);
GdkEventSequence *sequence;
@ -658,7 +633,7 @@ gtk_gesture_handle_event (GtkEventController *controller,
(event_type == GDK_TOUCHPAD_SWIPE && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN) ||
(event_type == GDK_TOUCHPAD_PINCH && phase == GDK_TOUCHPAD_GESTURE_PHASE_BEGIN))
{
if (_gtk_gesture_update_point (gesture, event, TRUE))
if (_gtk_gesture_update_point (gesture, event, x, y, TRUE))
{
gboolean triggered_recognition;
@ -692,7 +667,7 @@ gtk_gesture_handle_event (GtkEventController *controller,
{
gboolean was_claimed;
if (_gtk_gesture_update_point (gesture, event, FALSE))
if (_gtk_gesture_update_point (gesture, event, x, y, FALSE))
{
if (was_recognized &&
_gtk_gesture_check_recognized (gesture, sequence))
@ -717,7 +692,7 @@ gtk_gesture_handle_event (GtkEventController *controller,
return FALSE;
}
if (_gtk_gesture_update_point (gesture, event, FALSE) &&
if (_gtk_gesture_update_point (gesture, event, x, y, FALSE) &&
_gtk_gesture_check_recognized (gesture, sequence))
g_signal_emit (gesture, signals[UPDATE], 0, sequence);
}

View File

@ -307,13 +307,14 @@ gtk_gesture_click_reset (GtkEventController *controller)
static gboolean
gtk_gesture_click_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkEventControllerClass *parent_controller;
GtkGestureClickPrivate *priv;
GdkEventSequence *sequence;
guint button;
gdouble x, y;
priv = gtk_gesture_click_get_instance_private (GTK_GESTURE_CLICK (controller));
parent_controller = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_click_parent_class);
@ -326,12 +327,11 @@ gtk_gesture_click_handle_event (GtkEventController *controller,
{
if (!gdk_event_get_button (event, &button))
button = 0;
gdk_event_get_coords (event, &x, &y);
g_signal_emit (controller, signals[UNPAIRED_RELEASE], 0,
x, y, button, sequence);
}
return parent_controller->handle_event (controller, event);
return parent_controller->handle_event (controller, event, x, y);
}
static void

View File

@ -192,7 +192,9 @@ gtk_gesture_rotate_filter_event (GtkEventController *controller,
static gboolean
gtk_gesture_rotate_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkGestureRotate *rotate = GTK_GESTURE_ROTATE (controller);
GtkGestureRotatePrivate *priv;
@ -213,7 +215,7 @@ gtk_gesture_rotate_handle_event (GtkEventController *controller,
priv->accum_touchpad_angle += delta;
}
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_rotate_parent_class)->handle_event (controller, event);
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_rotate_parent_class)->handle_event (controller, event, x, y);
}
static void

View File

@ -131,7 +131,9 @@ gtk_gesture_single_cancel (GtkGesture *gesture,
static gboolean
gtk_gesture_single_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GdkEventSequence *sequence = NULL;
GtkGestureSinglePrivate *priv;
@ -201,8 +203,7 @@ gtk_gesture_single_handle_event (GtkEventController *controller,
case GDK_TOUCH_CANCEL:
case GDK_GRAB_BROKEN:
case GDK_TOUCHPAD_SWIPE:
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller,
event);
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event, x, y);
break;
default:
return FALSE;
@ -226,7 +227,7 @@ gtk_gesture_single_handle_event (GtkEventController *controller,
priv->current_button = button;
}
retval = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event);
retval = GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller, event, x, y);
if (sequence == priv->current_sequence &&
(event_type == GDK_BUTTON_RELEASE || event_type == GDK_TOUCH_END))

View File

@ -49,18 +49,17 @@ static guint signals[N_SIGNALS] = { 0, };
static gboolean
gtk_gesture_stylus_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GdkModifierType modifiers;
guint n_signal;
gdouble x, y;
GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_stylus_parent_class)->handle_event (controller, event);
GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_stylus_parent_class)->handle_event (controller, event, x, y);
if (!gdk_event_get_device_tool (event))
return FALSE;
if (!gdk_event_get_coords (event, &x, &y))
return FALSE;
switch ((guint) gdk_event_get_event_type (event))
{

View File

@ -229,7 +229,9 @@ gtk_pad_controller_filter_event (GtkEventController *controller,
static gboolean
gtk_pad_controller_handle_event (GtkEventController *controller,
const GdkEvent *event)
const GdkEvent *event,
double x,
double y)
{
GtkPadController *pad_controller = GTK_PAD_CONTROLLER (controller);
GdkEventType event_type = gdk_event_get_event_type (event);

View File

@ -4794,6 +4794,8 @@ gtk_widget_event (GtkWidget *widget,
gboolean
gtk_widget_run_controllers (GtkWidget *widget,
const GdkEvent *event,
double x,
double y,
GtkPropagationPhase phase)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
@ -4829,7 +4831,7 @@ gtk_widget_run_controllers (GtkWidget *widget,
gboolean is_gesture;
is_gesture = GTK_IS_GESTURE (controller);
this_handled = gtk_event_controller_handle_event (controller, event);
this_handled = gtk_event_controller_handle_event (controller, event, x, y);
handled |= this_handled;
@ -4852,16 +4854,15 @@ gtk_widget_run_controllers (GtkWidget *widget,
static gboolean
translate_event_coordinates (GdkEvent *event,
double event_x,
double event_y,
double *x,
double *y,
GtkWidget *widget);
gboolean
_gtk_widget_captured_event (GtkWidget *widget,
GdkEvent *event)
{
gboolean return_val = FALSE;
double old_x, old_y;
gboolean reset_event = FALSE;
double x, y;
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
@ -4869,18 +4870,12 @@ _gtk_widget_captured_event (GtkWidget *widget,
if (!event_surface_is_still_viewable (event))
return TRUE;
if (gdk_event_get_coords (event, &old_x, &old_y))
{
reset_event = TRUE;
translate_event_coordinates (event, old_x, old_y, widget);
}
x = y = 0;
translate_event_coordinates (event, &x, &y, widget);
return_val = gtk_widget_run_controllers (widget, event, GTK_PHASE_CAPTURE);
return_val = gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_CAPTURE);
return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
if (reset_event)
gdk_event_set_coords (event, old_x, old_y);
return return_val;
}
@ -4923,12 +4918,18 @@ event_surface_is_still_viewable (const GdkEvent *event)
static gboolean
translate_event_coordinates (GdkEvent *event,
double event_x,
double event_y,
double *x,
double *y,
GtkWidget *widget)
{
GtkWidget *event_widget;
graphene_point_t p;
double event_x, event_y;
*x = *y = 0;
if (!gdk_event_get_coords (event, &event_x, &event_y))
return FALSE;
event_widget = gtk_get_event_widget (event);
@ -4938,7 +4939,8 @@ translate_event_coordinates (GdkEvent *event,
&p))
return FALSE;
gdk_event_set_coords (event, p.x, p.y);
*x = p.x;
*y = p.y;
return TRUE;
}
@ -4948,8 +4950,7 @@ gtk_widget_event_internal (GtkWidget *widget,
GdkEvent *event)
{
gboolean return_val = FALSE;
gboolean reset_event = FALSE;
double old_x, old_y;
double x, y;
/* We check only once for is-still-visible; if someone
* hides the window in on of the signals on the widget,
@ -4962,26 +4963,20 @@ gtk_widget_event_internal (GtkWidget *widget,
if (!_gtk_widget_get_mapped (widget))
return FALSE;
if (gdk_event_get_coords (event, &old_x, &old_y))
{
reset_event = TRUE;
translate_event_coordinates (event, old_x, old_y, widget);
}
x = y = 0;
translate_event_coordinates (event, &x, &y, widget);
if (widget == gtk_get_event_target (event))
return_val |= gtk_widget_run_controllers (widget, event, GTK_PHASE_TARGET);
return_val |= gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_TARGET);
if (return_val == FALSE)
return_val |= gtk_widget_run_controllers (widget, event, GTK_PHASE_BUBBLE);
return_val |= gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_BUBBLE);
if (return_val == FALSE &&
(event->any.type == GDK_KEY_PRESS ||
event->any.type == GDK_KEY_RELEASE))
return_val |= gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *) event);
if (reset_event)
gdk_event_set_coords (event, old_x, old_y);
return return_val;
}

View File

@ -344,6 +344,8 @@ void gtk_widget_cancel_event_sequence (GtkWidget
gboolean gtk_widget_run_controllers (GtkWidget *widget,
const GdkEvent *event,
double x,
double y,
GtkPropagationPhase phase);