summaryrefslogtreecommitdiff
path: root/src/input.c
diff options
context:
space:
mode:
authorShawn <sabetts@juicebox>2008-02-06 14:16:37 -0800
committerShawn <sabetts@juicebox>2008-02-06 14:16:37 -0800
commitbd51b1705292845686f8f682d15f6b7b90ddc787 (patch)
tree17419004fb598453f019bc57cc1d33063a0f1327 /src/input.c
parentcbcc8f2882ac8985a027b5c8423b5e764c51c158 (diff)
downloadratpoison-bd51b1705292845686f8f682d15f6b7b90ddc787.zip
Change the way input is read
Before rp used xgrabkeyboard to read a key. Instead, the keyboard is frozen when a top level key is read. Then when rp reads a key it first sets the input focus to a suitable location such as key_window or input_window, then thaws the keyboard and waits for a keypress. When a key is pressed the keyboard is frozen again and the process repeats until ratpoison is done reading input. At that point the keyboard is thawed in a way that future keystrokes do not refreeze the keyboard.
Diffstat (limited to 'src/input.c')
-rw-r--r--src/input.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/input.c b/src/input.c
index 3350341..3297ac7 100644
--- a/src/input.c
+++ b/src/input.c
@@ -377,6 +377,30 @@ cook_keycode (XKeyEvent *ev, KeySym *keysym, unsigned int *mod, char *keysym_nam
return nbytes;
}
+/* Wait for a key and discard it. */
+void
+read_any_key ()
+{
+ char buffer[513];
+ unsigned int mod;
+ KeySym c;
+
+ read_single_key (&c, &mod, buffer, sizeof (buffer));
+}
+
+/* The same as read_key, but handle focusing the key_window and reverting focus. */
+int
+read_single_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
+{
+ Window focus;
+ int revert;
+
+ XGetInputFocus (dpy, &focus, &revert);
+ set_window_focus (current_screen()->key_window);
+ read_key (keysym, modifiers, keysym_name, len);
+ set_window_focus (focus);
+}
+
int
read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
{
@@ -386,10 +410,13 @@ read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
/* Read a key from the keyboard. */
do
{
- XMaskEvent (dpy, KeyPressMask, &ev);
+ /* The keyboard is frozen, so unfreeze it and allow another key to come in. */
+ XAllowEvents (dpy, SyncKeyboard, CurrentTime);
+
+ XMaskEvent (dpy, KeyPressMask|KeyRelease, &ev);
*modifiers = ev.xkey.state;
nbytes = cook_keycode (&ev.xkey, keysym, modifiers, keysym_name, len, 0);
- } while (IsModifierKey (*keysym));
+ } while (IsModifierKey (*keysym) || ev.xkey.type == KeyRelease);
return nbytes;
}
@@ -503,6 +530,8 @@ get_more_input (char *prompt, char *preinput,
rp_input_line *line;
char *final_input;
edit_status status;
+ Window focus;
+ int revert;
#ifdef HAVE_HISTORY
history_reset();
@@ -522,12 +551,13 @@ get_more_input (char *prompt, char *preinput,
XMapWindow (dpy, s->input_window);
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);
update_input_window (s, line);
- XGrabKeyboard (dpy, s->input_window, False, GrabModeSync, GrabModeAsync, CurrentTime);
-
for (;;)
{
nbytes = read_key (&ch, &modifier, keysym_buf, keysym_bufsize);
@@ -566,7 +596,7 @@ get_more_input (char *prompt, char *preinput,
input_line_free (line);
/* Revert focus. */
- XUngrabKeyboard (dpy, CurrentTime);
+ set_window_focus (focus);
XUnmapWindow (dpy, s->input_window);
/* Possibly restore colormap. */