Decouple the drawing of the background from drawing the indicator.
* Render background only once in main wl_surface * Render indicator on subsurface
This commit is contained in:
parent
6b3be42264
commit
7d5a73b0a9
@ -69,6 +69,7 @@ struct swaylock_state {
|
|||||||
struct loop_timer *clear_password_timer; // clears the password buffer
|
struct loop_timer *clear_password_timer; // clears the password buffer
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
struct wl_compositor *compositor;
|
struct wl_compositor *compositor;
|
||||||
|
struct wl_subcompositor *subcompositor;
|
||||||
struct zwlr_layer_shell_v1 *layer_shell;
|
struct zwlr_layer_shell_v1 *layer_shell;
|
||||||
struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager;
|
struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager;
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
@ -90,8 +91,11 @@ struct swaylock_surface {
|
|||||||
uint32_t output_global_name;
|
uint32_t output_global_name;
|
||||||
struct zxdg_output_v1 *xdg_output;
|
struct zxdg_output_v1 *xdg_output;
|
||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
|
struct wl_surface *child; // surface made into subsurface
|
||||||
|
struct wl_subsurface *subsurface;
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
struct pool_buffer buffers[2];
|
struct pool_buffer buffers[2];
|
||||||
|
struct pool_buffer indicator_buffers[2];
|
||||||
struct pool_buffer *current_buffer;
|
struct pool_buffer *current_buffer;
|
||||||
bool frame_pending, dirty;
|
bool frame_pending, dirty;
|
||||||
uint32_t width, height;
|
uint32_t width, height;
|
||||||
@ -111,6 +115,7 @@ struct swaylock_image {
|
|||||||
|
|
||||||
void swaylock_handle_key(struct swaylock_state *state,
|
void swaylock_handle_key(struct swaylock_state *state,
|
||||||
xkb_keysym_t keysym, uint32_t codepoint);
|
xkb_keysym_t keysym, uint32_t codepoint);
|
||||||
|
void render_frame_background(struct swaylock_surface *surface);
|
||||||
void render_frame(struct swaylock_surface *surface);
|
void render_frame(struct swaylock_surface *surface);
|
||||||
void render_frames(struct swaylock_state *state);
|
void render_frames(struct swaylock_state *state);
|
||||||
void damage_surface(struct swaylock_surface *surface);
|
void damage_surface(struct swaylock_surface *surface);
|
||||||
|
10
main.c
10
main.c
@ -126,6 +126,12 @@ static void create_layer_surface(struct swaylock_surface *surface) {
|
|||||||
surface->surface = wl_compositor_create_surface(state->compositor);
|
surface->surface = wl_compositor_create_surface(state->compositor);
|
||||||
assert(surface->surface);
|
assert(surface->surface);
|
||||||
|
|
||||||
|
surface->child = wl_compositor_create_surface(state->compositor);
|
||||||
|
assert(surface->child);
|
||||||
|
surface->subsurface = wl_subcompositor_get_subsurface(state->subcompositor, surface->child, surface->surface);
|
||||||
|
assert(surface->subsurface);
|
||||||
|
wl_subsurface_set_sync(surface->subsurface);
|
||||||
|
|
||||||
surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
surface->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
state->layer_shell, surface->surface, surface->output,
|
state->layer_shell, surface->surface, surface->output,
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
|
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "lockscreen");
|
||||||
@ -163,6 +169,7 @@ static void layer_surface_configure(void *data,
|
|||||||
surface->width = width;
|
surface->width = width;
|
||||||
surface->height = height;
|
surface->height = height;
|
||||||
zwlr_layer_surface_v1_ack_configure(layer_surface, serial);
|
zwlr_layer_surface_v1_ack_configure(layer_surface, serial);
|
||||||
|
render_frame_background(surface);
|
||||||
render_frame(surface);
|
render_frame(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +304,9 @@ static void handle_global(void *data, struct wl_registry *registry,
|
|||||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
state->compositor = wl_registry_bind(registry, name,
|
state->compositor = wl_registry_bind(registry, name,
|
||||||
&wl_compositor_interface, 3);
|
&wl_compositor_interface, 3);
|
||||||
|
} else if (strcmp(interface, wl_subcompositor_interface.name) == 0) {
|
||||||
|
state->subcompositor = wl_registry_bind(registry, name,
|
||||||
|
&wl_subcompositor_interface, 1);
|
||||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||||
state->shm = wl_registry_bind(registry, name,
|
state->shm = wl_registry_bind(registry, name,
|
||||||
&wl_shm_interface, 1);
|
&wl_shm_interface, 1);
|
||||||
|
81
render.c
81
render.c
@ -32,7 +32,7 @@ static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_frame(struct swaylock_surface *surface) {
|
void render_frame_background(struct swaylock_surface *surface) {
|
||||||
struct swaylock_state *state = surface->state;
|
struct swaylock_state *state = surface->state;
|
||||||
|
|
||||||
int buffer_width = surface->width * surface->scale;
|
int buffer_width = surface->width * surface->scale;
|
||||||
@ -49,13 +49,6 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
|
|
||||||
cairo_t *cairo = surface->current_buffer->cairo;
|
cairo_t *cairo = surface->current_buffer->cairo;
|
||||||
cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
|
cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
|
||||||
cairo_font_options_t *fo = cairo_font_options_create();
|
|
||||||
cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
|
|
||||||
cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
|
|
||||||
cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(surface->subpixel));
|
|
||||||
cairo_set_font_options(cairo, fo);
|
|
||||||
cairo_font_options_destroy(fo);
|
|
||||||
cairo_identity_matrix(cairo);
|
|
||||||
|
|
||||||
cairo_save(cairo);
|
cairo_save(cairo);
|
||||||
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||||
@ -69,15 +62,59 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
cairo_restore(cairo);
|
cairo_restore(cairo);
|
||||||
cairo_identity_matrix(cairo);
|
cairo_identity_matrix(cairo);
|
||||||
|
|
||||||
|
wl_surface_set_buffer_scale(surface->surface, surface->scale);
|
||||||
|
wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0);
|
||||||
|
wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height);
|
||||||
|
wl_surface_commit(surface->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_frame(struct swaylock_surface *surface) {
|
||||||
|
struct swaylock_state *state = surface->state;
|
||||||
|
|
||||||
int arc_radius = state->args.radius * surface->scale;
|
int arc_radius = state->args.radius * surface->scale;
|
||||||
int arc_thickness = state->args.thickness * surface->scale;
|
int arc_thickness = state->args.thickness * surface->scale;
|
||||||
|
int buffer_diameter = (arc_radius + arc_thickness) * 2;
|
||||||
|
int buffer_height = buffer_diameter * 2;
|
||||||
|
|
||||||
|
int indicator_radius = (state->args.radius + state->args.thickness) * surface->scale;
|
||||||
|
int subsurf_xpos = surface->width / 2 - indicator_radius;
|
||||||
|
int subsurf_ypos = surface->height / 2 - indicator_radius;
|
||||||
|
wl_subsurface_set_position(surface->subsurface, subsurf_xpos, subsurf_ypos);
|
||||||
|
|
||||||
|
surface->current_buffer = get_next_buffer(state->shm,
|
||||||
|
surface->indicator_buffers, buffer_diameter, buffer_height);
|
||||||
|
if (surface->current_buffer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide subsurface until we want it visible
|
||||||
|
wl_surface_attach(surface->child, NULL, 0, 0);
|
||||||
|
wl_surface_commit(surface->child);
|
||||||
|
|
||||||
|
cairo_t *cairo = surface->current_buffer->cairo;
|
||||||
|
cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
|
||||||
|
cairo_font_options_t *fo = cairo_font_options_create();
|
||||||
|
cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
|
||||||
|
cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
|
||||||
|
cairo_font_options_set_subpixel_order(fo, to_cairo_subpixel_order(surface->subpixel));
|
||||||
|
cairo_set_font_options(cairo, fo);
|
||||||
|
cairo_font_options_destroy(fo);
|
||||||
|
cairo_identity_matrix(cairo);
|
||||||
|
|
||||||
|
// Clear
|
||||||
|
cairo_save(cairo);
|
||||||
|
cairo_set_source_rgba(cairo, 0, 0, 0, 0);
|
||||||
|
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
|
||||||
|
cairo_paint(cairo);
|
||||||
|
cairo_restore(cairo);
|
||||||
|
|
||||||
float type_indicator_border_thickness =
|
float type_indicator_border_thickness =
|
||||||
TYPE_INDICATOR_BORDER_THICKNESS * surface->scale;
|
TYPE_INDICATOR_BORDER_THICKNESS * surface->scale;
|
||||||
|
|
||||||
if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) {
|
if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) {
|
||||||
// Draw circle
|
// Draw circle
|
||||||
cairo_set_line_width(cairo, arc_thickness);
|
cairo_set_line_width(cairo, arc_thickness);
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2, arc_radius,
|
||||||
0, 2 * M_PI);
|
0, 2 * M_PI);
|
||||||
set_color_for_state(cairo, state, &state->args.colors.inside);
|
set_color_for_state(cairo, state, &state->args.colors.inside);
|
||||||
cairo_fill_preserve(cairo);
|
cairo_fill_preserve(cairo);
|
||||||
@ -142,9 +179,9 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
double x, y;
|
double x, y;
|
||||||
cairo_text_extents(cairo, text, &extents);
|
cairo_text_extents(cairo, text, &extents);
|
||||||
cairo_font_extents(cairo, &fe);
|
cairo_font_extents(cairo, &fe);
|
||||||
x = (buffer_width / 2) -
|
x = (buffer_diameter / 2) -
|
||||||
(extents.width / 2 + extents.x_bearing);
|
(extents.width / 2 + extents.x_bearing);
|
||||||
y = (buffer_height / 2) +
|
y = (buffer_diameter / 2) +
|
||||||
(fe.height / 2 - fe.descent);
|
(fe.height / 2 - fe.descent);
|
||||||
|
|
||||||
cairo_move_to(cairo, x, y);
|
cairo_move_to(cairo, x, y);
|
||||||
@ -159,7 +196,7 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
static double highlight_start = 0;
|
static double highlight_start = 0;
|
||||||
highlight_start +=
|
highlight_start +=
|
||||||
(rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5;
|
(rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5;
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2,
|
||||||
arc_radius, highlight_start,
|
arc_radius, highlight_start,
|
||||||
highlight_start + TYPE_INDICATOR_RANGE);
|
highlight_start + TYPE_INDICATOR_RANGE);
|
||||||
if (state->auth_state == AUTH_STATE_INPUT) {
|
if (state->auth_state == AUTH_STATE_INPUT) {
|
||||||
@ -179,12 +216,12 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
|
|
||||||
// Draw borders
|
// Draw borders
|
||||||
cairo_set_source_u32(cairo, state->args.colors.separator);
|
cairo_set_source_u32(cairo, state->args.colors.separator);
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2,
|
||||||
arc_radius, highlight_start,
|
arc_radius, highlight_start,
|
||||||
highlight_start + type_indicator_border_thickness);
|
highlight_start + type_indicator_border_thickness);
|
||||||
cairo_stroke(cairo);
|
cairo_stroke(cairo);
|
||||||
|
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2,
|
||||||
arc_radius, highlight_start + TYPE_INDICATOR_RANGE,
|
arc_radius, highlight_start + TYPE_INDICATOR_RANGE,
|
||||||
highlight_start + TYPE_INDICATOR_RANGE +
|
highlight_start + TYPE_INDICATOR_RANGE +
|
||||||
type_indicator_border_thickness);
|
type_indicator_border_thickness);
|
||||||
@ -194,10 +231,10 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
// Draw inner + outer border of the circle
|
// Draw inner + outer border of the circle
|
||||||
set_color_for_state(cairo, state, &state->args.colors.line);
|
set_color_for_state(cairo, state, &state->args.colors.line);
|
||||||
cairo_set_line_width(cairo, 2.0 * surface->scale);
|
cairo_set_line_width(cairo, 2.0 * surface->scale);
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2,
|
||||||
arc_radius - arc_thickness / 2, 0, 2 * M_PI);
|
arc_radius - arc_thickness / 2, 0, 2 * M_PI);
|
||||||
cairo_stroke(cairo);
|
cairo_stroke(cairo);
|
||||||
cairo_arc(cairo, buffer_width / 2, buffer_height / 2,
|
cairo_arc(cairo, buffer_diameter / 2, buffer_diameter / 2,
|
||||||
arc_radius + arc_thickness / 2, 0, 2 * M_PI);
|
arc_radius + arc_thickness / 2, 0, 2 * M_PI);
|
||||||
cairo_stroke(cairo);
|
cairo_stroke(cairo);
|
||||||
|
|
||||||
@ -210,8 +247,8 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
cairo_text_extents(cairo, layout_text, &extents);
|
cairo_text_extents(cairo, layout_text, &extents);
|
||||||
cairo_font_extents(cairo, &fe);
|
cairo_font_extents(cairo, &fe);
|
||||||
// upper left coordinates for box
|
// upper left coordinates for box
|
||||||
x = (buffer_width / 2) - (extents.width / 2) - box_padding;
|
x = (buffer_diameter / 2) - (extents.width / 2) - box_padding;
|
||||||
y = (buffer_height / 2) + arc_radius + arc_thickness/2 +
|
y = (buffer_diameter / 2) + arc_radius + arc_thickness/2 +
|
||||||
box_padding; // use box_padding also as gap to indicator
|
box_padding; // use box_padding also as gap to indicator
|
||||||
|
|
||||||
// background box
|
// background box
|
||||||
@ -235,9 +272,11 @@ void render_frame(struct swaylock_surface *surface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_set_buffer_scale(surface->surface, surface->scale);
|
wl_surface_set_buffer_scale(surface->child, surface->scale);
|
||||||
wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0);
|
wl_surface_attach(surface->child, surface->current_buffer->buffer, 0, 0);
|
||||||
wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height);
|
wl_surface_damage(surface->child, 0, 0, surface->current_buffer->width, surface->current_buffer->height);
|
||||||
|
wl_surface_commit(surface->child);
|
||||||
|
|
||||||
wl_surface_commit(surface->surface);
|
wl_surface_commit(surface->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user