wayland: Don't set the surface to toplevel until it is shown

If we delay setting the surface to toplevel until it is shown then
that gives the application an opportunity to avoid calling show so
that it can set its own surface type.

Reviewed-by: Robert Bragg <robert@linux.intel.com>

(cherry picked from commit ab59c3a421968d7f159d89ca2f0ba8a9f098cbf6)
This commit is contained in:
Neil Roberts 2013-05-15 16:34:15 +01:00
parent 4543ed6ac3
commit 0b2b46ce4c
2 changed files with 40 additions and 6 deletions

View File

@ -273,6 +273,12 @@ cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
* This function will implicitly allocate the given @onscreen
* framebuffer before showing it if it hasn't already been allocated.
*
* When using the Wayland winsys calling this will set the surface to
* a toplevel type which will make it appear. If the application wants
* to set a different type for the surface, it can avoid calling
* cogl_onscreen_show() and set its own type directly with the Wayland
* client API via cogl_wayland_onscreen_get_surface().
*
* <note>Since Cogl doesn't explicitly track the visibility status of
* onscreen framebuffers it wont try to avoid redundant window system
* requests e.g. to show an already visible window. This also means

View File

@ -74,6 +74,8 @@ typedef struct _CoglOnscreenWayland
int pending_dx;
int pending_dy;
CoglBool has_pending;
CoglBool shell_surface_type_set;
} CoglOnscreenWayland;
static void
@ -377,12 +379,9 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
NULL);
if (!onscreen->foreign_surface)
{
wayland_onscreen->wayland_shell_surface =
wl_shell_get_shell_surface (wayland_renderer->wayland_shell,
wayland_onscreen->wayland_surface);
wl_shell_surface_set_toplevel (wayland_onscreen->wayland_shell_surface);
}
wayland_onscreen->wayland_shell_surface =
wl_shell_get_shell_surface (wayland_renderer->wayland_shell,
wayland_onscreen->wayland_surface);
return TRUE;
}
@ -460,6 +459,32 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
wl_display_flush (wayland_renderer->wayland_display);
}
static void
_cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
CoglBool visibility)
{
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglOnscreenWayland *wayland_onscreen = egl_onscreen->platform;
/* The first time the onscreen is shown we will set it to toplevel
* so that it will appear on the screen. If the surface is foreign
* then we won't have the shell surface and we'll just let the
* application deal with setting the surface type. */
if (visibility &&
wayland_onscreen->wayland_shell_surface &&
!wayland_onscreen->shell_surface_type_set)
{
wl_shell_surface_set_toplevel (wayland_onscreen->wayland_shell_surface);
wayland_onscreen->shell_surface_type_set = TRUE;
}
/* FIXME: We should also do something here to hide the surface when
* visilibity == FALSE. It sounds like there are currently ongoing
* discussions about adding support for hiding surfaces in the
* Wayland protocol so we might as well wait until then to add that
* here. */
}
void
cogl_wayland_renderer_set_foreign_display (CoglRenderer *renderer,
struct wl_display *display)
@ -657,6 +682,9 @@ _cogl_winsys_egl_wayland_get_vtable (void)
vtable.onscreen_swap_buffers_with_damage =
_cogl_winsys_onscreen_swap_buffers_with_damage;
vtable.onscreen_set_visibility =
_cogl_winsys_onscreen_set_visibility;
vtable_inited = TRUE;
}