More cleverness in midend_process_key()

It now strips off modifier flags from keys that shouldn't have them and
maps printable characters with MOD_CTRL to the corresponding control
characters.  It also catches Ctrl+Shift+Z because that obviously belongs
in the midend.

I've updated the JavaScript front-end to take advantage of these
changes.  Other front ends are unchanged and should work just as they
did before.
This commit is contained in:
Ben Harris
2023-02-23 22:32:53 +00:00
parent 015bd14474
commit 9dbcfa765b
3 changed files with 27 additions and 15 deletions

View File

@ -3191,8 +3191,9 @@ The front end calls this function to report a mouse or keyboard event.
The parameters \c{x} and \c{y} are identical to the ones passed to the The parameters \c{x} and \c{y} are identical to the ones passed to the
back end function \cw{interpret_move()} (\k{backend-interpret-move}). back end function \cw{interpret_move()} (\k{backend-interpret-move}).
\c{button} is \e{almost} identical to the parameter passed to \c{button} is similar to the parameter passed to
\cw{interpret_move()}. However, some additional special button values \cw{interpret_move()}. However, the midend is more relaxed about
values passed to in, and some additional special button values
are defined for the front end to pass to the midend (see below). are defined for the front end to pass to the midend (see below).
Also, the front end is \e{not} required to provide guarantees about Also, the front end is \e{not} required to provide guarantees about
@ -3266,6 +3267,11 @@ items the same, by translating each of them into a button code passed
to the midend, and handle quitting by noticing the \c{false} return to the midend, and handle quitting by noticing the \c{false} return
value from \cw{midend_process_key()}.) value from \cw{midend_process_key()}.)
The midend tolerates any modifier being set on any key and removes
them as necessary before passing the key on to the backend. It will
also handle translating printable characters combined with
\cw{MOD_CTRL} into control characters.
\H{midend-request-keys} \cw{midend_request_keys()} \H{midend-request-keys} \cw{midend_request_keys()}
\c key_label *midend_request_keys(midend *me, int *nkeys); \c key_label *midend_request_keys(midend *me, int *nkeys);

16
emcc.c
View File

@ -408,19 +408,9 @@ bool key(int keycode, const char *key, const char *chr, int location,
keyevent = keycode; keyevent = keycode;
if (keyevent >= 0) { if (keyevent >= 0) {
if (shift && (keyevent >= 0x100 && !IS_UI_FAKE_KEY(keyevent))) if (shift) keyevent |= MOD_SHFT;
keyevent |= MOD_SHFT; if (ctrl) keyevent |= MOD_CTRL;
if (location == DOM_KEY_LOCATION_NUMPAD) keyevent |= MOD_NUM_KEYPAD;
if (ctrl && !IS_UI_FAKE_KEY(keyevent)) {
if (keyevent >= 0x100)
keyevent |= MOD_CTRL;
else
keyevent &= 0x1F;
}
if ('0' <= keyevent && keyevent <= '9' &&
location == DOM_KEY_LOCATION_NUMPAD)
keyevent |= MOD_NUM_KEYPAD;
midend_process_key(me, 0, 0, keyevent, &handled); midend_process_key(me, 0, 0, keyevent, &handled);
post_move(); post_move();

View File

@ -1140,6 +1140,10 @@ bool midend_process_key(midend *me, int x, int y, int button, bool *handled)
* of '\n' etc for keyboard-based cursors. The choice of buttons * of '\n' etc for keyboard-based cursors. The choice of buttons
* here could eventually be controlled by a runtime configuration * here could eventually be controlled by a runtime configuration
* option. * option.
*
* We also handle converting MOD_CTRL|'a' etc into '\x01' etc,
* specially recognising Ctrl+Shift+Z, and stripping modifier
* flags off keys that aren't meant to have them.
*/ */
if (IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) { if (IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) {
if (me->pressed_mouse_button) { if (me->pressed_mouse_button) {
@ -1169,6 +1173,18 @@ bool midend_process_key(midend *me, int x, int y, int button, bool *handled)
(LEFT_RELEASE - LEFT_BUTTON)), handled); (LEFT_RELEASE - LEFT_BUTTON)), handled);
} }
/* Canonicalise CTRL+ASCII. */
if ((button & MOD_CTRL) && (button & ~MOD_MASK) < 0x80)
button = button & (0x1f | (MOD_MASK & ~MOD_CTRL));
/* Special handling to make CTRL+SHFT+Z into REDO. */
if ((button & (~MOD_MASK | MOD_SHFT)) == (MOD_SHFT | '\x1A'))
button = UI_REDO;
/* interpret_move() expects CTRL and SHFT only on cursor keys. */
if (!IS_CURSOR_MOVE(button & ~MOD_MASK))
button &= ~(MOD_CTRL | MOD_SHFT);
/* ... and NUM_KEYPAD only on ASCII values. */
if ((button & ~MOD_MASK) >= 0x80)
button &= ~MOD_NUM_KEYPAD;
/* /*
* Translate keyboard presses to cursor selection. * Translate keyboard presses to cursor selection.
*/ */