diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 100 |
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 | ||
112 | static 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 | |||
111 | static void surface_for_each_surface(struct wlr_surface *surface, | 144 | static 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, | |||
775 | static void render_container(struct sway_output *output, | 822 | static 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 | ||
1220 | void 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 | |||
1171 | static void output_damage_whole_container_iterator(struct sway_container *con, | 1229 | static 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, | |||
1182 | void output_damage_whole_container(struct sway_output *output, | 1240 | void 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) { | |||
1212 | static void handle_mode(struct wl_listener *listener, void *data) { | 1270 | static 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 | ||
1218 | static void handle_transform(struct wl_listener *listener, void *data) { | 1276 | static 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 | ||
1224 | static void handle_scale_iterator(struct sway_container *view, void *data) { | 1282 | 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) { | |||
1228 | static void handle_scale(struct wl_listener *listener, void *data) { | 1286 | static 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 | ||
1235 | void handle_new_output(struct wl_listener *listener, void *data) { | 1293 | void 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 | } |