summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-07-25 08:50:06 +0100
committerLibravatar emersion <contact@emersion.fr>2018-07-25 08:55:41 +0100
commit0e79b2114c0bd374c6b4a37fc2ee0e672b8fbb38 (patch)
treed0067d3466d26526bf2531e19e3a5e24532d312b
parentMerge pull request #2342 from RyanDwyer/update-cursor (diff)
downloadsway-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).
-rw-r--r--include/sway/output.h3
-rw-r--r--sway/desktop/output.c26
-rw-r--r--sway/desktop/render.c23
3 files changed, 17 insertions, 35 deletions
diff --git a/include/sway/output.h b/include/sway/output.h
index b6cda83c..c225e541 100644
--- a/include/sway/output.h
+++ b/include/sway/output.h
@@ -65,8 +65,7 @@ struct sway_container *output_by_name(const char *name);
65 65
66void output_enable(struct sway_output *output); 66void output_enable(struct sway_output *output);
67 67
68bool output_has_opaque_lockscreen(struct sway_output *output, 68bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
69 struct sway_seat *seat);
70 69
71struct sway_container *output_get_active_workspace(struct sway_output *output); 70struct sway_container *output_get_active_workspace(struct sway_output *output);
72 71
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
184bool output_has_opaque_lockscreen(struct sway_output *output, 184bool 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
227static void send_frame_done_iterator(struct wlr_surface *surface, 219static 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
281static void send_frame_done(struct sway_output *output, struct timespec *when) { 269static 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
303send_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
889render_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);