Merge branch 'synthetic-motion' into 'master'

Synthetic motion

See merge request GNOME/gtk!2493
This commit is contained in:
Matthias Clasen 2020-08-27 20:24:34 +00:00
commit 5533494839
3 changed files with 88 additions and 2 deletions

View File

@ -2338,6 +2338,43 @@ gdk_drag_begin (GdkSurface *surface,
return GDK_SURFACE_GET_CLASS (surface)->drag_begin (surface, device, content, actions, dx, dy);
}
static void
gdk_surface_ensure_motion (GdkSurface *surface)
{
GdkDisplay *display;
GdkSeat *seat;
GdkDevice *device;
GdkEvent *event;
double x, y;
GdkModifierType state;
if (!surface->request_motion)
return;
surface->request_motion = FALSE;
display = gdk_surface_get_display (surface);
seat = gdk_display_get_default_seat (display);
if (!seat)
return;
device = gdk_seat_get_pointer (seat);
if (!gdk_surface_get_device_position (surface, device, &x, &y, &state))
return;
event = gdk_motion_event_new (surface,
device,
NULL,
GDK_CURRENT_TIME,
state,
x, y,
NULL);
gdk_surface_handle_event (event);
gdk_event_unref (event);
}
static void
gdk_surface_flush_events (GdkFrameClock *clock,
void *data)
@ -2345,6 +2382,7 @@ gdk_surface_flush_events (GdkFrameClock *clock,
GdkSurface *surface = GDK_SURFACE (data);
_gdk_event_queue_flush (surface->display);
gdk_surface_ensure_motion (surface);
_gdk_display_pause_events (surface->display);
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS);
@ -2806,7 +2844,12 @@ gdk_surface_handle_event (GdkEvent *event)
}
else
{
g_signal_emit (gdk_event_get_surface (event), signals[EVENT], 0, event, &handled);
GdkSurface *surface = gdk_event_get_surface (event);
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
surface->request_motion = FALSE;
g_signal_emit (surface, signals[EVENT], 0, event, &handled);
}
if (GDK_PROFILER_IS_RUNNING)
@ -2815,6 +2858,27 @@ gdk_surface_handle_event (GdkEvent *event)
return handled;
}
/*
* gdk_surface_request_motion:
* @surface: a #GdkSurface
*
* Request that the next frame cycle should deliver a motion
* event for @surface if the pointer is over it, regardless
* whether the pointer has moved or not. This is used by GTK
* after moving widgets around.
*/
void
gdk_surface_request_motion (GdkSurface *surface)
{
GdkFrameClock *frame_clock;
surface->request_motion = TRUE;
frame_clock = gdk_surface_get_frame_clock (surface);
if (frame_clock)
gdk_frame_clock_request_phase (frame_clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
/**
* gdk_surface_translate_coordinates:
* @from: the origin surface

View File

@ -72,6 +72,7 @@ struct _GdkSurface
guint frame_clock_events_paused : 1;
guint autohide : 1;
guint shortcuts_inhibited : 1;
guint request_motion : 1;
struct {
GdkGravity surface_anchor;
@ -327,6 +328,9 @@ void gdk_surface_constrain_size (GdkGeometry *geometry,
int *new_width,
int *new_height);
GDK_AVAILABLE_IN_ALL
void gdk_surface_request_motion (GdkSurface *surface);
G_END_DECLS
#endif /* __GDK_SURFACE_PRIVATE_H__ */

View File

@ -199,7 +199,25 @@ gtk_root_layout_cb (GdkFrameClock *clock,
* since it doesn't cause any actual harm.
*/
if (gtk_widget_needs_allocate (widget))
gtk_native_check_resize (GTK_NATIVE (self));
{
gtk_native_check_resize (GTK_NATIVE (self));
if (GTK_IS_WINDOW (widget))
{
GdkSeat *seat;
seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
if (seat)
{
GdkDevice *device;
GtkWidget *focus;
device = gdk_seat_get_pointer (seat);
focus = gtk_window_lookup_pointer_focus_widget (GTK_WINDOW (widget), device, NULL);
if (focus)
gdk_surface_request_motion (gtk_native_get_surface (gtk_widget_get_native (focus)));
}
}
}
if (!gtk_root_needs_layout (self))
gtk_root_stop_layout (self);