mirror of
https://github.com/cage-kiosk/cage.git
synced 2025-10-29 05:40:19 -04:00
Render popups separately from their toplevel view when possible
This commit is contained in:
parent
2db815aa23
commit
a53dca91ce
7 changed files with 101 additions and 33 deletions
74
output.c
74
output.c
|
|
@ -100,7 +100,7 @@ output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, vo
|
|||
data->user_iterator(data->output, surface, &box, data->user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
output_surface_for_each_surface(struct cg_output *output, struct wlr_surface *surface,
|
||||
double ox, double oy, cg_surface_iterator_func_t iterator,
|
||||
void *user_data)
|
||||
|
|
@ -116,7 +116,7 @@ output_surface_for_each_surface(struct cg_output *output, struct wlr_surface *su
|
|||
wlr_surface_for_each_surface(surface, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
output_view_for_each_surface(struct cg_output *output, struct cg_view *view,
|
||||
cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
|
|
@ -132,6 +132,49 @@ output_view_for_each_surface(struct cg_output *output, struct cg_view *view,
|
|||
view_for_each_surface(view, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
output_view_for_each_popup(struct cg_output *output, struct cg_view *view,
|
||||
cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct surface_iterator_data data = {
|
||||
.user_iterator = iterator,
|
||||
.user_data = user_data,
|
||||
.output = output,
|
||||
.ox = view->lx,
|
||||
.oy = view->ly,
|
||||
};
|
||||
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &data.ox, &data.oy);
|
||||
view_for_each_popup(view, output_for_each_surface_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
output_drag_icons_for_each_surface(struct cg_output *output, struct wl_list *drag_icons,
|
||||
cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_drag_icon *drag_icon;
|
||||
wl_list_for_each(drag_icon, drag_icons, link) {
|
||||
if (drag_icon->wlr_drag_icon->mapped) {
|
||||
double ox = drag_icon->lx;
|
||||
double oy = drag_icon->ly;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &ox, &oy);
|
||||
output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface,
|
||||
ox, oy, iterator, user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_for_each_surface(struct cg_output *output, cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_view *view;
|
||||
wl_list_for_each_reverse(view, &output->server->views, link) {
|
||||
output_view_for_each_surface(output, view, iterator, user_data);
|
||||
}
|
||||
|
||||
output_drag_icons_for_each_surface(output, &output->server->seat->drag_icons, iterator, user_data);
|
||||
}
|
||||
|
||||
struct send_frame_done_data {
|
||||
struct timespec when;
|
||||
};
|
||||
|
|
@ -187,33 +230,6 @@ output_damage_surface(struct cg_output *output, struct wlr_surface *surface,
|
|||
output_surface_for_each_surface(output, surface, ox, oy, damage_surface_iterator, &whole);
|
||||
}
|
||||
|
||||
void
|
||||
output_drag_icons_for_each_surface(struct cg_output *output, struct wl_list *drag_icons,
|
||||
cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_drag_icon *drag_icon;
|
||||
wl_list_for_each(drag_icon, drag_icons, link) {
|
||||
if (drag_icon->wlr_drag_icon->mapped) {
|
||||
double ox = drag_icon->lx;
|
||||
double oy = drag_icon->ly;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &ox, &oy);
|
||||
output_surface_for_each_surface(output, drag_icon->wlr_drag_icon->surface,
|
||||
ox, oy, iterator, user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
output_for_each_surface(struct cg_output *output, cg_surface_iterator_func_t iterator, void *user_data)
|
||||
{
|
||||
struct cg_view *view;
|
||||
wl_list_for_each_reverse(view, &output->server->views, link) {
|
||||
output_view_for_each_surface(output, view, iterator, user_data);
|
||||
}
|
||||
|
||||
output_drag_icons_for_each_surface(output, &output->server->seat->drag_icons, iterator, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_output_damage_frame(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
|
|||
5
output.h
5
output.h
|
|
@ -26,7 +26,10 @@ struct cg_output {
|
|||
typedef void (*cg_surface_iterator_func_t)(struct cg_output *output, struct wlr_surface *surface, struct wlr_box *box, void *user_data);
|
||||
|
||||
void handle_new_output(struct wl_listener *listener, void *data);
|
||||
void output_view_for_each_surface(struct cg_output *output, struct cg_view *view, cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_surface_for_each_surface(struct cg_output *output, struct wlr_surface *surface,
|
||||
double ox, double oy, cg_surface_iterator_func_t iterator,
|
||||
void *user_data);
|
||||
void output_view_for_each_popup(struct cg_output *output, struct cg_view *view, cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_drag_icons_for_each_surface(struct cg_output *output, struct wl_list *drag_icons, cg_surface_iterator_func_t iterator, void *user_data);
|
||||
void output_damage_surface(struct cg_output *output, struct wlr_surface *surface, double lx, double ly, bool whole);
|
||||
void output_set_window_title(struct cg_output *output, const char *title);
|
||||
|
|
|
|||
33
render.c
33
render.c
|
|
@ -115,8 +115,32 @@ render_view_toplevels(struct cg_view *view, struct cg_output *output, pixman_reg
|
|||
struct render_data data = {
|
||||
.damage = damage,
|
||||
};
|
||||
double ox = view->lx;
|
||||
double oy = view->ly;
|
||||
wlr_output_layout_output_coords(output->server->output_layout, output->wlr_output, &ox, &oy);
|
||||
output_surface_for_each_surface(output, view->wlr_surface, ox, oy,
|
||||
render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
output_view_for_each_surface(output, view, render_surface_iterator, &data);
|
||||
static void
|
||||
render_popup_iterator(struct cg_output *output, struct wlr_surface *surface,
|
||||
struct wlr_box *box, void *data)
|
||||
{
|
||||
/* Render this popup's surface. */
|
||||
render_surface_iterator(output, surface, box, 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 cg_view *view, struct cg_output *output, pixman_region32_t *damage)
|
||||
{
|
||||
struct render_data data = {
|
||||
.damage = damage,
|
||||
};
|
||||
output_view_for_each_popup(output, view, render_popup_iterator, &data);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -151,8 +175,11 @@ output_render(struct cg_output *output, pixman_region32_t *damage)
|
|||
struct cg_view *view;
|
||||
wl_list_for_each_reverse(view, &server->views, link) {
|
||||
render_view_toplevels(view, output, damage);
|
||||
// TODO: popups on top view, possibly use focused view for this
|
||||
// TODO: render only top view, possibly use focused view for this
|
||||
}
|
||||
|
||||
struct cg_view *focused_view = seat_get_focus(server->seat);
|
||||
if (focused_view) {
|
||||
render_view_popups(focused_view, output, damage);
|
||||
}
|
||||
|
||||
render_drag_icons(output, damage, &server->seat->drag_icons);
|
||||
|
|
|
|||
9
view.c
9
view.c
|
|
@ -197,6 +197,15 @@ view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator
|
|||
view->impl->for_each_surface(view, iterator, data);
|
||||
}
|
||||
|
||||
void
|
||||
view_for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data)
|
||||
{
|
||||
if (!view->impl->for_each_popup) {
|
||||
return;
|
||||
}
|
||||
view->impl->for_each_popup(view, iterator, data);
|
||||
}
|
||||
|
||||
void
|
||||
view_unmap(struct cg_view *view)
|
||||
{
|
||||
|
|
|
|||
3
view.h
3
view.h
|
|
@ -46,6 +46,8 @@ struct cg_view_impl {
|
|||
void (*destroy)(struct cg_view *view);
|
||||
void (*for_each_surface)(struct cg_view *view, wlr_surface_iterator_func_t iterator,
|
||||
void *data);
|
||||
void (*for_each_popup)(struct cg_view *view, wlr_surface_iterator_func_t iterator,
|
||||
void *data);
|
||||
struct wlr_surface *(*wlr_surface_at)(struct cg_view *view, double sx, double sy,
|
||||
double *sub_x, double *sub_y);
|
||||
};
|
||||
|
|
@ -76,6 +78,7 @@ void view_damage_whole(struct cg_view *view);
|
|||
void view_activate(struct cg_view *view, bool activate);
|
||||
void view_position(struct cg_view *view);
|
||||
void view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data);
|
||||
void view_for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data);
|
||||
void view_unmap(struct cg_view *view);
|
||||
void view_map(struct cg_view *view, struct wlr_surface *surface);
|
||||
void view_destroy(struct cg_view *view);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,13 @@ for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, voi
|
|||
wlr_xdg_surface_for_each_surface(xdg_shell_view->xdg_surface, iterator, data);
|
||||
}
|
||||
|
||||
static void
|
||||
for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data)
|
||||
{
|
||||
struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
|
||||
wlr_xdg_surface_for_each_popup(xdg_shell_view->xdg_surface, iterator, data);
|
||||
}
|
||||
|
||||
static struct wlr_surface *
|
||||
wlr_surface_at(struct cg_view *view, double sx, double sy, double *sub_x, double *sub_y)
|
||||
{
|
||||
|
|
@ -297,6 +304,7 @@ static const struct cg_view_impl xdg_shell_view_impl = {
|
|||
.maximize = maximize,
|
||||
.destroy = destroy,
|
||||
.for_each_surface = for_each_surface,
|
||||
.for_each_popup = for_each_popup,
|
||||
.wlr_surface_at = wlr_surface_at,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -180,6 +180,8 @@ static const struct cg_view_impl xwayland_view_impl = {
|
|||
.maximize = maximize,
|
||||
.destroy = destroy,
|
||||
.for_each_surface = for_each_surface,
|
||||
/* XWayland doesn't have a separate popup iterator. */
|
||||
.for_each_popup = NULL,
|
||||
.wlr_surface_at = wlr_surface_at,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue