diff --git a/admin/notes/multi-tty b/admin/notes/multi-tty index c4273fd4431..08608b14c58 100644 --- a/admin/notes/multi-tty +++ b/admin/notes/multi-tty @@ -411,6 +411,9 @@ THINGS TO DO resolved introducing a complex protocol to remotely bail out of single-kboard mode by pressing C-g. + Update (from spwhitton): We have instead added the new + 'multiple-terminals-merge-keyboards' user option (bug#79892). + ** The session management module is prone to crashes when the X connection is closed and then later I try to connect to a new X session: diff --git a/etc/NEWS b/etc/NEWS index 04bf92aa78b..ef36df52ec1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -870,6 +870,13 @@ purple bar cursor on compatible terminals as well. See the Info node You can use this command to copy options from a theme into your user configuration. +--- +** New user option 'multiple-terminals-merge-keyboards'. +Customizing this option to non-nil disables entering single-keyboard +mode in most cases in which Emacs would by default enter that mode. +This can make things work better for some cases of X forwarding; see the +docstring for the new option. + * Editing Changes in Emacs 31.1 diff --git a/lisp/cus-start.el b/lisp/cus-start.el index d39381d8eec..0ba77b197cc 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -426,6 +426,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of ;; (directory :format "%v")))) (load-prefer-newer lisp boolean "24.4") (record-all-keys keyboard boolean) + (multiple-terminals-merge-keyboards keyboard boolean "31.1") ;; minibuf.c (minibuffer-follows-selected-frame minibuffer (choice (const :tag "Always" t) diff --git a/src/callint.c b/src/callint.c index ed86bc90048..398bfde468b 100644 --- a/src/callint.c +++ b/src/callint.c @@ -244,7 +244,8 @@ usage: (funcall-interactively FUNCTION &rest ARGUMENTS) */) (ptrdiff_t nargs, Lisp_Object *args) { specpdl_ref speccount = SPECPDL_INDEX (); - temporarily_switch_to_single_kboard (NULL); + if (!multiple_terminals_merge_keyboards) + temporarily_switch_to_single_kboard (NULL); /* Nothing special to do here, all the work is inside `called-interactively-p'. Which will look for us as a marker in the diff --git a/src/keyboard.c b/src/keyboard.c index 55fb2401f2b..994356b0919 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -826,7 +826,7 @@ This function is called by the editor initialization to begin editing. */) like it is done in the splash screen display, we have to make sure that we restore single_kboard as command_loop_1 would have done if it were left normally. */ - if (command_loop_level > 0) + if (command_loop_level > 0 && !multiple_terminals_merge_keyboards) temporarily_switch_to_single_kboard (SELECTED_FRAME ()); recursive_edit_1 (); @@ -2374,10 +2374,10 @@ read_event_from_main_queue (struct timespec *end_time, && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click)))) { - AUTO_STRING (locked, "Frame is locked while another" - " waits for input" - " or is otherwise in a recursive edit"); - message3_frame (locked, frame); + AUTO_STRING (locked, "Frame is locked; see" + " `multiple-terminals-merge-keyboards'" + " variable"); + message3_frame (Fformat_message (1, &locked), frame); } c = Qnil; goto start; @@ -14448,6 +14448,41 @@ function is called to remap that sequence. */); Vcurrent_key_remap_sequence = Qnil; DEFSYM (Qcurrent_key_remap_sequence, "current-key-remap-sequence"); + DEFVAR_BOOL ("multiple-terminals-merge-keyboards", + multiple_terminals_merge_keyboards, + doc: /* If non-nil, treat different terminals' keyboards as less isolated. + +Each terminal displaying Emacs frames has an associated keyboard. +Normally, Emacs assumes that these keyboards are physically +distinct, so that someone could be typing on one keyboard and +someone else typing on another, into different frames on different +terminals. In certain situations, however, Emacs enters +single-keyboard mode, in which input from all but one keyboard is +blocked. This prevents keys typed on one keyboard from interfering +with an operation started on another keyboard. The main operation +to which this applies is entering a recursive edit, which includes +all minibuffer prompting. + +Single-keyboard mode can be inconvenient when there are distinct +terminals and so distinct keyboards, but only one user and one +physical keyboard in control of Emacs. This can happen with X +forwarding: with a remote Emacs daemon and multiple frames created +with a command like `ssh -X daemon-host emacsclient -c', then from +the remote Emacs daemon's point of view there is one terminal and +one keyboard per `ssh -X daemon-host' command invoked, but in fact a +single local X server displays all frames, and there is just one +physical keyboard. In this situation, you may prefer to have the +different frames behave as though they had been created with +\\[make-frame-command]. In that case, starting a recursive edit in \ +one frame does +not mean that keyboard input into other frames is blocked. + +If this option is non-nil, Emacs will not enter single-keyboard +mode when entering a recursive edit. It will still enter +single-keyboard mode in certain other cases where doing so is +necessary for the operation to work at all. */); + multiple_terminals_merge_keyboards = false; + pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); DEFSYM (Qactivate_mark_hook, "activate-mark-hook"); diff --git a/src/minibuf.c b/src/minibuf.c index e49663e2f86..c716ac0d811 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -712,7 +712,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, if (minibuffer_auto_raise) Fraise_frame (mini_frame); - temporarily_switch_to_single_kboard (XFRAME (mini_frame)); + if (!multiple_terminals_merge_keyboards) + temporarily_switch_to_single_kboard (XFRAME (mini_frame)); /* We have to do this after saving the window configuration since that is what restores the current buffer. */