aboutsummaryrefslogtreecommitdiffstats
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 {
69 struct root_geometry root_geo; 69 struct root_geometry root_geo;
70 struct sway_output *output; 70 struct sway_output *output;
71 pixman_region32_t *damage; 71 pixman_region32_t *damage;
72 struct sway_view *view;
72 float alpha; 73 float alpha;
73}; 74};
74 75
@@ -108,6 +109,38 @@ static bool get_surface_box(struct root_geometry *geo,
108 return wlr_box_intersection(&output_box, &rotated_box, &intersection); 109 return wlr_box_intersection(&output_box, &rotated_box, &intersection);
109} 110}
110 111
112static bool get_view_box(struct root_geometry *geo,
113 struct sway_output *output, struct sway_view *view, int sx, int sy,
114 struct wlr_box *surface_box) {
115 int sw = view->width;
116 int sh = view->height;
117
118 double _sx = sx, _sy = sy;
119 rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height,
120 geo->rotation);
121
122 struct wlr_box box = {
123 .x = geo->x + _sx,
124 .y = geo->y + _sy,
125 .width = sw,
126 .height = sh,
127 };
128 if (surface_box != NULL) {
129 memcpy(surface_box, &box, sizeof(struct wlr_box));
130 }
131
132 struct wlr_box rotated_box;
133 wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box);
134
135 struct wlr_box output_box = {
136 .width = output->swayc->width,
137 .height = output->swayc->height,
138 };
139
140 struct wlr_box intersection;
141 return wlr_box_intersection(&output_box, &rotated_box, &intersection);
142}
143
111static void surface_for_each_surface(struct wlr_surface *surface, 144static void surface_for_each_surface(struct wlr_surface *surface,
112 double ox, double oy, struct root_geometry *geo, 145 double ox, double oy, struct root_geometry *geo,
113 wlr_surface_iterator_func_t iterator, void *user_data) { 146 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,
240 pixman_region32_t *output_damage = data->damage; 273 pixman_region32_t *output_damage = data->damage;
241 float alpha = data->alpha; 274 float alpha = data->alpha;
242 275
243 struct wlr_texture *texture = wlr_surface_get_texture(surface); 276 struct wlr_texture *texture = NULL;
244 if (texture == NULL) { 277 struct wlr_box box;
245 return; 278 bool intersects;
279
280 // If this is the main surface of a view, render the saved_texture instead
281 // if it exists. It exists when we are mid-transaction.
282 if (data->view && data->view->saved_texture &&
283 data->view->surface == surface) {
284 texture = data->view->saved_texture;
285 intersects = get_view_box(&data->root_geo, data->output, data->view,
286 sx, sy, &box);
287 } else {
288 texture = wlr_surface_get_texture(surface);
289 if (texture == NULL) {
290 return;
291 }
292 intersects = get_surface_box(&data->root_geo, data->output, surface,
293 sx, sy, &box);
246 } 294 }
247 295
248 struct wlr_box box;
249 bool intersects = get_surface_box(&data->root_geo, data->output, surface,
250 sx, sy, &box);
251 if (!intersects) { 296 if (!intersects) {
252 return; 297 return;
253 } 298 }
@@ -341,6 +386,7 @@ static void render_view_surfaces(struct sway_view *view,
341 struct render_data data = { 386 struct render_data data = {
342 .output = output, 387 .output = output,
343 .damage = damage, 388 .damage = damage,
389 .view = view,
344 .alpha = alpha, 390 .alpha = alpha,
345 }; 391 };
346 output_view_for_each_surface( 392 output_view_for_each_surface(
@@ -754,9 +800,10 @@ static void render_container_stacked(struct sway_output *output,
754 marks_texture = view ? view->marks_unfocused : NULL; 800 marks_texture = view ? view->marks_unfocused : NULL;
755 } 801 }
756 802
757 int y = con->y + container_titlebar_height() * i; 803 int y = con->current.swayc_y + container_titlebar_height() * i;
758 render_titlebar(output, damage, child, child->x, y, child->width, 804 render_titlebar(output, damage, child, child->current.swayc_x, y,
759 colors, title_texture, marks_texture); 805 child->current.swayc_width, colors,
806 title_texture, marks_texture);
760 807
761 if (child == current) { 808 if (child == current) {
762 current_colors = colors; 809 current_colors = colors;
@@ -775,7 +822,7 @@ static void render_container_stacked(struct sway_output *output,
775static void render_container(struct sway_output *output, 822static void render_container(struct sway_output *output,
776 pixman_region32_t *damage, struct sway_container *con, 823 pixman_region32_t *damage, struct sway_container *con,
777 bool parent_focused) { 824 bool parent_focused) {
778 switch (con->layout) { 825 switch (con->current.layout) {
779 case L_NONE: 826 case L_NONE:
780 case L_HORIZ: 827 case L_HORIZ:
781 case L_VERT: 828 case L_VERT:
@@ -812,9 +859,10 @@ static void render_floating_container(struct sway_output *soutput,
812 marks_texture = view->marks_unfocused; 859 marks_texture = view->marks_unfocused;
813 } 860 }
814 861
815 if (con->sway_view->border == B_NORMAL) { 862 if (con->current.border == B_NORMAL) {
816 render_titlebar(soutput, damage, con, con->x, con->y, con->width, 863 render_titlebar(soutput, damage, con, con->current.swayc_x,
817 colors, title_texture, marks_texture); 864 con->current.swayc_y, con->current.swayc_width, colors,
865 title_texture, marks_texture);
818 } else { 866 } else {
819 render_top_border(soutput, damage, con, colors); 867 render_top_border(soutput, damage, con, colors);
820 } 868 }
@@ -1168,6 +1216,16 @@ void output_damage_from_view(struct sway_output *output,
1168 output_damage_view(output, view, false); 1216 output_damage_view(output, view, false);
1169} 1217}
1170 1218
1219// Expecting an unscaled box in layout coordinates
1220void output_damage_box(struct sway_output *output, struct wlr_box *_box) {
1221 struct wlr_box box;
1222 memcpy(&box, _box, sizeof(struct wlr_box));
1223 box.x -= output->swayc->current.swayc_x;
1224 box.y -= output->swayc->current.swayc_y;
1225 scale_box(&box, output->wlr_output->scale);
1226 wlr_output_damage_add_box(output->damage, &box);
1227}
1228
1171static void output_damage_whole_container_iterator(struct sway_container *con, 1229static void output_damage_whole_container_iterator(struct sway_container *con,
1172 void *data) { 1230 void *data) {
1173 struct sway_output *output = data; 1231 struct sway_output *output = data;
@@ -1182,10 +1240,10 @@ static void output_damage_whole_container_iterator(struct sway_container *con,
1182void output_damage_whole_container(struct sway_output *output, 1240void output_damage_whole_container(struct sway_output *output,
1183 struct sway_container *con) { 1241 struct sway_container *con) {
1184 struct wlr_box box = { 1242 struct wlr_box box = {
1185 .x = con->x - output->wlr_output->lx, 1243 .x = con->current.swayc_x - output->wlr_output->lx,
1186 .y = con->y - output->wlr_output->ly, 1244 .y = con->current.swayc_y - output->wlr_output->ly,
1187 .width = con->width, 1245 .width = con->current.swayc_width,
1188 .height = con->height, 1246 .height = con->current.swayc_height,
1189 }; 1247 };
1190 scale_box(&box, output->wlr_output->scale); 1248 scale_box(&box, output->wlr_output->scale);
1191 wlr_output_damage_add_box(output->damage, &box); 1249 wlr_output_damage_add_box(output->damage, &box);
@@ -1212,13 +1270,13 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
1212static void handle_mode(struct wl_listener *listener, void *data) { 1270static void handle_mode(struct wl_listener *listener, void *data) {
1213 struct sway_output *output = wl_container_of(listener, output, mode); 1271 struct sway_output *output = wl_container_of(listener, output, mode);
1214 arrange_layers(output); 1272 arrange_layers(output);
1215 arrange_output(output->swayc); 1273 arrange_and_commit(output->swayc);
1216} 1274}
1217 1275
1218static void handle_transform(struct wl_listener *listener, void *data) { 1276static void handle_transform(struct wl_listener *listener, void *data) {
1219 struct sway_output *output = wl_container_of(listener, output, transform); 1277 struct sway_output *output = wl_container_of(listener, output, transform);
1220 arrange_layers(output); 1278 arrange_layers(output);
1221 arrange_output(output->swayc); 1279 arrange_and_commit(output->swayc);
1222} 1280}
1223 1281
1224static void handle_scale_iterator(struct sway_container *view, void *data) { 1282static 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) {
1228static void handle_scale(struct wl_listener *listener, void *data) { 1286static void handle_scale(struct wl_listener *listener, void *data) {
1229 struct sway_output *output = wl_container_of(listener, output, scale); 1287 struct sway_output *output = wl_container_of(listener, output, scale);
1230 arrange_layers(output); 1288 arrange_layers(output);
1231 arrange_output(output->swayc);
1232 container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL); 1289 container_descendants(output->swayc, C_VIEW, handle_scale_iterator, NULL);
1290 arrange_and_commit(output->swayc);
1233} 1291}
1234 1292
1235void handle_new_output(struct wl_listener *listener, void *data) { 1293void handle_new_output(struct wl_listener *listener, void *data) {
@@ -1293,5 +1351,5 @@ void output_enable(struct sway_output *output) {
1293 output->damage_destroy.notify = damage_handle_destroy; 1351 output->damage_destroy.notify = damage_handle_destroy;
1294 1352
1295 arrange_layers(output); 1353 arrange_layers(output);
1296 arrange_root(); 1354 arrange_and_commit(&root_container);
1297} 1355}