diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 7dc8ac461..8786223e1 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -37,6 +37,8 @@ struct sway_view_impl { bool (*wants_floating)(struct sway_view *view); void (*for_each_surface)(struct sway_view *view, wlr_surface_iterator_func_t iterator, void *user_data); + void (*for_each_popup)(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data); void (*close)(struct sway_view *view); void (*destroy)(struct sway_view *view); }; diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 5e91eadae..dc7610e41 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -247,6 +247,21 @@ static void render_saved_view(struct sway_view *view, float alpha) { render_texture(texture, &box, matrix, alpha); } +static void render_popup(struct wlr_surface *surface, int sx, int sy, + void *data) { + struct sway_view *view = data; + double ox = view->swayc->current.view_x - context.output_lx + sx; + double oy = view->swayc->current.view_y - context.output_ly + sy; + render_surface(surface, ox, oy, view->swayc->alpha); +} + +static void render_view_popups(struct sway_container *con, void *data) { + struct sway_view *view = con->sway_view; + if (view->impl->for_each_popup) { + view->impl->for_each_popup(view, render_popup, view); + } +} + /** * Render a view's surface and left/bottom/right borders. */ @@ -812,6 +827,7 @@ void render_output(struct sway_output *output, struct timespec *when, // TODO: handle views smaller than the output render_surfaces(fullscreen_view->surface, 0, 0, 1.0f); + render_view_popups(fullscreen_view->swayc, NULL); if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) { render_unmanaged(&root_container.sway_root->xwayland_unmanaged); @@ -833,6 +849,7 @@ void render_output(struct sway_output *output, struct timespec *when, struct sway_container *focus = seat_get_focus(seat); render_container(workspace, focus == workspace); render_floating(); + container_descendants(workspace, C_VIEW, render_view_popups, NULL); render_unmanaged(&root_container.sway_root->xwayland_unmanaged); render_layer(&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 82db40760..8683c56b1 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -147,6 +147,14 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_view_from_view(view) == NULL) { return; @@ -174,6 +182,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .destroy = destroy, }; diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 0d3c16443..f4a743053 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -143,6 +143,15 @@ static void for_each_surface(struct sway_view *view, user_data); } +static void for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (xdg_shell_v6_view_from_view(view) == NULL) { + return; + } + wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator, + user_data); +} + static void _close(struct sway_view *view) { if (xdg_shell_v6_view_from_view(view) == NULL) { return; @@ -170,6 +179,7 @@ static const struct sway_view_impl view_impl = { .set_fullscreen = set_fullscreen, .wants_floating = wants_floating, .for_each_surface = for_each_surface, + .for_each_popup = for_each_popup, .close = _close, .destroy = destroy, };