0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 7.4.1124

Problem:    MS-Windows: dead key behavior is not ideal.
Solution:   Handle dead keys differently when not in Insert or Select mode.
            (John Wellesz, closes #399)
This commit is contained in:
Bram Moolenaar 2016-01-17 20:53:12 +01:00
parent a24f0a550f
commit 25b2b94ea7
2 changed files with 91 additions and 19 deletions

View File

@ -312,7 +312,7 @@ static int s_y_pending;
static UINT s_kFlags_pending;
static UINT s_wait_timer = 0; /* Timer for get char from user */
static int s_timed_out = FALSE;
static int dead_key = 0; /* 0 - no dead key, 1 - dead key pressed */
static int dead_key = 0; /* 0: no dead key, 1: dead key pressed */
#ifdef WIN3264
static OSVERSIONINFO os_version; /* like it says. Init in gui_mch_init() */
@ -641,6 +641,8 @@ _OnSysChar(
int modifiers;
int ch = cch; /* special keys are negative */
dead_key = 0;
/* TRACE("OnSysChar(%d, %c)\n", ch, ch); */
/* OK, we have a character key (given by ch) which was entered with the
@ -1710,6 +1712,34 @@ gui_mch_draw_part_cursor(
DeleteBrush(hbr);
}
/*
* Generates a VK_SPACE when the internal dead_key flag is set to output the
* dead key's nominal character and re-post the original message.
*/
static void
outputDeadKey_rePost(MSG originalMsg)
{
static MSG deadCharExpel;
if (!dead_key)
return;
dead_key = 0;
/* Make Windows generate the dead key's character */
deadCharExpel.message = originalMsg.message;
deadCharExpel.hwnd = originalMsg.hwnd;
deadCharExpel.wParam = VK_SPACE;
MyTranslateMessage(&deadCharExpel);
/* re-generate the current character free of the dead char influence */
PostMessage(originalMsg.hwnd, originalMsg.message, originalMsg.wParam,
originalMsg.lParam);
}
/*
* Process a single Windows message.
* If one is not available we hang until one is.
@ -1790,22 +1820,49 @@ process_message(void)
if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
{
vk = (int) msg.wParam;
/*
* 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 with the dead char
* now, so do nothing special and let Windows handle it.
* Handle dead keys in special conditions in other cases we let Windows
* handle them and do not interfere.
*
* Note that VK_SPACE combines with the dead_key's character and only
* one WM_CHAR will be generated by TranslateMessage(), in the two
* other cases two WM_CHAR will be generated: the dead char and VK_BACK
* or VK_ESCAPE. That is most likely what the user expects.
* The dead_key flag must be reset on several occasions:
* - in _OnChar() (or _OnSysChar()) as any dead key was necessarily
* consumed at that point (This is when we let Windows combine the
* dead character on its own)
*
* - Before doing something special such as regenerating keypresses to
* expel the dead character as this could trigger an infinite loop if
* for some reason MyTranslateMessage() do not trigger a call
* immediately to _OnChar() (or _OnSysChar()).
*/
if (dead_key && (vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
if (dead_key)
{
/*
* 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
* with the dead char now, so do nothing special and let Windows
* handle it.
*
* Note that VK_SPACE combines with the dead_key's character and
* only one WM_CHAR will be generated by TranslateMessage(), in
* the two other cases two WM_CHAR will be generated: the dead
* char and VK_BACK or VK_ESCAPE. That is most likely what the
* user expects.
*/
if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
{
dead_key = 0;
MyTranslateMessage(&msg);
return;
}
/* In modes where we are not typing, dead keys should behave
* normally */
else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
{
outputDeadKey_rePost(msg);
return;
}
}
/* Check for CTRL-BREAK */
if (vk == VK_CANCEL)
@ -1822,6 +1879,19 @@ process_message(void)
if (special_keys[i].key_sym == vk
&& (vk != VK_SPACE || !(GetKeyState(VK_MENU) & 0x8000)))
{
/*
* Behave as exected if we have a dead key and the special key
* is a key that would normally trigger the dead key nominal
* character output (such as a NUMPAD printable character or
* the TAB key, etc...).
*/
if (dead_key && (special_keys[i].vim_code0 == 'K'
|| vk == VK_TAB || vk == CAR))
{
outputDeadKey_rePost(msg);
return;
}
#ifdef FEAT_MENU
/* Check for <F10>: Windows selects the menu. When <F10> is
* mapped we want to use the mapping instead. */

View File

@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1124,
/**/
1123,
/**/