diff --git a/devel.but b/devel.but index 366ec03..6496aef 100644 --- a/devel.but +++ b/devel.but @@ -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 back end function \cw{interpret_move()} (\k{backend-interpret-move}). -\c{button} is \e{almost} identical to the parameter passed to -\cw{interpret_move()}. However, some additional special button values +\c{button} is similar to the parameter passed to +\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). 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 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()} \c key_label *midend_request_keys(midend *me, int *nkeys); diff --git a/emcc.c b/emcc.c index 8037be4..eedfc35 100644 --- a/emcc.c +++ b/emcc.c @@ -408,19 +408,9 @@ bool key(int keycode, const char *key, const char *chr, int location, keyevent = keycode; if (keyevent >= 0) { - if (shift && (keyevent >= 0x100 && !IS_UI_FAKE_KEY(keyevent))) - keyevent |= MOD_SHFT; - - 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; + if (shift) keyevent |= MOD_SHFT; + if (ctrl) keyevent |= MOD_CTRL; + if (location == DOM_KEY_LOCATION_NUMPAD) keyevent |= MOD_NUM_KEYPAD; midend_process_key(me, 0, 0, keyevent, &handled); post_move(); diff --git a/midend.c b/midend.c index f566251..2365258 100644 --- a/midend.c +++ b/midend.c @@ -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 * here could eventually be controlled by a runtime configuration * 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 (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); } + /* 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. */