struct view base;
struct wlr_xwayland_surface *xwayland_surface;
- /* Used to detect stacking order updates */
- int stacking_order;
-
/* Events unique to XWayland views */
struct wl_listener associate;
struct wl_listener dissociate;
void xwayland_view_create(struct server *server,
struct wlr_xwayland_surface *xsurface, bool mapped);
-void xwayland_adjust_stacking_order(struct server *server);
-
struct wlr_xwayland_surface *xwayland_surface_from_view(struct view *view);
void xwayland_server_init(struct server *server,
move_to_front(view);
}
-#if HAVE_XWAYLAND
- if (view->type == LAB_XWAYLAND_VIEW) {
- xwayland_adjust_stacking_order(view->server);
- }
-#endif
-
cursor_update_focus(view->server);
desktop_update_top_layer_visibility(view->server);
}
for_each_subview(root, move_to_back);
move_to_back(root);
-#if HAVE_XWAYLAND
- if (view->type == LAB_XWAYLAND_VIEW) {
- xwayland_adjust_stacking_order(view->server);
- }
-#endif
-
cursor_update_focus(view->server);
desktop_update_top_layer_visibility(view->server);
}
view->shaded = shaded;
ssd_enable_shade(view->ssd, view->shaded);
wlr_scene_node_set_enabled(&view->content_tree->node, !view->shaded);
-
-#if HAVE_XWAYLAND
- if (view->type == LAB_XWAYLAND_VIEW) {
- xwayland_adjust_stacking_order(view->server);
- }
-#endif
}
void
view->type = LAB_XWAYLAND_VIEW;
view->impl = &xwayland_view_impl;
- /* Set to -1 so we always restack the view on map */
- xwayland_view->stacking_order = -1;
-
/*
* Set two-way view <-> xsurface association. Usually the association
* remains until the xsurface is destroyed (which also destroys the
}
}
-enum xwayland_view_layer {
- XWAYLAND_VIEW_HIDDEN,
- XWAYLAND_VIEW_BOTTOM,
- XWAYLAND_VIEW_NORMAL,
- XWAYLAND_VIEW_TOP,
-};
-
-static enum xwayland_view_layer
-get_layer(struct view *view)
-{
- if (view->workspace != view->server->workspaces.current) {
- /*
- * Until we expose the workspaces to xwayland we need a way to
- * ensure that xwayland views on the current workspace are
- * always stacked above xwayland views on other workspaces.
- *
- * If we fail to do so, issues arise in scenarios where we
- * change the mouse focus but do not change the (xwayland)
- * stacking order.
- *
- * Reproducer:
- * - open at least two xwayland windows which allow scrolling
- * (e.g. urxvt with 'man man')
- * - switch to another workspace, open another xwayland window
- * which allows scrolling and maximize it
- * - switch back to the previous workspace with the two windows
- * - move the mouse to the xwayland window that does *not* have
- * focus
- * - start scrolling
- * - all scroll events should end up on the maximized window on
- * the other workspace
- */
- return XWAYLAND_VIEW_HIDDEN;
- } else if (view->shaded) {
- /*
- * Ensure that we don't raise a shaded window to the front
- * which then steals mouse events.
- */
- return XWAYLAND_VIEW_HIDDEN;
- } else if (view_is_always_on_bottom(view)) {
- return XWAYLAND_VIEW_BOTTOM;
- } else if (view_is_always_on_top(view)) {
- return XWAYLAND_VIEW_TOP;
- } else {
- return XWAYLAND_VIEW_NORMAL;
- }
-}
-
-void
-xwayland_adjust_stacking_order(struct server *server)
-{
- if (!server->xwayland) {
- /* This happens when windows are unmapped on exit */
- return;
- }
-
- int stacking_order = 0;
- bool update = false;
-
- /*
- * Iterate over the windows from bottom to top and notify their
- * stacking order to xwayland if we detect updates in it. Note
- * that server->views are sorted from top to bottom but doesn't
- * consider always-on-{top,bottom} windows.
- */
- for (enum xwayland_view_layer layer = XWAYLAND_VIEW_HIDDEN;
- layer <= XWAYLAND_VIEW_TOP; layer++) {
- struct view *view;
- wl_list_for_each_reverse(view, &server->views, link) {
- if (view->type != LAB_XWAYLAND_VIEW
- || layer != get_layer(view)) {
- continue;
- }
-
- struct xwayland_view *xwayland_view =
- xwayland_view_from_view(view);
-
- /* On detecting update, restack all the views above it */
- update |= xwayland_view->stacking_order != stacking_order;
- if (update) {
- wlr_xwayland_surface_restack(
- xwayland_view->xwayland_surface,
- NULL, XCB_STACK_MODE_ABOVE);
- }
- xwayland_view->stacking_order = stacking_order;
- stacking_order++;
- }
- }
-}
-
void
xwayland_reset_cursor(struct server *server)
{