aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/output.c52
-rw-r--r--sway/desktop/render.c37
-rw-r--r--sway/desktop/xdg_shell.c9
-rw-r--r--sway/desktop/xdg_shell_v6.c10
4 files changed, 101 insertions, 7 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 31b53213..4c9d978c 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -119,7 +119,7 @@ static void output_for_each_surface_iterator(struct wlr_surface *surface,
119 data->user_data); 119 data->user_data);
120} 120}
121 121
122static void output_surface_for_each_surface(struct sway_output *output, 122void output_surface_for_each_surface(struct sway_output *output,
123 struct wlr_surface *surface, double ox, double oy, 123 struct wlr_surface *surface, double ox, double oy,
124 sway_surface_iterator_func_t iterator, void *user_data) { 124 sway_surface_iterator_func_t iterator, void *user_data) {
125 struct surface_iterator_data data = { 125 struct surface_iterator_data data = {
@@ -155,6 +155,23 @@ void output_view_for_each_surface(struct sway_output *output,
155 output_for_each_surface_iterator, &data); 155 output_for_each_surface_iterator, &data);
156} 156}
157 157
158void output_view_for_each_popup(struct sway_output *output,
159 struct sway_view *view, sway_surface_iterator_func_t iterator,
160 void *user_data) {
161 struct surface_iterator_data data = {
162 .user_iterator = iterator,
163 .user_data = user_data,
164 .output = output,
165 .ox = view->swayc->current.view_x - output->swayc->current.swayc_x,
166 .oy = view->swayc->current.view_y - output->swayc->current.swayc_y,
167 .width = view->swayc->current.view_width,
168 .height = view->swayc->current.view_height,
169 .rotation = 0, // TODO
170 };
171
172 view_for_each_popup(view, output_for_each_surface_iterator, &data);
173}
174
158void output_layer_for_each_surface(struct sway_output *output, 175void output_layer_for_each_surface(struct sway_output *output,
159 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator, 176 struct wl_list *layer_surfaces, sway_surface_iterator_func_t iterator,
160 void *user_data) { 177 void *user_data) {
@@ -295,8 +312,9 @@ static void send_frame_done_container_iterator(struct sway_container *con,
295 return; 312 return;
296 } 313 }
297 314
298 output_view_for_each_surface(data->output, con->sway_view, 315 // Toplevels only
299 send_frame_done_iterator, data->when); 316 output_surface_for_each_surface(data->output, con->sway_view->surface,
317 con->x, con->y, send_frame_done_iterator, data->when);
300} 318}
301 319
302static void send_frame_done_container(struct sway_output *output, 320static void send_frame_done_container(struct sway_output *output,
@@ -309,6 +327,27 @@ static void send_frame_done_container(struct sway_output *output,
309 send_frame_done_container_iterator, &data); 327 send_frame_done_container_iterator, &data);
310} 328}
311 329
330static void send_frame_done_popup_iterator(struct sway_output *output,
331 struct wlr_surface *surface, struct wlr_box *box, float rotation,
332 void *data) {
333 // Send frame done to this popup's surface
334 send_frame_done_iterator(output, surface, box, rotation, data);
335
336 // Send frame done to this popup's child toplevels
337 output_surface_for_each_surface(output, surface, box->x, box->y,
338 send_frame_done_iterator, data);
339}
340
341static void send_frame_done_popups(struct sway_output *output,
342 struct sway_view *view, struct timespec *when) {
343 struct send_frame_done_data data = {
344 .output = output,
345 .when = when,
346 };
347 output_view_for_each_popup(output, view,
348 send_frame_done_popup_iterator, &data);
349}
350
312static void send_frame_done(struct sway_output *output, struct timespec *when) { 351static void send_frame_done(struct sway_output *output, struct timespec *when) {
313 if (output_has_opaque_overlay_layer_surface(output)) { 352 if (output_has_opaque_overlay_layer_surface(output)) {
314 goto send_frame_overlay; 353 goto send_frame_overlay;
@@ -346,6 +385,13 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
346 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when); 385 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], when);
347 } 386 }
348 387
388 struct sway_seat *seat = input_manager_current_seat(input_manager);
389 struct sway_container *focus = seat_get_focus(seat);
390 if (focus && focus->type == C_VIEW) {
391 send_frame_done_popups(output, focus->sway_view, when);
392 }
393
394
349send_frame_overlay: 395send_frame_overlay:
350 send_frame_done_layer(output, 396 send_frame_done_layer(output,
351 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when); 397 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], when);
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index f25055b8..ea4361f2 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -186,13 +186,36 @@ static void premultiply_alpha(float color[4], float opacity) {
186 color[2] *= color[3]; 186 color[2] *= color[3];
187} 187}
188 188
189static void render_view_surfaces(struct sway_view *view, 189static void render_view_toplevels(struct sway_view *view,
190 struct sway_output *output, pixman_region32_t *damage, float alpha) { 190 struct sway_output *output, pixman_region32_t *damage, float alpha) {
191 struct render_data data = { 191 struct render_data data = {
192 .damage = damage, 192 .damage = damage,
193 .alpha = alpha, 193 .alpha = alpha,
194 }; 194 };
195 output_view_for_each_surface(output, view, render_surface_iterator, &data); 195 // Render all toplevels without descending into popups
196 output_surface_for_each_surface(output, view->surface,
197 view->swayc->current.view_x, view->swayc->current.view_y,
198 render_surface_iterator, &data);
199}
200
201static void render_popup_iterator(struct sway_output *output,
202 struct wlr_surface *surface, struct wlr_box *box, float rotation,
203 void *data) {
204 // Render this popup's surface
205 render_surface_iterator(output, surface, box, rotation, data);
206
207 // Render this popup's child toplevels
208 output_surface_for_each_surface(output, surface, box->x, box->y,
209 render_surface_iterator, data);
210}
211
212static void render_view_popups(struct sway_view *view,
213 struct sway_output *output, pixman_region32_t *damage, float alpha) {
214 struct render_data data = {
215 .damage = damage,
216 .alpha = alpha,
217 };
218 output_view_for_each_popup(output, view, render_popup_iterator, &data);
196} 219}
197 220
198static void render_saved_view(struct sway_view *view, 221static void render_saved_view(struct sway_view *view,
@@ -241,7 +264,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
241 if (view->swayc->instructions->length) { 264 if (view->swayc->instructions->length) {
242 render_saved_view(view, output, damage, view->swayc->alpha); 265 render_saved_view(view, output, damage, view->swayc->alpha);
243 } else { 266 } else {
244 render_view_surfaces(view, output, damage, view->swayc->alpha); 267 render_view_toplevels(view, output, damage, view->swayc->alpha);
245 } 268 }
246 269
247 if (view->using_csd) { 270 if (view->using_csd) {
@@ -845,7 +868,7 @@ void output_render(struct sway_output *output, struct timespec *when,
845 render_saved_view(fullscreen_con->sway_view, 868 render_saved_view(fullscreen_con->sway_view,
846 output, damage, 1.0f); 869 output, damage, 1.0f);
847 } else { 870 } else {
848 render_view_surfaces(fullscreen_con->sway_view, 871 render_view_toplevels(fullscreen_con->sway_view,
849 output, damage, 1.0f); 872 output, damage, 1.0f);
850 } 873 }
851 } else { 874 } else {
@@ -881,6 +904,12 @@ void output_render(struct sway_output *output, struct timespec *when,
881 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); 904 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
882 } 905 }
883 906
907 struct sway_seat *seat = input_manager_current_seat(input_manager);
908 struct sway_container *focus = seat_get_focus(seat);
909 if (focus && focus->type == C_VIEW) {
910 render_view_popups(focus->sway_view, output, damage, focus->alpha);
911 }
912
884render_overlay: 913render_overlay:
885 render_layer(output, damage, 914 render_layer(output, damage,
886 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); 915 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index e6e1527e..9f94bd74 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -179,6 +179,14 @@ static void for_each_surface(struct sway_view *view,
179 user_data); 179 user_data);
180} 180}
181 181
182static void for_each_popup(struct sway_view *view,
183 wlr_surface_iterator_func_t iterator, void *user_data) {
184 if (xdg_shell_view_from_view(view) == NULL) {
185 return;
186 }
187 wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data);
188}
189
182static void _close(struct sway_view *view) { 190static void _close(struct sway_view *view) {
183 if (xdg_shell_view_from_view(view) == NULL) { 191 if (xdg_shell_view_from_view(view) == NULL) {
184 return; 192 return;
@@ -207,6 +215,7 @@ static const struct sway_view_impl view_impl = {
207 .set_fullscreen = set_fullscreen, 215 .set_fullscreen = set_fullscreen,
208 .wants_floating = wants_floating, 216 .wants_floating = wants_floating,
209 .for_each_surface = for_each_surface, 217 .for_each_surface = for_each_surface,
218 .for_each_popup = for_each_popup,
210 .close = _close, 219 .close = _close,
211 .destroy = destroy, 220 .destroy = destroy,
212}; 221};
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 5feee3e4..4502c386 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -175,6 +175,15 @@ static void for_each_surface(struct sway_view *view,
175 user_data); 175 user_data);
176} 176}
177 177
178static void for_each_popup(struct sway_view *view,
179 wlr_surface_iterator_func_t iterator, void *user_data) {
180 if (xdg_shell_v6_view_from_view(view) == NULL) {
181 return;
182 }
183 wlr_xdg_surface_v6_for_each_popup(view->wlr_xdg_surface_v6, iterator,
184 user_data);
185}
186
178static void _close(struct sway_view *view) { 187static void _close(struct sway_view *view) {
179 if (xdg_shell_v6_view_from_view(view) == NULL) { 188 if (xdg_shell_v6_view_from_view(view) == NULL) {
180 return; 189 return;
@@ -203,6 +212,7 @@ static const struct sway_view_impl view_impl = {
203 .set_fullscreen = set_fullscreen, 212 .set_fullscreen = set_fullscreen,
204 .wants_floating = wants_floating, 213 .wants_floating = wants_floating,
205 .for_each_surface = for_each_surface, 214 .for_each_surface = for_each_surface,
215 .for_each_popup = for_each_popup,
206 .close = _close, 216 .close = _close,
207 .destroy = destroy, 217 .destroy = destroy,
208}; 218};