mirror of
https://github.com/swaywm/sway.git
synced 2026-05-03 06:46:26 -04:00
Merge dad4e099f1 into d3ea07f828
This commit is contained in:
commit
7c2c6c46e2
4 changed files with 113 additions and 52 deletions
|
|
@ -176,17 +176,10 @@ struct sway_container *container_parent(struct sway_container *container,
|
|||
* surface-local coordinates of the given layout coordinates if the container
|
||||
* is a view and the view contains a surface at those coordinates.
|
||||
*/
|
||||
struct sway_container *container_at(struct sway_container *container,
|
||||
double ox, double oy, struct wlr_surface **surface,
|
||||
struct sway_container *container_at(struct sway_container *workspace,
|
||||
double lx, double ly, struct wlr_surface **surface,
|
||||
double *sx, double *sy);
|
||||
|
||||
/**
|
||||
* Same as container_at, but only checks floating views and expects coordinates
|
||||
* to be layout coordinates, as that's what floating views use.
|
||||
*/
|
||||
struct sway_container *floating_container_at(double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy);
|
||||
|
||||
/**
|
||||
* Apply the function for each descendant of the container breadth first.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct render_data {
|
|||
struct root_geometry root_geo;
|
||||
struct sway_output *output;
|
||||
pixman_region32_t *damage;
|
||||
bool popups;
|
||||
float alpha;
|
||||
};
|
||||
|
||||
|
|
@ -232,9 +233,26 @@ damage_finish:
|
|||
pixman_region32_fini(&damage);
|
||||
}
|
||||
|
||||
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) {
|
||||
struct render_data *data = _data;
|
||||
if (data->popups != surface_is_popup(surface)) {
|
||||
return;
|
||||
}
|
||||
struct wlr_output *wlr_output = data->output->wlr_output;
|
||||
float rotation = data->root_geo.rotation;
|
||||
pixman_region32_t *output_damage = data->damage;
|
||||
|
|
@ -337,14 +355,16 @@ static void premultiply_alpha(float color[4], float opacity) {
|
|||
}
|
||||
|
||||
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 = {
|
||||
.output = output,
|
||||
.damage = damage,
|
||||
.alpha = alpha,
|
||||
.popups = popups,
|
||||
};
|
||||
output_view_for_each_surface(
|
||||
view, &data.root_geo, render_surface_iterator, &data);
|
||||
output_view_for_each_surface(view, &data.root_geo,
|
||||
render_surface_iterator, &data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -353,7 +373,8 @@ static void render_view_surfaces(struct sway_view *view,
|
|||
static void render_view(struct sway_output *output, pixman_region32_t *damage,
|
||||
struct sway_container *con, struct border_colors *colors) {
|
||||
struct sway_view *view = con->sway_view;
|
||||
render_view_surfaces(view, output, damage, view->swayc->alpha);
|
||||
|
||||
render_view_surfaces(view, output, damage, con->alpha, false);
|
||||
|
||||
struct wlr_box box;
|
||||
float output_scale = output->wlr_output->scale;
|
||||
|
|
@ -903,10 +924,11 @@ static void render_output(struct sway_output *output, struct timespec *when,
|
|||
}
|
||||
|
||||
// TODO: handle views smaller than the output
|
||||
render_view_surfaces(
|
||||
workspace->sway_workspace->fullscreen, output, damage, 1.0f);
|
||||
struct sway_view *view = workspace->sway_workspace->fullscreen;
|
||||
render_view_surfaces(view, output, damage, 1.0f, false);
|
||||
render_view_surfaces(view, output, damage, 1.0f, true);
|
||||
|
||||
if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) {
|
||||
if (view->type == SWAY_VIEW_XWAYLAND) {
|
||||
render_unmanaged(output, damage,
|
||||
&root_container.sway_root->xwayland_unmanaged);
|
||||
}
|
||||
|
|
@ -930,6 +952,11 @@ static void render_output(struct sway_output *output, struct timespec *when,
|
|||
render_container(output, damage, workspace, focus == workspace);
|
||||
render_floating(output, damage);
|
||||
|
||||
focus = seat_get_focus_inactive(seat, &root_container);
|
||||
if (focus && focus->type == C_VIEW) {
|
||||
render_view_surfaces(focus->sway_view, output, damage, 1.0f, true);
|
||||
}
|
||||
|
||||
render_unmanaged(output, damage,
|
||||
&root_container.sway_root->xwayland_unmanaged);
|
||||
render_layer(output, damage,
|
||||
|
|
|
|||
|
|
@ -108,9 +108,6 @@ static struct sway_container *container_at_coords(
|
|||
}
|
||||
|
||||
struct sway_container *c;
|
||||
if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
|
||||
return c;
|
||||
}
|
||||
if ((c = container_at(ws, lx, ly, surface, sx, sy))) {
|
||||
return c;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -489,9 +489,9 @@ struct sway_container *container_parent(struct sway_container *container,
|
|||
return container;
|
||||
}
|
||||
|
||||
static struct sway_container *container_at_view(struct sway_container *swayc,
|
||||
double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
static struct sway_container *surface_at_view(struct sway_container *swayc,
|
||||
double lx, double ly, struct wlr_surface **surface,
|
||||
double *sx, double *sy) {
|
||||
if (!sway_assert(swayc->type == C_VIEW, "Expected a view")) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -531,10 +531,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc,
|
|||
*sx = _sx;
|
||||
*sy = _sy;
|
||||
*surface = _surface;
|
||||
return swayc;
|
||||
}
|
||||
return swayc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct sway_container *container_at_container(
|
||||
struct sway_container *parent, double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy);
|
||||
|
||||
/**
|
||||
* container_at for a container with layout L_TABBED.
|
||||
*/
|
||||
|
|
@ -561,7 +566,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent,
|
|||
// Surfaces
|
||||
struct sway_container *current = seat_get_active_child(seat, parent);
|
||||
|
||||
return container_at(current, lx, ly, surface, sx, sy);
|
||||
return container_at_container(current, lx, ly, surface, sx, sy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -586,11 +591,14 @@ static struct sway_container *container_at_stacked(
|
|||
// Surfaces
|
||||
struct sway_container *current = seat_get_active_child(seat, parent);
|
||||
|
||||
return container_at(current, lx, ly, surface, sx, sy);
|
||||
return container_at_container(current, lx, ly, surface, sx, sy);
|
||||
}
|
||||
|
||||
/**
|
||||
* container_at for a container with layout L_HORIZ or L_VERT.
|
||||
* container_at for a container with layout L_HORIZ, L_VERT or L_FLOATING.
|
||||
*
|
||||
* Iterates the children, does a box check and descends into the child if it
|
||||
* passes.
|
||||
*/
|
||||
static struct sway_container *container_at_linear(struct sway_container *parent,
|
||||
double lx, double ly,
|
||||
|
|
@ -604,21 +612,18 @@ static struct sway_container *container_at_linear(struct sway_container *parent,
|
|||
.height = child->height,
|
||||
};
|
||||
if (wlr_box_contains_point(&box, lx, ly)) {
|
||||
return container_at(child, lx, ly, surface, sx, sy);
|
||||
return container_at_container(child, lx, ly, surface, sx, sy);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sway_container *container_at(struct sway_container *parent,
|
||||
double lx, double ly,
|
||||
static struct sway_container *container_at_container(
|
||||
struct sway_container *parent, double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
if (!sway_assert(parent->type >= C_WORKSPACE,
|
||||
"Expected workspace or deeper")) {
|
||||
return NULL;
|
||||
}
|
||||
if (parent->type == C_VIEW) {
|
||||
return container_at_view(parent, lx, ly, surface, sx, sy);
|
||||
surface_at_view(parent, lx, ly, surface, sx, sy);
|
||||
return parent;
|
||||
}
|
||||
if (!parent->children->length) {
|
||||
return NULL;
|
||||
|
|
@ -634,42 +639,81 @@ struct sway_container *container_at(struct sway_container *parent,
|
|||
return container_at_stacked(parent, lx, ly, surface, sx, sy);
|
||||
case L_FLOATING:
|
||||
sway_assert(false, "Didn't expect to see floating here");
|
||||
return NULL;
|
||||
// We can recover from this situation
|
||||
return container_at_linear(parent, lx, ly, surface, sx, sy);
|
||||
case L_NONE:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sway_container *floating_container_at(double lx, double ly,
|
||||
/**
|
||||
* Iterate all visible workspaces and run container_at for each floating
|
||||
* container.
|
||||
*/
|
||||
static struct sway_container *floating_container_at(double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
for (int i = 0; i < root_container.children->length; ++i) {
|
||||
struct sway_container *output = root_container.children->items[i];
|
||||
for (int j = 0; j < output->children->length; ++j) {
|
||||
struct sway_container *workspace = output->children->items[j];
|
||||
struct sway_workspace *ws = workspace->sway_workspace;
|
||||
if (!workspace_is_visible(workspace)) {
|
||||
struct sway_container *ws = output->children->items[j];
|
||||
if (!workspace_is_visible(ws)) {
|
||||
continue;
|
||||
}
|
||||
for (int k = 0; k < ws->floating->children->length; ++k) {
|
||||
struct sway_container *floater =
|
||||
ws->floating->children->items[k];
|
||||
struct wlr_box box = {
|
||||
.x = floater->x,
|
||||
.y = floater->y,
|
||||
.width = floater->width,
|
||||
.height = floater->height,
|
||||
};
|
||||
if (wlr_box_contains_point(&box, lx, ly)) {
|
||||
return container_at(floater, lx, ly, surface, sx, sy);
|
||||
}
|
||||
struct sway_container *c = container_at_linear(
|
||||
ws->sway_workspace->floating, lx, ly, surface, sx, sy);
|
||||
if (c) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
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,
|
||||
double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) {
|
||||
return NULL;
|
||||
}
|
||||
struct sway_container *c;
|
||||
// Focused view's popups
|
||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||
struct sway_container *focus =
|
||||
seat_get_focus_inactive(seat, &root_container);
|
||||
if (focus && focus->type == C_VIEW) {
|
||||
c = surface_at_view(focus, lx, ly, surface, sx, sy);
|
||||
if (*surface && !surface_is_popup(*surface)) {
|
||||
*surface = NULL;
|
||||
} else if (c) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
// Floating
|
||||
if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
|
||||
return c;
|
||||
}
|
||||
// Tiling
|
||||
if ((c = container_at_container(workspace, lx, ly, surface, sx, sy))) {
|
||||
return c;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void container_for_each_descendant_dfs(struct sway_container *container,
|
||||
void (*f)(struct sway_container *container, void *data),
|
||||
void *data) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue