ratpoison-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RP] [PATCH] Recover lost input focus when ringing bell


From: Joren Van Onder
Subject: [RP] [PATCH] Recover lost input focus when ringing bell
Date: Sun, 18 Mar 2018 14:11:48 -0700

When an application steals focus from input it becomes impossible to
control Ratpoison. An example (save any work before trying this since
you most likely will have to restart Ratpoison):

1. Create prompt.html with the following content:

<html><script>setTimeout(() => { prompt(); }, 3000);</script></html>

2. Open it with Chromium (tested with Chromium 65.0.3325.146)

3. Before the prompt pops up run `exec` (C-t !)

When the prompt pops up it will steal focus from the Ratpoison
input. There does not seem to be an easy way to recover from this,
since the default top keybindings provide no way to close the input.

A more realistic case in which this scenario happens is when opening a
web page protected with HTTP basic access authentication and trying to
open your password manager before the authentication prompt pops up.

To solve this refocus the input when ringing the bell. The bell is
rung when a key is pressed with a modifier that does not result in an
action. This includes `escape` (C-t), probably one of the first
commands a user will try to resolve this.

To do this without duplicating code this moves the already existing
focusing code in a reusable helper function.
---
 src/input.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/input.c b/src/input.c
index c71d58c..a7fdb71 100644
--- a/src/input.c
+++ b/src/input.c
@@ -523,6 +523,16 @@ get_input (char *prompt, int history_id, completion_fn fn)
   return get_more_input (prompt, "", history_id, BASIC, fn);
 }
 
+void
+set_focus_and_sync (rp_screen *s, Window *focus)
+{
+    int revert;
+
+    XGetInputFocus (dpy, focus, &revert);
+    set_window_focus (s->input_window);
+    XSync (dpy, False);
+}
+
 char *
 get_more_input (char *prompt, char *preinput, int history_id,
                 enum completion_styles style, completion_fn compl_fn)
@@ -536,7 +546,7 @@ get_more_input (char *prompt, char *preinput, int 
history_id,
   char *final_input;
   edit_status status;
   Window focus;
-  int revert, done = 0;
+  int done = 0;
 
   history_reset();
 
@@ -555,9 +565,7 @@ get_more_input (char *prompt, char *preinput, int 
history_id,
   XRaiseWindow (dpy, s->input_window);
   XClearWindow (dpy, s->input_window);
   /* Switch focus to our input window to read the next key events. */
-  XGetInputFocus (dpy, &focus, &revert);
-  set_window_focus (s->input_window);
-  XSync (dpy, False);
+  set_focus_and_sync (s, &focus);
 
   update_input_window (s, line);
 
@@ -584,6 +592,7 @@ get_more_input (char *prompt, char *preinput, int 
history_id,
           break;
         case EDIT_NO_OP:
           ring_bell ();
+          set_focus_and_sync (s, &focus);
           break;
         case EDIT_ABORT:
           final_input = NULL;
-- 
2.16.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]