mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
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.
This commit is contained in:
parent
891242920e
commit
5d3cec5441
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user