Restructure subsurface handling
Subsurfaces have been handled somewhat incorrectly. With the release of Firefox 87 this happens to trigger a couple of rendering bugs. Damage is not tracked properly for those subsurfaces.
This commit is contained in:
parent
5153eac0d3
commit
0e0ccfbffc
|
@ -16,7 +16,6 @@ struct hikari_renderer {
|
|||
struct wlr_renderer *wlr_renderer;
|
||||
pixman_region32_t *damage;
|
||||
struct wlr_box *geometry;
|
||||
struct timespec *when;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -57,6 +57,7 @@ struct hikari_view {
|
|||
struct wl_list group_views;
|
||||
struct wl_list visible_group_views;
|
||||
struct wl_list visible_server_views;
|
||||
struct wl_list children;
|
||||
|
||||
struct hikari_operation pending_operation;
|
||||
|
||||
|
@ -73,9 +74,13 @@ struct hikari_view {
|
|||
void (*activate)(struct hikari_view *, bool);
|
||||
void (*quit)(struct hikari_view *);
|
||||
void (*constraints)(struct hikari_view *, int *, int *, int *, int *);
|
||||
|
||||
struct wl_listener new_subsurface;
|
||||
};
|
||||
|
||||
struct hikari_view_child {
|
||||
struct wl_list link;
|
||||
|
||||
struct wlr_surface *surface;
|
||||
struct hikari_view *parent;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ struct hikari_xdg_view {
|
|||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener new_popup;
|
||||
struct wl_listener new_subsurface;
|
||||
struct wl_listener set_title;
|
||||
struct wl_listener request_fullscreen;
|
||||
};
|
||||
|
|
|
@ -484,18 +484,15 @@ render_overlay(struct hikari_renderer *renderer)
|
|||
#endif
|
||||
|
||||
static inline void
|
||||
render_output(struct hikari_output *output,
|
||||
pixman_region32_t *damage,
|
||||
struct timespec *now)
|
||||
render_output(struct hikari_output *output, pixman_region32_t *damage)
|
||||
{
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct wlr_renderer *wlr_renderer =
|
||||
wlr_backend_get_renderer(wlr_output->backend);
|
||||
|
||||
struct hikari_renderer renderer = { .wlr_output = wlr_output,
|
||||
.wlr_renderer = wlr_renderer,
|
||||
.when = now,
|
||||
.damage = damage };
|
||||
struct hikari_renderer renderer = {
|
||||
.wlr_output = wlr_output, .wlr_renderer = wlr_renderer, .damage = damage
|
||||
};
|
||||
|
||||
wlr_renderer_begin(wlr_renderer, wlr_output->width, wlr_output->height);
|
||||
|
||||
|
@ -531,12 +528,15 @@ send_frame_done(struct wlr_surface *surface, int sx, int sy, void *data)
|
|||
}
|
||||
|
||||
static inline void
|
||||
frame_done(struct hikari_output *output, struct timespec *now)
|
||||
frame_done(struct hikari_output *output)
|
||||
{
|
||||
struct hikari_view *view;
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
wl_list_for_each_reverse (view, &output->views, output_views) {
|
||||
hikari_node_for_each_surface(
|
||||
(struct hikari_node *)view, send_frame_done, now);
|
||||
(struct hikari_node *)view, send_frame_done, &now);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XWAYLAND
|
||||
|
@ -545,13 +545,13 @@ frame_done(struct hikari_output *output, struct timespec *now)
|
|||
&output->unmanaged_xwayland_views,
|
||||
unmanaged_output_views) {
|
||||
wlr_surface_for_each_surface(
|
||||
xwayland_unmanaged_view->surface->surface, send_frame_done, now);
|
||||
xwayland_unmanaged_view->surface->surface, send_frame_done, &now);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LAYERSHELL
|
||||
for (int i = 0; i < 4; i++) {
|
||||
layer_for_each(&output->layers[i], send_frame_done, now);
|
||||
layer_for_each(&output->layers[i], send_frame_done, &now);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -559,25 +559,29 @@ frame_done(struct hikari_output *output, struct timespec *now)
|
|||
void
|
||||
hikari_renderer_damage_frame_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
bool needs_frame;
|
||||
struct timespec now;
|
||||
struct hikari_output *output =
|
||||
wl_container_of(listener, output, damage_frame);
|
||||
|
||||
pixman_region32_t buffer_damage;
|
||||
pixman_region32_init(&buffer_damage);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
if (wlr_output_damage_attach_render(
|
||||
output->damage, &needs_frame, &buffer_damage) &&
|
||||
needs_frame) {
|
||||
render_output(output, &buffer_damage, &now);
|
||||
bool needs_frame;
|
||||
if (!wlr_output_damage_attach_render(
|
||||
output->damage, &needs_frame, &buffer_damage)) {
|
||||
goto render_done;
|
||||
}
|
||||
|
||||
if (!needs_frame) {
|
||||
wlr_output_rollback(output->wlr_output);
|
||||
goto render_done;
|
||||
}
|
||||
|
||||
render_output(output, &buffer_damage);
|
||||
|
||||
render_done:
|
||||
pixman_region32_fini(&buffer_damage);
|
||||
|
||||
frame_done(output, &now);
|
||||
frame_done(output);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
86
src/view.c
86
src/view.c
|
@ -431,6 +431,8 @@ hikari_view_init(
|
|||
|
||||
hikari_view_unset_dirty(view);
|
||||
view->pending_operation.tile = NULL;
|
||||
|
||||
wl_list_init(&view->children);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -773,6 +775,19 @@ MOVE(top_middle)
|
|||
MOVE(top_right)
|
||||
#undef MOVE
|
||||
|
||||
static void
|
||||
new_subsurface_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_view *view = wl_container_of(listener, view, new_subsurface);
|
||||
|
||||
struct wlr_subsurface *wlr_subsurface = data;
|
||||
|
||||
struct hikari_view_subsurface *view_subsurface =
|
||||
hikari_malloc(sizeof(struct hikari_view_subsurface));
|
||||
|
||||
hikari_view_subsurface_init(view_subsurface, view, wlr_subsurface);
|
||||
}
|
||||
|
||||
void
|
||||
hikari_view_map(struct hikari_view *view, struct wlr_surface *surface)
|
||||
{
|
||||
|
@ -788,6 +803,19 @@ hikari_view_map(struct hikari_view *view, struct wlr_surface *surface)
|
|||
struct hikari_view_config *view_config =
|
||||
hikari_configuration_resolve_view_config(hikari_configuration, view->id);
|
||||
|
||||
view->surface = surface;
|
||||
|
||||
view->new_subsurface.notify = new_subsurface_handler;
|
||||
wl_signal_add(&surface->events.new_subsurface, &view->new_subsurface);
|
||||
|
||||
struct wlr_subsurface *wlr_subsurface;
|
||||
wl_list_for_each (wlr_subsurface, &surface->subsurfaces, parent_link) {
|
||||
struct hikari_view_subsurface *subsurface =
|
||||
(struct hikari_view_subsurface *)malloc(
|
||||
sizeof(struct hikari_view_subsurface));
|
||||
hikari_view_subsurface_init(subsurface, view, wlr_subsurface);
|
||||
}
|
||||
|
||||
if (view_config != NULL) {
|
||||
struct hikari_mark *mark;
|
||||
struct hikari_view_properties *properties =
|
||||
|
@ -809,7 +837,6 @@ hikari_view_map(struct hikari_view *view, struct wlr_surface *surface)
|
|||
}
|
||||
|
||||
view->group = group;
|
||||
view->surface = surface;
|
||||
|
||||
wl_list_insert(&sheet->views, &view->sheet_views);
|
||||
wl_list_insert(&group->views, &view->group_views);
|
||||
|
@ -836,6 +863,16 @@ hikari_view_unmap(struct hikari_view *view)
|
|||
assert(!hikari_view_is_unmanaged(view));
|
||||
assert(hikari_view_is_mapped(view));
|
||||
|
||||
wl_list_remove(&view->new_subsurface.link);
|
||||
|
||||
struct hikari_view_child *child, *child_temp;
|
||||
wl_list_for_each_safe (child, child_temp, &view->children, link) {
|
||||
struct hikari_view_subsurface *subsurface =
|
||||
(struct hikari_view_subsurface *)child;
|
||||
hikari_view_subsurface_fini(subsurface);
|
||||
hikari_free(subsurface);
|
||||
}
|
||||
|
||||
if (hikari_view_is_forced(view)) {
|
||||
if (hikari_view_is_hidden(view)) {
|
||||
hide(view);
|
||||
|
@ -1561,6 +1598,7 @@ hikari_view_subsurface_init(struct hikari_view_subsurface *view_subsurface,
|
|||
void
|
||||
hikari_view_child_fini(struct hikari_view_child *view_child)
|
||||
{
|
||||
wl_list_remove(&view_child->link);
|
||||
wl_list_remove(&view_child->commit.link);
|
||||
wl_list_remove(&view_child->new_subsurface.link);
|
||||
}
|
||||
|
@ -1572,25 +1610,11 @@ hikari_view_subsurface_fini(struct hikari_view_subsurface *view_subsurface)
|
|||
wl_list_remove(&view_subsurface->destroy.link);
|
||||
}
|
||||
|
||||
static void
|
||||
new_subsurface_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_view_child *view_child =
|
||||
wl_container_of(listener, view_child, new_subsurface);
|
||||
|
||||
struct wlr_subsurface *wlr_subsurface = data;
|
||||
|
||||
struct hikari_view_subsurface *view_subsurface =
|
||||
hikari_malloc(sizeof(struct hikari_view_subsurface));
|
||||
|
||||
hikari_view_subsurface_init(
|
||||
view_subsurface, view_child->parent, wlr_subsurface);
|
||||
}
|
||||
|
||||
static void
|
||||
damage_surface(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||
{
|
||||
struct hikari_damage_data *damage_data = data;
|
||||
struct hikari_output *output = damage_data->output;
|
||||
|
||||
if (damage_data->whole) {
|
||||
damage_whole_surface(surface, sx, sy, data);
|
||||
|
@ -1618,18 +1642,32 @@ damage_single_surface(struct wlr_surface *surface, int sx, int sy, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
commit_view_child_handler(struct wl_listener *listener, void *data)
|
||||
commit_child_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_view_child *view_child =
|
||||
wl_container_of(listener, view_child, commit);
|
||||
|
||||
struct hikari_view *parent = view_child->parent;
|
||||
assert(!hikari_view_is_hidden(parent));
|
||||
|
||||
if (!hikari_view_is_hidden(parent)) {
|
||||
struct wlr_surface *surface = view_child->surface;
|
||||
struct wlr_surface *surface = view_child->surface;
|
||||
|
||||
hikari_view_damage_surface(parent, surface, false);
|
||||
}
|
||||
hikari_view_damage_surface(parent, surface, false);
|
||||
}
|
||||
|
||||
static void
|
||||
new_subsurface_child_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_view_child *view_child =
|
||||
wl_container_of(listener, view_child, new_subsurface);
|
||||
|
||||
struct wlr_subsurface *wlr_subsurface = data;
|
||||
|
||||
struct hikari_view_subsurface *view_subsurface =
|
||||
hikari_malloc(sizeof(struct hikari_view_subsurface));
|
||||
|
||||
hikari_view_subsurface_init(
|
||||
view_subsurface, view_child->parent, wlr_subsurface);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1640,11 +1678,13 @@ hikari_view_child_init(struct hikari_view_child *view_child,
|
|||
view_child->parent = parent;
|
||||
view_child->surface = surface;
|
||||
|
||||
view_child->new_subsurface.notify = new_subsurface_handler;
|
||||
view_child->new_subsurface.notify = new_subsurface_child_handler;
|
||||
wl_signal_add(&surface->events.new_subsurface, &view_child->new_subsurface);
|
||||
|
||||
view_child->commit.notify = commit_view_child_handler;
|
||||
view_child->commit.notify = commit_child_handler;
|
||||
wl_signal_add(&surface->events.commit, &view_child->commit);
|
||||
|
||||
wl_list_insert(&parent->children, &view_child->link);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
static void
|
||||
new_popup_handler(struct wl_listener *listener, void *data);
|
||||
|
||||
static void
|
||||
new_subsurface_handler(struct wl_listener *listener, void *data);
|
||||
|
||||
static void
|
||||
request_fullscreen_handler(struct wl_listener *listener, void *data);
|
||||
|
||||
|
@ -186,10 +183,6 @@ map(struct hikari_view *view, bool focus)
|
|||
xdg_view->new_popup.notify = new_popup_handler;
|
||||
wl_signal_add(&xdg_surface->events.new_popup, &xdg_view->new_popup);
|
||||
|
||||
xdg_view->new_subsurface.notify = new_subsurface_handler;
|
||||
wl_signal_add(
|
||||
&xdg_surface->surface->events.new_subsurface, &xdg_view->new_subsurface);
|
||||
|
||||
xdg_view->commit.notify = commit_handler;
|
||||
wl_signal_add(&xdg_view->surface->surface->events.commit, &xdg_view->commit);
|
||||
|
||||
|
@ -227,7 +220,6 @@ unmap(struct hikari_view *view)
|
|||
wl_list_remove(&xdg_view->set_title.link);
|
||||
wl_list_remove(&xdg_view->request_fullscreen.link);
|
||||
wl_list_remove(&xdg_view->new_popup.link);
|
||||
wl_list_remove(&xdg_view->new_subsurface.link);
|
||||
wl_list_remove(&xdg_view->commit.link);
|
||||
}
|
||||
|
||||
|
@ -435,24 +427,6 @@ xdg_popup_create(struct wlr_xdg_popup *wlr_popup, struct hikari_view *parent)
|
|||
popup_unconstrain(popup);
|
||||
}
|
||||
|
||||
static void
|
||||
new_subsurface_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct hikari_xdg_view *xdg_view =
|
||||
wl_container_of(listener, xdg_view, new_subsurface);
|
||||
|
||||
struct wlr_subsurface *subsurface = data;
|
||||
|
||||
struct hikari_view_subsurface *view_subsurface =
|
||||
hikari_malloc(sizeof(struct hikari_view_subsurface));
|
||||
|
||||
hikari_view_subsurface_init(view_subsurface, &xdg_view->view, subsurface);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
printf("SUBSURFACE\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
request_fullscreen_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue