aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-05-23 18:11:24 -0400
committerLibravatar GitHub <noreply@github.com>2018-05-23 18:11:24 -0400
commit50d1b80d507096ad55e9e2fbb56b31b09b6671dc (patch)
tree3dc61f6ba02d754e71df1499c406f8586b853f76
parentMerge pull request #2022 from RedSoxFan/ipc-get-marks (diff)
parentswaylock: remove unused field (diff)
downloadsway-50d1b80d507096ad55e9e2fbb56b31b09b6671dc.tar.gz
sway-50d1b80d507096ad55e9e2fbb56b31b09b6671dc.tar.zst
sway-50d1b80d507096ad55e9e2fbb56b31b09b6671dc.zip
Merge pull request #2003 from emersion/fix-swaylock-hotplugging
Fix swaylock crashing when plugging/unplugging output
-rw-r--r--include/swaylock/swaylock.h15
-rw-r--r--swaylock/main.c99
-rw-r--r--swaylock/render.c3
3 files changed, 78 insertions, 39 deletions
diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h
index e161ada9..dae823b8 100644
--- a/include/swaylock/swaylock.h
+++ b/include/swaylock/swaylock.h
@@ -10,13 +10,13 @@
10#include "wlr-layer-shell-unstable-v1-client-protocol.h" 10#include "wlr-layer-shell-unstable-v1-client-protocol.h"
11 11
12enum auth_state { 12enum auth_state {
13 AUTH_STATE_IDLE, 13 AUTH_STATE_IDLE,
14 AUTH_STATE_CLEAR, 14 AUTH_STATE_CLEAR,
15 AUTH_STATE_INPUT, 15 AUTH_STATE_INPUT,
16 AUTH_STATE_INPUT_NOP, 16 AUTH_STATE_INPUT_NOP,
17 AUTH_STATE_BACKSPACE, 17 AUTH_STATE_BACKSPACE,
18 AUTH_STATE_VALIDATING, 18 AUTH_STATE_VALIDATING,
19 AUTH_STATE_INVALID, 19 AUTH_STATE_INVALID,
20}; 20};
21 21
22struct swaylock_args { 22struct swaylock_args {
@@ -50,6 +50,7 @@ struct swaylock_surface {
50 cairo_surface_t *image; 50 cairo_surface_t *image;
51 struct swaylock_state *state; 51 struct swaylock_state *state;
52 struct wl_output *output; 52 struct wl_output *output;
53 uint32_t output_global_name;
53 struct zxdg_output_v1 *xdg_output; 54 struct zxdg_output_v1 *xdg_output;
54 struct wl_surface *surface; 55 struct wl_surface *surface;
55 struct zwlr_layer_surface_v1 *layer_surface; 56 struct zwlr_layer_surface_v1 *layer_surface;
diff --git a/swaylock/main.c b/swaylock/main.c
index 11b5e8c8..f89f2849 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -64,6 +64,52 @@ static void daemonize() {
64 } 64 }
65} 65}
66 66
67static void destroy_surface(struct swaylock_surface *surface) {
68 wl_list_remove(&surface->link);
69 if (surface->layer_surface != NULL) {
70 zwlr_layer_surface_v1_destroy(surface->layer_surface);
71 }
72 if (surface->surface != NULL) {
73 wl_surface_destroy(surface->surface);
74 }
75 destroy_buffer(&surface->buffers[0]);
76 destroy_buffer(&surface->buffers[1]);
77 wl_output_destroy(surface->output);
78 free(surface);
79}
80
81static const struct zwlr_layer_surface_v1_listener layer_surface_listener;
82
83static cairo_surface_t *select_image(struct swaylock_state *state,
84 struct swaylock_surface *surface);
85
86static void create_layer_surface(struct swaylock_surface *surface) {
87 struct swaylock_state *state = surface->state;
88
89 surface->image = select_image(state, surface);
90
91 surface->surface = wl_compositor_create_surface(state->compositor);
92 assert(surface->surface);
93
94 surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
95 state->layer_shell, surface->surface, surface->output,
96 ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
97 assert(surface->layer_surface);
98
99 zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0);
100 zwlr_layer_surface_v1_set_anchor(surface->layer_surface,
101 ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
102 ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
103 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
104 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
105 zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1);
106 zwlr_layer_surface_v1_set_keyboard_interactivity(
107 surface->layer_surface, true);
108 zwlr_layer_surface_v1_add_listener(surface->layer_surface,
109 &layer_surface_listener, surface);
110 wl_surface_commit(surface->surface);
111}
112
67static void layer_surface_configure(void *data, 113static void layer_surface_configure(void *data,
68 struct zwlr_layer_surface_v1 *layer_surface, 114 struct zwlr_layer_surface_v1 *layer_surface,
69 uint32_t serial, uint32_t width, uint32_t height) { 115 uint32_t serial, uint32_t width, uint32_t height) {
@@ -77,9 +123,7 @@ static void layer_surface_configure(void *data,
77static void layer_surface_closed(void *data, 123static void layer_surface_closed(void *data,
78 struct zwlr_layer_surface_v1 *layer_surface) { 124 struct zwlr_layer_surface_v1 *layer_surface) {
79 struct swaylock_surface *surface = data; 125 struct swaylock_surface *surface = data;
80 zwlr_layer_surface_v1_destroy(surface->layer_surface); 126 destroy_surface(surface);
81 wl_surface_destroy(surface->surface);
82 surface->state->run_display = false;
83} 127}
84 128
85static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { 129static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
@@ -181,14 +225,27 @@ static void handle_global(void *data, struct wl_registry *registry,
181 surface->state = state; 225 surface->state = state;
182 surface->output = wl_registry_bind(registry, name, 226 surface->output = wl_registry_bind(registry, name,
183 &wl_output_interface, 3); 227 &wl_output_interface, 3);
228 surface->output_global_name = name;
184 wl_output_add_listener(surface->output, &_wl_output_listener, surface); 229 wl_output_add_listener(surface->output, &_wl_output_listener, surface);
185 wl_list_insert(&state->surfaces, &surface->link); 230 wl_list_insert(&state->surfaces, &surface->link);
231
232 if (state->run_display) {
233 create_layer_surface(surface);
234 wl_display_roundtrip(state->display);
235 }
186 } 236 }
187} 237}
188 238
189static void handle_global_remove(void *data, struct wl_registry *registry, 239static void handle_global_remove(void *data, struct wl_registry *registry,
190 uint32_t name) { 240 uint32_t name) {
191 // who cares 241 struct swaylock_state *state = data;
242 struct swaylock_surface *surface;
243 wl_list_for_each(surface, &state->surfaces, link) {
244 if (surface->output_global_name == name) {
245 destroy_surface(surface);
246 break;
247 }
248 }
192} 249}
193 250
194static const struct wl_registry_listener registry_listener = { 251static const struct wl_registry_listener registry_listener = {
@@ -276,7 +333,7 @@ int main(int argc, char **argv) {
276 {0, 0, 0, 0} 333 {0, 0, 0, 0}
277 }; 334 };
278 335
279 const char *usage = 336 const char usage[] =
280 "Usage: swaylock [options...]\n" 337 "Usage: swaylock [options...]\n"
281 "\n" 338 "\n"
282 " -h, --help Show help message and quit.\n" 339 " -h, --help Show help message and quit.\n"
@@ -288,13 +345,13 @@ int main(int argc, char **argv) {
288 " -u, --no-unlock-indicator Disable the unlock indicator.\n" 345 " -u, --no-unlock-indicator Disable the unlock indicator.\n"
289 " -f, --daemonize Detach from the controlling terminal.\n"; 346 " -f, --daemonize Detach from the controlling terminal.\n";
290 347
291 struct swaylock_args args = { 348 state.args = (struct swaylock_args){
292 .mode = BACKGROUND_MODE_SOLID_COLOR, 349 .mode = BACKGROUND_MODE_SOLID_COLOR,
293 .color = 0xFFFFFFFF, 350 .color = 0xFFFFFFFF,
294 .show_indicator = true, 351 .show_indicator = true,
295 }; 352 };
296 state.args = args;
297 wl_list_init(&state.images); 353 wl_list_init(&state.images);
354
298 wlr_log_init(L_DEBUG, NULL); 355 wlr_log_init(L_DEBUG, NULL);
299 356
300 int c; 357 int c;
@@ -369,6 +426,8 @@ int main(int argc, char **argv) {
369 return 0; 426 return 0;
370 } 427 }
371 428
429 zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
430
372 if (state.zxdg_output_manager) { 431 if (state.zxdg_output_manager) {
373 struct swaylock_surface *surface; 432 struct swaylock_surface *surface;
374 wl_list_for_each(surface, &state.surfaces, link) { 433 wl_list_for_each(surface, &state.surfaces, link) {
@@ -385,33 +444,9 @@ int main(int argc, char **argv) {
385 444
386 struct swaylock_surface *surface; 445 struct swaylock_surface *surface;
387 wl_list_for_each(surface, &state.surfaces, link) { 446 wl_list_for_each(surface, &state.surfaces, link) {
388 surface->image = select_image(&state, surface); 447 create_layer_surface(surface);
389
390 surface->surface = wl_compositor_create_surface(state.compositor);
391 assert(surface->surface);
392
393 surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
394 state.layer_shell, surface->surface, surface->output,
395 ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
396 assert(surface->layer_surface);
397
398 zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0);
399 zwlr_layer_surface_v1_set_anchor(surface->layer_surface,
400 ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
401 ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
402 ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
403 ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
404 zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1);
405 zwlr_layer_surface_v1_set_keyboard_interactivity(
406 surface->layer_surface, true);
407 zwlr_layer_surface_v1_add_listener(surface->layer_surface,
408 &layer_surface_listener, surface);
409 wl_surface_commit(surface->surface);
410 wl_display_roundtrip(state.display);
411 } 448 }
412 449
413 zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
414
415 state.run_display = true; 450 state.run_display = true;
416 while (wl_display_dispatch(state.display) != -1 && state.run_display) { 451 while (wl_display_dispatch(state.display) != -1 && state.run_display) {
417 // This space intentionally left blank 452 // This space intentionally left blank
diff --git a/swaylock/render.c b/swaylock/render.c
index cc40f4e9..05236dea 100644
--- a/swaylock/render.c
+++ b/swaylock/render.c
@@ -17,6 +17,9 @@ void render_frame(struct swaylock_surface *surface) {
17 17
18 int buffer_width = surface->width * surface->scale; 18 int buffer_width = surface->width * surface->scale;
19 int buffer_height = surface->height * surface->scale; 19 int buffer_height = surface->height * surface->scale;
20 if (buffer_width == 0 || buffer_height == 0) {
21 return; // not yet configured
22 }
20 23
21 surface->current_buffer = get_next_buffer(state->shm, 24 surface->current_buffer = get_next_buffer(state->shm,
22 surface->buffers, buffer_width, buffer_height); 25 surface->buffers, buffer_width, buffer_height);