diff options
author | 2018-07-25 08:50:06 +0100 | |
---|---|---|
committer | 2018-07-25 08:55:41 +0100 | |
commit | 0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38 (patch) | |
tree | d0067d3466d26526bf2531e19e3a5e24532d312b /sway | |
parent | Merge pull request #2342 from RyanDwyer/update-cursor (diff) | |
download | sway-0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38.tar.gz sway-0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38.tar.zst sway-0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38.zip |
Improve rendering with a fullscreen opaque overlay surface
The rendering code doesn't use the exclusive input surface at all
anymore to decide to skip rendering of shell surfaces. This fixes
a weird situation in which a client requests exclusive input but
isn't an overlay layer surface.
The renderer also renders all overlay surfaces in this situation,
not just one. This simplifies the code and fixes rendering when
there are more than one overlay surfaces (e.g. for a virtual
keyboard to type the lockscreen password).
Diffstat (limited to 'sway')
-rw-r--r-- | sway/desktop/output.c | 26 | ||||
-rw-r--r-- | sway/desktop/render.c | 23 |
2 files changed, 16 insertions, 33 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a206ac6b..cbd6ef86 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -181,21 +181,14 @@ struct sway_container *output_get_active_workspace(struct sway_output *output) { | |||
181 | return workspace; | 181 | return workspace; |
182 | } | 182 | } |
183 | 183 | ||
184 | bool output_has_opaque_lockscreen(struct sway_output *output, | 184 | bool output_has_opaque_overlay_layer_surface(struct sway_output *output) { |
185 | struct sway_seat *seat) { | ||
186 | if (!seat->exclusive_client) { | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | struct wlr_layer_surface *wlr_layer_surface; | 185 | struct wlr_layer_surface *wlr_layer_surface; |
191 | wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { | 186 | wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { |
192 | if (wlr_layer_surface->output != output->wlr_output) { | 187 | if (wlr_layer_surface->output != output->wlr_output || |
188 | wlr_layer_surface->layer != ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) { | ||
193 | continue; | 189 | continue; |
194 | } | 190 | } |
195 | struct wlr_surface *wlr_surface = wlr_layer_surface->surface; | 191 | struct wlr_surface *wlr_surface = wlr_layer_surface->surface; |
196 | if (wlr_surface->resource->client != seat->exclusive_client) { | ||
197 | continue; | ||
198 | } | ||
199 | struct sway_layer_surface *sway_layer_surface = | 192 | struct sway_layer_surface *sway_layer_surface = |
200 | layer_from_wlr_layer_surface(wlr_layer_surface); | 193 | layer_from_wlr_layer_surface(wlr_layer_surface); |
201 | pixman_box32_t output_box = { | 194 | pixman_box32_t output_box = { |
@@ -221,16 +214,11 @@ struct send_frame_done_data { | |||
221 | struct root_geometry root_geo; | 214 | struct root_geometry root_geo; |
222 | struct sway_output *output; | 215 | struct sway_output *output; |
223 | struct timespec *when; | 216 | struct timespec *when; |
224 | struct wl_client *exclusive_client; | ||
225 | }; | 217 | }; |
226 | 218 | ||
227 | static void send_frame_done_iterator(struct wlr_surface *surface, | 219 | static void send_frame_done_iterator(struct wlr_surface *surface, |
228 | int sx, int sy, void *_data) { | 220 | int sx, int sy, void *_data) { |
229 | struct send_frame_done_data *data = _data; | 221 | struct send_frame_done_data *data = _data; |
230 | if (data->exclusive_client && | ||
231 | data->exclusive_client != surface->resource->client) { | ||
232 | return; | ||
233 | } | ||
234 | 222 | ||
235 | bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, | 223 | bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, |
236 | sx, sy, NULL); | 224 | sx, sy, NULL); |
@@ -279,14 +267,15 @@ static void send_frame_done_container(struct send_frame_done_data *data, | |||
279 | } | 267 | } |
280 | 268 | ||
281 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 269 | static void send_frame_done(struct sway_output *output, struct timespec *when) { |
282 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
283 | struct send_frame_done_data data = { | 270 | struct send_frame_done_data data = { |
284 | .output = output, | 271 | .output = output, |
285 | .when = when, | 272 | .when = when, |
286 | .exclusive_client = output_has_opaque_lockscreen(output, seat) ? | ||
287 | seat->exclusive_client : NULL, | ||
288 | }; | 273 | }; |
289 | 274 | ||
275 | if (output_has_opaque_overlay_layer_surface(output)) { | ||
276 | goto send_frame_overlay; | ||
277 | } | ||
278 | |||
290 | struct sway_container *workspace = output_get_active_workspace(output); | 279 | struct sway_container *workspace = output_get_active_workspace(output); |
291 | if (workspace->current.ws_fullscreen) { | 280 | if (workspace->current.ws_fullscreen) { |
292 | send_frame_done_container_iterator( | 281 | send_frame_done_container_iterator( |
@@ -311,6 +300,7 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
311 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); | 300 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); |
312 | } | 301 | } |
313 | 302 | ||
303 | send_frame_overlay: | ||
314 | send_frame_done_layer(&data, | 304 | send_frame_done_layer(&data, |
315 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); | 305 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); |
316 | send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); | 306 | send_frame_done_drag_icons(&data, &root_container.sway_root->drag_icons); |
diff --git a/sway/desktop/render.c b/sway/desktop/render.c index 7da54594..d6c3fa8c 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c | |||
@@ -836,21 +836,12 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
836 | 836 | ||
837 | struct sway_container *workspace = output_get_active_workspace(output); | 837 | struct sway_container *workspace = output_get_active_workspace(output); |
838 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; | 838 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; |
839 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 839 | |
840 | 840 | if (output_has_opaque_overlay_layer_surface(output)) { | |
841 | if (output_has_opaque_lockscreen(output, seat) && seat->focused_layer) { | 841 | goto render_overlay; |
842 | struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; | 842 | } |
843 | struct sway_layer_surface *sway_layer_surface = | 843 | |
844 | layer_from_wlr_layer_surface(seat->focused_layer); | 844 | if (fullscreen_view) { |
845 | struct render_data data = { | ||
846 | .output = output, | ||
847 | .damage = damage, | ||
848 | .alpha = 1.0f, | ||
849 | }; | ||
850 | output_surface_for_each_surface(wlr_layer_surface->surface, | ||
851 | sway_layer_surface->geo.x, sway_layer_surface->geo.y, | ||
852 | &data.root_geo, render_surface_iterator, &data); | ||
853 | } else if (fullscreen_view) { | ||
854 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 845 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
855 | 846 | ||
856 | int nrects; | 847 | int nrects; |
@@ -894,6 +885,8 @@ void output_render(struct sway_output *output, struct timespec *when, | |||
894 | render_layer(output, damage, | 885 | render_layer(output, damage, |
895 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); | 886 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); |
896 | } | 887 | } |
888 | |||
889 | render_overlay: | ||
897 | render_layer(output, damage, | 890 | render_layer(output, damage, |
898 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); | 891 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); |
899 | render_drag_icons(output, damage, &root_container.sway_root->drag_icons); | 892 | render_drag_icons(output, damage, &root_container.sway_root->drag_icons); |