diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-04-07 11:53:10 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-07 11:53:10 -0400 |
commit | c47b4d4edb7714612ec7236fafda5ca54cb92ce4 (patch) | |
tree | 9a7f991e9c3da20351b58c53e0b6dbe376f12dca | |
parent | Merge pull request #1700 from swaywm/move-cmd-full (diff) | |
parent | Damage all surfaces when damaging whole container (diff) | |
download | sway-c47b4d4edb7714612ec7236fafda5ca54cb92ce4.tar.gz sway-c47b4d4edb7714612ec7236fafda5ca54cb92ce4.tar.zst sway-c47b4d4edb7714612ec7236fafda5ca54cb92ce4.zip |
Merge pull request #1756 from emersion/output-damage
Fine-grained damage tracking
-rw-r--r-- | include/sway/desktop.h | 7 | ||||
-rw-r--r-- | include/sway/output.h | 8 | ||||
-rw-r--r-- | include/sway/tree/view.h | 4 | ||||
-rw-r--r-- | sway/commands/opacity.c | 5 | ||||
-rw-r--r-- | sway/desktop/desktop.c | 14 | ||||
-rw-r--r-- | sway/desktop/layer_shell.c | 44 | ||||
-rw-r--r-- | sway/desktop/output.c | 439 | ||||
-rw-r--r-- | sway/desktop/wl_shell.c | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 26 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 18 | ||||
-rw-r--r-- | sway/tree/view.c | 27 |
11 files changed, 332 insertions, 262 deletions
diff --git a/include/sway/desktop.h b/include/sway/desktop.h index 96bdc94c..f1ad759a 100644 --- a/include/sway/desktop.h +++ b/include/sway/desktop.h | |||
@@ -1,7 +1,4 @@ | |||
1 | #include <wlr/types/wlr_surface.h> | 1 | #include <wlr/types/wlr_surface.h> |
2 | 2 | ||
3 | void desktop_damage_whole_surface(struct wlr_surface *surface, double lx, | 3 | void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, |
4 | double ly); | 4 | bool whole); |
5 | |||
6 | void desktop_damage_from_surface(struct wlr_surface *surface, double lx, | ||
7 | double ly); | ||
diff --git a/include/sway/output.h b/include/sway/output.h index 4bffa2b7..56571548 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -34,11 +34,11 @@ struct sway_output { | |||
34 | 34 | ||
35 | void output_damage_whole(struct sway_output *output); | 35 | void output_damage_whole(struct sway_output *output); |
36 | 36 | ||
37 | void output_damage_whole_surface(struct sway_output *output, | 37 | void output_damage_surface(struct sway_output *output, double ox, double oy, |
38 | double ox, double oy, struct wlr_surface *surface); | 38 | struct wlr_surface *surface, bool whole); |
39 | 39 | ||
40 | void output_damage_whole_view(struct sway_output *output, | 40 | void output_damage_view(struct sway_output *output, struct sway_view *view, |
41 | struct sway_view *view); | 41 | bool whole); |
42 | 42 | ||
43 | void output_damage_whole_container(struct sway_output *output, | 43 | void output_damage_whole_container(struct sway_output *output, |
44 | struct sway_container *con); | 44 | struct sway_container *con); |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 611c4f0b..b51c54b5 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -157,9 +157,7 @@ void view_set_activated(struct sway_view *view, bool activated); | |||
157 | 157 | ||
158 | void view_close(struct sway_view *view); | 158 | void view_close(struct sway_view *view); |
159 | 159 | ||
160 | void view_damage_whole(struct sway_view *view); | 160 | void view_damage(struct sway_view *view, bool whole); |
161 | |||
162 | void view_damage_from(struct sway_view *view); | ||
163 | 161 | ||
164 | void view_for_each_surface(struct sway_view *view, | 162 | void view_for_each_surface(struct sway_view *view, |
165 | wlr_surface_iterator_func_t iterator, void *user_data); | 163 | wlr_surface_iterator_func_t iterator, void *user_data); |
diff --git a/sway/commands/opacity.c b/sway/commands/opacity.c index b8cd1f09..68fd9f42 100644 --- a/sway/commands/opacity.c +++ b/sway/commands/opacity.c | |||
@@ -30,10 +30,7 @@ struct cmd_results *cmd_opacity(int argc, char **argv) { | |||
30 | } | 30 | } |
31 | 31 | ||
32 | con->alpha = opacity; | 32 | con->alpha = opacity; |
33 | 33 | container_damage_whole(con); | |
34 | if (con->type == C_VIEW) { | ||
35 | view_damage_whole(con->sway_view); | ||
36 | } | ||
37 | 34 | ||
38 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 35 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
39 | } | 36 | } |
diff --git a/sway/desktop/desktop.c b/sway/desktop/desktop.c index 3a13191f..66f33151 100644 --- a/sway/desktop/desktop.c +++ b/sway/desktop/desktop.c | |||
@@ -2,19 +2,13 @@ | |||
2 | #include "sway/desktop.h" | 2 | #include "sway/desktop.h" |
3 | #include "sway/output.h" | 3 | #include "sway/output.h" |
4 | 4 | ||
5 | void desktop_damage_whole_surface(struct wlr_surface *surface, double lx, | 5 | void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, |
6 | double ly) { | 6 | bool whole) { |
7 | for (int i = 0; i < root_container.children->length; ++i) { | 7 | for (int i = 0; i < root_container.children->length; ++i) { |
8 | struct sway_container *cont = root_container.children->items[i]; | 8 | struct sway_container *cont = root_container.children->items[i]; |
9 | if (cont->type == C_OUTPUT) { | 9 | if (cont->type == C_OUTPUT) { |
10 | output_damage_whole_surface(cont->sway_output, | 10 | output_damage_surface(cont->sway_output, lx - cont->x, ly - cont->y, |
11 | lx - cont->x, ly - cont->y, surface); | 11 | surface, whole); |
12 | } | 12 | } |
13 | } | 13 | } |
14 | } | 14 | } |
15 | |||
16 | void desktop_damage_from_surface(struct wlr_surface *surface, double lx, | ||
17 | double ly) { | ||
18 | // TODO | ||
19 | desktop_damage_whole_surface(surface, lx, ly); | ||
20 | } | ||
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 663ec7ba..f841e5f1 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -229,33 +229,39 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
229 | wl_container_of(listener, layer, surface_commit); | 229 | wl_container_of(listener, layer, surface_commit); |
230 | struct wlr_layer_surface *layer_surface = layer->layer_surface; | 230 | struct wlr_layer_surface *layer_surface = layer->layer_surface; |
231 | struct wlr_output *wlr_output = layer_surface->output; | 231 | struct wlr_output *wlr_output = layer_surface->output; |
232 | if (wlr_output != NULL) { | 232 | if (wlr_output == NULL) { |
233 | struct sway_output *output = wlr_output->data; | 233 | return; |
234 | struct wlr_box old_geo = layer->geo; | 234 | } |
235 | arrange_layers(output); | 235 | |
236 | if (memcmp(&old_geo, &layer->geo, sizeof(struct wlr_box)) != 0) { | 236 | struct sway_output *output = wlr_output->data; |
237 | // TODO DAMAGE apply whole surface from previous and new geos | 237 | struct wlr_box old_geo = layer->geo; |
238 | } else { | 238 | arrange_layers(output); |
239 | // TODO DAMAGE from surface damage | 239 | if (memcmp(&old_geo, &layer->geo, sizeof(struct wlr_box)) != 0) { |
240 | } | 240 | output_damage_surface(output, old_geo.x, old_geo.y, |
241 | wlr_output_damage_add_box(output->damage, &old_geo); | 241 | layer_surface->surface, true); |
242 | wlr_output_damage_add_box(output->damage, &layer->geo); | 242 | output_damage_surface(output, layer->geo.x, layer->geo.y, |
243 | layer_surface->surface, true); | ||
244 | } else { | ||
245 | output_damage_surface(output, layer->geo.x, layer->geo.y, | ||
246 | layer_surface->surface, false); | ||
243 | } | 247 | } |
244 | } | 248 | } |
245 | 249 | ||
246 | static void unmap(struct sway_layer_surface *sway_layer) { | 250 | static void unmap(struct sway_layer_surface *sway_layer) { |
247 | struct wlr_output *wlr_output = sway_layer->layer_surface->output; | 251 | struct wlr_output *wlr_output = sway_layer->layer_surface->output; |
248 | if (wlr_output != NULL) { | 252 | if (wlr_output == NULL) { |
249 | struct sway_output *output = wlr_output->data; | 253 | return; |
250 | wlr_output_damage_add_box(output->damage, &sway_layer->geo); | ||
251 | } | 254 | } |
255 | struct sway_output *output = wlr_output->data; | ||
256 | output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y, | ||
257 | sway_layer->layer_surface->surface, true); | ||
252 | } | 258 | } |
253 | 259 | ||
254 | static void handle_destroy(struct wl_listener *listener, void *data) { | 260 | static void handle_destroy(struct wl_listener *listener, void *data) { |
255 | struct sway_layer_surface *sway_layer = wl_container_of(listener, | 261 | struct sway_layer_surface *sway_layer = |
256 | sway_layer, destroy); | 262 | wl_container_of(listener, sway_layer, destroy); |
257 | wlr_log(L_DEBUG, "Layer surface destroyed (%s)", | 263 | wlr_log(L_DEBUG, "Layer surface destroyed (%s)", |
258 | sway_layer->layer_surface->namespace); | 264 | sway_layer->layer_surface->namespace); |
259 | if (sway_layer->layer_surface->mapped) { | 265 | if (sway_layer->layer_surface->mapped) { |
260 | unmap(sway_layer); | 266 | unmap(sway_layer); |
261 | } | 267 | } |
@@ -277,7 +283,9 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
277 | struct sway_layer_surface *sway_layer = wl_container_of(listener, | 283 | struct sway_layer_surface *sway_layer = wl_container_of(listener, |
278 | sway_layer, map); | 284 | sway_layer, map); |
279 | struct sway_output *output = sway_layer->layer_surface->output->data; | 285 | struct sway_output *output = sway_layer->layer_surface->output->data; |
280 | wlr_output_damage_add_box(output->damage, &sway_layer->geo); | 286 | output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y, |
287 | sway_layer->layer_surface->surface, true); | ||
288 | // TODO: send enter to subsurfaces and popups | ||
281 | wlr_surface_send_enter(sway_layer->layer_surface->surface, | 289 | wlr_surface_send_enter(sway_layer->layer_surface->surface, |
282 | sway_layer->layer_surface->output); | 290 | sway_layer->layer_surface->output); |
283 | } | 291 | } |
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index ad777796..23d20b79 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -1,8 +1,8 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <time.h> | ||
5 | #include <strings.h> | 4 | #include <strings.h> |
5 | #include <time.h> | ||
6 | #include <wayland-server.h> | 6 | #include <wayland-server.h> |
7 | #include <wlr/render/wlr_renderer.h> | 7 | #include <wlr/render/wlr_renderer.h> |
8 | #include <wlr/types/wlr_box.h> | 8 | #include <wlr/types/wlr_box.h> |
@@ -12,6 +12,7 @@ | |||
12 | #include <wlr/types/wlr_output.h> | 12 | #include <wlr/types/wlr_output.h> |
13 | #include <wlr/types/wlr_surface.h> | 13 | #include <wlr/types/wlr_surface.h> |
14 | #include <wlr/types/wlr_wl_shell.h> | 14 | #include <wlr/types/wlr_wl_shell.h> |
15 | #include <wlr/util/region.h> | ||
15 | #include "log.h" | 16 | #include "log.h" |
16 | #include "sway/input/input-manager.h" | 17 | #include "sway/input/input-manager.h" |
17 | #include "sway/input/seat.h" | 18 | #include "sway/input/seat.h" |
@@ -38,191 +39,201 @@ struct sway_container *output_by_name(const char *name) { | |||
38 | */ | 39 | */ |
39 | static void rotate_child_position(double *sx, double *sy, double sw, double sh, | 40 | static void rotate_child_position(double *sx, double *sy, double sw, double sh, |
40 | double pw, double ph, float rotation) { | 41 | double pw, double ph, float rotation) { |
41 | if (rotation != 0.0) { | 42 | if (rotation == 0.0f) { |
42 | // Coordinates relative to the center of the subsurface | 43 | return; |
43 | double ox = *sx - pw/2 + sw/2, | ||
44 | oy = *sy - ph/2 + sh/2; | ||
45 | // Rotated coordinates | ||
46 | double rx = cos(-rotation)*ox - sin(-rotation)*oy, | ||
47 | ry = cos(-rotation)*oy + sin(-rotation)*ox; | ||
48 | *sx = rx + pw/2 - sw/2; | ||
49 | *sy = ry + ph/2 - sh/2; | ||
50 | } | 44 | } |
45 | |||
46 | // Coordinates relative to the center of the subsurface | ||
47 | double ox = *sx - pw/2 + sw/2, | ||
48 | oy = *sy - ph/2 + sh/2; | ||
49 | // Rotated coordinates | ||
50 | double rx = cos(-rotation)*ox - sin(-rotation)*oy, | ||
51 | ry = cos(-rotation)*oy + sin(-rotation)*ox; | ||
52 | *sx = rx + pw/2 - sw/2; | ||
53 | *sy = ry + ph/2 - sh/2; | ||
51 | } | 54 | } |
52 | 55 | ||
53 | /** | 56 | /** |
54 | * Checks whether a surface at (lx, ly) intersects an output. If `box` is not | 57 | * Contains a surface's root geometry information. For instance, when rendering |
55 | * NULL, it populates it with the surface box in the output, in output-local | 58 | * a popup, this will contain the parent view's position and size. |
56 | * coordinates. | ||
57 | */ | 59 | */ |
58 | static bool surface_intersect_output(struct wlr_surface *surface, | 60 | struct root_geometry { |
59 | struct wlr_output_layout *output_layout, struct wlr_output *wlr_output, | 61 | double x, y; |
60 | double ox, double oy, float rotation, struct wlr_box *box) { | 62 | int width, height; |
61 | if (box != NULL) { | 63 | float rotation; |
62 | box->x = ox * wlr_output->scale; | 64 | }; |
63 | box->y = oy * wlr_output->scale; | 65 | |
64 | box->width = surface->current->width * wlr_output->scale; | 66 | static bool get_surface_box(struct root_geometry *geo, |
65 | box->height = surface->current->height * wlr_output->scale; | 67 | struct sway_output *output, struct wlr_surface *surface, int sx, int sy, |
68 | struct wlr_box *surface_box) { | ||
69 | int sw = surface->current->width; | ||
70 | int sh = surface->current->height; | ||
71 | |||
72 | double _sx = sx, _sy = sy; | ||
73 | rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, | ||
74 | geo->rotation); | ||
75 | |||
76 | struct wlr_box box = { | ||
77 | .x = geo->x + _sx, | ||
78 | .y = geo->y + _sy, | ||
79 | .width = sw, | ||
80 | .height = sh, | ||
81 | }; | ||
82 | if (surface_box != NULL) { | ||
83 | memcpy(surface_box, &box, sizeof(struct wlr_box)); | ||
66 | } | 84 | } |
67 | 85 | ||
68 | struct wlr_box layout_box = { | 86 | struct wlr_box rotated_box; |
69 | .x = wlr_output->lx + ox, .y = wlr_output->ly + oy, | 87 | wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); |
70 | .width = surface->current->width, .height = surface->current->height, | 88 | |
89 | struct wlr_box output_box = { | ||
90 | .width = output->swayc->width, | ||
91 | .height = output->swayc->height, | ||
71 | }; | 92 | }; |
72 | wlr_box_rotated_bounds(&layout_box, rotation, &layout_box); | 93 | |
73 | return wlr_output_layout_intersects(output_layout, wlr_output, &layout_box); | 94 | struct wlr_box intersection; |
95 | return wlr_box_intersection(&output_box, &rotated_box, &intersection); | ||
74 | } | 96 | } |
75 | 97 | ||
76 | static void render_surface(struct wlr_surface *surface, | 98 | static void output_surface_for_each_surface(struct wlr_surface *surface, |
77 | struct wlr_output *wlr_output, struct timespec *when, | 99 | double ox, double oy, struct root_geometry *geo, |
78 | double ox, double oy, float rotation, float alpha) { | 100 | wlr_surface_iterator_func_t iterator, void *user_data) { |
79 | struct wlr_renderer *renderer = | 101 | geo->x = ox; |
80 | wlr_backend_get_renderer(wlr_output->backend); | 102 | geo->y = oy; |
103 | geo->width = surface->current->width; | ||
104 | geo->height = surface->current->height; | ||
105 | geo->rotation = 0; | ||
106 | |||
107 | wlr_surface_for_each_surface(surface, iterator, user_data); | ||
108 | } | ||
109 | |||
110 | static void output_view_for_each_surface(struct sway_view *view, | ||
111 | struct root_geometry *geo, wlr_surface_iterator_func_t iterator, | ||
112 | void *user_data) { | ||
113 | geo->x = view->swayc->x; | ||
114 | geo->y = view->swayc->y; | ||
115 | geo->width = view->surface->current->width; | ||
116 | geo->height = view->surface->current->height; | ||
117 | geo->rotation = 0; // TODO | ||
118 | |||
119 | view_for_each_surface(view, iterator, user_data); | ||
120 | } | ||
121 | |||
122 | static void scale_box(struct wlr_box *box, float scale) { | ||
123 | box->x *= scale; | ||
124 | box->y *= scale; | ||
125 | box->width *= scale; | ||
126 | box->height *= scale; | ||
127 | } | ||
128 | |||
129 | struct render_data { | ||
130 | struct root_geometry root_geo; | ||
131 | struct sway_output *output; | ||
132 | struct timespec *when; | ||
133 | float alpha; | ||
134 | }; | ||
135 | |||
136 | static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy, | ||
137 | void *_data) { | ||
138 | struct render_data *data = _data; | ||
139 | struct wlr_output *wlr_output = data->output->wlr_output; | ||
140 | struct timespec *when = data->when; | ||
141 | float rotation = data->root_geo.rotation; | ||
142 | float alpha = data->alpha; | ||
81 | 143 | ||
82 | if (!wlr_surface_has_buffer(surface)) { | 144 | if (!wlr_surface_has_buffer(surface)) { |
83 | return; | 145 | return; |
84 | } | 146 | } |
85 | 147 | ||
86 | struct wlr_output_layout *layout = root_container.sway_root->output_layout; | ||
87 | |||
88 | struct wlr_box box; | 148 | struct wlr_box box; |
89 | bool intersects = surface_intersect_output(surface, layout, wlr_output, | 149 | bool intersects = get_surface_box(&data->root_geo, data->output, surface, |
90 | ox, oy, rotation, &box); | 150 | sx, sy, &box); |
91 | if (intersects) { | 151 | if (!intersects) { |
92 | float matrix[9]; | 152 | return; |
93 | enum wl_output_transform transform = | ||
94 | wlr_output_transform_invert(surface->current->transform); | ||
95 | wlr_matrix_project_box(matrix, &box, transform, rotation, | ||
96 | wlr_output->transform_matrix); | ||
97 | |||
98 | wlr_render_texture_with_matrix(renderer, surface->texture, | ||
99 | matrix, alpha); | ||
100 | |||
101 | wlr_surface_send_frame_done(surface, when); | ||
102 | } | 153 | } |
103 | 154 | ||
104 | struct wlr_subsurface *subsurface; | 155 | struct wlr_renderer *renderer = |
105 | wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { | 156 | wlr_backend_get_renderer(wlr_output->backend); |
106 | struct wlr_surface_state *state = subsurface->surface->current; | 157 | if (!sway_assert(renderer != NULL, |
107 | double sx = state->subsurface_position.x; | 158 | "expected the output backend to have a renderer")) { |
108 | double sy = state->subsurface_position.y; | 159 | return; |
109 | rotate_child_position(&sx, &sy, state->width, state->height, | ||
110 | surface->current->width, surface->current->height, rotation); | ||
111 | |||
112 | render_surface(subsurface->surface, wlr_output, when, | ||
113 | ox + sx, oy + sy, rotation, alpha); | ||
114 | } | 160 | } |
161 | |||
162 | scale_box(&box, wlr_output->scale); | ||
163 | |||
164 | float matrix[9]; | ||
165 | enum wl_output_transform transform = | ||
166 | wlr_output_transform_invert(surface->current->transform); | ||
167 | wlr_matrix_project_box(matrix, &box, transform, rotation, | ||
168 | wlr_output->transform_matrix); | ||
169 | |||
170 | wlr_render_texture_with_matrix(renderer, surface->texture, | ||
171 | matrix, alpha); | ||
172 | |||
173 | // TODO: don't send the frame done event now | ||
174 | wlr_surface_send_frame_done(surface, when); | ||
115 | } | 175 | } |
116 | 176 | ||
117 | static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, | 177 | static void render_surface(struct sway_output *output, struct timespec *when, |
118 | struct wlr_output *wlr_output, struct timespec *when, double base_x, | 178 | struct wlr_surface *surface, double ox, double oy) { |
119 | double base_y, float rotation, float alpha) { | 179 | struct render_data data = { |
120 | double width = surface->surface->current->width; | 180 | .output = output, |
121 | double height = surface->surface->current->height; | 181 | .when = when, |
122 | 182 | .alpha = 1.0f, | |
123 | struct wlr_xdg_popup_v6 *popup_state; | 183 | }; |
124 | wl_list_for_each(popup_state, &surface->popups, link) { | ||
125 | struct wlr_xdg_surface_v6 *popup = popup_state->base; | ||
126 | if (!popup->configured) { | ||
127 | continue; | ||
128 | } | ||
129 | 184 | ||
130 | double popup_width = popup->surface->current->width; | 185 | output_surface_for_each_surface(surface, ox, oy, &data.root_geo, |
131 | double popup_height = popup->surface->current->height; | 186 | render_surface_iterator, &data); |
187 | } | ||
132 | 188 | ||
133 | double popup_sx, popup_sy; | 189 | static void render_view(struct sway_output *output, struct timespec *when, |
134 | wlr_xdg_surface_v6_popup_get_position(popup, &popup_sx, &popup_sy); | 190 | struct sway_view *view) { |
135 | rotate_child_position(&popup_sx, &popup_sy, popup_width, popup_height, | 191 | struct render_data data = { |
136 | width, height, rotation); | 192 | .output = output, |
193 | .when = when, | ||
194 | .alpha = view->swayc->alpha, | ||
195 | }; | ||
137 | 196 | ||
138 | render_surface(popup->surface, wlr_output, when, | 197 | output_view_for_each_surface(view, &data.root_geo, |
139 | base_x + popup_sx, base_y + popup_sy, rotation, alpha); | 198 | render_surface_iterator, &data); |
140 | render_xdg_v6_popups(popup, wlr_output, when, | ||
141 | base_x + popup_sx, base_y + popup_sy, rotation, alpha); | ||
142 | } | ||
143 | } | 199 | } |
144 | 200 | ||
145 | static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, | 201 | static void render_layer(struct sway_output *output, struct timespec *when, |
146 | struct wlr_output *wlr_output, struct timespec *when, | 202 | struct wl_list *layer_surfaces) { |
147 | double lx, double ly, float rotation, float alpha, | 203 | struct sway_layer_surface *layer_surface; |
148 | bool is_child) { | 204 | wl_list_for_each(layer_surface, layer_surfaces, link) { |
149 | if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { | 205 | struct wlr_layer_surface *wlr_layer_surface = |
150 | render_surface(surface->surface, wlr_output, when, | 206 | layer_surface->layer_surface; |
151 | lx, ly, rotation, alpha); | 207 | render_surface(output, when, wlr_layer_surface->surface, |
152 | 208 | layer_surface->geo.x, layer_surface->geo.y); | |
153 | double width = surface->surface->current->width; | ||
154 | double height = surface->surface->current->height; | ||
155 | |||
156 | struct wlr_wl_shell_surface *popup; | ||
157 | wl_list_for_each(popup, &surface->popups, popup_link) { | ||
158 | double popup_width = popup->surface->current->width; | ||
159 | double popup_height = popup->surface->current->height; | ||
160 | |||
161 | double popup_x = popup->transient_state->x; | ||
162 | double popup_y = popup->transient_state->y; | ||
163 | rotate_child_position(&popup_x, &popup_y, popup_width, popup_height, | ||
164 | width, height, rotation); | ||
165 | |||
166 | render_wl_shell_surface(popup, wlr_output, when, | ||
167 | lx + popup_x, ly + popup_y, rotation, alpha, true); | ||
168 | } | ||
169 | } | 209 | } |
170 | } | 210 | } |
171 | 211 | ||
172 | struct render_data { | 212 | struct render_view_data { |
173 | struct sway_output *output; | 213 | struct sway_output *output; |
174 | struct timespec *when; | 214 | struct timespec *when; |
175 | }; | 215 | }; |
176 | 216 | ||
177 | static void render_view(struct sway_container *view, void *data) { | 217 | static void render_view_iterator(struct sway_container *con, void *_data) { |
178 | struct render_data *rdata = data; | 218 | struct render_view_data *data = _data; |
179 | struct sway_output *output = rdata->output; | ||
180 | struct timespec *when = rdata->when; | ||
181 | struct wlr_output *wlr_output = output->wlr_output; | ||
182 | struct sway_view *sway_view = view->sway_view; | ||
183 | struct wlr_surface *surface = sway_view->surface; | ||
184 | float alpha = sway_view->swayc->alpha; | ||
185 | 219 | ||
186 | if (!surface) { | 220 | if (!sway_assert(con->type == C_VIEW, "expected a view")) { |
187 | return; | 221 | return; |
188 | } | 222 | } |
189 | 223 | ||
190 | switch (sway_view->type) { | 224 | render_view(data->output, data->when, con->sway_view); |
191 | case SWAY_VIEW_XDG_SHELL_V6: { | ||
192 | int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x; | ||
193 | int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y; | ||
194 | render_surface(surface, wlr_output, when, | ||
195 | view->x - window_offset_x, view->y - window_offset_y, 0, alpha); | ||
196 | render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output, | ||
197 | when, view->x - window_offset_x, view->y - window_offset_y, 0, alpha); | ||
198 | break; | ||
199 | } | ||
200 | case SWAY_VIEW_WL_SHELL: | ||
201 | render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output, | ||
202 | when, view->x, view->y, 0, alpha, false); | ||
203 | break; | ||
204 | case SWAY_VIEW_XWAYLAND: | ||
205 | render_surface(surface, wlr_output, when, view->x, view->y, 0, alpha); | ||
206 | break; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static void render_layer(struct sway_output *output, struct timespec *when, | ||
211 | struct wl_list *layer) { | ||
212 | struct sway_layer_surface *sway_layer; | ||
213 | wl_list_for_each(sway_layer, layer, link) { | ||
214 | struct wlr_layer_surface *layer = sway_layer->layer_surface; | ||
215 | render_surface(layer->surface, output->wlr_output, when, | ||
216 | sway_layer->geo.x, sway_layer->geo.y, 0, 1.0f); | ||
217 | wlr_surface_send_frame_done(layer->surface, when); | ||
218 | } | ||
219 | } | 225 | } |
220 | 226 | ||
221 | static void render_output(struct sway_output *output, struct timespec *when, | 227 | static void render_output(struct sway_output *output, struct timespec *when, |
222 | pixman_region32_t *damage) { | 228 | pixman_region32_t *damage) { |
223 | struct wlr_output *wlr_output = output->wlr_output; | 229 | struct wlr_output *wlr_output = output->wlr_output; |
230 | |||
224 | struct wlr_renderer *renderer = | 231 | struct wlr_renderer *renderer = |
225 | wlr_backend_get_renderer(wlr_output->backend); | 232 | wlr_backend_get_renderer(wlr_output->backend); |
233 | if (!sway_assert(renderer != NULL, | ||
234 | "expected the output backend to have a renderer")) { | ||
235 | return; | ||
236 | } | ||
226 | 237 | ||
227 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); | 238 | wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); |
228 | 239 | ||
@@ -231,7 +242,7 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
231 | goto renderer_end; | 242 | goto renderer_end; |
232 | } | 243 | } |
233 | 244 | ||
234 | // TODO: don't damage the whole output here | 245 | // TODO: don't damage the whole output |
235 | int width, height; | 246 | int width, height; |
236 | wlr_output_transformed_resolution(wlr_output, &width, &height); | 247 | wlr_output_transformed_resolution(wlr_output, &width, &height); |
237 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); | 248 | pixman_region32_union_rect(damage, damage, 0, 0, width, height); |
@@ -239,16 +250,12 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
239 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; | 250 | float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; |
240 | wlr_renderer_clear(renderer, clear_color); | 251 | wlr_renderer_clear(renderer, clear_color); |
241 | 252 | ||
242 | struct wlr_output_layout *output_layout = | ||
243 | root_container.sway_root->output_layout; | ||
244 | const struct wlr_box *output_box = | ||
245 | wlr_output_layout_get_box(output_layout, wlr_output); | ||
246 | |||
247 | render_layer(output, when, | 253 | render_layer(output, when, |
248 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); | 254 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); |
249 | render_layer(output, when, | 255 | render_layer(output, when, |
250 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); | 256 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); |
251 | 257 | ||
258 | // Render all views in the current workspace | ||
252 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 259 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
253 | struct sway_container *focus = | 260 | struct sway_container *focus = |
254 | seat_get_focus_inactive(seat, output->swayc); | 261 | seat_get_focus_inactive(seat, output->swayc); |
@@ -258,36 +265,21 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
258 | } | 265 | } |
259 | struct sway_container *workspace = focus->type == C_WORKSPACE ? | 266 | struct sway_container *workspace = focus->type == C_WORKSPACE ? |
260 | focus : container_parent(focus, C_WORKSPACE); | 267 | focus : container_parent(focus, C_WORKSPACE); |
268 | struct render_view_data data = { .output = output, .when = when }; | ||
269 | container_descendants(workspace, C_VIEW, render_view_iterator, &data); | ||
261 | 270 | ||
262 | struct render_data rdata = { | 271 | // Render unmanaged views on top |
263 | .output = output, | ||
264 | .when = when, | ||
265 | }; | ||
266 | container_descendants(workspace, C_VIEW, render_view, &rdata); | ||
267 | |||
268 | // render unmanaged views on top | ||
269 | struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged; | 272 | struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged; |
270 | struct sway_xwayland_unmanaged *unmanaged_surface; | 273 | struct sway_xwayland_unmanaged *unmanaged_surface; |
271 | wl_list_for_each(unmanaged_surface, unmanaged, link) { | 274 | wl_list_for_each(unmanaged_surface, unmanaged, link) { |
272 | struct wlr_xwayland_surface *xsurface = | 275 | struct wlr_xwayland_surface *xsurface = |
273 | unmanaged_surface->wlr_xwayland_surface; | 276 | unmanaged_surface->wlr_xwayland_surface; |
274 | 277 | double ox = unmanaged_surface->lx - output->swayc->x; | |
275 | const struct wlr_box view_box = { | 278 | double oy = unmanaged_surface->ly - output->swayc->y; |
276 | .x = unmanaged_surface->lx, | 279 | render_surface(output, when, xsurface->surface, ox, oy); |
277 | .y = unmanaged_surface->ly, | ||
278 | .width = xsurface->width, | ||
279 | .height = xsurface->height, | ||
280 | }; | ||
281 | struct wlr_box intersection; | ||
282 | if (!wlr_box_intersection(&view_box, output_box, &intersection)) { | ||
283 | continue; | ||
284 | } | ||
285 | |||
286 | render_surface(xsurface->surface, wlr_output, &output->last_frame, | ||
287 | view_box.x - output_box->x, view_box.y - output_box->y, 0, 1.0f); | ||
288 | } | 280 | } |
289 | 281 | ||
290 | // TODO: Consider revising this when fullscreen windows are supported | 282 | // TODO: consider revising this when fullscreen windows are supported |
291 | render_layer(output, when, | 283 | render_layer(output, when, |
292 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); | 284 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); |
293 | render_layer(output, when, | 285 | render_layer(output, when, |
@@ -337,22 +329,107 @@ void output_damage_whole(struct sway_output *output) { | |||
337 | wlr_output_damage_add_whole(output->damage); | 329 | wlr_output_damage_add_whole(output->damage); |
338 | } | 330 | } |
339 | 331 | ||
340 | void output_damage_whole_surface(struct sway_output *output, | 332 | struct damage_data { |
341 | double ox, double oy, struct wlr_surface *surface) { | 333 | struct root_geometry root_geo; |
342 | // TODO | 334 | struct sway_output *output; |
343 | output_damage_whole(output); | 335 | bool whole; |
336 | }; | ||
337 | |||
338 | static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, | ||
339 | void *_data) { | ||
340 | struct damage_data *data = _data; | ||
341 | struct sway_output *output = data->output; | ||
342 | float rotation = data->root_geo.rotation; | ||
343 | bool whole = data->whole; | ||
344 | |||
345 | if (!wlr_surface_has_buffer(surface)) { | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | struct wlr_box box; | ||
350 | bool intersects = get_surface_box(&data->root_geo, data->output, surface, | ||
351 | sx, sy, &box); | ||
352 | if (!intersects) { | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | scale_box(&box, output->wlr_output->scale); | ||
357 | |||
358 | if (whole) { | ||
359 | wlr_box_rotated_bounds(&box, rotation, &box); | ||
360 | wlr_output_damage_add_box(output->damage, &box); | ||
361 | } else { | ||
362 | int center_x = box.x + box.width/2; | ||
363 | int center_y = box.y + box.height/2; | ||
364 | |||
365 | pixman_region32_t damage; | ||
366 | pixman_region32_init(&damage); | ||
367 | pixman_region32_copy(&damage, &surface->current->surface_damage); | ||
368 | wlr_region_scale(&damage, &damage, output->wlr_output->scale); | ||
369 | if (ceil(output->wlr_output->scale) > surface->current->scale) { | ||
370 | // When scaling up a surface, it'll become blurry so we need to | ||
371 | // expand the damage region | ||
372 | wlr_region_expand(&damage, &damage, | ||
373 | ceil(output->wlr_output->scale) - surface->current->scale); | ||
374 | } | ||
375 | pixman_region32_translate(&damage, box.x, box.y); | ||
376 | wlr_region_rotated_bounds(&damage, &damage, rotation, | ||
377 | center_x, center_y); | ||
378 | wlr_output_damage_add(output->damage, &damage); | ||
379 | pixman_region32_fini(&damage); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | void output_damage_surface(struct sway_output *output, double ox, double oy, | ||
384 | struct wlr_surface *surface, bool whole) { | ||
385 | struct damage_data data = { | ||
386 | .output = output, | ||
387 | .whole = whole, | ||
388 | }; | ||
389 | |||
390 | output_surface_for_each_surface(surface, ox, oy, &data.root_geo, | ||
391 | damage_surface_iterator, &data); | ||
344 | } | 392 | } |
345 | 393 | ||
346 | void output_damage_whole_view(struct sway_output *output, | 394 | void output_damage_view(struct sway_output *output, struct sway_view *view, |
347 | struct sway_view *view) { | 395 | bool whole) { |
348 | // TODO | 396 | if (!sway_assert(view->swayc != NULL, "expected a view in the tree")) { |
349 | output_damage_whole(output); | 397 | return; |
398 | } | ||
399 | |||
400 | struct damage_data data = { | ||
401 | .output = output, | ||
402 | .whole = whole, | ||
403 | }; | ||
404 | |||
405 | output_view_for_each_surface(view, &data.root_geo, | ||
406 | damage_surface_iterator, &data); | ||
407 | } | ||
408 | |||
409 | static void output_damage_whole_container_iterator(struct sway_container *con, | ||
410 | void *data) { | ||
411 | struct sway_output *output = data; | ||
412 | |||
413 | if (!sway_assert(con->type != C_VIEW, "expected a view")) { | ||
414 | return; | ||
415 | } | ||
416 | |||
417 | output_damage_view(output, con->sway_view, true); | ||
350 | } | 418 | } |
351 | 419 | ||
352 | void output_damage_whole_container(struct sway_output *output, | 420 | void output_damage_whole_container(struct sway_output *output, |
353 | struct sway_container *con) { | 421 | struct sway_container *con) { |
354 | // TODO | 422 | float scale = output->wlr_output->scale; |
355 | output_damage_whole(output); | 423 | struct wlr_box box = { |
424 | .x = con->x * scale, | ||
425 | .y = con->y * scale, | ||
426 | .width = con->width * scale, | ||
427 | .height = con->height * scale, | ||
428 | }; | ||
429 | wlr_output_damage_add_box(output->damage, &box); | ||
430 | |||
431 | container_descendants(con, C_VIEW, output_damage_whole_container_iterator, | ||
432 | output); | ||
356 | } | 433 | } |
357 | 434 | ||
358 | static void damage_handle_destroy(struct wl_listener *listener, void *data) { | 435 | static void damage_handle_destroy(struct wl_listener *listener, void *data) { |
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c index fff31da8..b63c220c 100644 --- a/sway/desktop/wl_shell.c +++ b/sway/desktop/wl_shell.c | |||
@@ -79,7 +79,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
79 | // TODO: Let floating views do whatever | 79 | // TODO: Let floating views do whatever |
80 | view_update_size(view, wl_shell_view->pending_width, | 80 | view_update_size(view, wl_shell_view->pending_width, |
81 | wl_shell_view->pending_height); | 81 | wl_shell_view->pending_height); |
82 | view_damage_from(view); | 82 | view_damage(view, false); |
83 | } | 83 | } |
84 | 84 | ||
85 | static void handle_destroy(struct wl_listener *listener, void *data) { | 85 | static void handle_destroy(struct wl_listener *listener, void *data) { |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 8361aab3..e4703040 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -143,9 +143,7 @@ static void destroy(struct sway_view *view) { | |||
143 | if (xdg_shell_v6_view == NULL) { | 143 | if (xdg_shell_v6_view == NULL) { |
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | wl_list_remove(&xdg_shell_v6_view->commit.link); | ||
147 | wl_list_remove(&xdg_shell_v6_view->destroy.link); | 146 | wl_list_remove(&xdg_shell_v6_view->destroy.link); |
148 | wl_list_remove(&xdg_shell_v6_view->new_popup.link); | ||
149 | wl_list_remove(&xdg_shell_v6_view->map.link); | 147 | wl_list_remove(&xdg_shell_v6_view->map.link); |
150 | wl_list_remove(&xdg_shell_v6_view->unmap.link); | 148 | wl_list_remove(&xdg_shell_v6_view->unmap.link); |
151 | free(xdg_shell_v6_view); | 149 | free(xdg_shell_v6_view); |
@@ -169,7 +167,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
169 | // TODO: Let floating views do whatever | 167 | // TODO: Let floating views do whatever |
170 | view_update_size(view, xdg_shell_v6_view->pending_width, | 168 | view_update_size(view, xdg_shell_v6_view->pending_width, |
171 | xdg_shell_v6_view->pending_height); | 169 | xdg_shell_v6_view->pending_height); |
172 | view_damage_from(view); | 170 | view_damage(view, false); |
173 | } | 171 | } |
174 | 172 | ||
175 | static void handle_new_popup(struct wl_listener *listener, void *data) { | 173 | static void handle_new_popup(struct wl_listener *listener, void *data) { |
@@ -182,14 +180,28 @@ static void handle_new_popup(struct wl_listener *listener, void *data) { | |||
182 | static void handle_unmap(struct wl_listener *listener, void *data) { | 180 | static void handle_unmap(struct wl_listener *listener, void *data) { |
183 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 181 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = |
184 | wl_container_of(listener, xdg_shell_v6_view, unmap); | 182 | wl_container_of(listener, xdg_shell_v6_view, unmap); |
183 | |||
185 | view_unmap(&xdg_shell_v6_view->view); | 184 | view_unmap(&xdg_shell_v6_view->view); |
185 | |||
186 | wl_list_remove(&xdg_shell_v6_view->commit.link); | ||
187 | wl_list_remove(&xdg_shell_v6_view->new_popup.link); | ||
186 | } | 188 | } |
187 | 189 | ||
188 | static void handle_map(struct wl_listener *listener, void *data) { | 190 | static void handle_map(struct wl_listener *listener, void *data) { |
189 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = | 191 | struct sway_xdg_shell_v6_view *xdg_shell_v6_view = |
190 | wl_container_of(listener, xdg_shell_v6_view, map); | 192 | wl_container_of(listener, xdg_shell_v6_view, map); |
191 | struct sway_view *view = &xdg_shell_v6_view->view; | 193 | struct sway_view *view = &xdg_shell_v6_view->view; |
194 | struct wlr_xdg_surface_v6 *xdg_surface = view->wlr_xdg_surface_v6; | ||
195 | |||
192 | view_map(view, view->wlr_xdg_surface_v6->surface); | 196 | view_map(view, view->wlr_xdg_surface_v6->surface); |
197 | |||
198 | xdg_shell_v6_view->commit.notify = handle_commit; | ||
199 | wl_signal_add(&xdg_surface->surface->events.commit, | ||
200 | &xdg_shell_v6_view->commit); | ||
201 | |||
202 | xdg_shell_v6_view->new_popup.notify = handle_new_popup; | ||
203 | wl_signal_add(&xdg_surface->events.new_popup, | ||
204 | &xdg_shell_v6_view->new_popup); | ||
193 | } | 205 | } |
194 | 206 | ||
195 | static void handle_destroy(struct wl_listener *listener, void *data) { | 207 | static void handle_destroy(struct wl_listener *listener, void *data) { |
@@ -226,14 +238,6 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
226 | // - Look up pid and open on appropriate workspace | 238 | // - Look up pid and open on appropriate workspace |
227 | // - Criteria | 239 | // - Criteria |
228 | 240 | ||
229 | xdg_shell_v6_view->commit.notify = handle_commit; | ||
230 | wl_signal_add(&xdg_surface->surface->events.commit, | ||
231 | &xdg_shell_v6_view->commit); | ||
232 | |||
233 | xdg_shell_v6_view->new_popup.notify = handle_new_popup; | ||
234 | wl_signal_add(&xdg_surface->events.new_popup, | ||
235 | &xdg_shell_v6_view->new_popup); | ||
236 | |||
237 | xdg_shell_v6_view->map.notify = handle_map; | 241 | xdg_shell_v6_view->map.notify = handle_map; |
238 | wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); | 242 | wl_signal_add(&xdg_surface->events.map, &xdg_shell_v6_view->map); |
239 | 243 | ||
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 10bfcc89..6de1365d 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -32,15 +32,15 @@ static void unmanaged_handle_commit(struct wl_listener *listener, void *data) { | |||
32 | 32 | ||
33 | if (xsurface->x != surface->lx || xsurface->y != surface->ly) { | 33 | if (xsurface->x != surface->lx || xsurface->y != surface->ly) { |
34 | // Surface has moved | 34 | // Surface has moved |
35 | desktop_damage_whole_surface(xsurface->surface, | 35 | desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, |
36 | surface->lx, surface->ly); | 36 | true); |
37 | surface->lx = xsurface->x; | 37 | surface->lx = xsurface->x; |
38 | surface->ly = xsurface->y; | 38 | surface->ly = xsurface->y; |
39 | desktop_damage_whole_surface(xsurface->surface, | 39 | desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, |
40 | surface->lx, surface->ly); | 40 | true); |
41 | } else { | 41 | } else { |
42 | desktop_damage_from_surface(xsurface->surface, | 42 | desktop_damage_surface(xsurface->surface, xsurface->x, xsurface->y, |
43 | xsurface->x, xsurface->y); | 43 | false); |
44 | } | 44 | } |
45 | } | 45 | } |
46 | 46 | ||
@@ -57,7 +57,7 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { | |||
57 | 57 | ||
58 | surface->lx = xsurface->x; | 58 | surface->lx = xsurface->x; |
59 | surface->ly = xsurface->y; | 59 | surface->ly = xsurface->y; |
60 | desktop_damage_whole_surface(xsurface->surface, surface->lx, surface->ly); | 60 | desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); |
61 | 61 | ||
62 | // TODO: we don't send surface enter/leave events to xwayland unmanaged | 62 | // TODO: we don't send surface enter/leave events to xwayland unmanaged |
63 | // surfaces, but xwayland doesn't support HiDPI anyway | 63 | // surfaces, but xwayland doesn't support HiDPI anyway |
@@ -67,7 +67,7 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { | |||
67 | struct sway_xwayland_unmanaged *surface = | 67 | struct sway_xwayland_unmanaged *surface = |
68 | wl_container_of(listener, surface, unmap); | 68 | wl_container_of(listener, surface, unmap); |
69 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; | 69 | struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; |
70 | desktop_damage_whole_surface(xsurface->surface, xsurface->x, xsurface->y); | 70 | desktop_damage_surface(xsurface->surface, xsurface->x, xsurface->y, true); |
71 | wl_list_remove(&surface->link); | 71 | wl_list_remove(&surface->link); |
72 | wl_list_remove(&surface->commit.link); | 72 | wl_list_remove(&surface->commit.link); |
73 | } | 73 | } |
@@ -209,7 +209,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { | |||
209 | // TODO: Let floating views do whatever | 209 | // TODO: Let floating views do whatever |
210 | view_update_size(view, xwayland_view->pending_width, | 210 | view_update_size(view, xwayland_view->pending_width, |
211 | xwayland_view->pending_height); | 211 | xwayland_view->pending_height); |
212 | view_damage_from(view); | 212 | view_damage(view, false); |
213 | } | 213 | } |
214 | 214 | ||
215 | static void handle_unmap(struct wl_listener *listener, void *data) { | 215 | static void handle_unmap(struct wl_listener *listener, void *data) { |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 9855c5e1..99b44720 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -79,20 +79,15 @@ void view_close(struct sway_view *view) { | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | void view_damage_whole(struct sway_view *view) { | 82 | void view_damage(struct sway_view *view, bool whole) { |
83 | for (int i = 0; i < root_container.children->length; ++i) { | 83 | for (int i = 0; i < root_container.children->length; ++i) { |
84 | struct sway_container *cont = root_container.children->items[i]; | 84 | struct sway_container *cont = root_container.children->items[i]; |
85 | if (cont->type == C_OUTPUT) { | 85 | if (cont->type == C_OUTPUT) { |
86 | output_damage_whole_view(cont->sway_output, view); | 86 | output_damage_view(cont->sway_output, view, whole); |
87 | } | 87 | } |
88 | } | 88 | } |
89 | } | 89 | } |
90 | 90 | ||
91 | void view_damage_from(struct sway_view *view) { | ||
92 | // TODO | ||
93 | view_damage_whole(view); | ||
94 | } | ||
95 | |||
96 | static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) { | 91 | static void view_get_layout_box(struct sway_view *view, struct wlr_box *box) { |
97 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 92 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |
98 | 93 | ||
@@ -191,7 +186,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
191 | arrange_windows(cont->parent, -1, -1); | 186 | arrange_windows(cont->parent, -1, -1); |
192 | input_manager_set_focus(input_manager, cont); | 187 | input_manager_set_focus(input_manager, cont); |
193 | 188 | ||
194 | view_damage_whole(view); | 189 | view_damage(view, true); |
195 | view_handle_container_reparent(&view->container_reparent, NULL); | 190 | view_handle_container_reparent(&view->container_reparent, NULL); |
196 | } | 191 | } |
197 | 192 | ||
@@ -202,7 +197,7 @@ void view_unmap(struct sway_view *view) { | |||
202 | 197 | ||
203 | wl_signal_emit(&view->events.unmap, view); | 198 | wl_signal_emit(&view->events.unmap, view); |
204 | 199 | ||
205 | view_damage_whole(view); | 200 | view_damage(view, true); |
206 | 201 | ||
207 | wl_list_remove(&view->surface_new_subsurface.link); | 202 | wl_list_remove(&view->surface_new_subsurface.link); |
208 | wl_list_remove(&view->container_reparent.link); | 203 | wl_list_remove(&view->container_reparent.link); |
@@ -220,10 +215,10 @@ void view_update_position(struct sway_view *view, double ox, double oy) { | |||
220 | return; | 215 | return; |
221 | } | 216 | } |
222 | 217 | ||
223 | view_damage_whole(view); | 218 | view_damage(view, true); |
224 | view->swayc->x = ox; | 219 | view->swayc->x = ox; |
225 | view->swayc->y = oy; | 220 | view->swayc->y = oy; |
226 | view_damage_whole(view); | 221 | view_damage(view, true); |
227 | } | 222 | } |
228 | 223 | ||
229 | void view_update_size(struct sway_view *view, int width, int height) { | 224 | void view_update_size(struct sway_view *view, int width, int height) { |
@@ -231,10 +226,10 @@ void view_update_size(struct sway_view *view, int width, int height) { | |||
231 | return; | 226 | return; |
232 | } | 227 | } |
233 | 228 | ||
234 | view_damage_whole(view); | 229 | view_damage(view, true); |
235 | view->width = width; | 230 | view->width = width; |
236 | view->height = height; | 231 | view->height = height; |
237 | view_damage_whole(view); | 232 | view_damage(view, true); |
238 | } | 233 | } |
239 | 234 | ||
240 | 235 | ||
@@ -253,7 +248,7 @@ static void view_child_handle_surface_commit(struct wl_listener *listener, | |||
253 | struct sway_view_child *child = | 248 | struct sway_view_child *child = |
254 | wl_container_of(listener, child, surface_commit); | 249 | wl_container_of(listener, child, surface_commit); |
255 | // TODO: only accumulate damage from the child | 250 | // TODO: only accumulate damage from the child |
256 | view_damage_from(child->view); | 251 | view_damage(child->view, false); |
257 | } | 252 | } |
258 | 253 | ||
259 | static void view_child_handle_surface_new_subsurface( | 254 | static void view_child_handle_surface_new_subsurface( |
@@ -315,12 +310,12 @@ void view_child_init(struct sway_view_child *child, | |||
315 | view_init_subsurfaces(child->view, surface); | 310 | view_init_subsurfaces(child->view, surface); |
316 | 311 | ||
317 | // TODO: only damage the whole child | 312 | // TODO: only damage the whole child |
318 | view_damage_whole(child->view); | 313 | view_damage(child->view, true); |
319 | } | 314 | } |
320 | 315 | ||
321 | void view_child_destroy(struct sway_view_child *child) { | 316 | void view_child_destroy(struct sway_view_child *child) { |
322 | // TODO: only damage the whole child | 317 | // TODO: only damage the whole child |
323 | view_damage_whole(child->view); | 318 | view_damage(child->view, true); |
324 | 319 | ||
325 | wl_list_remove(&child->surface_commit.link); | 320 | wl_list_remove(&child->surface_commit.link); |
326 | wl_list_remove(&child->surface_destroy.link); | 321 | wl_list_remove(&child->surface_destroy.link); |