]> git.sur5r.net Git - i3/i3lock/commitdiff
Displaying locking message when grabbing the pointer/keyboard. (#88)
authoreplanet <emeric.planet@gmail.com>
Wed, 28 Sep 2016 01:39:52 +0000 (03:39 +0200)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Wed, 28 Sep 2016 01:39:52 +0000 (18:39 -0700)
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.

i3lock.c
unlock_indicator.c
unlock_indicator.h
xcb.c

index 6778e5e661650a2ac5773e7ce4d98dc6a63c1dfd..06531e61e0485489f9699fffab213b603b71dc31 100644 (file)
--- 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);
index 7e697b02da8f8c6d54cf0137ecf1701285f92a34..ee3f0cc407980773534cd3d45621ce9a38b1f4b8 100644 (file)
@@ -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;
index d08fd0cb951daeae13e92eea0ec1047843fe038f..e6795647d37350cc0442bd1cb62e5c523be9768e 100644 (file)
@@ -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 3e8cd071c455954b1189fed6e4392ce3338f7140..92c78469c664a5e1c0819f4bb4d6fa815112af81 100644 (file)
--- a/xcb.c
+++ b/xcb.c
 #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)