aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/output.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-07-30 13:12:22 -0400
committerLibravatar GitHub <noreply@github.com>2018-07-30 13:12:22 -0400
commitcbd0c3ec40d76bbdc91f5f60d59d1b5b0f2da6b3 (patch)
tree9b4e713d28cffdd69c99ab2f3a2347ef8c52979b /sway/desktop/output.c
parentMerge pull request #2387 from 1ace/feature/bash-completion (diff)
parentMake output_surface_for_each_surface_iterator static (diff)
downloadsway-cbd0c3ec40d76bbdc91f5f60d59d1b5b0f2da6b3.tar.gz
sway-cbd0c3ec40d76bbdc91f5f60d59d1b5b0f2da6b3.tar.zst
sway-cbd0c3ec40d76bbdc91f5f60d59d1b5b0f2da6b3.zip
Merge pull request #2367 from emersion/iterator-redesign
Refactor surface iterators
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r--sway/desktop/output.c266
1 files changed, 139 insertions, 127 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index fb52e7b1..6b2eb0c2 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -57,9 +57,21 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh,
57 *sy = ry + ph/2 - sh/2; 57 *sy = ry + ph/2 - sh/2;
58} 58}
59 59
60bool output_get_surface_box(struct root_geometry *geo, 60struct surface_iterator_data {
61 struct sway_output *output, struct wlr_surface *surface, int sx, int sy, 61 sway_surface_iterator_func_t user_iterator;
62 void *user_data;
63
64 struct sway_output *output;
65 double ox, oy;
66 int width, height;
67 float rotation;
68};
69
70static bool get_surface_box(struct surface_iterator_data *data,
71 struct wlr_surface *surface, int sx, int sy,
62 struct wlr_box *surface_box) { 72 struct wlr_box *surface_box) {
73 struct sway_output *output = data->output;
74
63 if (!wlr_surface_has_buffer(surface)) { 75 if (!wlr_surface_has_buffer(surface)) {
64 return false; 76 return false;
65 } 77 }
@@ -68,12 +80,12 @@ bool output_get_surface_box(struct root_geometry *geo,
68 int sh = surface->current.height; 80 int sh = surface->current.height;
69 81
70 double _sx = sx, _sy = sy; 82 double _sx = sx, _sy = sy;
71 rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, 83 rotate_child_position(&_sx, &_sy, sw, sh, data->width, data->height,
72 geo->rotation); 84 data->rotation);
73 85
74 struct wlr_box box = { 86 struct wlr_box box = {
75 .x = geo->x + _sx, 87 .x = data->ox + _sx,
76 .y = geo->y + _sy, 88 .y = data->oy + _sy,
77 .width = sw, 89 .width = sw,
78 .height = sh, 90 .height = sh,
79 }; 91 };
@@ -82,7 +94,7 @@ bool output_get_surface_box(struct root_geometry *geo,
82 } 94 }
83 95
84 struct wlr_box rotated_box; 96 struct wlr_box rotated_box;
85 wlr_box_rotated_bounds(&box, geo->rotation, &rotated_box); 97 wlr_box_rotated_bounds(&box, data->rotation, &rotated_box);
86 98
87 struct wlr_box output_box = { 99 struct wlr_box output_box = {
88 .width = output->swayc->current.swayc_width, 100 .width = output->swayc->current.swayc_width,
@@ -93,46 +105,73 @@ bool output_get_surface_box(struct root_geometry *geo,
93 return wlr_box_intersection(&output_box, &rotated_box, &intersection); 105 return wlr_box_intersection(&output_box, &rotated_box, &intersection);
94} 106}
95 107
96void output_surface_for_each_surface(struct wlr_surface *surface, 108static void output_for_each_surface_iterator(struct wlr_surface *surface,
97 double ox, double oy, struct root_geometry *geo, 109 int sx, int sy, void *_data) {
98 wlr_surface_iterator_func_t iterator, void *user_data) { 110 struct surface_iterator_data *data = _data;
99 geo->x = ox;
100 geo->y = oy;
101 geo->width = surface->current.width;
102 geo->height = surface->current.height;
103 geo->rotation = 0;
104 111
105 wlr_surface_for_each_surface(surface, iterator, user_data); 112 struct wlr_box box;
113 bool intersects = get_surface_box(data, surface, sx, sy, &box);
114 if (!intersects) {
115 return;
116 }
117
118 data->user_iterator(data->output, surface, &box, data->rotation,
119 data->user_data);
106} 120}
107 121
108void output_view_for_each_surface(struct sway_view *view, 122static void output_surface_for_each_surface(struct sway_output *output,
109 struct sway_output *output, struct root_geometry *geo, 123 struct wlr_surface *surface, double ox, double oy,
110 wlr_surface_iterator_func_t iterator, void *user_data) { 124 sway_surface_iterator_func_t iterator, void *user_data) {
111 geo->x = view->swayc->current.view_x - output->swayc->current.swayc_x; 125 struct surface_iterator_data data = {
112 geo->y = view->swayc->current.view_y - output->swayc->current.swayc_y; 126 .user_iterator = iterator,
113 geo->width = view->swayc->current.view_width; 127 .user_data = user_data,
114 geo->height = view->swayc->current.view_height; 128 .output = output,
115 geo->rotation = 0; // TODO 129 .ox = ox,
130 .oy = oy,
131 .width = surface->current.width,
132 .height = surface->current.height,
133 .rotation = 0,
134 };
116 135
117 view_for_each_surface(view, iterator, user_data); 136 wlr_surface_for_each_surface(surface,
137 output_for_each_surface_iterator, &data);
118} 138}
119 139
120void output_layer_for_each_surface(struct wl_list *layer_surfaces, 140void output_view_for_each_surface(struct sway_output *output,
121 struct root_geometry *geo, wlr_surface_iterator_func_t iterator, 141 struct sway_view *view, sway_surface_iterator_func_t iterator,
142 void *user_data) {
143 struct surface_iterator_data data = {
144 .user_iterator = iterator,
145 .user_data = user_data,
146 .output = output,
147 .ox = view->swayc->current.view_x - output->swayc->current.swayc_x,
148 .oy = view->swayc->current.view_y - output->swayc->current.swayc_y,
149 .width = view->swayc->current.view_width,
150 .height = view->swayc->current.view_height,
151 .rotation = 0, // TODO
152 };
153
154 view_for_each_surface(view,
155 output_for_each_surface_iterator, &data);
156}
157
158void output_layer_for_each_surface(struct sway_output *output,
159 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
122 void *user_data) { 160 void *user_data) {
123 struct sway_layer_surface *layer_surface; 161 struct sway_layer_surface *layer_surface;
124 wl_list_for_each(layer_surface, layer_surfaces, link) { 162 wl_list_for_each(layer_surface, layer_surfaces, link) {
125 struct wlr_layer_surface *wlr_layer_surface = 163 struct wlr_layer_surface *wlr_layer_surface =
126 layer_surface->layer_surface; 164 layer_surface->layer_surface;
127 output_surface_for_each_surface(wlr_layer_surface->surface, 165 output_surface_for_each_surface(output, wlr_layer_surface->surface,
128 layer_surface->geo.x, layer_surface->geo.y, geo, iterator, 166 layer_surface->geo.x, layer_surface->geo.y, iterator,
129 user_data); 167 user_data);
130 } 168 }
131} 169}
170
132#ifdef HAVE_XWAYLAND 171#ifdef HAVE_XWAYLAND
133void output_unmanaged_for_each_surface(struct wl_list *unmanaged, 172void output_unmanaged_for_each_surface(struct sway_output *output,
134 struct sway_output *output, struct root_geometry *geo, 173 struct wl_list *unmanaged, sway_surface_iterator_func_t iterator,
135 wlr_surface_iterator_func_t iterator, void *user_data) { 174 void *user_data) {
136 struct sway_xwayland_unmanaged *unmanaged_surface; 175 struct sway_xwayland_unmanaged *unmanaged_surface;
137 wl_list_for_each(unmanaged_surface, unmanaged, link) { 176 wl_list_for_each(unmanaged_surface, unmanaged, link) {
138 struct wlr_xwayland_surface *xsurface = 177 struct wlr_xwayland_surface *xsurface =
@@ -140,22 +179,24 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged,
140 double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; 179 double ox = unmanaged_surface->lx - output->swayc->current.swayc_x;
141 double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; 180 double oy = unmanaged_surface->ly - output->swayc->current.swayc_y;
142 181
143 output_surface_for_each_surface(xsurface->surface, ox, oy, geo, 182 output_surface_for_each_surface(output, xsurface->surface, ox, oy,
144 iterator, user_data); 183 iterator, user_data);
145 } 184 }
146} 185}
147#endif 186#endif
148void output_drag_icons_for_each_surface(struct wl_list *drag_icons, 187
149 struct sway_output *output, struct root_geometry *geo, 188void output_drag_icons_for_each_surface(struct sway_output *output,
150 wlr_surface_iterator_func_t iterator, void *user_data) { 189 struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
190 void *user_data) {
151 struct sway_drag_icon *drag_icon; 191 struct sway_drag_icon *drag_icon;
152 wl_list_for_each(drag_icon, drag_icons, link) { 192 wl_list_for_each(drag_icon, drag_icons, link) {
153 double ox = drag_icon->x - output->swayc->x; 193 double ox = drag_icon->x - output->swayc->x;
154 double oy = drag_icon->y - output->swayc->y; 194 double oy = drag_icon->y - output->swayc->y;
155 195
156 if (drag_icon->wlr_drag_icon->mapped) { 196 if (drag_icon->wlr_drag_icon->mapped) {
157 output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, 197 output_surface_for_each_surface(output,
158 ox, oy, geo, iterator, user_data); 198 drag_icon->wlr_drag_icon->surface, ox, oy,
199 iterator, user_data);
159 } 200 }
160 } 201 }
161} 202}
@@ -211,41 +252,38 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output) {
211 return false; 252 return false;
212} 253}
213 254
214struct send_frame_done_data { 255static void send_frame_done_iterator(struct sway_output *output,
215 struct root_geometry root_geo; 256 struct wlr_surface *surface, struct wlr_box *box, float rotation,
216 struct sway_output *output; 257 void *_data) {
217 struct timespec *when; 258 struct timespec *when = _data;
218}; 259 wlr_surface_send_frame_done(surface, when);
219
220static void send_frame_done_iterator(struct wlr_surface *surface,
221 int sx, int sy, void *_data) {
222 struct send_frame_done_data *data = _data;
223
224 bool intersects = output_get_surface_box(&data->root_geo, data->output, surface,
225 sx, sy, NULL);
226 if (intersects) {
227 wlr_surface_send_frame_done(surface, data->when);
228 }
229} 260}
230 261
231static void send_frame_done_layer(struct send_frame_done_data *data, 262static void send_frame_done_layer(struct sway_output *output,
232 struct wl_list *layer_surfaces) { 263 struct wl_list *layer_surfaces, struct timespec *when) {
233 output_layer_for_each_surface(layer_surfaces, &data->root_geo, 264 output_layer_for_each_surface(output, layer_surfaces,
234 send_frame_done_iterator, data); 265 send_frame_done_iterator, when);
235} 266}
267
236#ifdef HAVE_XWAYLAND 268#ifdef HAVE_XWAYLAND
237static void send_frame_done_unmanaged(struct send_frame_done_data *data, 269static void send_frame_done_unmanaged(struct sway_output *output,
238 struct wl_list *unmanaged) { 270 struct wl_list *unmanaged, struct timespec *when) {
239 output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, 271 output_unmanaged_for_each_surface(output, unmanaged,
240 send_frame_done_iterator, data); 272 send_frame_done_iterator, when);
241} 273}
242#endif 274#endif
243static void send_frame_done_drag_icons(struct send_frame_done_data *data, 275
244 struct wl_list *drag_icons) { 276static void send_frame_done_drag_icons(struct sway_output *output,
245 output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, 277 struct wl_list *drag_icons, struct timespec *when) {
246 send_frame_done_iterator, data); 278 output_drag_icons_for_each_surface(output, drag_icons,
279 send_frame_done_iterator, when);
247} 280}
248 281
282struct send_frame_done_data {
283 struct sway_output *output;
284 struct timespec *when;
285};
286
249static void send_frame_done_container_iterator(struct sway_container *con, 287static void send_frame_done_container_iterator(struct sway_container *con,
250 void *_data) { 288 void *_data) {
251 struct send_frame_done_data *data = _data; 289 struct send_frame_done_data *data = _data;
@@ -257,22 +295,21 @@ static void send_frame_done_container_iterator(struct sway_container *con,
257 return; 295 return;
258 } 296 }
259 297
260 output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, 298 output_view_for_each_surface(data->output, con->sway_view,
261 send_frame_done_iterator, data); 299 send_frame_done_iterator, data->when);
262} 300}
263 301
264static void send_frame_done_container(struct send_frame_done_data *data, 302static void send_frame_done_container(struct sway_output *output,
265 struct sway_container *con) { 303 struct sway_container *con, struct timespec *when) {
266 container_descendants(con, C_VIEW,
267 send_frame_done_container_iterator, data);
268}
269
270static void send_frame_done(struct sway_output *output, struct timespec *when) {
271 struct send_frame_done_data data = { 304 struct send_frame_done_data data = {
272 .output = output, 305 .output = output,
273 .when = when, 306 .when = when,
274 }; 307 };
308 container_descendants(con, C_VIEW,
309 send_frame_done_container_iterator, &data);
310}
275 311
312static void send_frame_done(struct sway_output *output, struct timespec *when) {
276 if (output_has_opaque_overlay_layer_surface(output)) { 313 if (output_has_opaque_overlay_layer_surface(output)) {
277 goto send_frame_overlay; 314 goto send_frame_overlay;
278 } 315 }
@@ -281,35 +318,38 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
281 if (workspace->current.ws_fullscreen) { 318 if (workspace->current.ws_fullscreen) {
282 if (workspace->current.ws_fullscreen->type == C_VIEW) { 319 if (workspace->current.ws_fullscreen->type == C_VIEW) {
283 send_frame_done_container_iterator( 320 send_frame_done_container_iterator(
284 workspace->current.ws_fullscreen, &data); 321 workspace->current.ws_fullscreen, when);
285 } else { 322 } else {
286 send_frame_done_container(&data, workspace->current.ws_fullscreen); 323 send_frame_done_container(output, workspace->current.ws_fullscreen,
324 when);
287 } 325 }
288#ifdef HAVE_XWAYLAND 326#ifdef HAVE_XWAYLAND
289 send_frame_done_unmanaged(&data, 327 send_frame_done_unmanaged(output,
290 &root_container.sway_root->xwayland_unmanaged); 328 &root_container.sway_root->xwayland_unmanaged, when);
291#endif 329#endif
292 } else { 330 } else {
293 send_frame_done_layer(&data, 331 send_frame_done_layer(output,
294 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); 332 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], when);
295 send_frame_done_layer(&data, 333 send_frame_done_layer(output,
296 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 334 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], when);
297 335
298 send_frame_done_container(&data, workspace); 336 send_frame_done_container(output, workspace, when);
299 send_frame_done_container(&data, workspace->sway_workspace->floating); 337 send_frame_done_container(output, workspace->sway_workspace->floating,
338 when);
300 339
301#ifdef HAVE_XWAYLAND 340#ifdef HAVE_XWAYLAND
302 send_frame_done_unmanaged(&data, 341 send_frame_done_unmanaged(output,
303 &root_container.sway_root->xwayland_unmanaged); 342 &root_container.sway_root->xwayland_unmanaged, when);
304#endif 343#endif
305 send_frame_done_layer(&data, 344 send_frame_done_layer(output,
306 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 345 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when);
307 } 346 }
308 347
309send_frame_overlay: 348send_frame_overlay:
310 send_frame_done_layer(&data, 349 send_frame_done_layer(output,
311 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 350 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when);
312 send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); 351 send_frame_done_drag_icons(output, &root_container.sway_root->drag_icons,
352 when);
313} 353}
314 354
315static void damage_handle_frame(struct wl_listener *listener, void *data) { 355static void damage_handle_frame(struct wl_listener *listener, void *data) {
@@ -344,26 +384,13 @@ void output_damage_whole(struct sway_output *output) {
344 wlr_output_damage_add_whole(output->damage); 384 wlr_output_damage_add_whole(output->damage);
345} 385}
346 386
347struct damage_data { 387static void damage_surface_iterator(struct sway_output *output,
348 struct root_geometry root_geo; 388 struct wlr_surface *surface, struct wlr_box *_box, float rotation,
349 struct sway_output *output;
350 bool whole;
351};
352
353static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy,
354 void *_data) { 389 void *_data) {
355 struct damage_data *data = _data; 390 bool *data = _data;
356 struct sway_output *output = data->output; 391 bool whole = *data;
357 float rotation = data->root_geo.rotation;
358 bool whole = data->whole;
359
360 struct wlr_box box;
361 bool intersects = output_get_surface_box(&data->root_geo, data->output, surface,
362 sx, sy, &box);
363 if (!intersects) {
364 return;
365 }
366 392
393 struct wlr_box box = *_box;
367 scale_box(&box, output->wlr_output->scale); 394 scale_box(&box, output->wlr_output->scale);
368 395
369 int center_x = box.x + box.width/2; 396 int center_x = box.x + box.width/2;
@@ -403,13 +430,8 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy,
403 430
404void output_damage_surface(struct sway_output *output, double ox, double oy, 431void output_damage_surface(struct sway_output *output, double ox, double oy,
405 struct wlr_surface *surface, bool whole) { 432 struct wlr_surface *surface, bool whole) {
406 struct damage_data data = { 433 output_surface_for_each_surface(output, surface, ox, oy,
407 .output = output, 434 damage_surface_iterator, &whole);
408 .whole = whole,
409 };
410
411 output_surface_for_each_surface(surface, ox, oy, &data.root_geo,
412 damage_surface_iterator, &data);
413} 435}
414 436
415static void output_damage_view(struct sway_output *output, 437static void output_damage_view(struct sway_output *output,
@@ -422,13 +444,7 @@ static void output_damage_view(struct sway_output *output,
422 return; 444 return;
423 } 445 }
424 446
425 struct damage_data data = { 447 output_view_for_each_surface(output, view, damage_surface_iterator, &whole);
426 .output = output,
427 .whole = whole,
428 };
429
430 output_view_for_each_surface(view, output, &data.root_geo,
431 damage_surface_iterator, &data);
432} 448}
433 449
434void output_damage_from_view(struct sway_output *output, 450void output_damage_from_view(struct sway_output *output,
@@ -514,10 +530,6 @@ static void handle_scale(struct wl_listener *listener, void *data) {
514 transaction_commit_dirty(); 530 transaction_commit_dirty();
515} 531}
516 532
517struct sway_output *output_from_wlr_output(struct wlr_output *wlr_output) {
518 return wlr_output->data;
519}
520
521void handle_new_output(struct wl_listener *listener, void *data) { 533void handle_new_output(struct wl_listener *listener, void *data) {
522 struct sway_server *server = wl_container_of(listener, server, new_output); 534 struct sway_server *server = wl_container_of(listener, server, new_output);
523 struct wlr_output *wlr_output = data; 535 struct wlr_output *wlr_output = data;