mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
patch 9.0.0087: MS-Windows: CTRL-[ on Belgian keyboard does not work like Esc
Problem: MS-Windows: CTRL-[ on Belgian keyboard does not work like Esc. Solution: Figure out what the key code means. (Anton Sharonov, closes #10687, closes #10454)
This commit is contained in:
committed by
Bram Moolenaar
parent
6791adca53
commit
3f0266739d
@@ -29,6 +29,12 @@
|
|||||||
# include "gui_dwrite.h"
|
# include "gui_dwrite.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// values for "dead_key"
|
||||||
|
#define DEAD_KEY_OFF 0 // no dead key
|
||||||
|
#define DEAD_KEY_SET_DEFAULT 1 // dead key pressed
|
||||||
|
#define DEAD_KEY_TRANSIENT_IN_ON_CHAR 2 // wait for next key press
|
||||||
|
#define DEAD_KEY_SKIP_ON_CHAR 3 // skip next _OnChar()
|
||||||
|
|
||||||
#if defined(FEAT_DIRECTX)
|
#if defined(FEAT_DIRECTX)
|
||||||
static DWriteContext *s_dwc = NULL;
|
static DWriteContext *s_dwc = NULL;
|
||||||
static int s_directx_enabled = 0;
|
static int s_directx_enabled = 0;
|
||||||
@@ -533,7 +539,7 @@ static int s_y_pending;
|
|||||||
static UINT s_kFlags_pending;
|
static UINT s_kFlags_pending;
|
||||||
static UINT_PTR s_wait_timer = 0; // Timer for get char from user
|
static UINT_PTR s_wait_timer = 0; // Timer for get char from user
|
||||||
static int s_timed_out = FALSE;
|
static int s_timed_out = FALSE;
|
||||||
static int dead_key = 0; // 0: no dead key, 1: dead key pressed
|
static int dead_key = DEAD_KEY_OFF;
|
||||||
static UINT surrogate_pending_ch = 0; // 0: no surrogate pending,
|
static UINT surrogate_pending_ch = 0; // 0: no surrogate pending,
|
||||||
// else a high surrogate
|
// else a high surrogate
|
||||||
|
|
||||||
@@ -866,7 +872,13 @@ _OnChar(
|
|||||||
int modifiers;
|
int modifiers;
|
||||||
int ch = cch; // special keys are negative
|
int ch = cch; // special keys are negative
|
||||||
|
|
||||||
dead_key = 0;
|
if (dead_key == DEAD_KEY_SKIP_ON_CHAR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// keep DEAD_KEY_TRANSIENT_IN_ON_CHAR value for later handling in
|
||||||
|
// process_message()
|
||||||
|
if (dead_key != DEAD_KEY_TRANSIENT_IN_ON_CHAR)
|
||||||
|
dead_key = DEAD_KEY_OFF;
|
||||||
|
|
||||||
modifiers = get_active_modifiers();
|
modifiers = get_active_modifiers();
|
||||||
|
|
||||||
@@ -912,7 +924,7 @@ _OnSysChar(
|
|||||||
int modifiers;
|
int modifiers;
|
||||||
int ch = cch; // special keys are negative
|
int ch = cch; // special keys are negative
|
||||||
|
|
||||||
dead_key = 0;
|
dead_key = DEAD_KEY_OFF;
|
||||||
|
|
||||||
// OK, we have a character key (given by ch) which was entered with the
|
// OK, we have a character key (given by ch) which was entered with the
|
||||||
// ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
|
// ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
|
||||||
@@ -1844,14 +1856,14 @@ gui_mch_draw_part_cursor(
|
|||||||
* dead key's nominal character and re-post the original message.
|
* dead key's nominal character and re-post the original message.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
outputDeadKey_rePost(MSG originalMsg)
|
outputDeadKey_rePost_Ex(MSG originalMsg, int dead_key2set)
|
||||||
{
|
{
|
||||||
static MSG deadCharExpel;
|
static MSG deadCharExpel;
|
||||||
|
|
||||||
if (!dead_key)
|
if (dead_key == DEAD_KEY_OFF)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dead_key = 0;
|
dead_key = dead_key2set;
|
||||||
|
|
||||||
// Make Windows generate the dead key's character
|
// Make Windows generate the dead key's character
|
||||||
deadCharExpel.message = originalMsg.message;
|
deadCharExpel.message = originalMsg.message;
|
||||||
@@ -1865,6 +1877,15 @@ outputDeadKey_rePost(MSG originalMsg)
|
|||||||
originalMsg.lParam);
|
originalMsg.lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper for outputDeadKey_rePost_Ex which always reset dead_key value.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
outputDeadKey_rePost(MSG originalMsg)
|
||||||
|
{
|
||||||
|
outputDeadKey_rePost_Ex(originalMsg, DEAD_KEY_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process a single Windows message.
|
* Process a single Windows message.
|
||||||
* If one is not available we hang until one is.
|
* If one is not available we hang until one is.
|
||||||
@@ -1936,8 +1957,47 @@ process_message(void)
|
|||||||
* for some reason TranslateMessage() do not trigger a call
|
* for some reason TranslateMessage() do not trigger a call
|
||||||
* immediately to _OnChar() (or _OnSysChar()).
|
* immediately to _OnChar() (or _OnSysChar()).
|
||||||
*/
|
*/
|
||||||
if (dead_key)
|
|
||||||
|
/*
|
||||||
|
* We are at the moment after WM_CHAR with DEAD_KEY_SKIP_ON_CHAR event
|
||||||
|
* was handled by _WndProc, this keypress we want to process normally
|
||||||
|
*/
|
||||||
|
if (dead_key == DEAD_KEY_SKIP_ON_CHAR)
|
||||||
|
dead_key = DEAD_KEY_OFF;
|
||||||
|
|
||||||
|
if (dead_key != DEAD_KEY_OFF)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Expell the dead key pressed with Ctrl in a special way.
|
||||||
|
*
|
||||||
|
* After dead key was pressed with Ctrl in some cases, ESC was
|
||||||
|
* artificially injected and handled by _OnChar(), now we are
|
||||||
|
* dealing with completely new key press from the user. If we don't
|
||||||
|
* do anything, ToUnicode() call will interpret this vk+scan_code
|
||||||
|
* under influence of "dead-modifier". To prevent this we translate
|
||||||
|
* this message replacing current char from user with VK_SPACE,
|
||||||
|
* which will cause WM_CHAR with dead_key's character itself. Using
|
||||||
|
* DEAD_KEY_SKIP_ON_CHAR value of dead_char we force _OnChar() to
|
||||||
|
* ignore this one WM_CHAR event completely. Afterwards (due to
|
||||||
|
* usage of PostMessage), this procedure is scheduled to be called
|
||||||
|
* again with user char and on next entry we will clean
|
||||||
|
* DEAD_KEY_SKIP_ON_CHAR. We cannot use original
|
||||||
|
* outputDeadKey_rePost() since we do not wish to reset dead_key
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
if (dead_key == DEAD_KEY_TRANSIENT_IN_ON_CHAR)
|
||||||
|
{
|
||||||
|
outputDeadKey_rePost_Ex(msg,
|
||||||
|
/*dead_key2set=*/DEAD_KEY_SKIP_ON_CHAR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dead_key != DEAD_KEY_SET_DEFAULT)
|
||||||
|
{
|
||||||
|
// should never happen - is there a way to make ASSERT here?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a dead key was pressed and the user presses VK_SPACE,
|
* If a dead key was pressed and the user presses VK_SPACE,
|
||||||
* VK_BACK, or VK_ESCAPE it means that he actually wants to deal
|
* VK_BACK, or VK_ESCAPE it means that he actually wants to deal
|
||||||
@@ -1952,7 +2012,7 @@ process_message(void)
|
|||||||
*/
|
*/
|
||||||
if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
|
if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
|
||||||
{
|
{
|
||||||
dead_key = 0;
|
dead_key = DEAD_KEY_OFF;
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1995,7 +2055,7 @@ process_message(void)
|
|||||||
* character output (such as a NUMPAD printable character or
|
* character output (such as a NUMPAD printable character or
|
||||||
* the TAB key, etc...).
|
* the TAB key, etc...).
|
||||||
*/
|
*/
|
||||||
if (dead_key && (special_keys[i].vim_code0 == 'K'
|
if (dead_key == DEAD_KEY_SET_DEFAULT && (special_keys[i].vim_code0 == 'K'
|
||||||
|| vk == VK_TAB || vk == CAR))
|
|| vk == VK_TAB || vk == CAR))
|
||||||
{
|
{
|
||||||
outputDeadKey_rePost(msg);
|
outputDeadKey_rePost(msg);
|
||||||
@@ -2081,10 +2141,28 @@ process_message(void)
|
|||||||
// If this is a dead key ToUnicode returns a negative value.
|
// If this is a dead key ToUnicode returns a negative value.
|
||||||
len = ToUnicode(vk, scan_code, keyboard_state, ch, ARRAY_LENGTH(ch),
|
len = ToUnicode(vk, scan_code, keyboard_state, ch, ARRAY_LENGTH(ch),
|
||||||
0);
|
0);
|
||||||
dead_key = len < 0;
|
if (len < 0)
|
||||||
|
dead_key = DEAD_KEY_SET_DEFAULT;
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
|
{
|
||||||
|
if ( dead_key == DEAD_KEY_SET_DEFAULT
|
||||||
|
&& (GetKeyState(VK_CONTROL) & 0x8000)
|
||||||
|
&& ( (vk == 221 && scan_code == 26) // AZERTY CTRL+dead_circumflex
|
||||||
|
|| (vk == 220 && scan_code == 41) // QWERTZ CTRL+dead_circumflex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// post WM_CHAR='[' - which will be interpreted with CTRL
|
||||||
|
// stil hold as ESC
|
||||||
|
PostMessageW(msg.hwnd, WM_CHAR, '[', msg.lParam);
|
||||||
|
// ask _OnChar() to not touch this state, wait for next key
|
||||||
|
// press and maintain knowledge that we are "poisoned" with
|
||||||
|
// "dead state"
|
||||||
|
dead_key = DEAD_KEY_TRANSIENT_IN_ON_CHAR;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Post the message as TranslateMessage would do.
|
// Post the message as TranslateMessage would do.
|
||||||
if (msg.message == WM_KEYDOWN)
|
if (msg.message == WM_KEYDOWN)
|
||||||
|
@@ -735,6 +735,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
87,
|
||||||
/**/
|
/**/
|
||||||
86,
|
86,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user