summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-13 03:33:59 +0200
committerBenjamin Otte <otte@redhat.com>2023-04-13 04:23:35 +0200
commit5d3cec5441ca1fa28e5e77c0572e629eded419c9 (patch)
treeed9ee4fc0e5b41c2c52ac0e3f8b40a231531585e
parent891242920e785f01f758629c7bbd5cf263219476 (diff)
downloadgtk+-5d3cec5441ca1fa28e5e77c0572e629eded419c9.tar.gz
wayland: Don't destroy the wl_surface on hide()
We want to keep the wl_surface around, because surfaces create their resources on construct and keep them until destroyed. See the HWND ond Windows and the XWindow on X11. This is relevant for graphics resources, where we want to have access to the VkSurface and eglSurface while the GdkSurface is hidden. We also want these surfaces to be permanent and not change during the lifetime of the GdkSurface. What we can - and must - destroy however are the xdg surfaces, because those handle visibility on screen. And we also need to ensure no buffer is attached, so that during the next creation of the xdg surface we don't get a protocol error.
-rw-r--r--gdk/wayland/gdkdragsurface-wayland.c3
-rw-r--r--gdk/wayland/gdkpopup-wayland.c5
-rw-r--r--gdk/wayland/gdksurface-wayland-private.h1
-rw-r--r--gdk/wayland/gdksurface-wayland.c268
-rw-r--r--gdk/wayland/gdktoplevel-wayland.c3
5 files changed, 133 insertions, 147 deletions
diff --git a/gdk/wayland/gdkdragsurface-wayland.c b/gdk/wayland/gdkdragsurface-wayland.c
index a52b7e6148..ed130271fc 100644
--- a/gdk/wayland/gdkdragsurface-wayland.c
+++ b/gdk/wayland/gdkdragsurface-wayland.c
@@ -127,9 +127,6 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
- if (!impl->display_server.wl_surface)
- gdk_wayland_surface_create_wl_surface (surface);
-
impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
diff --git a/gdk/wayland/gdkpopup-wayland.c b/gdk/wayland/gdkpopup-wayland.c
index 4b150d1d30..c062c8e3e5 100644
--- a/gdk/wayland/gdkpopup-wayland.c
+++ b/gdk/wayland/gdkpopup-wayland.c
@@ -1289,11 +1289,6 @@ show_popup (GdkWaylandPopup *wayland_popup,
int height,
GdkPopupLayout *layout)
{
- GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (wayland_popup);
-
- if (!wayland_surface->display_server.wl_surface)
- gdk_wayland_surface_create_wl_surface (GDK_SURFACE (wayland_popup));
-
if (wayland_popup->thaw_upon_show)
{
wayland_popup->thaw_upon_show = FALSE;
diff --git a/gdk/wayland/gdksurface-wayland-private.h b/gdk/wayland/gdksurface-wayland-private.h
index 1d87cc4b09..614b56bec4 100644
--- a/gdk/wayland/gdksurface-wayland-private.h
+++ b/gdk/wayland/gdksurface-wayland-private.h
@@ -104,7 +104,6 @@ struct _GdkWaylandSurfaceClass
#define GDK_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
-void gdk_wayland_surface_create_wl_surface (GdkSurface *surface);
void gdk_wayland_surface_update_size (GdkSurface *surface,
int32_t width,
int32_t height,
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 22dede3cf4..7e970f4a73 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -481,102 +481,6 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
}
-GdkSurface *
-_gdk_wayland_display_create_surface (GdkDisplay *display,
- GdkSurfaceType surface_type,
- GdkSurface *parent,
- int x,
- int y,
- int width,
- int height)
-{
- GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
- GdkSurface *surface;
- GdkFrameClock *frame_clock;
-
- if (parent)
- frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
- else
- frame_clock = _gdk_frame_clock_idle_new ();
-
- switch (surface_type)
- {
- case GDK_SURFACE_TOPLEVEL:
- g_warn_if_fail (parent == NULL);
- surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
- "display", display,
- "frame-clock", frame_clock,
- "title", get_default_title (),
- NULL);
- display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
- break;
- case GDK_SURFACE_POPUP:
- g_warn_if_fail (parent != NULL);
- surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
- "parent", parent,
- "display", display,
- "frame-clock", frame_clock,
- NULL);
- break;
- case GDK_SURFACE_DRAG:
- g_warn_if_fail (parent == NULL);
- surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
- "display", display,
- "frame-clock", frame_clock,
- NULL);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- if (width > 65535)
- {
- g_warning ("Native Surfaces wider than 65535 pixels are not supported");
- width = 65535;
- }
- if (height > 65535)
- {
- g_warning ("Native Surfaces taller than 65535 pixels are not supported");
- height = 65535;
- }
-
- surface->x = x;
- surface->y = y;
- surface->width = width;
- surface->height = height;
-
- g_object_ref (surface);
-
- /* More likely to be right than just assuming 1 */
- if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
- {
- GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
- if (monitor)
- {
- GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
- guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
-
- if (monitor_scale != 1)
- {
- impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
- impl->buffer_scale_dirty = TRUE;
- }
-
- g_object_unref (monitor);
- }
- }
-
- gdk_wayland_surface_create_wl_surface (surface);
-
- g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
- g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
-
- g_object_unref (frame_clock);
-
- return surface;
-}
-
void
gdk_wayland_surface_attach_image (GdkSurface *surface,
cairo_surface_t *cairo_surface,
@@ -883,7 +787,7 @@ static const struct wl_surface_listener surface_listener = {
surface_leave
};
-void
+static void
gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
{
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
@@ -921,6 +825,102 @@ gdk_wayland_surface_destroy_wl_surface (GdkWaylandSurface *self)
g_clear_pointer (&self->display_server.outputs, g_slist_free);
}
+GdkSurface *
+_gdk_wayland_display_create_surface (GdkDisplay *display,
+ GdkSurfaceType surface_type,
+ GdkSurface *parent,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
+ GdkSurface *surface;
+ GdkFrameClock *frame_clock;
+
+ if (parent)
+ frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
+ else
+ frame_clock = _gdk_frame_clock_idle_new ();
+
+ switch (surface_type)
+ {
+ case GDK_SURFACE_TOPLEVEL:
+ g_warn_if_fail (parent == NULL);
+ surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
+ "display", display,
+ "frame-clock", frame_clock,
+ "title", get_default_title (),
+ NULL);
+ display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
+ break;
+ case GDK_SURFACE_POPUP:
+ g_warn_if_fail (parent != NULL);
+ surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
+ "parent", parent,
+ "display", display,
+ "frame-clock", frame_clock,
+ NULL);
+ break;
+ case GDK_SURFACE_DRAG:
+ g_warn_if_fail (parent == NULL);
+ surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
+ "display", display,
+ "frame-clock", frame_clock,
+ NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (width > 65535)
+ {
+ g_warning ("Native Surfaces wider than 65535 pixels are not supported");
+ width = 65535;
+ }
+ if (height > 65535)
+ {
+ g_warning ("Native Surfaces taller than 65535 pixels are not supported");
+ height = 65535;
+ }
+
+ surface->x = x;
+ surface->y = y;
+ surface->width = width;
+ surface->height = height;
+
+ g_object_ref (surface);
+
+ /* More likely to be right than just assuming 1 */
+ if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
+ {
+ GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
+ if (monitor)
+ {
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
+
+ if (monitor_scale != 1)
+ {
+ impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
+ impl->buffer_scale_dirty = TRUE;
+ }
+
+ g_object_unref (monitor);
+ }
+ }
+
+ gdk_wayland_surface_create_wl_surface (surface);
+
+ g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
+ g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
+
+ g_object_unref (frame_clock);
+
+ return surface;
+}
+
static void
maybe_notify_mapped (GdkSurface *surface)
{
@@ -1048,53 +1048,49 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ if (!impl->mapped)
+ return;
+
unmap_popups_for_surface (surface);
- if (impl->display_server.wl_surface)
+ if (impl->display_server.egl_window)
{
- if (impl->display_server.egl_window)
- {
- gdk_surface_set_egl_native_window (surface, NULL);
- wl_egl_window_destroy (impl->display_server.egl_window);
- impl->display_server.egl_window = NULL;
- }
+ gdk_surface_set_egl_native_window (surface, NULL);
+ wl_egl_window_destroy (impl->display_server.egl_window);
+ impl->display_server.egl_window = NULL;
+ }
- impl->awaiting_frame = FALSE;
- if (impl->awaiting_frame_frozen)
- {
- impl->awaiting_frame_frozen = FALSE;
- gdk_surface_thaw_updates (surface);
- }
+ impl->awaiting_frame = FALSE;
+ if (impl->awaiting_frame_frozen)
+ {
+ impl->awaiting_frame_frozen = FALSE;
+ gdk_surface_thaw_updates (surface);
+ }
- GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
+ GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
- if (impl->display_server.xdg_surface)
- {
- xdg_surface_destroy (impl->display_server.xdg_surface);
- impl->display_server.xdg_surface = NULL;
- if (!impl->initial_configure_received)
- gdk_surface_thaw_updates (surface);
- else
- impl->initial_configure_received = FALSE;
- }
- if (impl->display_server.zxdg_surface_v6)
- {
- g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
- if (!impl->initial_configure_received)
- gdk_surface_thaw_updates (surface);
- else
- impl->initial_configure_received = FALSE;
- }
-
- gdk_wayland_surface_destroy_wl_surface (impl);
+ if (impl->display_server.xdg_surface)
+ {
+ xdg_surface_destroy (impl->display_server.xdg_surface);
+ impl->display_server.xdg_surface = NULL;
+ if (!impl->initial_configure_received)
+ gdk_surface_thaw_updates (surface);
+ else
+ impl->initial_configure_received = FALSE;
+ }
+ if (impl->display_server.zxdg_surface_v6)
+ {
+ g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
+ if (!impl->initial_configure_received)
+ gdk_surface_thaw_updates (surface);
+ else
+ impl->initial_configure_received = FALSE;
}
+ wl_surface_attach (impl->display_server.wl_surface, NULL, 0, 0);
+ wl_surface_commit (impl->display_server.wl_surface);
+
impl->has_uncommitted_ack_configure = FALSE;
- impl->input_region_dirty = TRUE;
- impl->opaque_region_dirty = TRUE;
- impl->viewport_dirty = TRUE;
- if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
- impl->buffer_scale_dirty = TRUE;
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
impl->mapped = FALSE;
@@ -1235,6 +1231,8 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
gdk_wayland_surface_hide_surface (surface);
+ gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE(surface));
+
frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_after_paint, surface);
diff --git a/gdk/wayland/gdktoplevel-wayland.c b/gdk/wayland/gdktoplevel-wayland.c
index 6954795f0e..416aab4840 100644
--- a/gdk/wayland/gdktoplevel-wayland.c
+++ b/gdk/wayland/gdktoplevel-wayland.c
@@ -1526,9 +1526,6 @@ gdk_wayland_toplevel_show (GdkWaylandToplevel *toplevel)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
- if (!impl->display_server.wl_surface)
- gdk_wayland_surface_create_wl_surface (GDK_SURFACE (impl));
-
if (impl->mapped)
return;