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:
parent
a24f0a550f
commit
25b2b94ea7
108
src/gui_w48.c
108
src/gui_w48.c
@ -301,18 +301,18 @@ static struct
|
||||
};
|
||||
|
||||
/* Local variables */
|
||||
static int s_button_pending = -1;
|
||||
static int s_button_pending = -1;
|
||||
|
||||
/* s_getting_focus is set when we got focus but didn't see mouse-up event yet,
|
||||
* so don't reset s_button_pending. */
|
||||
static int s_getting_focus = FALSE;
|
||||
static int s_getting_focus = FALSE;
|
||||
|
||||
static int s_x_pending;
|
||||
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 s_x_pending;
|
||||
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 */
|
||||
|
||||
#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,21 +1820,48 @@ 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)
|
||||
{
|
||||
dead_key = 0;
|
||||
MyTranslateMessage(&msg);
|
||||
return;
|
||||
/*
|
||||
* 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 */
|
||||
@ -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. */
|
||||
|
@ -741,6 +741,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1124,
|
||||
/**/
|
||||
1123,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user