1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-21 06:55:39 +00:00

Improve touch screen and text conversion behavior of many commands

* doc/lispref/commands.texi (Key Sequence Input): Document new
argument to `read-key-sequence' etc.
* lisp/help-macro.el (make-help-screen):
* lisp/subr.el (read-key, read-char-choice-with-read-key):
Disable text conversion and display the OSK before reading a key
sequence.
* lisp/touch-screen.el (touch-screen-window-selection-changed):
Only cancel the minibuffer OSK timer.
(touch-screen-handle-point-up): Update comment accordingly.
* src/keyboard.c (command_loop_1, read_menu_command)
(read_key_sequence, read_key_sequence_vs, Fread_key_sequence)
(Fread_key_sequence_vector): New arg DISABLE_TEXT_CONVERSION.
All callers changed.
This commit is contained in:
Po Lu 2023-07-21 21:23:35 +08:00
parent 2df3f89014
commit ae174f266d
6 changed files with 84 additions and 34 deletions

View File

@ -3160,7 +3160,7 @@ debugging terminal input.
@code{read-key-sequence}. Lisp programs can also call this function;
for example, @code{describe-key} uses it to read the key to describe.
@defun read-key-sequence prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop
@defun read-key-sequence prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop disable-text-conversion
This function reads a key sequence and returns it as a string or
vector. It keeps reading events until it has accumulated a complete key
sequence; that is, enough to specify a non-prefix command using the
@ -3200,6 +3200,12 @@ key sequence is being read by something that will read commands one
after another. It should be @code{nil} if the caller will read just
one key sequence.
The argument @var{disable-text-conversion}, if non-@code{nil}, means
that system input methods will not directly perform edits to buffer
text while this key sequence is being read; user input will always
generated individual key events instead. @xref{Misc Events} for more
about text conversion.
In the following example, Emacs displays the prompt @samp{?} in the
echo area, and then the user types @kbd{C-x C-f}.
@ -3220,7 +3226,7 @@ typed while reading with this function works like any other character,
and does not set @code{quit-flag}. @xref{Quitting}.
@end defun
@defun read-key-sequence-vector prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop
@defun read-key-sequence-vector prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop disable-text-conversion
This is like @code{read-key-sequence} except that it always
returns the key sequence as a vector, never as a string.
@xref{Strings of Events}.

View File

@ -166,6 +166,7 @@ and then returns."
(error nil))
(let ((cursor-in-echo-area t)
(overriding-local-map local-map))
(frame-toggle-on-screen-keyboard nil nil)
(setq key (read-key-sequence
(format "Type one of listed options%s: "
(if (pos-visible-in-window-p
@ -179,7 +180,13 @@ and then returns."
(help--key-description-fontified (kbd "SPC"))
"/"
(help--key-description-fontified (kbd "DEL"))
" to scroll"))))
" to scroll")))
nil nil nil nil
;; Disable ``text conversion''. OS
;; input methods might otherwise chose
;; to insert user input directly into
;; a buffer.
t)
char (aref key 0)))
;; If this is a scroll bar command, just run it.

View File

@ -3097,6 +3097,11 @@ So escape sequences and keyboard encoding are taken into account.
When there's an ambiguity because the key looks like the prefix of
some sort of escape sequence, the ambiguity is resolved via `read-key-delay'.
Also in contrast to `read-event', input method text conversion
will be disabled while the key sequence is read, so that
character input events will always be generated for keyboard
input.
If the optional argument PROMPT is non-nil, display that as a
prompt.
@ -3155,7 +3160,8 @@ only unbound fallback disabled is downcasing of the last event."
(lookup-key global-map [tool-bar])))
map))
(let* ((keys
(catch 'read-key (read-key-sequence-vector prompt nil t)))
(catch 'read-key (read-key-sequence-vector prompt nil t
nil nil t)))
(key (aref keys 0)))
(if (and (> (length keys) 1)
(memq key '(mode-line header-line
@ -3341,6 +3347,8 @@ causes it to evaluate `help-form' and display the result."
(while (not done)
(unless (get-text-property 0 'face prompt)
(setq prompt (propertize prompt 'face 'minibuffer-prompt)))
;; Display the on screen keyboard if it exists.
(frame-toggle-on-screen-keyboard nil t)
(setq char (let ((inhibit-quit inhibit-keyboard-quit))
(read-key prompt)))
(and show-help (buffer-live-p (get-buffer helpbuf))

View File

@ -926,16 +926,14 @@ then move point to the position of POINT."
(defun touch-screen-window-selection-changed (frame)
"Notice that FRAME's selected window has changed.
If point is now on read only text, hide the on screen keyboard.
Otherwise, cancel any timer that is supposed to hide the keyboard
in response to the minibuffer being closed."
Cancel any timer that is supposed to hide the keyboard in
response to the minibuffer being closed."
(with-selected-frame frame
(if (and (or buffer-read-only
(get-text-property (point) 'read-only))
;; Don't hide the on-screen keyboard if it's always
;; supposed to be displayed.
(not touch-screen-display-keyboard))
(frame-toggle-on-screen-keyboard (selected-frame) t)
(unless (and (or buffer-read-only
(get-text-property (point) 'read-only))
;; Don't hide the on-screen keyboard if it's always
;; supposed to be displayed.
(not touch-screen-display-keyboard))
;; Prevent hiding the minibuffer from hiding the on screen
;; keyboard.
(when minibuffer-on-screen-keyboard-timer
@ -1027,10 +1025,8 @@ is not read-only."
;; opened, add
;; `touch-screen-window-selection-changed'
;; as a window selection change function
;; This allows the on screen keyboard to be
;; hidden if the selected window's point
;; becomes read only at some point in the
;; future.
;; This then prevents it from being hidden
;; after exiting the minibuffer.
(progn
(add-hook 'window-selection-change-functions
#'touch-screen-window-selection-changed)

View File

@ -537,7 +537,8 @@ invoke it (via an `interactive' spec that contains, for instance, an
make_fixnum (SCHARS (callint_message)),
Qface, Qminibuffer_prompt, callint_message);
args[i] = Fread_key_sequence (callint_message,
Qnil, Qnil, Qnil, Qnil);
Qnil, Qnil, Qnil, Qnil,
Qnil);
unbind_to (speccount1, Qnil);
visargs[i] = Fkey_description (args[i], Qnil);
@ -567,7 +568,8 @@ invoke it (via an `interactive' spec that contains, for instance, an
make_fixnum (SCHARS (callint_message)),
Qface, Qminibuffer_prompt, callint_message);
args[i] = Fread_key_sequence_vector (callint_message,
Qnil, Qt, Qnil, Qnil);
Qnil, Qt, Qnil, Qnil,
Qnil);
visargs[i] = Fkey_description (args[i], Qnil);
unbind_to (speccount1, Qnil);

View File

@ -1294,7 +1294,7 @@ some_mouse_moved (void)
enum { READ_KEY_ELTS = 30 };
static int read_key_sequence (Lisp_Object *, Lisp_Object,
bool, bool, bool, bool);
bool, bool, bool, bool, bool);
static void adjust_point_for_property (ptrdiff_t, bool);
static Lisp_Object
@ -1405,7 +1405,8 @@ command_loop_1 (void)
/* Read next key sequence; i gets its length. */
raw_keybuf_count = 0;
Lisp_Object keybuf[READ_KEY_ELTS];
int i = read_key_sequence (keybuf, Qnil, false, true, true, false);
int i = read_key_sequence (keybuf, Qnil, false, true, true, false,
false);
/* A filter may have run while we were reading the input. */
if (! FRAME_LIVE_P (XFRAME (selected_frame)))
@ -1680,7 +1681,8 @@ read_menu_command (void)
specbind (Qecho_keystrokes, make_fixnum (0));
Lisp_Object keybuf[READ_KEY_ELTS];
int i = read_key_sequence (keybuf, Qnil, false, true, true, true);
int i = read_key_sequence (keybuf, Qnil, false, true, true, true,
false);
unbind_to (count, Qnil);
@ -10276,12 +10278,16 @@ restore_reading_key_sequence (int old_reading_key_sequence)
read_char will return it.
If FIX_CURRENT_BUFFER, we restore current_buffer
from the selected window's buffer. */
from the selected window's buffer.
If DISABLE_TEXT_CONVERSION_P, disable text conversion so the input
method will always send key events. */
static int
read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
bool dont_downcase_last, bool can_return_switch_frame,
bool fix_current_buffer, bool prevent_redisplay)
bool fix_current_buffer, bool prevent_redisplay,
bool disable_text_conversion_p)
{
specpdl_ref count = SPECPDL_INDEX ();
@ -10351,7 +10357,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
/* Whether or not text conversion has already been disabled. */
disabled_conversion = false;
#endif
#endif /* HAVE_TEXT_CONVERSION */
struct buffer *starting_buffer;
@ -10445,6 +10451,18 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
if (INTERACTIVE && t < mock_input)
echo_truncate (echo_start);
/* If text conversion is supposed to be disabled immediately, do it
now. */
#ifdef HAVE_TEXT_CONVERSION
if (disable_text_conversion_p)
{
disable_text_conversion ();
record_unwind_protect_void (resume_text_conversion);
disabled_conversion = true;
}
#endif /* HAVE_TEXT_CONVERSION */
/* If the best binding for the current key sequence is a keymap, or
we may be looking at a function key's escape sequence, keep on
reading. */
@ -11279,7 +11297,8 @@ static Lisp_Object
read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo,
Lisp_Object dont_downcase_last,
Lisp_Object can_return_switch_frame,
Lisp_Object cmd_loop, bool allow_string)
Lisp_Object cmd_loop, bool allow_string,
bool disable_text_conversion)
{
specpdl_ref count = SPECPDL_INDEX ();
@ -11306,7 +11325,8 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo,
raw_keybuf_count = 0;
Lisp_Object keybuf[READ_KEY_ELTS];
int i = read_key_sequence (keybuf, prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), false, false);
! NILP (can_return_switch_frame), false, false,
disable_text_conversion);
#if 0 /* The following is fine for code reading a key sequence and
then proceeding with a lengthy computation, but it's not good
@ -11328,7 +11348,7 @@ read_key_sequence_vs (Lisp_Object prompt, Lisp_Object continue_echo,
(i, keybuf)));
}
DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 5, 0,
DEFUN ("read-key-sequence", Fread_key_sequence, Sread_key_sequence, 1, 6, 0,
doc: /* Read a sequence of keystrokes and return as a string or vector.
The sequence is sufficient to specify a non-prefix command in the
current local and global maps.
@ -11374,20 +11394,31 @@ sequences, where they wouldn't conflict with ordinary bindings. See
The optional fifth argument CMD-LOOP, if non-nil, means
that this key sequence is being read by something that will
read commands one after another. It should be nil if the caller
will read just one key sequence. */)
(Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop)
will read just one key sequence.
The optional sixth argument DISABLE-TEXT-CONVERSION, if non-nil, means
disable input method text conversion for the duration of reading this
key sequence, and that keyboard input will always result in key events
being sent. */)
(Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last,
Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop,
Lisp_Object disable_text_conversion)
{
return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last,
can_return_switch_frame, cmd_loop, true);
can_return_switch_frame, cmd_loop, true,
!NILP (disable_text_conversion));
}
DEFUN ("read-key-sequence-vector", Fread_key_sequence_vector,
Sread_key_sequence_vector, 1, 5, 0,
Sread_key_sequence_vector, 1, 6, 0,
doc: /* Like `read-key-sequence' but always return a vector. */)
(Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last, Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop)
(Lisp_Object prompt, Lisp_Object continue_echo, Lisp_Object dont_downcase_last,
Lisp_Object can_return_switch_frame, Lisp_Object cmd_loop,
Lisp_Object disable_text_conversion)
{
return read_key_sequence_vs (prompt, continue_echo, dont_downcase_last,
can_return_switch_frame, cmd_loop, false);
can_return_switch_frame, cmd_loop, false,
!NILP (disable_text_conversion));
}
/* Return true if input events are pending. */