xwayland: reintroduce XWayland workaround

This was temporarily removed when introducing proper view abstractions.
Now that we have the cg_xwayland_view struct, we reintroduce this
workaround in its proper place.

This also fixes the previous workaround, which checked whether a view
was *currently* mapped and not if it *has ever* been mapped.

See #18, #19 and 443d955dfd.
This commit is contained in:
Jente Hidskes 2019-01-30 17:19:40 +01:00
parent 7175100d0d
commit 41d4ccfe44
3 changed files with 27 additions and 1 deletions

13
view.c
View file

@ -20,6 +20,9 @@
#include "seat.h"
#include "server.h"
#include "view.h"
#if CAGE_HAS_XWAYLAND
#include "xwayland.h"
#endif
char *
view_get_title(struct cg_view *view)
@ -115,6 +118,14 @@ void
view_destroy(struct cg_view *view)
{
struct cg_server *server = view->server;
bool ever_been_mapped = true;
#if CAGE_HAS_XWAYLAND
if (view->type == CAGE_XWAYLAND_VIEW) {
struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view);
ever_been_mapped = xwayland_view->ever_been_mapped;
}
#endif
if (view->wlr_surface != NULL) {
view_unmap(view);
@ -127,7 +138,7 @@ view_destroy(struct cg_view *view)
if (!empty) {
struct cg_view *prev = wl_container_of(server->views.next, prev, link);
seat_set_focus(server->seat, prev);
} else {
} else if (ever_been_mapped) {
/* The list is empty and the last view has been
mapped, so we can safely exit. */
wl_display_terminate(server->wl_display);

View file

@ -106,6 +106,7 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *data)
struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, map);
struct cg_view *view = &xwayland_view->view;
xwayland_view->ever_been_mapped = true;
view_map(view, xwayland_view->xwayland_surface->surface);
}

View file

@ -10,6 +10,20 @@ struct cg_xwayland_view {
struct cg_view view;
struct wlr_xwayland_surface *xwayland_surface;
/* Some applications that aren't yet Wayland-native or
otherwise "special" (e.g. Firefox Nightly and Google
Chrome/Chromium) spawn an XWayland surface upon startup
that is almost immediately closed again. This makes Cage
think there are no views left, which results in it
exiting. However, after this initial (unmapped) surface,
the "real" application surface is opened. This leads to
these applications' startup sequences being interrupted by
Cage exiting. Hence, to work around this issue, Cage checks
whether an XWayland surface has ever been mapped and exits
only if 1) the XWayland surface has ever been mapped and 2)
this was the last surface Cage manages. */
bool ever_been_mapped;
struct wl_listener destroy;
struct wl_listener unmap;
struct wl_listener map;