diff options
Diffstat (limited to 'sway/desktop/output.c')
-rw-r--r-- | sway/desktop/output.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 1211cc07..e5a42db0 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c | |||
@@ -915,6 +915,42 @@ static struct sway_container *output_get_active_workspace( | |||
915 | return workspace; | 915 | return workspace; |
916 | } | 916 | } |
917 | 917 | ||
918 | bool output_has_opaque_lockscreen(struct sway_output *output, | ||
919 | struct sway_seat *seat) { | ||
920 | if (!seat->exclusive_client) { | ||
921 | return false; | ||
922 | } | ||
923 | |||
924 | struct wlr_layer_surface *wlr_layer_surface; | ||
925 | wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { | ||
926 | if (wlr_layer_surface->output != output->wlr_output) { | ||
927 | continue; | ||
928 | } | ||
929 | struct wlr_surface *wlr_surface = wlr_layer_surface->surface; | ||
930 | if (wlr_surface->resource->client != seat->exclusive_client) { | ||
931 | continue; | ||
932 | } | ||
933 | struct sway_layer_surface *sway_layer_surface = | ||
934 | layer_from_wlr_layer_surface(wlr_layer_surface); | ||
935 | pixman_box32_t output_box = { | ||
936 | .x2 = output->swayc->current.swayc_width, | ||
937 | .y2 = output->swayc->current.swayc_height, | ||
938 | }; | ||
939 | pixman_region32_t surface_opaque_box; | ||
940 | pixman_region32_init(&surface_opaque_box); | ||
941 | pixman_region32_copy(&surface_opaque_box, &wlr_surface->current.opaque); | ||
942 | pixman_region32_translate(&surface_opaque_box, | ||
943 | sway_layer_surface->geo.x, sway_layer_surface->geo.y); | ||
944 | bool contains = pixman_region32_contains_rectangle( | ||
945 | &wlr_surface->current.opaque, &output_box); | ||
946 | pixman_region32_fini(&surface_opaque_box); | ||
947 | if (contains) { | ||
948 | return true; | ||
949 | } | ||
950 | } | ||
951 | return false; | ||
952 | } | ||
953 | |||
918 | static void render_output(struct sway_output *output, struct timespec *when, | 954 | static void render_output(struct sway_output *output, struct timespec *when, |
919 | pixman_region32_t *damage) { | 955 | pixman_region32_t *damage) { |
920 | struct wlr_output *wlr_output = output->wlr_output; | 956 | struct wlr_output *wlr_output = output->wlr_output; |
@@ -948,8 +984,21 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
948 | 984 | ||
949 | struct sway_container *workspace = output_get_active_workspace(output); | 985 | struct sway_container *workspace = output_get_active_workspace(output); |
950 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; | 986 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; |
987 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
951 | 988 | ||
952 | if (fullscreen_view) { | 989 | if (output_has_opaque_lockscreen(output, seat)) { |
990 | struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer; | ||
991 | struct sway_layer_surface *sway_layer_surface = | ||
992 | layer_from_wlr_layer_surface(seat->focused_layer); | ||
993 | struct render_data data = { | ||
994 | .output = output, | ||
995 | .damage = damage, | ||
996 | .alpha = 1.0f, | ||
997 | }; | ||
998 | surface_for_each_surface(wlr_layer_surface->surface, | ||
999 | sway_layer_surface->geo.x, sway_layer_surface->geo.y, | ||
1000 | &data.root_geo, render_surface_iterator, &data); | ||
1001 | } else if (fullscreen_view) { | ||
953 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 1002 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
954 | 1003 | ||
955 | int nrects; | 1004 | int nrects; |
@@ -1019,11 +1068,16 @@ struct send_frame_done_data { | |||
1019 | struct root_geometry root_geo; | 1068 | struct root_geometry root_geo; |
1020 | struct sway_output *output; | 1069 | struct sway_output *output; |
1021 | struct timespec *when; | 1070 | struct timespec *when; |
1071 | struct wl_client *exclusive_client; | ||
1022 | }; | 1072 | }; |
1023 | 1073 | ||
1024 | static void send_frame_done_iterator(struct wlr_surface *surface, | 1074 | static void send_frame_done_iterator(struct wlr_surface *surface, |
1025 | int sx, int sy, void *_data) { | 1075 | int sx, int sy, void *_data) { |
1026 | struct send_frame_done_data *data = _data; | 1076 | struct send_frame_done_data *data = _data; |
1077 | if (data->exclusive_client && | ||
1078 | data->exclusive_client != surface->resource->client) { | ||
1079 | return; | ||
1080 | } | ||
1027 | 1081 | ||
1028 | bool intersects = get_surface_box(&data->root_geo, data->output, surface, | 1082 | bool intersects = get_surface_box(&data->root_geo, data->output, surface, |
1029 | sx, sy, NULL); | 1083 | sx, sy, NULL); |
@@ -1072,9 +1126,12 @@ static void send_frame_done_container(struct send_frame_done_data *data, | |||
1072 | } | 1126 | } |
1073 | 1127 | ||
1074 | static void send_frame_done(struct sway_output *output, struct timespec *when) { | 1128 | static void send_frame_done(struct sway_output *output, struct timespec *when) { |
1129 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
1075 | struct send_frame_done_data data = { | 1130 | struct send_frame_done_data data = { |
1076 | .output = output, | 1131 | .output = output, |
1077 | .when = when, | 1132 | .when = when, |
1133 | .exclusive_client = output_has_opaque_lockscreen(output, seat) ? | ||
1134 | seat->exclusive_client : NULL, | ||
1078 | }; | 1135 | }; |
1079 | 1136 | ||
1080 | struct sway_container *workspace = output_get_active_workspace(output); | 1137 | struct sway_container *workspace = output_get_active_workspace(output); |