From 528ec4ddedbf7600c9456e684e5fa82752d8ecf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 19 Nov 2020 10:54:20 +0100 Subject: [PATCH] wayland: Only set mapped state when mapped Mapping a surface under Wayland is an asynchronous process, where one creates a surface and commits an initial state without having drawn anything, then waiting for a configuration, which then is acknowledged and content is painted and committed. Not until having received this configuration is a surface actually mapped, so wait with setting the mappedness until this. --- gdk/wayland/gdkdevice-wayland.c | 2 +- gdk/wayland/gdkprivate-wayland.h | 1 + gdk/wayland/gdksurface-wayland.c | 38 ++++++++++++++++++-------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 8671561175..c975c2069d 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -4502,7 +4502,7 @@ gdk_wayland_seat_grab (GdkSeat *seat, if (prepare_func) (prepare_func) (seat, surface, prepare_func_data); - if (!gdk_surface_get_mapped (surface)) + if (!gdk_wayland_surface_has_surface (surface)) { gdk_wayland_seat_set_grab_surface (wayland_seat, NULL); return GDK_GRAB_NOT_VIEWABLE; diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 19a4e91c0b..eadacffbb9 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -96,6 +96,7 @@ void gdk_wayland_surface_sync (GdkSurface *surface); void gdk_wayland_surface_commit (GdkSurface *surface); void gdk_wayland_surface_notify_committed (GdkSurface *surface); void gdk_wayland_surface_request_frame (GdkSurface *surface); +gboolean gdk_wayland_surface_has_surface (GdkSurface *surface); void gdk_wayland_surface_attach_image (GdkSurface *surface, cairo_surface_t *cairo_surface, const cairo_region_t *damage); diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index c992ff4214..1c6c27c1c0 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -603,6 +603,14 @@ gdk_wayland_surface_request_frame (GdkSurface *surface) impl->awaiting_frame = TRUE; } +gboolean +gdk_wayland_surface_has_surface (GdkSurface *surface) +{ + GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); + + return !!impl->display_server.wl_surface; +} + void gdk_wayland_surface_commit (GdkSurface *surface) { @@ -1448,6 +1456,19 @@ gdk_wayland_surface_configure_popup (GdkSurface *surface) gdk_surface_invalidate_rect (surface, NULL); } +static void +maybe_notify_mapped (GdkSurface *surface) +{ + if (surface->destroyed) + return; + + if (!GDK_SURFACE_IS_MAPPED (surface)) + { + gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); + gdk_surface_invalidate_rect (surface, NULL); + } +} + static void gdk_wayland_surface_configure (GdkSurface *surface) { @@ -1458,6 +1479,7 @@ gdk_wayland_surface_configure (GdkSurface *surface) gdk_surface_thaw_updates (surface); impl->initial_configure_received = TRUE; impl->pending.is_initial_configure = TRUE; + maybe_notify_mapped (surface); } impl->has_uncommitted_ack_configure = TRUE; @@ -2948,19 +2970,6 @@ is_relayout_finished (GdkSurface *surface) return TRUE; } -static void -maybe_notify_mapped (GdkSurface *surface) -{ - if (surface->destroyed) - return; - - if (!GDK_SURFACE_IS_MAPPED (surface)) - { - gdk_synthesize_surface_state (surface, GDK_TOPLEVEL_STATE_WITHDRAWN, 0); - gdk_surface_invalidate_rect (surface, NULL); - } -} - static void gdk_wayland_surface_map_popup (GdkSurface *surface, int width, @@ -2995,8 +3004,6 @@ gdk_wayland_surface_map_popup (GdkSurface *surface, impl->popup.unconstrained_width = width; impl->popup.unconstrained_height = height; impl->mapped = TRUE; - - maybe_notify_mapped (surface); } static void @@ -4801,7 +4808,6 @@ gdk_wayland_toplevel_present (GdkToplevel *toplevel, impl->toplevel.layout = gdk_toplevel_layout_copy (layout); gdk_wayland_surface_show (surface, FALSE); - maybe_notify_mapped (surface); display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); callback = wl_display_sync (display_wayland->wl_display);