aboutsummaryrefslogtreecommitdiff
path: root/swaylock/main.c
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-05-23 18:11:24 -0400
committerGitHub <noreply@github.com>2018-05-23 18:11:24 -0400
commit50d1b80d507096ad55e9e2fbb56b31b09b6671dc (patch)
tree3dc61f6ba02d754e71df1499c406f8586b853f76 /swaylock/main.c
parent12a12878b9883c345dd73752a9cf714aeb245b8a (diff)
parentdf61bfbb57ac9f7054dd6fe1c1e9398f0545d76b (diff)
Merge pull request #2003 from emersion/fix-swaylock-hotplugging
Fix swaylock crashing when plugging/unplugging output
Diffstat (limited to 'swaylock/main.c')
-rw-r--r--swaylock/main.c99
1 files changed, 67 insertions, 32 deletions
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() {
}
}
+static void destroy_surface(struct swaylock_surface *surface) {
+ wl_list_remove(&surface->link);
+ if (surface->layer_surface != NULL) {
+ zwlr_layer_surface_v1_destroy(surface->layer_surface);
+ }
+ if (surface->surface != NULL) {
+ wl_surface_destroy(surface->surface);
+ }
+ destroy_buffer(&surface->buffers[0]);
+ destroy_buffer(&surface->buffers[1]);
+ wl_output_destroy(surface->output);
+ free(surface);
+}
+
+static const struct zwlr_layer_surface_v1_listener layer_surface_listener;
+
+static cairo_surface_t *select_image(struct swaylock_state *state,
+ struct swaylock_surface *surface);
+
+static void create_layer_surface(struct swaylock_surface *surface) {
+ struct swaylock_state *state = surface->state;
+
+ surface->image = select_image(state, surface);
+
+ surface->surface = wl_compositor_create_surface(state->compositor);
+ assert(surface->surface);
+
+ surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
+ state->layer_shell, surface->surface, surface->output,
+ ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
+ assert(surface->layer_surface);
+
+ zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0);
+ zwlr_layer_surface_v1_set_anchor(surface->layer_surface,
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
+ zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1);
+ zwlr_layer_surface_v1_set_keyboard_interactivity(
+ surface->layer_surface, true);
+ zwlr_layer_surface_v1_add_listener(surface->layer_surface,
+ &layer_surface_listener, surface);
+ wl_surface_commit(surface->surface);
+}
+
static void layer_surface_configure(void *data,
struct zwlr_layer_surface_v1 *layer_surface,
uint32_t serial, uint32_t width, uint32_t height) {
@@ -77,9 +123,7 @@ static void layer_surface_configure(void *data,
static void layer_surface_closed(void *data,
struct zwlr_layer_surface_v1 *layer_surface) {
struct swaylock_surface *surface = data;
- zwlr_layer_surface_v1_destroy(surface->layer_surface);
- wl_surface_destroy(surface->surface);
- surface->state->run_display = false;
+ destroy_surface(surface);
}
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
@@ -181,14 +225,27 @@ static void handle_global(void *data, struct wl_registry *registry,
surface->state = state;
surface->output = wl_registry_bind(registry, name,
&wl_output_interface, 3);
+ surface->output_global_name = name;
wl_output_add_listener(surface->output, &_wl_output_listener, surface);
wl_list_insert(&state->surfaces, &surface->link);
+
+ if (state->run_display) {
+ create_layer_surface(surface);
+ wl_display_roundtrip(state->display);
+ }
}
}
static void handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name) {
- // who cares
+ struct swaylock_state *state = data;
+ struct swaylock_surface *surface;
+ wl_list_for_each(surface, &state->surfaces, link) {
+ if (surface->output_global_name == name) {
+ destroy_surface(surface);
+ break;
+ }
+ }
}
static const struct wl_registry_listener registry_listener = {
@@ -276,7 +333,7 @@ int main(int argc, char **argv) {
{0, 0, 0, 0}
};
- const char *usage =
+ const char usage[] =
"Usage: swaylock [options...]\n"
"\n"
" -h, --help Show help message and quit.\n"
@@ -288,13 +345,13 @@ int main(int argc, char **argv) {
" -u, --no-unlock-indicator Disable the unlock indicator.\n"
" -f, --daemonize Detach from the controlling terminal.\n";
- struct swaylock_args args = {
+ state.args = (struct swaylock_args){
.mode = BACKGROUND_MODE_SOLID_COLOR,
.color = 0xFFFFFFFF,
.show_indicator = true,
};
- state.args = args;
wl_list_init(&state.images);
+
wlr_log_init(L_DEBUG, NULL);
int c;
@@ -369,6 +426,8 @@ int main(int argc, char **argv) {
return 0;
}
+ zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
+
if (state.zxdg_output_manager) {
struct swaylock_surface *surface;
wl_list_for_each(surface, &state.surfaces, link) {
@@ -385,33 +444,9 @@ int main(int argc, char **argv) {
struct swaylock_surface *surface;
wl_list_for_each(surface, &state.surfaces, link) {
- surface->image = select_image(&state, surface);
-
- surface->surface = wl_compositor_create_surface(state.compositor);
- assert(surface->surface);
-
- surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
- state.layer_shell, surface->surface, surface->output,
- ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
- assert(surface->layer_surface);
-
- zwlr_layer_surface_v1_set_size(surface->layer_surface, 0, 0);
- zwlr_layer_surface_v1_set_anchor(surface->layer_surface,
- ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
- ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
- zwlr_layer_surface_v1_set_exclusive_zone(surface->layer_surface, -1);
- zwlr_layer_surface_v1_set_keyboard_interactivity(
- surface->layer_surface, true);
- zwlr_layer_surface_v1_add_listener(surface->layer_surface,
- &layer_surface_listener, surface);
- wl_surface_commit(surface->surface);
- wl_display_roundtrip(state.display);
+ create_layer_surface(surface);
}
- zwlr_input_inhibit_manager_v1_get_inhibitor(state.input_inhibit_manager);
-
state.run_display = true;
while (wl_display_dispatch(state.display) != -1 && state.run_display) {
// This space intentionally left blank