Skip to content

Commit

Permalink
Fix output-specific images when output reappears
Browse files Browse the repository at this point in the history
When setting an image with `--image <output>:<path>`, the image used to
fail to apply if the relevant output appears some time after swaylock
executes.

Co-authored-by: Alexander Bakker <[email protected]>
  • Loading branch information
mortie and alexbakker committed Dec 6, 2023
1 parent 7cecd39 commit ff3be92
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/swaylock.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ struct swaylock_surface {
struct wl_subsurface *subsurface;
struct ext_session_lock_surface_v1 *ext_session_lock_surface_v1;
struct pool_buffer indicator_buffers[2];
bool ready;
bool frame_pending, dirty;
uint32_t width, height;
int32_t scale;
Expand Down
42 changes: 40 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ static bool surface_is_opaque(struct swaylock_surface *surface) {
return (surface->state->args.colors.background & 0xff) == 0xff;
}

static const struct wl_callback_listener surface_ready_listener;

static void create_surface(struct swaylock_surface *surface) {
struct swaylock_state *state = surface->state;

Expand All @@ -143,6 +145,14 @@ static void create_surface(struct swaylock_surface *surface) {
ext_session_lock_surface_v1_add_listener(surface->ext_session_lock_surface_v1,
&ext_session_lock_surface_v1_listener, surface);

// We need to wait for the wl_output.name event to be received before we
// can decide which image to display
wl_callback_add_listener(
wl_display_sync(surface->state->display),
&surface_ready_listener, surface);
}

static void initially_render_surface(struct swaylock_surface *surface) {
if (surface_is_opaque(surface) &&
surface->state->args.mode != BACKGROUND_MODE_CENTER &&
surface->state->args.mode != BACKGROUND_MODE_FIT) {
Expand All @@ -152,17 +162,29 @@ static void create_surface(struct swaylock_surface *surface) {
wl_surface_set_opaque_region(surface->surface, region);
wl_region_destroy(region);
}

render_frame_background(surface);
render_frame(surface);
}

static void handle_surface_ready(void *data, struct wl_callback *callback,
uint32_t time) {
struct swaylock_surface *surface = (struct swaylock_surface *)data;
initially_render_surface(surface);
surface->ready = true;
}

static const struct wl_callback_listener surface_ready_listener = {
.done = handle_surface_ready,
};

static void ext_session_lock_surface_v1_handle_configure(void *data,
struct ext_session_lock_surface_v1 *lock_surface, uint32_t serial,
uint32_t width, uint32_t height) {
struct swaylock_surface *surface = data;
surface->width = width;
surface->height = height;
ext_session_lock_surface_v1_ack_configure(lock_surface, serial);
render_frame_background(surface);
render_frame(surface);
}

static const struct ext_session_lock_surface_v1_listener ext_session_lock_surface_v1_listener = {
Expand Down Expand Up @@ -250,6 +272,13 @@ static void handle_wl_output_name(void *data, struct wl_output *output,
const char *name) {
struct swaylock_surface *surface = data;
surface->output_name = strdup(name);

if (surface->output_name != NULL) {
cairo_surface_t *new_image = select_image(surface->state, surface);
if (new_image != surface->image) {
surface->image = new_image;
}
}
}

static void handle_wl_output_description(void *data, struct wl_output *output,
Expand Down Expand Up @@ -1247,6 +1276,15 @@ int main(int argc, char **argv) {
create_surface(surface);
}

wl_list_for_each(surface, &state.surfaces, link) {
while (!surface->ready) {
if (wl_display_dispatch(state.display) < 0) {
swaylock_log(LOG_ERROR, "wl_display_dispatch() failed");
return 2;
}
}
}

while (!state.locked) {
if (wl_display_dispatch(state.display) < 0) {
swaylock_log(LOG_ERROR, "wl_display_dispatch() failed");
Expand Down

0 comments on commit ff3be92

Please sign in to comment.