* src/keyboard.c: Fix bug#5803.

A long time ago, `read_key_sequence` used to read the keymaps at the
start, so if something happened between this start and the moment
the user actually hits a key, `read_key_sequence` could end up using
the wrong keymaps.  To work around this problem, the code used
`record_asynch_buffer_change` to try and trigger `read_key_sequence`
to re-read the keymaps in some known cases.

Several years ago, `read_key_sequence` was changed so as to read the keymaps
only once the user hits a key, making this machinery now redundant
(and also harmful apparently in bug#5803 because it introduces
"spurious" events).

So we here remove `record_asynch_buffer_change` and the
`BUFFER_SWITCH_EVENT` and `Qbuffer_switch` pseudo-events it generated.

* src/termhooks.h (enum event_kind): Delete `BUFFER_SWITCH_EVENT`.
* src/keyboard.c: (record_asynch_buffer_change): Delete function.
(syms_of_keyboard): Delete `Qbuffer_switch`.
(force_auto_save_soon, readable_events)
(kbd_buffer_store_buffered_event, kbd_buffer_get_event)
(make_lispy_event):
* src/xterm.c (handle_one_xevent):
* src/w32term.c (w32_read_socket):
* src/process.c (wait_reading_process_output)
(read_and_dispose_of_process_output, exec_sentinel): Simplify accordingly.
This commit is contained in:
Stefan Monnier 2020-12-12 09:56:04 -05:00
parent 7ee0fc0dc1
commit adbb4eacc2
7 changed files with 1 additions and 122 deletions

View file

@ -741,9 +741,6 @@ void
force_auto_save_soon (void)
{
last_auto_save = - auto_save_interval - 1;
/* FIXME: What's the relationship between forcing auto-save and adding
a buffer-switch event? */
record_asynch_buffer_change ();
}
#endif
@ -3431,8 +3428,7 @@ readable_events (int flags)
&& event->ie.part == scroll_bar_handle
&& event->ie.modifiers == 0)
#endif
&& !((flags & READABLE_EVENTS_FILTER_EVENTS)
&& event->kind == BUFFER_SWITCH_EVENT))
)
return 1;
event = next_kbd_event (event);
}
@ -3583,12 +3579,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
return;
}
}
/* Don't insert two BUFFER_SWITCH_EVENT's in a row.
Just ignore the second one. */
else if (event->kind == BUFFER_SWITCH_EVENT
&& kbd_fetch_ptr != kbd_store_ptr
&& prev_kbd_event (kbd_store_ptr)->kind == BUFFER_SWITCH_EVENT)
return;
/* Don't let the very last slot in the buffer become full,
since that would make the two pointers equal,
@ -3622,7 +3612,6 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
case ICONIFY_EVENT: ignore_event = Qiconify_frame; break;
case DEICONIFY_EVENT: ignore_event = Qmake_frame_visible; break;
case SELECTION_REQUEST_EVENT: ignore_event = Qselection_request; break;
case BUFFER_SWITCH_EVENT: ignore_event = Qbuffer_switch; break;
default: ignore_event = Qnil; break;
}
@ -3961,7 +3950,6 @@ kbd_buffer_get_event (KBOARD **kbp,
#ifdef HAVE_XWIDGETS
case XWIDGET_EVENT:
#endif
case BUFFER_SWITCH_EVENT:
case SAVE_SESSION_EVENT:
case NO_EVENT:
case HELP_EVENT:
@ -5341,14 +5329,6 @@ make_lispy_event (struct input_event *event)
return list2 (Qmove_frame, list1 (event->frame_or_window));
#endif
case BUFFER_SWITCH_EVENT:
{
/* The value doesn't matter here; only the type is tested. */
Lisp_Object obj;
XSETBUFFER (obj, current_buffer);
return obj;
}
/* Just discard these, by returning nil.
With MULTI_KBOARD, these events are used as placeholders
when we need to randomly delete events from the queue.
@ -6805,41 +6785,6 @@ get_input_pending (int flags)
return input_pending;
}
/* Put a BUFFER_SWITCH_EVENT in the buffer
so that read_key_sequence will notice the new current buffer. */
void
record_asynch_buffer_change (void)
{
/* We don't need a buffer-switch event unless Emacs is waiting for input.
The purpose of the event is to make read_key_sequence look up the
keymaps again. If we aren't in read_key_sequence, we don't need one,
and the event could cause trouble by messing up (input-pending-p).
Note: Fwaiting_for_user_input_p always returns nil when async
subprocesses aren't supported. */
if (!NILP (Fwaiting_for_user_input_p ()))
{
struct input_event event;
EVENT_INIT (event);
event.kind = BUFFER_SWITCH_EVENT;
event.frame_or_window = Qnil;
event.arg = Qnil;
/* Make sure no interrupt happens while storing the event. */
#ifdef USABLE_SIGIO
if (interrupt_input)
kbd_buffer_store_event (&event);
else
#endif
{
stop_polling ();
kbd_buffer_store_event (&event);
start_polling ();
}
}
}
/* Read any terminal input already buffered up by the system
into the kbd_buffer, but do not wait.
@ -11573,8 +11518,6 @@ syms_of_keyboard (void)
/* Menu and tool bar item parts. */
DEFSYM (Qmenu_enable, "menu-enable");
DEFSYM (Qbuffer_switch, "buffer-switch");
#ifdef HAVE_NTGUI
DEFSYM (Qlanguage_change, "language-change");
DEFSYM (Qend_session, "end-session");

View file

@ -446,7 +446,6 @@ extern void push_kboard (struct kboard *);
extern void push_frame_kboard (struct frame *);
extern void pop_kboard (void);
extern void temporarily_switch_to_single_kboard (struct frame *);
extern void record_asynch_buffer_change (void);
extern void input_poll_signal (int);
extern void start_polling (void);
extern void stop_polling (void);

View file

@ -5333,14 +5333,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
timer_delay = timer_check ();
/* If a timer has run, this might have changed buffers
an alike. Make read_key_sequence aware of that. */
if (timers_run != old_timers_run
&& (old_buffer != current_buffer
|| !EQ (old_window, selected_window))
&& waiting_for_user_input_p == -1)
record_asynch_buffer_change ();
if (timers_run != old_timers_run && do_display)
/* We must retry, since a timer may have requeued itself
and that could alter the time_delay. */
@ -5706,14 +5698,6 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
leave = true;
}
/* If a timer has run, this might have changed buffers
an alike. Make read_key_sequence aware of that. */
if (timers_run != old_timers_run
&& waiting_for_user_input_p == -1
&& (old_buffer != current_buffer
|| !EQ (old_window, selected_window)))
record_asynch_buffer_change ();
if (leave)
break;
}
@ -6213,18 +6197,6 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
/* Restore waiting_for_user_input_p as it was
when we were called, in case the filter clobbered it. */
waiting_for_user_input_p = waiting;
#if 0 /* Call record_asynch_buffer_change unconditionally,
because we might have changed minor modes or other things
that affect key bindings. */
if (! EQ (Fcurrent_buffer (), obuffer)
|| ! EQ (current_buffer->keymap, okeymap))
#endif
/* But do it only if the caller is actually going to read events.
Otherwise there's no need to make him wake up, and it could
cause trouble (for example it would make sit_for return). */
if (waiting_for_user_input_p == -1)
record_asynch_buffer_change ();
}
DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
@ -7390,16 +7362,6 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
when we were called, in case the filter clobbered it. */
waiting_for_user_input_p = waiting;
#if 0
if (! EQ (Fcurrent_buffer (), obuffer)
|| ! EQ (current_buffer->keymap, okeymap))
#endif
/* But do it only if the caller is actually going to read events.
Otherwise there's no need to make him wake up, and it could
cause trouble (for example it would make sit_for return). */
if (waiting_for_user_input_p == -1)
record_asynch_buffer_change ();
unbind_to (count, Qnil);
}

View file

@ -159,7 +159,6 @@ enum event_kind
SELECTION_REQUEST_EVENT, /* Another X client wants a selection from us.
See `struct selection_input_event'. */
SELECTION_CLEAR_EVENT, /* Another X client cleared our selection. */
BUFFER_SWITCH_EVENT, /* A process filter has switched buffers. */
DELETE_WINDOW_EVENT, /* An X client said "delete this window". */
#ifdef HAVE_NTGUI
END_SESSION_EVENT, /* The user is logging out or shutting down. */

View file

@ -140,7 +140,6 @@ struct thread_state
for user-input when that process-filter was called.
waiting_for_input cannot be used as that is by definition 0 when
lisp code is being evalled.
This is also used in record_asynch_buffer_change.
For that purpose, this must be 0
when not inside wait_reading_process_output. */
int m_waiting_for_user_input_p;

View file

@ -4858,10 +4858,6 @@ w32_read_socket (struct terminal *terminal,
inev.kind = DEICONIFY_EVENT;
XSETFRAME (inev.frame_or_window, f);
}
else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list)))
/* Force a redisplay sooner or later to update the
frame titles in case this is the second frame. */
record_asynch_buffer_change ();
}
else
{
@ -5479,12 +5475,6 @@ w32_read_socket (struct terminal *terminal,
inev.kind = DEICONIFY_EVENT;
XSETFRAME (inev.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
/* Force a redisplay sooner or later
to update the frame titles
in case this is the second frame. */
record_asynch_buffer_change ();
/* Windows can send us a SIZE_MAXIMIZED message even
when fullscreen is fullboth. The following is a
@ -5532,12 +5522,6 @@ w32_read_socket (struct terminal *terminal,
inev.kind = DEICONIFY_EVENT;
XSETFRAME (inev.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
/* Force a redisplay sooner or later
to update the frame titles
in case this is the second frame. */
record_asynch_buffer_change ();
}
if (EQ (get_frame_param (f, Qfullscreen), Qmaximized))
@ -5829,9 +5813,6 @@ w32_read_socket (struct terminal *terminal,
SET_FRAME_GARBAGED (f);
DebPrint (("obscured frame %p (%s) found to be visible\n",
f, SDATA (f->name)));
/* Force a redisplay sooner or later. */
record_asynch_buffer_change ();
}
}
}

View file

@ -8383,10 +8383,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
inev.ie.kind = DEICONIFY_EVENT;
XSETFRAME (inev.ie.frame_or_window, f);
}
else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
/* Force a redisplay sooner or later to update the
frame titles in case this is the second frame. */
record_asynch_buffer_change ();
}
goto OTHER;