Compare commits

...

4 Commits

Author SHA1 Message Date
Nikolay Nechaev 9a874cc4fb
Merge 014233ee6f into 46aa0b3719 2024-02-24 17:12:46 -05:00
James Pilcher 46aa0b3719
Removed dead link from README (#293) 2024-01-17 21:20:14 -08:00
Nikolay Nechaev 014233ee6f Fixed behavior when user unlocks too early
If user has entered a correct password and pressed enter before the
initialization has completed, i3lock used to verify the password but not
exit correctly, which was easy to encounter with a high sigma value for blurring.

I wonder if there is a more elegant implementation...
2023-05-20 17:09:24 +03:00
Nikolay Nechaev 2b005468bf When blur is requested, open the window before blurring
When locking screen, first open the window with a color (specified with
`--color`) as background, then, if blurring is requested, do that and
redraw window.

Relates to #239
2023-05-20 17:09:24 +03:00
2 changed files with 44 additions and 25 deletions

View File

@ -158,7 +158,7 @@ A FreeBSD port is available on freshports: [x11/i3lock-color/](https://www.fresh
## Running i3lock-color
Simply invoke the 'i3lock' command. To get out of it, enter your password and press enter.
A [sample script](examples/lock.sh) is included in this repository. [See the script in action](https://streamable.com/fpl46)
A [sample script](examples/lock.sh) is included in this repository.
On OpenBSD the `i3lock` binary needs to be setgid `auth` to call the authentication helpers, e.g. `/usr/libexec/auth/login_passwd`.

View File

@ -232,6 +232,10 @@ int failed_attempts = 0;
bool show_failed_attempts = false;
bool retry_verification = false;
/* Set to true by `input_done` when the password is correct.
* Needed if user has entered password before intialization completed. */
bool unlocked = false;
static struct xkb_state *xkb_state;
static struct xkb_context *xkb_context;
static struct xkb_keymap *xkb_keymap;
@ -564,6 +568,7 @@ static void input_done(void) {
if (no_verify) {
ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}
@ -578,6 +583,7 @@ static void input_done(void) {
clear_password_memory();
ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}
#else
@ -593,6 +599,7 @@ static void input_done(void) {
pam_cleanup = true;
ev_break(EV_DEFAULT, EVBREAK_ALL);
unlocked = true;
return;
}
#endif
@ -2533,20 +2540,10 @@ int main(int argc, char *argv[]) {
free(image_raw_format);
xcb_pixmap_t bg_pixmap = bg_pixmap; // Initialized only `if (blur)`
if (blur) {
xcb_pixmap_t bg_pixmap = capture_bg_pixmap(conn, screen, last_resolution);
cairo_surface_t *xcb_img = cairo_xcb_surface_create(conn, bg_pixmap, get_root_visual_type(screen), last_resolution[0], last_resolution[1]);
blur_bg_img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, last_resolution[0], last_resolution[1]);
cairo_t *ctx = cairo_create(blur_bg_img);
cairo_set_source_surface(ctx, xcb_img, 0, 0);
cairo_paint(ctx);
blur_image_surface(blur_bg_img, blur_sigma);
cairo_destroy(ctx);
cairo_surface_destroy(xcb_img);
xcb_free_pixmap(conn, bg_pixmap);
// Make the screenshot before opening the window, blur it later
bg_pixmap = capture_bg_pixmap(conn, screen, last_resolution);
}
xcb_window_t stolen_focus = find_focused_window(conn, screen->root);
@ -2581,6 +2578,23 @@ int main(int argc, char *argv[]) {
}
}
if (blur) {
// Blurring the earlier taken screenshot (`bg_pixmap`)
cairo_surface_t *xcb_img = cairo_xcb_surface_create(conn, bg_pixmap, get_root_visual_type(screen), last_resolution[0], last_resolution[1]);
blur_bg_img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, last_resolution[0], last_resolution[1]);
cairo_t *ctx = cairo_create(blur_bg_img);
cairo_set_source_surface(ctx, xcb_img, 0, 0);
cairo_paint(ctx);
blur_image_surface(blur_bg_img, blur_sigma);
cairo_destroy(ctx);
cairo_surface_destroy(xcb_img);
xcb_free_pixmap(conn, bg_pixmap);
}
pid_t pid = fork();
/* The pid == -1 case is intentionally ignored here:
* While the child process is useful for preventing other windows from
@ -2626,19 +2640,24 @@ int main(int argc, char *argv[]) {
* file descriptor becomes readable). */
ev_invoke(main_loop, xcb_check, 0);
if (show_clock || bar_enabled || slideshow_enabled) {
if (redraw_thread) {
struct timespec ts;
double s;
double ns = modf(refresh_rate, &s);
ts.tv_sec = (time_t) s;
ts.tv_nsec = ns * NANOSECONDS_IN_SECOND;
(void) pthread_create(&draw_thread, NULL, start_time_redraw_tick_pthread, (void*) &ts);
} else {
start_time_redraw_tick(main_loop);
/* If the user was fast enough to have typed their password (and pressed Enter) before
* i3lock has finished intializing, all of that is processed in the above `ev_invoke`.
* If the password was correct (`unlocked` is true), we should not enter the event loop. */
if (!unlocked) {
if (show_clock || bar_enabled || slideshow_enabled) {
if (redraw_thread) {
struct timespec ts;
double s;
double ns = modf(refresh_rate, &s);
ts.tv_sec = (time_t) s;
ts.tv_nsec = ns * NANOSECONDS_IN_SECOND;
(void) pthread_create(&draw_thread, NULL, start_time_redraw_tick_pthread, (void*) &ts);
} else {
start_time_redraw_tick(main_loop);
}
}
ev_loop(main_loop, 0);
}
ev_loop(main_loop, 0);
#ifndef __OpenBSD__
if (pam_cleanup) {