diff options
-rw-r--r-- | include/sway/output.h | 4 | ||||
-rw-r--r-- | sway/desktop/output.c | 35 | ||||
-rw-r--r-- | swaylock/main.c | 15 |
3 files changed, 52 insertions, 2 deletions
diff --git a/include/sway/output.h b/include/sway/output.h index 19fc5e99..e6fe55c6 100644 --- a/include/sway/output.h +++ b/include/sway/output.h | |||
@@ -54,4 +54,8 @@ void output_damage_whole_container(struct sway_output *output, | |||
54 | struct sway_container *output_by_name(const char *name); | 54 | struct sway_container *output_by_name(const char *name); |
55 | 55 | ||
56 | void output_enable(struct sway_output *output); | 56 | void output_enable(struct sway_output *output); |
57 | |||
58 | bool output_has_opaque_lockscreen(struct sway_output *output, | ||
59 | struct sway_seat *seat); | ||
60 | |||
57 | #endif | 61 | #endif |
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( | |||
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 | int nrects; | ||
934 | pixman_box32_t *rects = | ||
935 | pixman_region32_rectangles(&wlr_surface->current->opaque, &nrects); | ||
936 | for (int i = 0; i < nrects; ++i) { | ||
937 | pixman_box32_t *rect = &rects[i]; | ||
938 | if (rect->x1 <= 0 && rect->y1 <= 0 && | ||
939 | rect->x2 >= output->swayc->current.swayc_width && | ||
940 | rect->y2 >= output->swayc->current.swayc_height) { | ||
941 | return true; | ||
942 | } | ||
943 | } | ||
944 | } | ||
945 | return false; | ||
946 | } | ||
947 | |||
918 | static void render_output(struct sway_output *output, struct timespec *when, | 948 | static void render_output(struct sway_output *output, struct timespec *when, |
919 | pixman_region32_t *damage) { | 949 | pixman_region32_t *damage) { |
920 | struct wlr_output *wlr_output = output->wlr_output; | 950 | struct wlr_output *wlr_output = output->wlr_output; |
@@ -950,7 +980,7 @@ static void render_output(struct sway_output *output, struct timespec *when, | |||
950 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; | 980 | struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; |
951 | struct sway_seat *seat = input_manager_current_seat(input_manager); | 981 | struct sway_seat *seat = input_manager_current_seat(input_manager); |
952 | 982 | ||
953 | if (seat->exclusive_client && seat->focused_layer) { | 983 | if (output_has_opaque_lockscreen(output, seat)) { |
954 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; | 984 | float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f}; |
955 | 985 | ||
956 | int nrects; | 986 | int nrects; |
@@ -1103,7 +1133,8 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) { | |||
1103 | struct send_frame_done_data data = { | 1133 | struct send_frame_done_data data = { |
1104 | .output = output, | 1134 | .output = output, |
1105 | .when = when, | 1135 | .when = when, |
1106 | .exclusive_client = seat->exclusive_client, | 1136 | .exclusive_client = output_has_opaque_lockscreen(output, seat) ? |
1137 | seat->exclusive_client : NULL, | ||
1107 | }; | 1138 | }; |
1108 | 1139 | ||
1109 | struct sway_container *workspace = output_get_active_workspace(output); | 1140 | struct sway_container *workspace = output_get_active_workspace(output); |
diff --git a/swaylock/main.c b/swaylock/main.c index f31ed679..a7a68e9b 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -111,12 +111,27 @@ static void create_layer_surface(struct swaylock_surface *surface) { | |||
111 | wl_surface_commit(surface->surface); | 111 | wl_surface_commit(surface->surface); |
112 | } | 112 | } |
113 | 113 | ||
114 | static bool image_is_opaque(cairo_surface_t *image) { | ||
115 | return cairo_surface_get_content(image) == CAIRO_CONTENT_COLOR; | ||
116 | } | ||
117 | |||
114 | static void layer_surface_configure(void *data, | 118 | static void layer_surface_configure(void *data, |
115 | struct zwlr_layer_surface_v1 *layer_surface, | 119 | struct zwlr_layer_surface_v1 *layer_surface, |
116 | uint32_t serial, uint32_t width, uint32_t height) { | 120 | uint32_t serial, uint32_t width, uint32_t height) { |
117 | struct swaylock_surface *surface = data; | 121 | struct swaylock_surface *surface = data; |
118 | surface->width = width; | 122 | surface->width = width; |
119 | surface->height = height; | 123 | surface->height = height; |
124 | |||
125 | if (image_is_opaque(surface->image) && | ||
126 | surface->state->args.mode != BACKGROUND_MODE_CENTER && | ||
127 | surface->state->args.mode != BACKGROUND_MODE_FIT) { | ||
128 | struct wl_region *region = | ||
129 | wl_compositor_create_region(surface->state->compositor); | ||
130 | wl_region_add(region, 0, 0, width, height); | ||
131 | wl_surface_set_opaque_region(surface->surface, region); | ||
132 | wl_region_destroy(region); | ||
133 | } | ||
134 | |||
120 | zwlr_layer_surface_v1_ack_configure(layer_surface, serial); | 135 | zwlr_layer_surface_v1_ack_configure(layer_surface, serial); |
121 | render_frame(surface); | 136 | render_frame(surface); |
122 | } | 137 | } |