aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c100
1 files changed, 79 insertions, 21 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index d4115be8..37528cac 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -69,6 +69,7 @@ struct render_data {
struct root_geometry root_geo;
struct sway_output *output;
pixman_region32_t *damage;
+ struct sway_view *view;
float alpha;
};
@@ -108,6 +109,38 @@ static bool get_surface_box(struct root_geometry *geo,
return wlr_box_intersection(&output_box, &rotated_box, &intersection);
}
+static bool get_view_box(struct root_geometry *geo,
+ struct sway_output *output, struct sway_view *view, int sx, int sy,
+ struct wlr_box *surface_box) {
+ int sw = view->width;
+ int sh = view->height;
+
+ double _sx = sx, _sy = sy;
+ rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height,
+ geo->rotation);
+
+ struct wlr_box box = {
+ .x = geo->x + _sx,
+ .y = geo->y + _sy,
+ .width = sw,
+ .height = sh,
+ };
+ if (surface_box != NULL) {
+ memcpy(surface_box, &box, sizeof(struct wlr_box));
+ }
+
+ struct wlr_box rotated_box;
+ wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box);
+
+ struct wlr_box output_box = {
+ .width = output->swayc->width,
+ .height = output->swayc->height,
+ };
+
+ struct wlr_box intersection;
+ return wlr_box_intersection(&output_box, &rotated_box, &intersection);
+}
+
static void surface_for_each_surface(struct wlr_surface *surface,
double ox, double oy, struct root_geometry *geo,
wlr_surface_iterator_func_t iterator, void *user_data) {
@@ -240,14 +273,26 @@ static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
pixman_region32_t *output_damage = data->damage;
float alpha = data->alpha;
- struct wlr_texture *texture = wlr_surface_get_texture(surface);
- if (texture == NULL) {
- return;
+ struct wlr_texture *texture = NULL;
+ struct wlr_box box;
+ bool intersects;
+
+ // If this is the main surface of a view, render the saved_texture instead
+ // if it exists. It exists when we are mid-transaction.
+ if (data->view && data->view->saved_texture &&
+ data->view->surface == surface) {
+ texture = data->view->saved_texture;
+ intersects = get_view_box(&data->root_geo, data->output, data->view,
+ sx, sy, &box);
+ } else {
+ texture = wlr_surface_get_texture(surface);
+ if (texture == NULL) {
+ return;
+ }
+ intersects = get_surface_box(&data->root_geo, data->output, surface,
+ sx, sy, &box);
}
- struct wlr_box box;
- bool intersects = get_surface_box(&data->root_geo, data->output, surface,
- sx, sy, &box);
if (!intersects) {
return;
}
@@ -341,6 +386,7 @@ static void render_view_surfaces(struct sway_view *view,
struct render_data data = {
.output = output,
.damage = damage,
+ .view = view,
.alpha = alpha,
};
output_view_for_each_surface(
@@ -754,9 +800,10 @@ static void render_container_stacked(struct sway_output *output,
marks_texture = view ? view->marks_unfocused : NULL;
}
- int y = con->y + container_titlebar_height() * i;
- render_titlebar(output, damage, child, child->x, y, child->width,
- colors, title_texture, marks_texture);
+ int y = con->current.swayc_y + container_titlebar_height() * i;
+ render_titlebar(output, damage, child, child->current.swayc_x, y,
+ child->current.swayc_width, colors,
+ title_texture, marks_texture);
if (child == current) {
current_colors = colors;
@@ -775,7 +822,7 @@ static void render_container_stacked(struct sway_output *output,
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) {
- switch (con->layout) {
+ switch (con->current.layout) {
case L_NONE:
case L_HORIZ:
case L_VERT:
@@ -812,9 +859,10 @@ static void render_floating_container(struct sway_output *soutput,
marks_texture = view->marks_unfocused;
}
- if (con->sway_view->border == B_NORMAL) {
- render_titlebar(soutput, damage, con, con->x, con->y, con->width,
- colors, title_texture, marks_texture);
+ if (con->current.border == B_NORMAL) {
+ render_titlebar(soutput, damage, con, con->current.swayc_x,
+ con->current.swayc_y, con->current.swayc_width, colors,
+ title_texture, marks_texture);
} else {
render_top_border(soutput, damage, con, colors);
}
@@ -1168,6 +1216,16 @@ void output_damage_from_view(struct sway_output *output,
output_damage_view(output, view, false);
}
+// Expecting an unscaled box in layout coordinates
+void output_damage_box(struct sway_output *output, struct wlr_box *_box) {
+ struct wlr_box box;
+ memcpy(&box, _box, sizeof(struct wlr_box));
+ box.x -= output->swayc->current.swayc_x;
+ box.y -= output->swayc->current.swayc_y;
+ scale_box(&box, output->wlr_output->scale);
+ wlr_output_damage_add_box(output->damage, &box);
+}
+
static void output_damage_whole_container_iterator(struct sway_container *con,
void *data) {
struct sway_output *output = data;
@@ -1182,10 +1240,10 @@ static void output_damage_whole_container_iterator(struct sway_container *con,
void output_damage_whole_container(struct sway_output *output,
struct sway_container *con) {
struct wlr_box box = {
- .x = con->x - output->wlr_output->lx,
- .y = con->y - output->wlr_output->ly,
- .width = con->width,
- .height = con->height,
+ .x = con->current.swayc_x - output->wlr_output->lx,
+ .y = con->current.swayc_y - output->wlr_output->ly,
+ .width = con->current.swayc_width,
+ .height = con->current.swayc_height,
};
scale_box(&box, output->wlr_output->scale);
wlr_output_damage_add_box(output->damage, &box);
@@ -1212,13 +1270,13 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
static void handle_mode(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, mode);
arrange_layers(output);
- arrange_output(output->swayc);
+ arrange_and_commit(output->swayc);
}
static void handle_transform(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, transform);
arrange_layers(output);
- arrange_output(output->swayc);
+ arrange_and_commit(output->swayc);
}
static void handle_scale_iterator(struct sway_container *view, void *data) {
@@ -1228,8 +1286,8 @@ static void handle_scale_iterator(struct sway_container *view, void *data) {
static void handle_scale(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, scale);
arrange_layers(output);
- arrange_output(output->swayc);
container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL);
+ arrange_and_commit(output->swayc);
}
void handle_new_output(struct wl_listener *listener, void *data) {
@@ -1293,5 +1351,5 @@ void output_enable(struct sway_output *output) {
output->damage_destroy.notify = damage_handle_destroy;
arrange_layers(output);
- arrange_root();
+ arrange_and_commit(&root_container);
}