Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show wayland client's popup/subsurface #108

Merged
merged 7 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/zen/scene/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ struct zn_view;

struct zn_view_impl {
struct wlr_surface *(*get_wlr_surface)(struct zn_view *view);
void (*for_each_popup_surface)(struct zn_view *view,
wlr_surface_iterator_func_t iterator, void *user_data);
};

enum zn_view_type {
Expand Down
84 changes: 77 additions & 7 deletions zen/render-2d.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,93 @@
#include "zen/render-2d.h"

#include <string.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_surface.h>

#include "zen-common.h"
#include "zen/output.h"
#include "zen/scene/screen.h"
#include "zen/scene/view.h"
#include "zen/seat.h"

typedef void (*zn_surface_iterator_func_t)(struct wlr_surface *surface,
struct wlr_renderer *renderer, const struct wlr_fbox *box);

struct zn_surface_iterator_data {
zn_surface_iterator_func_t iterator;

struct zn_view *view;
struct wlr_renderer *renderer;
};
shierote marked this conversation as resolved.
Show resolved Hide resolved

static void
zn_render_2d_view(struct zn_view *view, struct wlr_renderer *renderer)
zn_render_get_surface_fbox(struct wlr_surface *surface, struct zn_view *view,
int surface_x, int surface_y, struct wlr_fbox *surface_box)
shierote marked this conversation as resolved.
Show resolved Hide resolved
{
struct wlr_surface *wlr_surface = view->impl->get_wlr_surface(view);
struct wlr_texture *texture = wlr_surface_get_texture(wlr_surface);
struct wlr_fbox fbox;
struct wlr_fbox box = {
.x = view->x + surface_x,
.y = view->y + surface_y,
.width = surface->current.width,
.height = surface->current.height,
};

memcpy(surface_box, &box, sizeof(box));
shierote marked this conversation as resolved.
Show resolved Hide resolved
}

static void
zn_render_wlr_surface_iterator(
struct wlr_surface *surface, int surface_x, int surface_y, void *user_data)
shierote marked this conversation as resolved.
Show resolved Hide resolved
{
struct zn_surface_iterator_data *data = user_data;
struct wlr_fbox surface_box;

zn_render_get_surface_fbox(
surface, data->view, surface_x, surface_y, &surface_box);

data->iterator(surface, data->renderer, &surface_box);
}

static void
zn_render_surface_iterator(struct wlr_surface *surface,
shierote marked this conversation as resolved.
Show resolved Hide resolved
struct wlr_renderer *renderer, const struct wlr_fbox *box)
shierote marked this conversation as resolved.
Show resolved Hide resolved
{
struct wlr_texture *texture = wlr_surface_get_texture(surface);
float transform[9] = {
1, 0, 0, //
0, 1, 0, //
0, 0, 1 //
};

zn_view_get_fbox(view, &fbox);
wlr_render_texture(renderer, texture, transform, fbox.x, fbox.y, 1);
wlr_render_texture(renderer, texture, transform, box->x, box->y, 1.f);
}

static void
zn_render_2d_view_popups(struct zn_view *view, struct wlr_renderer *renderer)
{
struct zn_surface_iterator_data data = {
.iterator = zn_render_surface_iterator,
.view = view,
.renderer = renderer,
};

if (view->impl->for_each_popup_surface) {
view->impl->for_each_popup_surface(
view, zn_render_wlr_surface_iterator, &data);
}
}

static void
zn_render_2d_view(struct zn_view *view, struct wlr_renderer *renderer)
{
struct wlr_surface *wlr_surface = view->impl->get_wlr_surface(view);
struct zn_surface_iterator_data data = {
.iterator = zn_render_surface_iterator,
.view = view,
.renderer = renderer,
};

wlr_surface_for_each_surface(
wlr_surface, zn_render_wlr_surface_iterator, &data);
shierote marked this conversation as resolved.
Show resolved Hide resolved
}

static void
Expand All @@ -49,7 +114,12 @@ zn_render_2d_screen(struct zn_screen *screen, struct wlr_renderer *renderer)
struct zn_cursor *cursor = server->input_manager->seat->cursor;

wl_list_for_each(view, &screen->views, link)
zn_render_2d_view(view, renderer);
{
zn_render_2d_view(view, renderer);

// TODO: render popups only focused view
zn_render_2d_view_popups(view, renderer);
shierote marked this conversation as resolved.
Show resolved Hide resolved
}

zn_render_2d_cursor(cursor, screen, renderer);
}
17 changes: 17 additions & 0 deletions zen/xdg-toplevel-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,25 @@ zn_xdg_toplevel_view_impl_get_wlr_surface(struct zn_view* view)
return self->wlr_xdg_toplevel->base->surface;
}

static void
zn_xdg_toplevel_view_impl_for_each_popup_surface(
struct zn_view* view, wlr_surface_iterator_func_t iterator, void* user_data)
{
struct zn_xdg_toplevel_view* self;

if (!zn_assert(
view->type == ZN_VIEW_XDG_TOPLEVEL, "Expected xdg toplevel view"))
return;

self = zn_container_of(view, self, base);

wlr_xdg_surface_for_each_popup_surface(
self->wlr_xdg_toplevel->base, iterator, user_data);
}

static const struct zn_view_impl zn_xdg_toplevel_view_impl = {
.get_wlr_surface = zn_xdg_toplevel_view_impl_get_wlr_surface,
.for_each_popup_surface = zn_xdg_toplevel_view_impl_for_each_popup_surface,
};

struct zn_xdg_toplevel_view*
Expand Down