summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreplanet <emeric.planet@gmail.com>2016-09-28 03:39:52 +0200
committerMichael Stapelberg <stapelberg@users.noreply.github.com>2016-09-27 18:39:52 -0700
commit1c97a8484723b7db6c96c3b7bfa4c86c26f47b5a (patch)
tree0b25192dc3cd1d9fb0151d58174755292cd891f5
parentfd2215b0f08991f0f710533b122a182438ff2237 (diff)
Displaying locking message when grabbing the pointer/keyboard. (#88)
Display "locking…" message when grabbing the pointer/keyboard, after at least 250 ms of unfruitful attempts. If grabbing eventually fails, application will not fork and return 1.
-rw-r--r--i3lock.c15
-rw-r--r--unlock_indicator.c5
-rw-r--r--unlock_indicator.h3
-rw-r--r--xcb.c22
4 files changed, 40 insertions, 5 deletions
diff --git a/i3lock.c b/i3lock.c
index 6778e5e..06531e6 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -977,10 +977,16 @@ int main(int argc, char *argv[]) {
/* Pixmap on which the image is rendered to (if any) */
xcb_pixmap_t bg_pixmap = draw_image(last_resolution);
- /* open the fullscreen window, already with the correct pixmap in place */
+ /* Open the fullscreen window, already with the correct pixmap in place */
win = open_fullscreen_window(conn, screen, color, bg_pixmap);
xcb_free_pixmap(conn, bg_pixmap);
+ cursor = create_cursor(conn, screen, win, curs_choice);
+
+ /* Display the "locking…" message while trying to grab the pointer/keyboard. */
+ pam_state = STATE_PAM_LOCK;
+ grab_pointer_and_keyboard(conn, screen, cursor);
+
pid_t pid = fork();
/* The pid == -1 case is intentionally ignored here:
* While the child process is useful for preventing other windows from
@@ -993,9 +999,6 @@ int main(int argc, char *argv[]) {
exit(EXIT_SUCCESS);
}
- cursor = create_cursor(conn, screen, win, curs_choice);
-
- grab_pointer_and_keyboard(conn, screen, cursor);
/* Load the keymap again to sync the current modifier state. Since we first
* loaded the keymap, there might have been changes, but starting from now,
* we should get all key presses/releases due to having grabbed the
@@ -1007,6 +1010,10 @@ int main(int argc, char *argv[]) {
if (main_loop == NULL)
errx(EXIT_FAILURE, "Could not initialize libev. Bad LIBEV_FLAGS?\n");
+ /* Explicitly call the screen redraw in case "locking…" message was displayed */
+ pam_state = STATE_PAM_IDLE;
+ redraw_screen();
+
struct ev_io *xcb_watcher = calloc(sizeof(struct ev_io), 1);
struct ev_check *xcb_check = calloc(sizeof(struct ev_check), 1);
struct ev_prepare *xcb_prepare = calloc(sizeof(struct ev_prepare), 1);
diff --git a/unlock_indicator.c b/unlock_indicator.c
index 7e697b0..ee3f0cc 100644
--- a/unlock_indicator.c
+++ b/unlock_indicator.c
@@ -156,6 +156,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
* (currently verifying, wrong password, or default) */
switch (pam_state) {
case STATE_PAM_VERIFY:
+ case STATE_PAM_LOCK:
cairo_set_source_rgba(ctx, 0, 114.0 / 255, 255.0 / 255, 0.75);
break;
case STATE_PAM_WRONG:
@@ -169,6 +170,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
switch (pam_state) {
case STATE_PAM_VERIFY:
+ case STATE_PAM_LOCK:
cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255);
break;
case STATE_PAM_WRONG:
@@ -205,6 +207,9 @@ xcb_pixmap_t draw_image(uint32_t *resolution) {
case STATE_PAM_VERIFY:
text = "verifying…";
break;
+ case STATE_PAM_LOCK:
+ text = "locking…";
+ break;
case STATE_PAM_WRONG:
text = "wrong!";
break;
diff --git a/unlock_indicator.h b/unlock_indicator.h
index d08fd0c..e679564 100644
--- a/unlock_indicator.h
+++ b/unlock_indicator.h
@@ -13,7 +13,8 @@ typedef enum {
typedef enum {
STATE_PAM_IDLE = 0, /* no PAM interaction at the moment */
STATE_PAM_VERIFY = 1, /* currently verifying the password via PAM */
- STATE_PAM_WRONG = 2 /* the password was wrong */
+ STATE_PAM_LOCK = 2, /* currently locking the screen */
+ STATE_PAM_WRONG = 3 /* the password was wrong */
} pam_state_t;
xcb_pixmap_t draw_image(uint32_t* resolution);
diff --git a/xcb.c b/xcb.c
index 3e8cd07..92c7846 100644
--- a/xcb.c
+++ b/xcb.c
@@ -18,8 +18,10 @@
#include <unistd.h>
#include <assert.h>
#include <err.h>
+#include <time.h>
#include "cursors.h"
+#include "unlock_indicator.h"
xcb_connection_t *conn;
xcb_screen_t *screen;
@@ -170,6 +172,10 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb
int tries = 10000;
+ /* Using few variables to trigger a redraw_screen() if too many tries */
+ bool redrawn = false;
+ time_t start = clock();
+
while (tries-- > 0) {
pcookie = xcb_grab_pointer(
conn,
@@ -190,6 +196,14 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb
/* Make this quite a bit slower */
usleep(50);
+
+ /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */
+ if (!redrawn &&
+ (tries % 100) == 0 &&
+ (clock() - start) > 250000) {
+ redraw_screen();
+ redrawn = true;
+ }
}
while (tries-- > 0) {
@@ -209,6 +223,14 @@ void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb
/* Make this quite a bit slower */
usleep(50);
+
+ /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */
+ if (!redrawn &&
+ (tries % 100) == 0 &&
+ (clock() - start) > 250000) {
+ redraw_screen();
+ redrawn = true;
+ }
}
if (tries <= 0)