From 0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 25 Jul 2018 08:50:06 +0100 Subject: Improve rendering with a fullscreen opaque overlay surface The rendering code doesn't use the exclusive input surface at all anymore to decide to skip rendering of shell surfaces. This fixes a weird situation in which a client requests exclusive input but isn't an overlay layer surface. The renderer also renders all overlay surfaces in this situation, not just one. This simplifies the code and fixes rendering when there are more than one overlay surfaces (e.g. for a virtual keyboard to type the lockscreen password). --- include/sway/output.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index b6cda83c..c225e541 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -65,8 +65,7 @@ struct sway_container *output_by_name(const char *name); void output_enable(struct sway_output *output); -bool output_has_opaque_lockscreen(struct sway_output *output, - struct sway_seat *seat); +bool output_has_opaque_overlay_layer_surface(struct sway_output *output); struct sway_container *output_get_active_workspace(struct sway_output *output); -- cgit v1.2.3 From d2172bd331937ab406175a6b4c5a76db6f406fbe Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:17:47 +0100 Subject: wip: redesign output_unmanaged_for_each_surface iterator --- include/sway/output.h | 17 +++++++++--- sway/desktop/output.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- sway/desktop/render.c | 31 ++++++++++++++++++++-- 3 files changed, 110 insertions(+), 11 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index c225e541..99b0bcc6 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -5,6 +5,7 @@ #include #include #include +#include "config.h" #include "sway/tree/view.h" struct sway_server; @@ -48,6 +49,10 @@ struct root_geometry { float rotation; }; +typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *user_data); + void output_damage_whole(struct sway_output *output); void output_damage_surface(struct sway_output *output, double ox, double oy, @@ -80,6 +85,10 @@ void output_surface_for_each_surface(struct wlr_surface *surface, double ox, double oy, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); +void output_surface_for_each_surface2(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation, + sway_surface_iterator_func_t iterator, void *user_data); + void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); @@ -88,9 +97,11 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +#ifdef HAVE_XWAYLAND +void output_unmanaged_for_each_surface(struct sway_output *output, + struct wl_list *unmanaged, sway_surface_iterator_func_t iterator, + void *user_data); +#endif void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index cecd300a..9c2a1a07 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -105,6 +105,56 @@ void output_surface_for_each_surface(struct wlr_surface *surface, wlr_surface_for_each_surface(surface, iterator, user_data); } +struct surface_iterator_data { + sway_surface_iterator_func_t user_iterator; + void *user_data; + + struct sway_output *output; + double ox, oy; + int width, height; + float rotation; +}; + +void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, + int sx, int sy, void *_data) { + struct surface_iterator_data *data = _data; + + struct root_geometry geo = { + .x = data->ox, + .y = data->oy, + .width = data->width, + .height = data->height, + .rotation = data->rotation, + }; + struct wlr_box box; + bool intersects = output_get_surface_box(&geo, data->output, + surface, sx, sy, &box); + if (!intersects) { + return; + } + + data->user_iterator(data->output, surface, &box, data->rotation, + data->user_data); +} + +void output_surface_for_each_surface2(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation, + sway_surface_iterator_func_t iterator, void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = ox, + .oy = oy, + .width = surface->current.width, + .height = surface->current.height, + .rotation = rotation, + }; + + wlr_surface_for_each_surface(surface, + output_surface_for_each_surface2_iterator, &data); +} + void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -129,10 +179,11 @@ void output_layer_for_each_surface(struct wl_list *layer_surfaces, user_data); } } + #ifdef HAVE_XWAYLAND -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_unmanaged_for_each_surface(struct sway_output *output, + struct wl_list *unmanaged, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_xwayland_unmanaged *unmanaged_surface; wl_list_for_each(unmanaged_surface, unmanaged, link) { struct wlr_xwayland_surface *xsurface = @@ -140,11 +191,12 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(xsurface->surface, ox, oy, geo, + output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } #endif + void output_drag_icons_for_each_surface(struct wl_list *drag_icons, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { @@ -228,18 +280,27 @@ static void send_frame_done_iterator(struct wlr_surface *surface, } } +static void send_frame_done_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *_data) { + struct send_frame_done_data *data = _data; + wlr_surface_send_frame_done(surface, data->when); +} + static void send_frame_done_layer(struct send_frame_done_data *data, struct wl_list *layer_surfaces) { output_layer_for_each_surface(layer_surfaces, &data->root_geo, send_frame_done_iterator, data); } + #ifdef HAVE_XWAYLAND static void send_frame_done_unmanaged(struct send_frame_done_data *data, struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_unmanaged_for_each_surface(data->output, unmanaged, + send_frame_done_iterator2, data); } #endif + static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c9fdfd95..8eea19e0 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -123,6 +123,31 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); } +static void render_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct render_data *data = _data; + struct wlr_output *wlr_output = output->wlr_output; + pixman_region32_t *output_damage = data->damage; + float alpha = data->alpha; + + struct wlr_texture *texture = wlr_surface_get_texture(surface); + if (!texture) { + return; + } + + struct wlr_box box = *_box; + scale_box(&box, wlr_output->scale); + + float matrix[9]; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, rotation, + wlr_output->transform_matrix); + + render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); +} + static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { @@ -133,6 +158,7 @@ static void render_layer(struct sway_output *output, output_layer_for_each_surface(layer_surfaces, &data.root_geo, render_surface_iterator, &data); } + #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { @@ -141,10 +167,11 @@ static void render_unmanaged(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo, - render_surface_iterator, &data); + output_unmanaged_for_each_surface(output, unmanaged, + render_surface_iterator2, &data); } #endif + static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { -- cgit v1.2.3 From dbf6dd0daec9e712a002c3e01accbd0fee769fac Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:44:36 +0100 Subject: wip: redesign output_drag_icons_for_each_surface iterator --- include/sway/output.h | 6 +++--- sway/desktop/output.c | 15 ++++++++------- sway/desktop/render.c | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 99b0bcc6..10a14207 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -103,8 +103,8 @@ void output_unmanaged_for_each_surface(struct sway_output *output, void *user_data); #endif -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data); #endif diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 9c2a1a07..e83a9a3d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -197,17 +197,18 @@ void output_unmanaged_for_each_surface(struct sway_output *output, } #endif -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { +void output_drag_icons_for_each_surface(struct sway_output *output, + struct wl_list *drag_icons, sway_surface_iterator_func_t iterator, + void *user_data) { struct sway_drag_icon *drag_icon; wl_list_for_each(drag_icon, drag_icons, link) { double ox = drag_icon->x - output->swayc->x; double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, - ox, oy, geo, iterator, user_data); + output_surface_for_each_surface2(output, + drag_icon->wlr_drag_icon->surface, ox, oy, 0, + iterator, user_data); } } } @@ -303,8 +304,8 @@ static void send_frame_done_unmanaged(struct send_frame_done_data *data, static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_drag_icons_for_each_surface(data->output, drag_icons, + send_frame_done_iterator2, data); } static void send_frame_done_container_iterator(struct sway_container *con, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 8eea19e0..1270b7cf 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -179,8 +179,8 @@ static void render_drag_icons(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_drag_icons_for_each_surface(drag_icons, output, &data.root_geo, - render_surface_iterator, &data); + output_drag_icons_for_each_surface(output, drag_icons, + render_surface_iterator2, &data); } static void render_rect(struct wlr_output *wlr_output, -- cgit v1.2.3 From a0dd9776172796f65b0fce0a8e5cfb66bdb2e2e5 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:53:15 +0100 Subject: wip: redesign output_layer_for_each_surface iterator --- include/sway/output.h | 4 ++-- sway/desktop/output.c | 32 ++++++++++++++++---------------- sway/desktop/render.c | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 10a14207..c1763b26 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -93,8 +93,8 @@ void output_view_for_each_surface(struct sway_view *view, struct sway_output *output, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data); -void output_layer_for_each_surface(struct wl_list *layer_surfaces, - struct root_geometry *geo, wlr_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct sway_output *output, + struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data); #ifdef HAVE_XWAYLAND diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e83a9a3d..5e309250 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -167,15 +167,15 @@ void output_view_for_each_surface(struct sway_view *view, view_for_each_surface(view, iterator, user_data); } -void output_layer_for_each_surface(struct wl_list *layer_surfaces, - struct root_geometry *geo, wlr_surface_iterator_func_t iterator, +void output_layer_for_each_surface(struct sway_output *output, + struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { struct sway_layer_surface *layer_surface; wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface(wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, geo, iterator, + output_surface_for_each_surface2(output, wlr_layer_surface->surface, + layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } } @@ -288,10 +288,10 @@ static void send_frame_done_iterator2(struct sway_output *output, wlr_surface_send_frame_done(surface, data->when); } -static void send_frame_done_layer(struct send_frame_done_data *data, - struct wl_list *layer_surfaces) { - output_layer_for_each_surface(layer_surfaces, &data->root_geo, - send_frame_done_iterator, data); +static void send_frame_done_layer(struct sway_output *output, + struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + output_layer_for_each_surface(output, layer_surfaces, + send_frame_done_iterator2, data); } #ifdef HAVE_XWAYLAND @@ -352,10 +352,10 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &root_container.sway_root->xwayland_unmanaged); #endif } else { - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); send_frame_done_container(&data, workspace); send_frame_done_container(&data, workspace->sway_workspace->floating); @@ -364,13 +364,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { send_frame_done_unmanaged(&data, &root_container.sway_root->xwayland_unmanaged); #endif - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); } send_frame_overlay: - send_frame_done_layer(&data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + send_frame_done_layer(output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); } diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1270b7cf..35dc3edc 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -155,8 +155,8 @@ static void render_layer(struct sway_output *output, .damage = damage, .alpha = 1.0f, }; - output_layer_for_each_surface(layer_surfaces, &data.root_geo, - render_surface_iterator, &data); + output_layer_for_each_surface(output, layer_surfaces, + render_surface_iterator2, &data); } #ifdef HAVE_XWAYLAND -- cgit v1.2.3 From e9d674cfd294f13a32893dd584826ed7481e05e3 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 18:59:14 +0100 Subject: wip: redesign output_view_for_each_surface iterator --- include/sway/output.h | 6 ++--- sway/desktop/output.c | 75 ++++++++++++++++++++++++++++++++++++++++++--------- sway/desktop/render.c | 3 +-- 3 files changed, 66 insertions(+), 18 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index c1763b26..7a458a84 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -89,9 +89,9 @@ void output_surface_for_each_surface2(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data); -void output_view_for_each_surface(struct sway_view *view, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); +void output_view_for_each_surface(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data); void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 5e309250..31033ee3 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -155,16 +155,22 @@ void output_surface_for_each_surface2(struct sway_output *output, output_surface_for_each_surface2_iterator, &data); } -void output_view_for_each_surface(struct sway_view *view, - struct sway_output *output, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = view->swayc->current.view_x - output->swayc->current.swayc_x; - geo->y = view->swayc->current.view_y - output->swayc->current.swayc_y; - geo->width = view->swayc->current.view_width; - geo->height = view->swayc->current.view_height; - geo->rotation = 0; // TODO +void output_view_for_each_surface(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; - view_for_each_surface(view, iterator, user_data); + view_for_each_surface(view, + output_surface_for_each_surface2_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -319,8 +325,8 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, - send_frame_done_iterator, data); + output_view_for_each_surface(data->output, con->sway_view, + send_frame_done_iterator2, data); } static void send_frame_done_container(struct send_frame_done_data *data, @@ -463,6 +469,50 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, wlr_output_schedule_frame(output->wlr_output); } +static void damage_surface_iterator2(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *_box, float rotation, + void *_data) { + struct damage_data *data = _data; + bool whole = data->whole; + + struct wlr_box box = *_box; + scale_box(&box, output->wlr_output->scale); + + int center_x = box.x + box.width/2; + int center_y = box.y + box.height/2; + + if (pixman_region32_not_empty(&surface->buffer_damage)) { + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + + pixman_region32_t damage; + pixman_region32_init(&damage); + pixman_region32_copy(&damage, &surface->buffer_damage); + wlr_region_transform(&damage, &damage, transform, + surface->current.buffer_width, surface->current.buffer_height); + wlr_region_scale(&damage, &damage, + output->wlr_output->scale / (float)surface->current.scale); + if (ceil(output->wlr_output->scale) > surface->current.scale) { + // When scaling up a surface, it'll become blurry so we need to + // expand the damage region + wlr_region_expand(&damage, &damage, + ceil(output->wlr_output->scale) - surface->current.scale); + } + pixman_region32_translate(&damage, box.x, box.y); + wlr_region_rotated_bounds(&damage, &damage, rotation, + center_x, center_y); + wlr_output_damage_add(output->damage, &damage); + pixman_region32_fini(&damage); + } + + if (whole) { + wlr_box_rotated_bounds(&box, rotation, &box); + wlr_output_damage_add_box(output->damage, &box); + } + + wlr_output_schedule_frame(output->wlr_output); +} + void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { struct damage_data data = { @@ -489,8 +539,7 @@ static void output_damage_view(struct sway_output *output, .whole = whole, }; - output_view_for_each_surface(view, output, &data.root_geo, - damage_surface_iterator, &data); + output_view_for_each_surface(output, view, damage_surface_iterator2, &data); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 35dc3edc..18d076df 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -231,8 +231,7 @@ static void render_view_surfaces(struct sway_view *view, .view = view, .alpha = alpha, }; - output_view_for_each_surface(view, output, &data.root_geo, - render_surface_iterator, &data); + output_view_for_each_surface(output, view, render_surface_iterator2, &data); } static void render_saved_view(struct sway_view *view, -- cgit v1.2.3 From 8d5cc8625ce04c657eab6bd5f242a02e97ddd647 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:16:36 +0100 Subject: Completely switch over to new iterators --- include/sway/output.h | 18 ---- sway/desktop/output.c | 243 +++++++++++++++----------------------------------- sway/desktop/render.c | 49 ++-------- 3 files changed, 79 insertions(+), 231 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 7a458a84..70f631a0 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -39,16 +39,6 @@ struct sway_output { } events; }; -/** - * Contains a surface's root geometry information. For instance, when rendering - * a popup, this will contain the parent view's position and size. - */ -struct root_geometry { - double x, y; - int width, height; - float rotation; -}; - typedef void (*sway_surface_iterator_func_t)(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *user_data); @@ -77,14 +67,6 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); -bool output_get_surface_box(struct root_geometry *geo, - struct sway_output *output, struct wlr_surface *surface, int sx, int sy, - struct wlr_box *surface_box); - -void output_surface_for_each_surface(struct wlr_surface *surface, - double ox, double oy, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data); - void output_surface_for_each_surface2(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31033ee3..e1d85b10 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -57,9 +57,21 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, *sy = ry + ph/2 - sh/2; } -bool output_get_surface_box(struct root_geometry *geo, - struct sway_output *output, struct wlr_surface *surface, int sx, int sy, +struct surface_iterator_data { + sway_surface_iterator_func_t user_iterator; + void *user_data; + + struct sway_output *output; + double ox, oy; + int width, height; + float rotation; +}; + +static bool get_surface_box(struct surface_iterator_data *data, + struct wlr_surface *surface, int sx, int sy, struct wlr_box *surface_box) { + struct sway_output *output = data->output; + if (!wlr_surface_has_buffer(surface)) { return false; } @@ -68,12 +80,12 @@ bool output_get_surface_box(struct root_geometry *geo, int sh = surface->current.height; double _sx = sx, _sy = sy; - rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, - geo->rotation); + rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height, + data->rotation); struct wlr_box box = { - .x = geo->x + _sx, - .y = geo->y + _sy, + .x = data->ox + _sx, + .y = data->oy + _sy, .width = sw, .height = sh, }; @@ -82,7 +94,7 @@ bool output_get_surface_box(struct root_geometry *geo, } struct wlr_box rotated_box; - wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); + wlr_box_rotated_bounds(&box, data->rotation, &rotated_box); struct wlr_box output_box = { .width = output->swayc->current.swayc_width, @@ -93,42 +105,12 @@ bool output_get_surface_box(struct root_geometry *geo, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -void output_surface_for_each_surface(struct wlr_surface *surface, - double ox, double oy, struct root_geometry *geo, - wlr_surface_iterator_func_t iterator, void *user_data) { - geo->x = ox; - geo->y = oy; - geo->width = surface->current.width; - geo->height = surface->current.height; - geo->rotation = 0; - - wlr_surface_for_each_surface(surface, iterator, user_data); -} - -struct surface_iterator_data { - sway_surface_iterator_func_t user_iterator; - void *user_data; - - struct sway_output *output; - double ox, oy; - int width, height; - float rotation; -}; - -void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, +void output_surface_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct surface_iterator_data *data = _data; - struct root_geometry geo = { - .x = data->ox, - .y = data->oy, - .width = data->width, - .height = data->height, - .rotation = data->rotation, - }; struct wlr_box box; - bool intersects = output_get_surface_box(&geo, data->output, - surface, sx, sy, &box); + bool intersects = get_surface_box(data, surface, sx, sy, &box); if (!intersects) { return; } @@ -137,7 +119,7 @@ void output_surface_for_each_surface2_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface2(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, float rotation, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -152,7 +134,7 @@ void output_surface_for_each_surface2(struct sway_output *output, }; wlr_surface_for_each_surface(surface, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_view_for_each_surface(struct sway_output *output, @@ -170,7 +152,7 @@ void output_view_for_each_surface(struct sway_output *output, }; view_for_each_surface(view, - output_surface_for_each_surface2_iterator, &data); + output_surface_for_each_surface_iterator, &data); } void output_layer_for_each_surface(struct sway_output *output, @@ -180,7 +162,7 @@ void output_layer_for_each_surface(struct sway_output *output, wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface2(output, wlr_layer_surface->surface, + output_surface_for_each_surface(output, wlr_layer_surface->surface, layer_surface->geo.x, layer_surface->geo.y, 0, iterator, user_data); } @@ -197,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface2(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, iterator, user_data); } } @@ -212,7 +194,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface2(output, + output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface, ox, oy, 0, iterator, user_data); } @@ -270,50 +252,38 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { return false; } -struct send_frame_done_data { - struct root_geometry root_geo; - struct sway_output *output; - struct timespec *when; -}; - -static void send_frame_done_iterator(struct wlr_surface *surface, - int sx, int sy, void *_data) { - struct send_frame_done_data *data = _data; - - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, NULL); - if (intersects) { - wlr_surface_send_frame_done(surface, data->when); - } -} - -static void send_frame_done_iterator2(struct sway_output *output, +static void send_frame_done_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *box, float rotation, void *_data) { - struct send_frame_done_data *data = _data; - wlr_surface_send_frame_done(surface, data->when); + struct timespec *when = _data; + wlr_surface_send_frame_done(surface, when); } static void send_frame_done_layer(struct sway_output *output, - struct wl_list *layer_surfaces, struct send_frame_done_data *data) { + struct wl_list *layer_surfaces, struct timespec *when) { output_layer_for_each_surface(output, layer_surfaces, - send_frame_done_iterator2, data); + send_frame_done_iterator, when); } #ifdef HAVE_XWAYLAND -static void send_frame_done_unmanaged(struct send_frame_done_data *data, - struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(data->output, unmanaged, - send_frame_done_iterator2, data); +static void send_frame_done_unmanaged(struct sway_output *output, + struct wl_list *unmanaged, struct timespec *when) { + output_unmanaged_for_each_surface(output, unmanaged, + send_frame_done_iterator, when); } #endif -static void send_frame_done_drag_icons(struct send_frame_done_data *data, - struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(data->output, drag_icons, - send_frame_done_iterator2, data); +static void send_frame_done_drag_icons(struct sway_output *output, + struct wl_list *drag_icons, struct timespec *when) { + output_drag_icons_for_each_surface(output, drag_icons, + send_frame_done_iterator, when); } +struct send_frame_done_data { + struct sway_output *output; + struct timespec *when; +}; + static void send_frame_done_container_iterator(struct sway_container *con, void *_data) { struct send_frame_done_data *data = _data; @@ -326,21 +296,20 @@ static void send_frame_done_container_iterator(struct sway_container *con, } output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator2, data); -} - -static void send_frame_done_container(struct send_frame_done_data *data, - struct sway_container *con) { - container_descendants(con, C_VIEW, - send_frame_done_container_iterator, data); + send_frame_done_iterator, data->when); } -static void send_frame_done(struct sway_output *output, struct timespec *when) { +static void send_frame_done_container(struct sway_output *output, + struct sway_container *con, struct timespec *when) { struct send_frame_done_data data = { .output = output, .when = when, }; + container_descendants(con, C_VIEW, + send_frame_done_container_iterator, &data); +} +static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; } @@ -349,35 +318,38 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { if (workspace->current.ws_fullscreen) { if (workspace->current.ws_fullscreen->type == C_VIEW) { send_frame_done_container_iterator( - workspace->current.ws_fullscreen, &data); + workspace->current.ws_fullscreen, when); } else { - send_frame_done_container(&data, workspace->current.ws_fullscreen); + send_frame_done_container(output, workspace->current.ws_fullscreen, + when); } #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif } else { send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when); send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when); - send_frame_done_container(&data, workspace); - send_frame_done_container(&data, workspace->sway_workspace->floating); + send_frame_done_container(output, workspace, when); + send_frame_done_container(output, workspace->sway_workspace->floating, + when); #ifdef HAVE_XWAYLAND - send_frame_done_unmanaged(&data, - &root_container.sway_root->xwayland_unmanaged); + send_frame_done_unmanaged(output, + &root_container.sway_root->xwayland_unmanaged, when); #endif send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &data); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } send_frame_overlay: send_frame_done_layer(output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &data); - send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); + send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons, + when); } static void damage_handle_frame(struct wl_listener *listener, void *data) { @@ -412,68 +384,11 @@ void output_damage_whole(struct sway_output *output) { wlr_output_damage_add_whole(output->damage); } -struct damage_data { - struct root_geometry root_geo; - struct sway_output *output; - bool whole; -}; - -static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct damage_data *data = _data; - struct sway_output *output = data->output; - float rotation = data->root_geo.rotation; - bool whole = data->whole; - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, - sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, output->wlr_output->scale); - - int center_x = box.x + box.width/2; - int center_y = box.y + box.height/2; - - if (pixman_region32_not_empty(&surface->buffer_damage)) { - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->buffer_damage); - wlr_region_transform(&damage, &damage, transform, - surface->current.buffer_width, surface->current.buffer_height); - wlr_region_scale(&damage, &damage, - output->wlr_output->scale / (float)surface->current.scale); - if (ceil(output->wlr_output->scale) > surface->current.scale) { - // When scaling up a surface, it'll become blurry so we need to - // expand the damage region - wlr_region_expand(&damage, &damage, - ceil(output->wlr_output->scale) - surface->current.scale); - } - pixman_region32_translate(&damage, box.x, box.y); - wlr_region_rotated_bounds(&damage, &damage, rotation, - center_x, center_y); - wlr_output_damage_add(output->damage, &damage); - pixman_region32_fini(&damage); - } - - if (whole) { - wlr_box_rotated_bounds(&box, rotation, &box); - wlr_output_damage_add_box(output->damage, &box); - } - - wlr_output_schedule_frame(output->wlr_output); -} - -static void damage_surface_iterator2(struct sway_output *output, +static void damage_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { - struct damage_data *data = _data; - bool whole = data->whole; + bool *data = _data; + bool whole = *data; struct wlr_box box = *_box; scale_box(&box, output->wlr_output->scale); @@ -515,13 +430,8 @@ static void damage_surface_iterator2(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_surface_for_each_surface(surface, ox, oy, &data.root_geo, - damage_surface_iterator, &data); + output_surface_for_each_surface(output, surface, ox, oy, 0, + damage_surface_iterator, &whole); } static void output_damage_view(struct sway_output *output, @@ -534,12 +444,7 @@ static void output_damage_view(struct sway_output *output, return; } - struct damage_data data = { - .output = output, - .whole = whole, - }; - - output_view_for_each_surface(output, view, damage_surface_iterator2, &data); + output_view_for_each_surface(output, view, damage_surface_iterator, &whole); } void output_damage_from_view(struct sway_output *output, diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 18d076df..f25055b8 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -29,10 +29,7 @@ #include "sway/tree/workspace.h" struct render_data { - struct root_geometry root_geo; - struct sway_output *output; pixman_region32_t *damage; - struct sway_view *view; float alpha; }; @@ -92,38 +89,7 @@ damage_finish: pixman_region32_fini(&damage); } -static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *_data) { - struct render_data *data = _data; - struct wlr_output *wlr_output = data->output->wlr_output; - float rotation = data->root_geo.rotation; - pixman_region32_t *output_damage = data->damage; - float alpha = data->alpha; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (!texture) { - return; - } - - struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, - surface, sx, sy, &box); - if (!intersects) { - return; - } - - scale_box(&box, wlr_output->scale); - - float matrix[9]; - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, &box, transform, rotation, - wlr_output->transform_matrix); - - render_texture(wlr_output, output_damage, texture, &box, matrix, alpha); -} - -static void render_surface_iterator2(struct sway_output *output, +static void render_surface_iterator(struct sway_output *output, struct wlr_surface *surface, struct wlr_box *_box, float rotation, void *_data) { struct render_data *data = _data; @@ -151,36 +117,33 @@ static void render_surface_iterator2(struct sway_output *output, static void render_layer(struct sway_output *output, pixman_region32_t *damage, struct wl_list *layer_surfaces) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_layer_for_each_surface(output, layer_surfaces, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #ifdef HAVE_XWAYLAND static void render_unmanaged(struct sway_output *output, pixman_region32_t *damage, struct wl_list *unmanaged) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_unmanaged_for_each_surface(output, unmanaged, - render_surface_iterator2, &data); + render_surface_iterator, &data); } #endif static void render_drag_icons(struct sway_output *output, pixman_region32_t *damage, struct wl_list *drag_icons) { struct render_data data = { - .output = output, .damage = damage, .alpha = 1.0f, }; output_drag_icons_for_each_surface(output, drag_icons, - render_surface_iterator2, &data); + render_surface_iterator, &data); } static void render_rect(struct wlr_output *wlr_output, @@ -226,12 +189,10 @@ static void premultiply_alpha(float color[4], float opacity) { static void render_view_surfaces(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { - .output = output, .damage = damage, - .view = view, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator2, &data); + output_view_for_each_surface(output, view, render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view, -- cgit v1.2.3 From fe0750fec107f692be4f47659b446ed3d8d8f3b6 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 27 Jul 2018 19:19:30 +0100 Subject: Remove output_surface_for_each_surface from header --- include/sway/output.h | 4 ---- sway/desktop/output.c | 14 +++++++------- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 70f631a0..6283db68 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -67,10 +67,6 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); -void output_surface_for_each_surface2(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation, - sway_surface_iterator_func_t iterator, void *user_data); - void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e1d85b10..8272b35b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,8 +119,8 @@ void output_surface_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation, +static void output_surface_for_each_surface(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { .user_iterator = iterator, @@ -130,7 +130,7 @@ void output_surface_for_each_surface(struct sway_output *output, .oy = oy, .width = surface->current.width, .height = surface->current.height, - .rotation = rotation, + .rotation = 0, }; wlr_surface_for_each_surface(surface, @@ -163,7 +163,7 @@ void output_layer_for_each_surface(struct sway_output *output, struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; output_surface_for_each_surface(output, wlr_layer_surface->surface, - layer_surface->geo.x, layer_surface->geo.y, 0, iterator, + layer_surface->geo.x, layer_surface->geo.y, iterator, user_data); } } @@ -179,7 +179,7 @@ void output_unmanaged_for_each_surface(struct sway_output *output, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(output, xsurface->surface, ox, oy, 0, + output_surface_for_each_surface(output, xsurface->surface, ox, oy, iterator, user_data); } } @@ -195,7 +195,7 @@ void output_drag_icons_for_each_surface(struct sway_output *output, if (drag_icon->wlr_drag_icon->mapped) { output_surface_for_each_surface(output, - drag_icon->wlr_drag_icon->surface, ox, oy, 0, + drag_icon->wlr_drag_icon->surface, ox, oy, iterator, user_data); } } @@ -430,7 +430,7 @@ static void damage_surface_iterator(struct sway_output *output, void output_damage_surface(struct sway_output *output, double ox, double oy, struct wlr_surface *surface, bool whole) { - output_surface_for_each_surface(output, surface, ox, oy, 0, + output_surface_for_each_surface(output, surface, ox, oy, damage_surface_iterator, &whole); } -- cgit v1.2.3 From de86d65627e96cffe77f4abf11c4a0b982326ff9 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 31 Jul 2018 18:41:30 +1000 Subject: Fix popups Fixes the render and container_at order for popups. Fixes #2210 For rendering: * render_view_surfaces has been renamed to render_view_toplevels * render_view_toplevels now uses output_surface_for_each_surface (which is now public), as that function uses wlr_surface_for_each_surface which doesn't descend into popups * Views now have a for_each_popup iterator, which is used by the renderer to render the focused view's popups * When rendering a popup, toplevels (xdg subsurfaces) of that popup are also rendered For sending frame done, the logic has been updated to match the rendering logic: * send_frame_done_container no longer descends into popups * for_each_popup is used to send frame done to the focused view's popups and their child toplevels For container_at: * floating_container_at is now static, which means it had to be moved higher in the file. * container_at now considers popups for the focused view before checking containers. * tiling_container_at has been introduced, so that it doesn't call container_at recursively (it would check popups recursively if it did) --- include/sway/output.h | 8 +++ include/sway/tree/container.h | 11 +--- include/sway/tree/view.h | 11 ++++ sway/desktop/output.c | 52 +++++++++++++++- sway/desktop/render.c | 37 ++++++++++-- sway/desktop/xdg_shell.c | 9 +++ sway/desktop/xdg_shell_v6.c | 10 ++++ sway/input/cursor.c | 3 - sway/tree/container.c | 134 ++++++++++++++++++++++++++++++------------ sway/tree/view.c | 10 ++++ 10 files changed, 228 insertions(+), 57 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 6283db68..80dcd37b 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -67,10 +67,18 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); +void output_surface_for_each_surface(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, + sway_surface_iterator_func_t iterator, void *user_data); + void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data); +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data); + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index d4a42a71..12ff8a5a 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -230,17 +230,10 @@ struct sway_container *container_parent(struct sway_container *container, * surface-local coordinates of the given layout coordinates if the container * is a view and the view contains a surface at those coordinates. */ -struct sway_container *container_at(struct sway_container *container, - double ox, double oy, struct wlr_surface **surface, +struct sway_container *container_at(struct sway_container *workspace, + double lx, double ly, struct wlr_surface **surface, double *sx, double *sy); -/** - * Same as container_at, but only checks floating views and expects coordinates - * to be layout coordinates, as that's what floating views use. - */ -struct sway_container *floating_container_at(double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy); - /** * Apply the function for each descendant of the container breadth first. */ diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 0152ed55..9f6d36fe 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -47,6 +47,8 @@ struct sway_view_impl { bool (*has_client_side_decorations)(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); }; @@ -248,9 +250,18 @@ void view_close(struct sway_view *view); void view_damage_from(struct sway_view *view); +/** + * Iterate all surfaces of a view (toplevels + popups). + */ void view_for_each_surface(struct sway_view *view, wlr_surface_iterator_func_t iterator, void *user_data); +/** + * Iterate all popups recursively. + */ +void view_for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data); + // view implementation void view_init(struct sway_view *view, enum sway_view_type type, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31b53213..4c9d978c 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -static void output_surface_for_each_surface(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; + + view_for_each_popup(view, output_for_each_surface_iterator, &data); +} + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { @@ -295,8 +312,9 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(data->output, con->sway_view, - send_frame_done_iterator, data->when); + // Toplevels only + output_surface_for_each_surface(data->output, con->sway_view->surface, + con->x, con->y, send_frame_done_iterator, data->when); } static void send_frame_done_container(struct sway_output *output, @@ -309,6 +327,27 @@ static void send_frame_done_container(struct sway_output *output, send_frame_done_container_iterator, &data); } +static void send_frame_done_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Send frame done to this popup's surface + send_frame_done_iterator(output, surface, box, rotation, data); + + // Send frame done to this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + send_frame_done_iterator, data); +} + +static void send_frame_done_popups(struct sway_output *output, + struct sway_view *view, struct timespec *when) { + struct send_frame_done_data data = { + .output = output, + .when = when, + }; + output_view_for_each_popup(output, view, + send_frame_done_popup_iterator, &data); +} + static void send_frame_done(struct sway_output *output, struct timespec *when) { if (output_has_opaque_overlay_layer_surface(output)) { goto send_frame_overlay; @@ -346,6 +385,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + send_frame_done_popups(output, focus->sway_view, when); + } + + send_frame_overlay: send_frame_done_layer(output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f25055b8..ea4361f2 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_surfaces(struct sway_view *view, +static void render_view_toplevels(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator, &data); + // Render all toplevels without descending into popups + output_surface_for_each_surface(output, view->surface, + view->swayc->current.view_x, view->swayc->current.view_y, + render_surface_iterator, &data); +} + +static void render_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Render this popup's surface + render_surface_iterator(output, surface, box, rotation, data); + + // Render this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + render_surface_iterator, data); +} + +static void render_view_popups(struct sway_view *view, + struct sway_output *output, pixman_region32_t *damage, float alpha) { + struct render_data data = { + .damage = damage, + .alpha = alpha, + }; + output_view_for_each_popup(output, view, render_popup_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -241,7 +264,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->swayc->instructions->length) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_surfaces(view, output, damage, view->swayc->alpha); + render_view_toplevels(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -845,7 +868,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_surfaces(fullscreen_con->sway_view, + render_view_toplevels(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -881,6 +904,12 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + render_view_popups(focus->sway_view, output, damage, focus->alpha); + } + render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index e6e1527e..9f94bd74 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,6 +179,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; @@ -207,6 +215,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 5feee3e4..4502c386 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,6 +175,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; @@ -203,6 +212,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/input/cursor.c b/sway/input/cursor.c index 96ac7b33..ad4b1718 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -109,9 +109,6 @@ static struct sway_container *container_at_coords( } struct sway_container *c; - if ((c = floating_container_at(lx, ly, surface, sx, sy))) { - return c; - } if ((c = container_at(ws, lx, ly, surface, sx, sy))) { return c; } diff --git a/sway/tree/container.c b/sway/tree/container.c index 4e85021d..b5fefd17 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -561,10 +561,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc, *sx = _sx; *sy = _sy; *surface = _surface; + return swayc; } - return swayc; + return NULL; } +static struct sway_container *tiling_container_at( + struct sway_container *con, double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy); + /** * container_at for a container with layout L_TABBED. */ @@ -591,7 +596,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return container_at(current, lx, ly, surface, sx, sy); + return tiling_container_at(current, lx, ly, surface, sx, sy); } /** @@ -616,7 +621,7 @@ static struct sway_container *container_at_stacked( // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return container_at(current, lx, ly, surface, sx, sy); + return tiling_container_at(current, lx, ly, surface, sx, sy); } /** @@ -634,45 +639,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent, .height = child->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return container_at(child, lx, ly, surface, sx, sy); + return tiling_container_at(child, lx, ly, surface, sx, sy); } } return NULL; } -struct sway_container *container_at(struct sway_container *parent, - double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - if (!sway_assert(parent->type >= C_WORKSPACE, - "Expected workspace or deeper")) { - return NULL; - } - if (parent->type == C_VIEW) { - return container_at_view(parent, lx, ly, surface, sx, sy); - } - if (!parent->children->length) { - return NULL; - } - - switch (parent->layout) { - case L_HORIZ: - case L_VERT: - return container_at_linear(parent, lx, ly, surface, sx, sy); - case L_TABBED: - return container_at_tabbed(parent, lx, ly, surface, sx, sy); - case L_STACKED: - return container_at_stacked(parent, lx, ly, surface, sx, sy); - case L_FLOATING: - sway_assert(false, "Didn't expect to see floating here"); - return NULL; - case L_NONE: - return NULL; - } - - return NULL; -} - -struct sway_container *floating_container_at(double lx, double ly, +static struct sway_container *floating_container_at(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *output = root_container.children->items[i]; @@ -694,7 +667,8 @@ struct sway_container *floating_container_at(double lx, double ly, .height = floater->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return container_at(floater, lx, ly, surface, sx, sy); + return tiling_container_at(floater, lx, ly, + surface, sx, sy); } } } @@ -702,6 +676,90 @@ struct sway_container *floating_container_at(double lx, double ly, return NULL; } +static struct sway_container *tiling_container_at( + struct sway_container *con, double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy) { + if (con->type == C_VIEW) { + return container_at_view(con, lx, ly, surface, sx, sy); + } + if (!con->children->length) { + return NULL; + } + + switch (con->layout) { + case L_HORIZ: + case L_VERT: + return container_at_linear(con, lx, ly, surface, sx, sy); + case L_TABBED: + return container_at_tabbed(con, lx, ly, surface, sx, sy); + case L_STACKED: + return container_at_stacked(con, lx, ly, surface, sx, sy); + case L_FLOATING: + sway_assert(false, "Didn't expect to see floating here"); + return NULL; + case L_NONE: + return NULL; + } + return NULL; +} + +static bool surface_is_popup(struct wlr_surface *surface) { + if (wlr_surface_is_xdg_surface(surface)) { + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_from_wlr_surface(surface); + while (xdg_surface) { + if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { + return true; + } + xdg_surface = xdg_surface->toplevel->parent; + } + return false; + } + + if (wlr_surface_is_xdg_surface_v6(surface)) { + struct wlr_xdg_surface_v6 *xdg_surface_v6 = + wlr_xdg_surface_v6_from_wlr_surface(surface); + while (xdg_surface_v6) { + if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { + return true; + } + xdg_surface_v6 = xdg_surface_v6->toplevel->parent; + } + return false; + } + + return false; +} + +struct sway_container *container_at(struct sway_container *workspace, + double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy) { + if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { + return NULL; + } + struct sway_container *c; + // Focused view's popups + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = + seat_get_focus_inactive(seat, &root_container); + if (focus && focus->type == C_VIEW) { + container_at_view(focus, lx, ly, surface, sx, sy); + if (*surface && surface_is_popup(*surface)) { + return focus; + } + *surface = NULL; + } + // Floating + if ((c = floating_container_at(lx, ly, surface, sx, sy))) { + return c; + } + // Tiling + if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { + return c; + } + return NULL; +} + void container_for_each_descendant_dfs(struct sway_container *container, void (*f)(struct sway_container *container, void *data), void *data) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 8f54cc11..c1207821 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -332,6 +332,16 @@ void view_for_each_surface(struct sway_view *view, } } +void view_for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (!view->surface) { + return; + } + if (view->impl->for_each_popup) { + view->impl->for_each_popup(view, iterator, user_data); + } +} + static void view_subsurface_create(struct sway_view *view, struct wlr_subsurface *subsurface); -- cgit v1.2.3 From 9aa258d33a9baa42895214da7e82f4568fcb8f76 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 2 Aug 2018 09:05:46 -0400 Subject: Revert "Fix popups" This reverts commit de86d65627e96cffe77f4abf11c4a0b982326ff9. --- include/sway/output.h | 8 --- include/sway/tree/container.h | 11 +++- include/sway/tree/view.h | 11 ---- sway/desktop/output.c | 19 +----- sway/desktop/render.c | 37 ++---------- sway/desktop/xdg_shell.c | 9 --- sway/desktop/xdg_shell_v6.c | 10 ---- sway/input/cursor.c | 3 + sway/tree/container.c | 134 ++++++++++++------------------------------ sway/tree/view.c | 10 ---- 10 files changed, 55 insertions(+), 197 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 80dcd37b..6283db68 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -67,18 +67,10 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); -void output_surface_for_each_surface(struct sway_output *output, - struct wlr_surface *surface, double ox, double oy, - sway_surface_iterator_func_t iterator, void *user_data); - void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data); -void output_view_for_each_popup(struct sway_output *output, - struct sway_view *view, sway_surface_iterator_func_t iterator, - void *user_data); - void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 12ff8a5a..d4a42a71 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -230,10 +230,17 @@ struct sway_container *container_parent(struct sway_container *container, * surface-local coordinates of the given layout coordinates if the container * is a view and the view contains a surface at those coordinates. */ -struct sway_container *container_at(struct sway_container *workspace, - double lx, double ly, struct wlr_surface **surface, +struct sway_container *container_at(struct sway_container *container, + double ox, double oy, struct wlr_surface **surface, double *sx, double *sy); +/** + * Same as container_at, but only checks floating views and expects coordinates + * to be layout coordinates, as that's what floating views use. + */ +struct sway_container *floating_container_at(double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy); + /** * Apply the function for each descendant of the container breadth first. */ diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 37fd02bc..6d8c3e6c 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -47,8 +47,6 @@ struct sway_view_impl { bool (*has_client_side_decorations)(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 (*close_popups)(struct sway_view *view); void (*destroy)(struct sway_view *view); @@ -256,18 +254,9 @@ void view_close_popups(struct sway_view *view); void view_damage_from(struct sway_view *view); -/** - * Iterate all surfaces of a view (toplevels + popups). - */ void view_for_each_surface(struct sway_view *view, wlr_surface_iterator_func_t iterator, void *user_data); -/** - * Iterate all popups recursively. - */ -void view_for_each_popup(struct sway_view *view, - wlr_surface_iterator_func_t iterator, void *user_data); - // view implementation void view_init(struct sway_view *view, enum sway_view_type type, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 66747a3f..31b53213 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -void output_surface_for_each_surface(struct sway_output *output, +static void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,23 +155,6 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } -void output_view_for_each_popup(struct sway_output *output, - struct sway_view *view, sway_surface_iterator_func_t iterator, - void *user_data) { - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .output = output, - .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, - .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, - .width = view->swayc->current.view_width, - .height = view->swayc->current.view_height, - .rotation = 0, // TODO - }; - - view_for_each_popup(view, output_for_each_surface_iterator, &data); -} - void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 1f374740..f0e47c95 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,36 +186,13 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_toplevels(struct sway_view *view, +static void render_view_surfaces(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - // Render all toplevels without descending into popups - output_surface_for_each_surface(output, view->surface, - view->swayc->current.view_x, view->swayc->current.view_y, - render_surface_iterator, &data); -} - -static void render_popup_iterator(struct sway_output *output, - struct wlr_surface *surface, struct wlr_box *box, float rotation, - void *data) { - // Render this popup's surface - render_surface_iterator(output, surface, box, rotation, data); - - // Render this popup's child toplevels - output_surface_for_each_surface(output, surface, box->x, box->y, - render_surface_iterator, data); -} - -static void render_view_popups(struct sway_view *view, - struct sway_output *output, pixman_region32_t *damage, float alpha) { - struct render_data data = { - .damage = damage, - .alpha = alpha, - }; - output_view_for_each_popup(output, view, render_popup_iterator, &data); + output_view_for_each_surface(output, view, render_surface_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -262,7 +239,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->saved_buffer) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_toplevels(view, output, damage, view->swayc->alpha); + render_view_surfaces(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -866,7 +843,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_toplevels(fullscreen_con->sway_view, + render_view_surfaces(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -902,12 +879,6 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = seat_get_focus(seat); - if (focus && focus->type == C_VIEW) { - render_view_popups(focus->sway_view, output, damage, focus->alpha); - } - render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index b364663d..9d6b27e5 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,14 +179,6 @@ 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; @@ -227,7 +219,6 @@ 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, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index ffea03ad..6e4aae62 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,15 +175,6 @@ 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; @@ -224,7 +215,6 @@ 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, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 79f6ec46..d6fdc1da 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -109,6 +109,9 @@ static struct sway_container *container_at_coords( } struct sway_container *c; + if ((c = floating_container_at(lx, ly, surface, sx, sy))) { + return c; + } if ((c = container_at(ws, lx, ly, surface, sx, sy))) { return c; } diff --git a/sway/tree/container.c b/sway/tree/container.c index b980c5e9..b6ff4d30 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -569,15 +569,10 @@ static struct sway_container *container_at_view(struct sway_container *swayc, *sx = _sx; *sy = _sy; *surface = _surface; - return swayc; } - return NULL; + return swayc; } -static struct sway_container *tiling_container_at( - struct sway_container *con, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy); - /** * container_at for a container with layout L_TABBED. */ @@ -604,7 +599,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return tiling_container_at(current, lx, ly, surface, sx, sy); + return container_at(current, lx, ly, surface, sx, sy); } /** @@ -629,7 +624,7 @@ static struct sway_container *container_at_stacked( // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return tiling_container_at(current, lx, ly, surface, sx, sy); + return container_at(current, lx, ly, surface, sx, sy); } /** @@ -647,13 +642,45 @@ static struct sway_container *container_at_linear(struct sway_container *parent, .height = child->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return tiling_container_at(child, lx, ly, surface, sx, sy); + return container_at(child, lx, ly, surface, sx, sy); } } return NULL; } -static struct sway_container *floating_container_at(double lx, double ly, +struct sway_container *container_at(struct sway_container *parent, + double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy) { + if (!sway_assert(parent->type >= C_WORKSPACE, + "Expected workspace or deeper")) { + return NULL; + } + if (parent->type == C_VIEW) { + return container_at_view(parent, lx, ly, surface, sx, sy); + } + if (!parent->children->length) { + return NULL; + } + + switch (parent->layout) { + case L_HORIZ: + case L_VERT: + return container_at_linear(parent, lx, ly, surface, sx, sy); + case L_TABBED: + return container_at_tabbed(parent, lx, ly, surface, sx, sy); + case L_STACKED: + return container_at_stacked(parent, lx, ly, surface, sx, sy); + case L_FLOATING: + sway_assert(false, "Didn't expect to see floating here"); + return NULL; + case L_NONE: + return NULL; + } + + return NULL; +} + +struct sway_container *floating_container_at(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *output = root_container.children->items[i]; @@ -675,8 +702,7 @@ static struct sway_container *floating_container_at(double lx, double ly, .height = floater->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return tiling_container_at(floater, lx, ly, - surface, sx, sy); + return container_at(floater, lx, ly, surface, sx, sy); } } } @@ -684,90 +710,6 @@ static struct sway_container *floating_container_at(double lx, double ly, return NULL; } -static struct sway_container *tiling_container_at( - struct sway_container *con, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - if (con->type == C_VIEW) { - return container_at_view(con, lx, ly, surface, sx, sy); - } - if (!con->children->length) { - return NULL; - } - - switch (con->layout) { - case L_HORIZ: - case L_VERT: - return container_at_linear(con, lx, ly, surface, sx, sy); - case L_TABBED: - return container_at_tabbed(con, lx, ly, surface, sx, sy); - case L_STACKED: - return container_at_stacked(con, lx, ly, surface, sx, sy); - case L_FLOATING: - sway_assert(false, "Didn't expect to see floating here"); - return NULL; - case L_NONE: - return NULL; - } - return NULL; -} - -static bool surface_is_popup(struct wlr_surface *surface) { - if (wlr_surface_is_xdg_surface(surface)) { - struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_from_wlr_surface(surface); - while (xdg_surface) { - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - return true; - } - xdg_surface = xdg_surface->toplevel->parent; - } - return false; - } - - if (wlr_surface_is_xdg_surface_v6(surface)) { - struct wlr_xdg_surface_v6 *xdg_surface_v6 = - wlr_xdg_surface_v6_from_wlr_surface(surface); - while (xdg_surface_v6) { - if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { - return true; - } - xdg_surface_v6 = xdg_surface_v6->toplevel->parent; - } - return false; - } - - return false; -} - -struct sway_container *container_at(struct sway_container *workspace, - double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { - return NULL; - } - struct sway_container *c; - // Focused view's popups - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - seat_get_focus_inactive(seat, &root_container); - if (focus && focus->type == C_VIEW) { - container_at_view(focus, lx, ly, surface, sx, sy); - if (*surface && surface_is_popup(*surface)) { - return focus; - } - *surface = NULL; - } - // Floating - if ((c = floating_container_at(lx, ly, surface, sx, sy))) { - return c; - } - // Tiling - if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { - return c; - } - return NULL; -} - void container_for_each_descendant_dfs(struct sway_container *container, void (*f)(struct sway_container *container, void *data), void *data) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 97318daa..27a6a8bd 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -339,16 +339,6 @@ void view_for_each_surface(struct sway_view *view, } } -void view_for_each_popup(struct sway_view *view, - wlr_surface_iterator_func_t iterator, void *user_data) { - if (!view->surface) { - return; - } - if (view->impl->for_each_popup) { - view->impl->for_each_popup(view, iterator, user_data); - } -} - static void view_subsurface_create(struct sway_view *view, struct wlr_subsurface *subsurface); -- cgit v1.2.3 From 8392eae40f17e550338b8b7058d8e9c1a6ad4f78 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 2 Aug 2018 23:30:26 +1000 Subject: Revert "Revert "Fix popups"" This reverts commit 9aa258d33a9baa42895214da7e82f4568fcb8f76. Reverting the revert, so that popups can be fixed. --- include/sway/output.h | 8 +++ include/sway/tree/container.h | 11 +--- include/sway/tree/view.h | 11 ++++ sway/desktop/output.c | 19 +++++- sway/desktop/render.c | 37 ++++++++++-- sway/desktop/xdg_shell.c | 9 +++ sway/desktop/xdg_shell_v6.c | 10 ++++ sway/input/cursor.c | 3 - sway/tree/container.c | 134 ++++++++++++++++++++++++++++++------------ sway/tree/view.c | 10 ++++ 10 files changed, 197 insertions(+), 55 deletions(-) (limited to 'include/sway/output.h') diff --git a/include/sway/output.h b/include/sway/output.h index 6283db68..80dcd37b 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -67,10 +67,18 @@ struct sway_container *output_get_active_workspace(struct sway_output *output); void output_render(struct sway_output *output, struct timespec *when, pixman_region32_t *damage); +void output_surface_for_each_surface(struct sway_output *output, + struct wlr_surface *surface, double ox, double oy, + sway_surface_iterator_func_t iterator, void *user_data); + void output_view_for_each_surface(struct sway_output *output, struct sway_view *view, sway_surface_iterator_func_t iterator, void *user_data); +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data); + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data); diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index d4a42a71..12ff8a5a 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -230,17 +230,10 @@ struct sway_container *container_parent(struct sway_container *container, * surface-local coordinates of the given layout coordinates if the container * is a view and the view contains a surface at those coordinates. */ -struct sway_container *container_at(struct sway_container *container, - double ox, double oy, struct wlr_surface **surface, +struct sway_container *container_at(struct sway_container *workspace, + double lx, double ly, struct wlr_surface **surface, double *sx, double *sy); -/** - * Same as container_at, but only checks floating views and expects coordinates - * to be layout coordinates, as that's what floating views use. - */ -struct sway_container *floating_container_at(double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy); - /** * Apply the function for each descendant of the container breadth first. */ diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 6d8c3e6c..37fd02bc 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -47,6 +47,8 @@ struct sway_view_impl { bool (*has_client_side_decorations)(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 (*close_popups)(struct sway_view *view); void (*destroy)(struct sway_view *view); @@ -254,9 +256,18 @@ void view_close_popups(struct sway_view *view); void view_damage_from(struct sway_view *view); +/** + * Iterate all surfaces of a view (toplevels + popups). + */ void view_for_each_surface(struct sway_view *view, wlr_surface_iterator_func_t iterator, void *user_data); +/** + * Iterate all popups recursively. + */ +void view_for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data); + // view implementation void view_init(struct sway_view *view, enum sway_view_type type, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 31b53213..66747a3f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface, data->user_data); } -static void output_surface_for_each_surface(struct sway_output *output, +void output_surface_for_each_surface(struct sway_output *output, struct wlr_surface *surface, double ox, double oy, sway_surface_iterator_func_t iterator, void *user_data) { struct surface_iterator_data data = { @@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output, output_for_each_surface_iterator, &data); } +void output_view_for_each_popup(struct sway_output *output, + struct sway_view *view, sway_surface_iterator_func_t iterator, + void *user_data) { + struct surface_iterator_data data = { + .user_iterator = iterator, + .user_data = user_data, + .output = output, + .ox = view->swayc->current.view_x - output->swayc->current.swayc_x, + .oy = view->swayc->current.view_y - output->swayc->current.swayc_y, + .width = view->swayc->current.view_width, + .height = view->swayc->current.view_height, + .rotation = 0, // TODO + }; + + view_for_each_popup(view, output_for_each_surface_iterator, &data); +} + void output_layer_for_each_surface(struct sway_output *output, struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, void *user_data) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c index f0e47c95..1f374740 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) { color[2] *= color[3]; } -static void render_view_surfaces(struct sway_view *view, +static void render_view_toplevels(struct sway_view *view, struct sway_output *output, pixman_region32_t *damage, float alpha) { struct render_data data = { .damage = damage, .alpha = alpha, }; - output_view_for_each_surface(output, view, render_surface_iterator, &data); + // Render all toplevels without descending into popups + output_surface_for_each_surface(output, view->surface, + view->swayc->current.view_x, view->swayc->current.view_y, + render_surface_iterator, &data); +} + +static void render_popup_iterator(struct sway_output *output, + struct wlr_surface *surface, struct wlr_box *box, float rotation, + void *data) { + // Render this popup's surface + render_surface_iterator(output, surface, box, rotation, data); + + // Render this popup's child toplevels + output_surface_for_each_surface(output, surface, box->x, box->y, + render_surface_iterator, data); +} + +static void render_view_popups(struct sway_view *view, + struct sway_output *output, pixman_region32_t *damage, float alpha) { + struct render_data data = { + .damage = damage, + .alpha = alpha, + }; + output_view_for_each_popup(output, view, render_popup_iterator, &data); } static void render_saved_view(struct sway_view *view, @@ -239,7 +262,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, if (view->saved_buffer) { render_saved_view(view, output, damage, view->swayc->alpha); } else { - render_view_surfaces(view, output, damage, view->swayc->alpha); + render_view_toplevels(view, output, damage, view->swayc->alpha); } if (view->using_csd) { @@ -843,7 +866,7 @@ void output_render(struct sway_output *output, struct timespec *when, render_saved_view(fullscreen_con->sway_view, output, damage, 1.0f); } else { - render_view_surfaces(fullscreen_con->sway_view, + render_view_toplevels(fullscreen_con->sway_view, output, damage, 1.0f); } } else { @@ -879,6 +902,12 @@ void output_render(struct sway_output *output, struct timespec *when, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + if (focus && focus->type == C_VIEW) { + render_view_popups(focus->sway_view, output, damage, focus->alpha); + } + render_overlay: render_layer(output, damage, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 9d6b27e5..b364663d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -179,6 +179,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; @@ -219,6 +227,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, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 6e4aae62..ffea03ad 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -175,6 +175,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; @@ -215,6 +224,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, .close_popups = close_popups, .destroy = destroy, diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d6fdc1da..79f6ec46 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -109,9 +109,6 @@ static struct sway_container *container_at_coords( } struct sway_container *c; - if ((c = floating_container_at(lx, ly, surface, sx, sy))) { - return c; - } if ((c = container_at(ws, lx, ly, surface, sx, sy))) { return c; } diff --git a/sway/tree/container.c b/sway/tree/container.c index b6ff4d30..b980c5e9 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -569,10 +569,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc, *sx = _sx; *sy = _sy; *surface = _surface; + return swayc; } - return swayc; + return NULL; } +static struct sway_container *tiling_container_at( + struct sway_container *con, double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy); + /** * container_at for a container with layout L_TABBED. */ @@ -599,7 +604,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return container_at(current, lx, ly, surface, sx, sy); + return tiling_container_at(current, lx, ly, surface, sx, sy); } /** @@ -624,7 +629,7 @@ static struct sway_container *container_at_stacked( // Surfaces struct sway_container *current = seat_get_active_child(seat, parent); - return container_at(current, lx, ly, surface, sx, sy); + return tiling_container_at(current, lx, ly, surface, sx, sy); } /** @@ -642,45 +647,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent, .height = child->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return container_at(child, lx, ly, surface, sx, sy); + return tiling_container_at(child, lx, ly, surface, sx, sy); } } return NULL; } -struct sway_container *container_at(struct sway_container *parent, - double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - if (!sway_assert(parent->type >= C_WORKSPACE, - "Expected workspace or deeper")) { - return NULL; - } - if (parent->type == C_VIEW) { - return container_at_view(parent, lx, ly, surface, sx, sy); - } - if (!parent->children->length) { - return NULL; - } - - switch (parent->layout) { - case L_HORIZ: - case L_VERT: - return container_at_linear(parent, lx, ly, surface, sx, sy); - case L_TABBED: - return container_at_tabbed(parent, lx, ly, surface, sx, sy); - case L_STACKED: - return container_at_stacked(parent, lx, ly, surface, sx, sy); - case L_FLOATING: - sway_assert(false, "Didn't expect to see floating here"); - return NULL; - case L_NONE: - return NULL; - } - - return NULL; -} - -struct sway_container *floating_container_at(double lx, double ly, +static struct sway_container *floating_container_at(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *output = root_container.children->items[i]; @@ -702,7 +675,8 @@ struct sway_container *floating_container_at(double lx, double ly, .height = floater->height, }; if (wlr_box_contains_point(&box, lx, ly)) { - return container_at(floater, lx, ly, surface, sx, sy); + return tiling_container_at(floater, lx, ly, + surface, sx, sy); } } } @@ -710,6 +684,90 @@ struct sway_container *floating_container_at(double lx, double ly, return NULL; } +static struct sway_container *tiling_container_at( + struct sway_container *con, double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy) { + if (con->type == C_VIEW) { + return container_at_view(con, lx, ly, surface, sx, sy); + } + if (!con->children->length) { + return NULL; + } + + switch (con->layout) { + case L_HORIZ: + case L_VERT: + return container_at_linear(con, lx, ly, surface, sx, sy); + case L_TABBED: + return container_at_tabbed(con, lx, ly, surface, sx, sy); + case L_STACKED: + return container_at_stacked(con, lx, ly, surface, sx, sy); + case L_FLOATING: + sway_assert(false, "Didn't expect to see floating here"); + return NULL; + case L_NONE: + return NULL; + } + return NULL; +} + +static bool surface_is_popup(struct wlr_surface *surface) { + if (wlr_surface_is_xdg_surface(surface)) { + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_from_wlr_surface(surface); + while (xdg_surface) { + if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { + return true; + } + xdg_surface = xdg_surface->toplevel->parent; + } + return false; + } + + if (wlr_surface_is_xdg_surface_v6(surface)) { + struct wlr_xdg_surface_v6 *xdg_surface_v6 = + wlr_xdg_surface_v6_from_wlr_surface(surface); + while (xdg_surface_v6) { + if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { + return true; + } + xdg_surface_v6 = xdg_surface_v6->toplevel->parent; + } + return false; + } + + return false; +} + +struct sway_container *container_at(struct sway_container *workspace, + double lx, double ly, + struct wlr_surface **surface, double *sx, double *sy) { + if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { + return NULL; + } + struct sway_container *c; + // Focused view's popups + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = + seat_get_focus_inactive(seat, &root_container); + if (focus && focus->type == C_VIEW) { + container_at_view(focus, lx, ly, surface, sx, sy); + if (*surface && surface_is_popup(*surface)) { + return focus; + } + *surface = NULL; + } + // Floating + if ((c = floating_container_at(lx, ly, surface, sx, sy))) { + return c; + } + // Tiling + if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { + return c; + } + return NULL; +} + void container_for_each_descendant_dfs(struct sway_container *container, void (*f)(struct sway_container *container, void *data), void *data) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 27a6a8bd..97318daa 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -339,6 +339,16 @@ void view_for_each_surface(struct sway_view *view, } } +void view_for_each_popup(struct sway_view *view, + wlr_surface_iterator_func_t iterator, void *user_data) { + if (!view->surface) { + return; + } + if (view->impl->for_each_popup) { + view->impl->for_each_popup(view, iterator, user_data); + } +} + static void view_subsurface_create(struct sway_view *view, struct wlr_subsurface *subsurface); -- cgit v1.2.3