
--- a/greeter/Login.h	2020-09-22 08:15:48.445614405 -0700
+++ b/greeter/Login.h	2020-09-22 08:16:04.418229439 -0700
@@ -95,6 +95,7 @@
 # define XtNgreetFace		"greetFace"
 # define XtNfailFace		"failFace"
 # define XtNfailTimeout		"failTimeout"
+# define XtNgrabDelay           "grabDelay"
 # define XtNsessionArgument	"sessionArgument"
 # define XtNsecureSession	"secureSession"
 # define XtNallowAccess		"allowAccess"
--- a/greeter/LoginP.h	2020-09-22 08:16:19.588151594 -0700
+++ b/greeter/LoginP.h	2020-09-22 08:16:33.452749073 -0700
@@ -127,6 +127,7 @@
 	char		*sessionArg;	/* argument passed to session */
 	LoginFunc	notify_done;	/* proc to call when done */
 	int		failTimeout;	/* seconds til drop fail msg */
+	int             grabDelay;      /* time to retry to set the input focus to the login widget */
 	XtIntervalId	interval_id;	/* drop fail message note */
 	Boolean		secure_session;	/* session is secured */
 	Boolean		allow_access;	/* disable access control on login */
--- a/greeter/Login.c	2020-09-22 08:16:45.129246397 -0700
+++ b/greeter/Login.c	2020-09-22 08:19:03.626851807 -0700
@@ -210,6 +210,8 @@
 	(XtPointer) "Password Change Required" },
     {XtNfailTimeout, XtCFailTimeout, XtRInt, sizeof (int),
 	offset(failTimeout), XtRImmediate, (XtPointer) 10},
+    {XtNgrabDelay, XtCGrabDelay, XtRInt, sizeof (int),
+       offset(grabDelay), XtRImmediate, (XtPointer) 10},
     {XtNnotifyDone, XtCCallback, XtRFunction, sizeof (XtPointer),
 	offset(notify_done), XtRFunction, (XtPointer) 0},
     {XtNsessionArgument, XtCSessionArgument, XtRString,	sizeof (char *),
@@ -695,6 +697,37 @@
     ErrorMessage(ctx, w->login.passwdChangeMsg, False);
 }
 
+const char *
+xerrMessage(int e)
+{
+       const char *s;
+
+       switch (e) {
+
+               case BadMatch:
+                       s = "window is not visible";
+                       break;
+
+               case BadWindow:
+                       s = "window is no longer valid";
+                       break;
+
+               default:
+                       s = "generic failure";
+                       break;
+       }
+       return s;
+}
+
+static volatile int xerr;
+
+static int
+xErrorHandler(Display *d, XErrorEvent *xeep)
+{
+       xerr = xeep->error_code;
+       return xerr;
+}
+
 static void
 draw_it (LoginWidget w)
 {
@@ -802,8 +835,40 @@
     }
     RedrawFail (w);
     XorCursor (w);
-    XSetInputFocus (XtDisplay (w), XtWindow (w),
-		    RevertToPointerRoot, CurrentTime);
+
+   if (XGrabKeyboard (XtDisplay (w), XtWindow (w), False, GrabModeAsync,
+                       GrabModeAsync, CurrentTime) != GrabSuccess)
+   {
+                       typedef int (*x_e_h)(Display *, XErrorEvent *);
+               x_e_h originalHandler = XSetErrorHandler(xErrorHandler);
+               int waitsecs = w->login.grabDelay;
+               for (;;) {
+                       xerr = Success;
+                       XSetInputFocus (XtDisplay (w), XtWindow (w),
+                       RevertToPointerRoot, CurrentTime);
+                       XSync(XtDisplay (w), False);
+
+                       if (xerr != BadMatch) {
+                               break;
+                       }
+
+                       if (waitsecs == 0) {    /* timed out */
+                               break;
+                       }
+
+                       if (waitsecs > 0) {
+                               sleep(1);
+                               --waitsecs;
+                       }
+               }
+               (void) XSetErrorHandler(originalHandler);
+
+               if (xerr != Success) {
+                       fprintf(stderr, "%s: failed to set focus; %s\n",
+                                       "greeter", xerrMessage(xerr));
+               }
+  }
+
 }
 
 /* Returns 0 on success, -1 on failure */
--- a/config/Xresources.in	2020-09-22 08:19:33.923767351 -0700
+++ b/config/Xresources.in	2020-09-22 08:20:02.447969714 -0700
@@ -1,4 +1,5 @@
 Xcursor.theme: whiteglass
+xlogin*grabDelay: 5
 
 xlogin*login.translations: #override BS
 	Ctrl<Key>R: abort-display()NLBS
--- a/greeter/Login.h	2020-09-22 10:42:07.782375282 -0700
+++ b/greeter/Login.h	2020-09-22 10:43:04.572299383 -0700
@@ -139,6 +139,7 @@
 # define XtCPasswdPrompt	"PasswdPrompt"
 # define XtCFail		"Fail"
 # define XtCFailTimeout		"FailTimeout"
+# define XtCGrabDelay           "GrabDelay"
 # define XtCSessionArgument	"SessionArgument"
 # define XtCSecureSession	"SecureSession"
 # define XtCAllowAccess		"AllowAccess"
