From 58befcf2cdf261b8898b6fd1288a69d367101ff1 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 1 Jul 2018 10:58:13 +1000 Subject: Don't send frame done to surfaces behind lockscreen Also, when rendering, don't descend into the tree if the lockscreen is active. Just render the lockscreen's surfaces. --- sway/desktop/output.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 1211cc07..52bd1666 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -948,8 +948,30 @@ static void render_output(struct sway_output *output, struct timespec *when, struct sway_container *workspace = output_get_active_workspace(output); struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; + struct sway_seat *seat = input_manager_current_seat(input_manager); + + if (seat->exclusive_client && seat->focused_layer) { + float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; + + int nrects; + pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); + for (int i = 0; i < nrects; ++i) { + scissor_output(wlr_output, &rects[i]); + wlr_renderer_clear(renderer, clear_color); + } - if (fullscreen_view) { + struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; + struct sway_layer_surface *sway_layer_surface = + layer_from_wlr_layer_surface(seat->focused_layer); + struct render_data data = { + .output = output, + .damage = damage, + .alpha = 1.0f, + }; + surface_for_each_surface(wlr_layer_surface->surface, + sway_layer_surface->geo.x, sway_layer_surface->geo.y, + &data.root_geo, render_surface_iterator, &data); + } else if (fullscreen_view) { float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; int nrects; @@ -1019,11 +1041,16 @@ struct send_frame_done_data { struct root_geometry root_geo; struct sway_output *output; struct timespec *when; + struct wl_client *exclusive_client; }; static void send_frame_done_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct send_frame_done_data *data = _data; + if (data->exclusive_client && + data->exclusive_client != surface->resource->client) { + return; + } bool intersects = get_surface_box(&data->root_geo, data->output, surface, sx, sy, NULL); @@ -1072,9 +1099,11 @@ static void send_frame_done_container(struct send_frame_done_data *data, } static void send_frame_done(struct sway_output *output, struct timespec *when) { + struct sway_seat *seat = input_manager_current_seat(input_manager); struct send_frame_done_data data = { .output = output, .when = when, + .exclusive_client = seat->exclusive_client, }; struct sway_container *workspace = output_get_active_workspace(output); -- cgit v1.2.3 From 839c3a550043fd38096a15ff8dcd7de1a084efdc Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 3 Jul 2018 17:29:23 +1000 Subject: Use opaque region to determine if frame done should be sent --- sway/desktop/output.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 52bd1666..a6b2ebc2 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -915,6 +915,36 @@ static struct sway_container *output_get_active_workspace( return workspace; } +bool output_has_opaque_lockscreen(struct sway_output *output, + struct sway_seat *seat) { + if (!seat->exclusive_client) { + return false; + } + + struct wlr_layer_surface *wlr_layer_surface; + wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { + if (wlr_layer_surface->output != output->wlr_output) { + continue; + } + struct wlr_surface *wlr_surface = wlr_layer_surface->surface; + if (wlr_surface->resource->client != seat->exclusive_client) { + continue; + } + int nrects; + pixman_box32_t *rects = + pixman_region32_rectangles(&wlr_surface->current->opaque, &nrects); + for (int i = 0; i < nrects; ++i) { + pixman_box32_t *rect = &rects[i]; + if (rect->x1 <= 0 && rect->y1 <= 0 && + rect->x2 >= output->swayc->current.swayc_width && + rect->y2 >= output->swayc->current.swayc_height) { + return true; + } + } + } + return false; +} + static void render_output(struct sway_output *output, struct timespec *when, pixman_region32_t *damage) { struct wlr_output *wlr_output = output->wlr_output; @@ -950,7 +980,7 @@ static void render_output(struct sway_output *output, struct timespec *when, struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; struct sway_seat *seat = input_manager_current_seat(input_manager); - if (seat->exclusive_client && seat->focused_layer) { + if (output_has_opaque_lockscreen(output, seat)) { float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; int nrects; @@ -1103,7 +1133,8 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { struct send_frame_done_data data = { .output = output, .when = when, - .exclusive_client = seat->exclusive_client, + .exclusive_client = output_has_opaque_lockscreen(output, seat) ? + seat->exclusive_client : NULL, }; struct sway_container *workspace = output_get_active_workspace(output); -- cgit v1.2.3 From f1fadef923ef8b1278bf2e380ab639f32c0cf79b Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 3 Jul 2018 18:14:46 +1000 Subject: Use pixman_region32_contains_rectangle --- sway/desktop/output.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a6b2ebc2..fa85d260 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -930,16 +930,13 @@ bool output_has_opaque_lockscreen(struct sway_output *output, if (wlr_surface->resource->client != seat->exclusive_client) { continue; } - int nrects; - pixman_box32_t *rects = - pixman_region32_rectangles(&wlr_surface->current->opaque, &nrects); - for (int i = 0; i < nrects; ++i) { - pixman_box32_t *rect = &rects[i]; - if (rect->x1 <= 0 && rect->y1 <= 0 && - rect->x2 >= output->swayc->current.swayc_width && - rect->y2 >= output->swayc->current.swayc_height) { - return true; - } + pixman_box32_t output_box = { + .x2 = output->swayc->current.swayc_width, + .y2 = output->swayc->current.swayc_height, + }; + if (pixman_region32_contains_rectangle(&wlr_surface->current->opaque, + &output_box)) { + return true; } } return false; -- cgit v1.2.3 From 3b842f4eed7276f44b0a9154976ecfeef07aa867 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 7 Jul 2018 00:17:08 +1000 Subject: Detect opaque lockscreen when using a solid color --- sway/desktop/output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index fa85d260..329632b6 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -934,7 +934,7 @@ bool output_has_opaque_lockscreen(struct sway_output *output, .x2 = output->swayc->current.swayc_width, .y2 = output->swayc->current.swayc_height, }; - if (pixman_region32_contains_rectangle(&wlr_surface->current->opaque, + if (pixman_region32_contains_rectangle(&wlr_surface->current.opaque, &output_box)) { return true; } -- cgit v1.2.3 From 948078122932a9782bbf1042356b62099b0cd25f Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 7 Jul 2018 00:21:39 +1000 Subject: Don't clear when using opaque lockscreen --- sway/desktop/output.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 329632b6..3c34040b 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -978,15 +978,6 @@ static void render_output(struct sway_output *output, struct timespec *when, struct sway_seat *seat = input_manager_current_seat(input_manager); if (output_has_opaque_lockscreen(output, seat)) { - float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; - - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); - for (int i = 0; i < nrects; ++i) { - scissor_output(wlr_output, &rects[i]); - wlr_renderer_clear(renderer, clear_color); - } - struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; struct sway_layer_surface *sway_layer_surface = layer_from_wlr_layer_surface(seat->focused_layer); -- cgit v1.2.3 From 464d4d58892597f31da3fcdbcfcd7928643a9ec3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 7 Jul 2018 01:18:54 +1000 Subject: Translate surface by its geo when doing opaque box check --- sway/desktop/output.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sway') diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 3c34040b..e5a42db0 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -930,12 +930,21 @@ bool output_has_opaque_lockscreen(struct sway_output *output, if (wlr_surface->resource->client != seat->exclusive_client) { continue; } + struct sway_layer_surface *sway_layer_surface = + layer_from_wlr_layer_surface(wlr_layer_surface); pixman_box32_t output_box = { .x2 = output->swayc->current.swayc_width, .y2 = output->swayc->current.swayc_height, }; - if (pixman_region32_contains_rectangle(&wlr_surface->current.opaque, - &output_box)) { + pixman_region32_t surface_opaque_box; + pixman_region32_init(&surface_opaque_box); + pixman_region32_copy(&surface_opaque_box, &wlr_surface->current.opaque); + pixman_region32_translate(&surface_opaque_box, + sway_layer_surface->geo.x, sway_layer_surface->geo.y); + bool contains = pixman_region32_contains_rectangle( + &wlr_surface->current.opaque, &output_box); + pixman_region32_fini(&surface_opaque_box); + if (contains) { return true; } } -- cgit v1.2.3