mirror of
https://github.com/swaywm/sway.git
synced 2026-05-03 06:46:26 -04:00
Differentiate popups from subsurfaces for rendering and container_at
This commit is contained in:
parent
250367259f
commit
dad4e099f1
2 changed files with 44 additions and 31 deletions
|
|
@ -69,8 +69,7 @@ struct render_data {
|
||||||
struct root_geometry root_geo;
|
struct root_geometry root_geo;
|
||||||
struct sway_output *output;
|
struct sway_output *output;
|
||||||
pixman_region32_t *damage;
|
pixman_region32_t *damage;
|
||||||
struct sway_view *view;
|
bool popups;
|
||||||
bool only_popups;
|
|
||||||
float alpha;
|
float alpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -219,10 +218,24 @@ damage_finish:
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_surface(struct wlr_surface *surface, int sx, int sy,
|
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);
|
||||||
|
return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
|
||||||
|
}
|
||||||
|
if (wlr_surface_is_xdg_surface_v6(surface)) {
|
||||||
|
struct wlr_xdg_surface_v6 *xdg_surface_v6 =
|
||||||
|
wlr_xdg_surface_v6_from_wlr_surface(surface);
|
||||||
|
return xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
|
||||||
void *_data) {
|
void *_data) {
|
||||||
struct render_data *data = _data;
|
struct render_data *data = _data;
|
||||||
if (data->only_popups && surface == data->view->surface) {
|
if (data->popups != surface_is_popup(surface)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct wlr_output *wlr_output = data->output->wlr_output;
|
struct wlr_output *wlr_output = data->output->wlr_output;
|
||||||
|
|
@ -261,7 +274,7 @@ static void render_layer(struct sway_output *output,
|
||||||
.alpha = 1.0f,
|
.alpha = 1.0f,
|
||||||
};
|
};
|
||||||
layer_for_each_surface(layer_surfaces, &data.root_geo,
|
layer_for_each_surface(layer_surfaces, &data.root_geo,
|
||||||
render_surface, &data);
|
render_surface_iterator, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_unmanaged(struct sway_output *output,
|
static void render_unmanaged(struct sway_output *output,
|
||||||
|
|
@ -272,7 +285,7 @@ static void render_unmanaged(struct sway_output *output,
|
||||||
.alpha = 1.0f,
|
.alpha = 1.0f,
|
||||||
};
|
};
|
||||||
unmanaged_for_each_surface(unmanaged, output, &data.root_geo,
|
unmanaged_for_each_surface(unmanaged, output, &data.root_geo,
|
||||||
render_surface, &data);
|
render_surface_iterator, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_rect(struct wlr_output *wlr_output,
|
static void render_rect(struct wlr_output *wlr_output,
|
||||||
|
|
@ -315,16 +328,17 @@ static void premultiply_alpha(float color[4], float opacity) {
|
||||||
color[2] *= color[3];
|
color[2] *= color[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_view_popups(struct sway_view *view,
|
static void render_view_surfaces(struct sway_view *view,
|
||||||
struct sway_output *output, pixman_region32_t *damage, float alpha) {
|
struct sway_output *output, pixman_region32_t *damage, float alpha,
|
||||||
|
bool popups) {
|
||||||
struct render_data data = {
|
struct render_data data = {
|
||||||
.output = output,
|
.output = output,
|
||||||
.damage = damage,
|
.damage = damage,
|
||||||
.alpha = alpha,
|
.alpha = alpha,
|
||||||
.view = view,
|
.popups = popups,
|
||||||
.only_popups = true,
|
|
||||||
};
|
};
|
||||||
output_view_for_each_surface(view, &data.root_geo, render_surface, &data);
|
output_view_for_each_surface(view, &data.root_geo,
|
||||||
|
render_surface_iterator, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -334,16 +348,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
||||||
struct sway_container *con, struct border_colors *colors) {
|
struct sway_container *con, struct border_colors *colors) {
|
||||||
struct sway_view *view = con->sway_view;
|
struct sway_view *view = con->sway_view;
|
||||||
|
|
||||||
// We'll only render the view's primary surface here.
|
render_view_surfaces(view, output, damage, con->alpha, false);
|
||||||
// Popups need to be rendered too, but only for the focused view, and they
|
|
||||||
// need to render on top of everything else so we do them separately.
|
|
||||||
struct render_data data = {
|
|
||||||
.output = output,
|
|
||||||
.damage = damage,
|
|
||||||
.alpha = view->swayc->alpha,
|
|
||||||
};
|
|
||||||
render_surface(view->surface, view->x - output->swayc->x,
|
|
||||||
view->y - output->swayc->y, &data);
|
|
||||||
|
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
float output_scale = output->wlr_output->scale;
|
float output_scale = output->wlr_output->scale;
|
||||||
|
|
@ -894,13 +899,8 @@ static void render_output(struct sway_output *output, struct timespec *when,
|
||||||
|
|
||||||
// TODO: handle views smaller than the output
|
// TODO: handle views smaller than the output
|
||||||
struct sway_view *view = workspace->sway_workspace->fullscreen;
|
struct sway_view *view = workspace->sway_workspace->fullscreen;
|
||||||
struct render_data data = {
|
render_view_surfaces(view, output, damage, 1.0f, false);
|
||||||
.output = output,
|
render_view_surfaces(view, output, damage, 1.0f, true);
|
||||||
.damage = damage,
|
|
||||||
.alpha = 1.0f,
|
|
||||||
};
|
|
||||||
output_view_for_each_surface(
|
|
||||||
view, &data.root_geo, render_surface, &data);
|
|
||||||
|
|
||||||
if (view->type == SWAY_VIEW_XWAYLAND) {
|
if (view->type == SWAY_VIEW_XWAYLAND) {
|
||||||
render_unmanaged(output, damage,
|
render_unmanaged(output, damage,
|
||||||
|
|
@ -928,7 +928,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
|
||||||
|
|
||||||
focus = seat_get_focus_inactive(seat, &root_container);
|
focus = seat_get_focus_inactive(seat, &root_container);
|
||||||
if (focus && focus->type == C_VIEW) {
|
if (focus && focus->type == C_VIEW) {
|
||||||
render_view_popups(focus->sway_view, output, damage, 1.0f);
|
render_view_surfaces(focus->sway_view, output, damage, 1.0f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_unmanaged(output, damage,
|
render_unmanaged(output, damage,
|
||||||
|
|
|
||||||
|
|
@ -655,6 +655,20 @@ static struct sway_container *floating_container_at(double lx, double ly,
|
||||||
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);
|
||||||
|
return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
|
||||||
|
}
|
||||||
|
if (wlr_surface_is_xdg_surface_v6(surface)) {
|
||||||
|
struct wlr_xdg_surface_v6 *xdg_surface_v6 =
|
||||||
|
wlr_xdg_surface_v6_from_wlr_surface(surface);
|
||||||
|
return xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct sway_container *container_at(struct sway_container *workspace,
|
struct sway_container *container_at(struct sway_container *workspace,
|
||||||
double lx, double ly,
|
double lx, double ly,
|
||||||
struct wlr_surface **surface, double *sx, double *sy) {
|
struct wlr_surface **surface, double *sx, double *sy) {
|
||||||
|
|
@ -668,8 +682,7 @@ struct sway_container *container_at(struct sway_container *workspace,
|
||||||
seat_get_focus_inactive(seat, &root_container);
|
seat_get_focus_inactive(seat, &root_container);
|
||||||
if (focus && focus->type == C_VIEW) {
|
if (focus && focus->type == C_VIEW) {
|
||||||
c = surface_at_view(focus, lx, ly, surface, sx, sy);
|
c = surface_at_view(focus, lx, ly, surface, sx, sy);
|
||||||
if (*surface && *surface == focus->sway_view->surface) {
|
if (*surface && !surface_is_popup(*surface)) {
|
||||||
// Not a popup
|
|
||||||
*surface = NULL;
|
*surface = NULL;
|
||||||
} else if (c) {
|
} else if (c) {
|
||||||
return c;
|
return c;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue