From: Johan Malm Date: Tue, 29 Sep 2020 19:48:50 +0000 (+0100) Subject: view_impl: add for_each_surface() X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=16c3869fca29246f65f35c239888d11bd6900424;p=proto%2Flabwc.git view_impl: add for_each_surface() --- diff --git a/include/labwc.h b/include/labwc.h index dedae5c4..b29d330f 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -110,6 +110,8 @@ enum deco_part { struct view_impl { void (*configure)(struct view *view, struct wlr_box geo); void (*close)(struct view *view); + void (*for_each_surface)(struct view *view, + wlr_surface_iterator_func_t iterator, void *data); void (*map)(struct view *view); void (*unmap)(struct view *view); }; @@ -200,6 +202,8 @@ struct wlr_box view_geometry(struct view *view); void view_resize(struct view *view, struct wlr_box geo); void view_minimize(struct view *view); void view_unminimize(struct view *view); +void view_for_each_surface(struct view *view, + wlr_surface_iterator_func_t iterator, void *user_data); void desktop_focus_view(struct view *view); diff --git a/src/output.c b/src/output.c index 7058b01c..02e8bfa1 100644 --- a/src/output.c +++ b/src/output.c @@ -182,20 +182,22 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data) struct render_data *rdata = data; struct wlr_texture *texture = wlr_surface_get_texture(surface); - if (!texture) + if (!texture) { return; + } - /* The view has a position in layout coordinates. If you have two + /* + * The view has a position in layout coordinates. If you have two * displays, one next to the other, both 1080p, a view on the rightmost * display might have layout coordinates of 2000,100. We need to - * translate that to output-local coordinates, or (2000 - 1920). */ + * translate that to output-local coordinates, or (2000 - 1920). + */ double ox = 0, oy = 0; - wlr_output_layout_output_coords(rdata->output_layout, rdata->output, - &ox, &oy); + wlr_output_layout_output_coords( + rdata->output_layout, rdata->output, &ox, &oy); ox += rdata->lx + sx; oy += rdata->ly + sy; - /* TODO: Support HiDPI */ struct wlr_box box = { .x = ox * rdata->output->scale, .y = oy * rdata->output->scale, @@ -203,32 +205,13 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data) .height = surface->current.height * rdata->output->scale, }; - /* - * Those familiar with OpenGL are also familiar with the role of - * matricies in graphics programming. We need to prepare a matrix to - * render the view with. wlr_matrix_project_box is a helper which takes - * a box with a desired x, y coordinates, width and height, and an - * output geometry, then prepares an orthographic projection and - * multiplies the necessary transforms to produce a - * model-view-projection matrix. - * - * Naturally you can do this any way you like, for example to make a 3D - * compositor. - */ float matrix[9]; enum wl_output_transform transform = wlr_output_transform_invert(surface->current.transform); wlr_matrix_project_box(matrix, &box, transform, 0, - rdata->output->transform_matrix); + rdata->output->transform_matrix); - /* - * This takes our matrix, the texture, and an alpha, and performs the - * actual rendering on the GPU. - */ wlr_render_texture_with_matrix(rdata->renderer, texture, matrix, 1); - - /* This lets the client know that we've displayed that frame and it can - * prepare another one now if it likes. */ wlr_surface_send_frame_done(surface, rdata->when); } @@ -265,6 +248,8 @@ output_frame_notify(struct wl_listener *listener, void *data) if (!view->mapped) continue; + render_decorations(output->wlr_output, view); + struct render_data rdata = { .output = output->wlr_output, .output_layout = output->server->output_layout, @@ -274,16 +259,7 @@ output_frame_notify(struct wl_listener *listener, void *data) .when = &now, }; - render_decorations(output->wlr_output, view); - - if (view->type == LAB_XDG_SHELL_VIEW) { - /* render each xdg toplevel and popup surface */ - wlr_xdg_surface_for_each_surface( - view->xdg_surface, render_surface, &rdata); - } else if (view->type == LAB_XWAYLAND_VIEW) { - render_surface(view->xwayland_surface->surface, 0, 0, - &rdata); - } + view_for_each_surface(view, render_surface, &rdata); } /* If in cycle (alt-tab) mode, highlight selected view */ diff --git a/src/view.c b/src/view.c index c662d267..a21e2407 100644 --- a/src/view.c +++ b/src/view.c @@ -31,3 +31,11 @@ view_unminimize(struct view *view) view->minimized = false; view->impl->map(view); } + +void +view_for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator, + void *user_data) +{ + view->impl->for_each_surface(view, iterator, user_data); +} + diff --git a/src/xdg.c b/src/xdg.c index 744fbb3a..5bf1956e 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -144,6 +144,13 @@ xdg_toplevel_view_close(struct view *view) wlr_xdg_toplevel_send_close(view->xdg_surface); } +static void +xdg_toplevel_view_for_each_surface(struct view *view, + wlr_surface_iterator_func_t iterator, void *data) +{ + wlr_xdg_surface_for_each_surface(view->xdg_surface, iterator, data); +} + static struct border xdg_shell_border(struct view *view) { @@ -203,6 +210,7 @@ xdg_toplevel_view_unmap(struct view *view) static const struct view_impl xdg_toplevel_view_impl = { .configure = xdg_toplevel_view_configure, .close = xdg_toplevel_view_close, + .for_each_surface = xdg_toplevel_view_for_each_surface, .map = xdg_toplevel_view_map, .unmap = xdg_toplevel_view_unmap, }; diff --git a/src/xwayland.c b/src/xwayland.c index c303dc85..413a5815 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -62,6 +62,13 @@ _close(struct view *view) wlr_xwayland_surface_close(view->xwayland_surface); } +static void +for_each_surface(struct view *view, wlr_surface_iterator_func_t iterator, + void *data) +{ + wlr_surface_for_each_surface(view->surface, iterator, data); +} + static bool want_deco(struct view *view) { @@ -119,6 +126,7 @@ unmap(struct view *view) static const struct view_impl xwl_view_impl = { .configure = configure, .close = _close, + .for_each_surface = for_each_surface, .map = map, .unmap = unmap, };