[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#45292: Acknowledgement (28.0.50; first key typed ignores current inp
From: |
Stefan Monnier |
Subject: |
bug#45292: Acknowledgement (28.0.50; first key typed ignores current input method (in magit commit buffer)) |
Date: |
Wed, 23 Dec 2020 18:32:20 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
> Digged into it further. Here's what I found:
>
> 1. quail-input-method is used to translate keys according current keymap.
>
> 2. At the time of the first keystroke ("j" in my example) quail-input-method
> sees incorrect buffer (verified this by calling and printing buffer-name
> from inside quail-input-method). It sees "magit: test-repo" on the first
> keystroke, and "COMMIT_EDITMSG" on subsequent keystrokes. And since "magit:
> test-repo" is read-only, no translation is done and key is returned as-is.
>
> 3. So apparently record_asynch_buffer_change() was crucial to update the
> current buffer.
Here's what's happening:
1- after hitting `c c`, Magit launches `git` in the background
2- at this point we're entering `read_char` and the current buffer is the
Magit buffer.
3- soon after, git launches the editor, which Magit has set to emacsclient
4- emacsclient contacts us
5- while still in `read_char` is waiting in `sit_for`, we process
emacsclient which sets up the git-commit buffer,
displays it and select it as the main window.
6- `sit_for` carefully preserves the current buffer so after step 5,
we're still in the Magit buffer even though the selected windows is
not the git-commit one.
7- we hit `j` in the git-commit buffer/window but it's read while in
cvs-commit
8- boom!
I installed the patch below which fixes this problem.
Stefan
diff --git a/src/dispnew.c b/src/dispnew.c
index bcea26a66a..534002584e 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6062,6 +6062,8 @@ sit_for (Lisp_Object timeout, bool reading, int
display_option)
intmax_t sec;
int nsec;
bool do_display = display_option > 0;
+ bool curbuf_eq_winbuf
+ = (current_buffer == XBUFFER (XWINDOW (selected_window)->contents));
swallow_events (do_display);
@@ -6116,6 +6118,13 @@ sit_for (Lisp_Object timeout, bool reading, int
display_option)
wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
Qnil, NULL, 0);
+ if (reading && curbuf_eq_winbuf)
+ /* Timers and process filters/sentinels may have changed the selected
+ window (e.g. in response to a connection from emacsclient), in which
+ case we should follow it (unless we weren't in the selected-window's
+ buffer to start with). */
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
+
return detect_input_pending () ? Qnil : Qt;
}