Skip to content

Commit 25b2b94

Browse files
committed
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)
1 parent a24f0a5 commit 25b2b94

File tree

2 files changed

+91
-19
lines changed

2 files changed

+91
-19
lines changed

src/gui_w48.c

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,18 @@ static struct
301301
};
302302

303303
/* Local variables */
304-
static int s_button_pending = -1;
304+
static int s_button_pending = -1;
305305

306306
/* s_getting_focus is set when we got focus but didn't see mouse-up event yet,
307307
* so don't reset s_button_pending. */
308-
static int s_getting_focus = FALSE;
308+
static int s_getting_focus = FALSE;
309309

310-
static int s_x_pending;
311-
static int s_y_pending;
312-
static UINT s_kFlags_pending;
313-
static UINT s_wait_timer = 0; /* Timer for get char from user */
314-
static int s_timed_out = FALSE;
315-
static int dead_key = 0; /* 0 - no dead key, 1 - dead key pressed */
310+
static int s_x_pending;
311+
static int s_y_pending;
312+
static UINT s_kFlags_pending;
313+
static UINT s_wait_timer = 0; /* Timer for get char from user */
314+
static int s_timed_out = FALSE;
315+
static int dead_key = 0; /* 0: no dead key, 1: dead key pressed */
316316

317317
#ifdef WIN3264
318318
static OSVERSIONINFO os_version; /* like it says. Init in gui_mch_init() */
@@ -641,6 +641,8 @@ _OnSysChar(
641641
int modifiers;
642642
int ch = cch; /* special keys are negative */
643643

644+
dead_key = 0;
645+
644646
/* TRACE("OnSysChar(%d, %c)\n", ch, ch); */
645647

646648
/* OK, we have a character key (given by ch) which was entered with the
@@ -1710,6 +1712,34 @@ gui_mch_draw_part_cursor(
17101712
DeleteBrush(hbr);
17111713
}
17121714

1715+
1716+
/*
1717+
* Generates a VK_SPACE when the internal dead_key flag is set to output the
1718+
* dead key's nominal character and re-post the original message.
1719+
*/
1720+
static void
1721+
outputDeadKey_rePost(MSG originalMsg)
1722+
{
1723+
static MSG deadCharExpel;
1724+
1725+
if (!dead_key)
1726+
return;
1727+
1728+
dead_key = 0;
1729+
1730+
/* Make Windows generate the dead key's character */
1731+
deadCharExpel.message = originalMsg.message;
1732+
deadCharExpel.hwnd = originalMsg.hwnd;
1733+
deadCharExpel.wParam = VK_SPACE;
1734+
1735+
MyTranslateMessage(&deadCharExpel);
1736+
1737+
/* re-generate the current character free of the dead char influence */
1738+
PostMessage(originalMsg.hwnd, originalMsg.message, originalMsg.wParam,
1739+
originalMsg.lParam);
1740+
}
1741+
1742+
17131743
/*
17141744
* Process a single Windows message.
17151745
* If one is not available we hang until one is.
@@ -1790,21 +1820,48 @@ process_message(void)
17901820
if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
17911821
{
17921822
vk = (int) msg.wParam;
1823+
17931824
/*
1794-
* If a dead key was pressed and the user presses VK_SPACE, VK_BACK, or
1795-
* VK_ESCAPE it means that he actually wants to deal with the dead char
1796-
* now, so do nothing special and let Windows handle it.
1825+
* Handle dead keys in special conditions in other cases we let Windows
1826+
* handle them and do not interfere.
1827+
*
1828+
* The dead_key flag must be reset on several occasions:
1829+
* - in _OnChar() (or _OnSysChar()) as any dead key was necessarily
1830+
* consumed at that point (This is when we let Windows combine the
1831+
* dead character on its own)
17971832
*
1798-
* Note that VK_SPACE combines with the dead_key's character and only
1799-
* one WM_CHAR will be generated by TranslateMessage(), in the two
1800-
* other cases two WM_CHAR will be generated: the dead char and VK_BACK
1801-
* or VK_ESCAPE. That is most likely what the user expects.
1833+
* - Before doing something special such as regenerating keypresses to
1834+
* expel the dead character as this could trigger an infinite loop if
1835+
* for some reason MyTranslateMessage() do not trigger a call
1836+
* immediately to _OnChar() (or _OnSysChar()).
18021837
*/
1803-
if (dead_key && (vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
1838+
if (dead_key)
18041839
{
1805-
dead_key = 0;
1806-
MyTranslateMessage(&msg);
1807-
return;
1840+
/*
1841+
* If a dead key was pressed and the user presses VK_SPACE,
1842+
* VK_BACK, or VK_ESCAPE it means that he actually wants to deal
1843+
* with the dead char now, so do nothing special and let Windows
1844+
* handle it.
1845+
*
1846+
* Note that VK_SPACE combines with the dead_key's character and
1847+
* only one WM_CHAR will be generated by TranslateMessage(), in
1848+
* the two other cases two WM_CHAR will be generated: the dead
1849+
* char and VK_BACK or VK_ESCAPE. That is most likely what the
1850+
* user expects.
1851+
*/
1852+
if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
1853+
{
1854+
dead_key = 0;
1855+
MyTranslateMessage(&msg);
1856+
return;
1857+
}
1858+
/* In modes where we are not typing, dead keys should behave
1859+
* normally */
1860+
else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
1861+
{
1862+
outputDeadKey_rePost(msg);
1863+
return;
1864+
}
18081865
}
18091866

18101867
/* Check for CTRL-BREAK */
@@ -1822,6 +1879,19 @@ process_message(void)
18221879
if (special_keys[i].key_sym == vk
18231880
&& (vk != VK_SPACE || !(GetKeyState(VK_MENU) & 0x8000)))
18241881
{
1882+
/*
1883+
* Behave as exected if we have a dead key and the special key
1884+
* is a key that would normally trigger the dead key nominal
1885+
* character output (such as a NUMPAD printable character or
1886+
* the TAB key, etc...).
1887+
*/
1888+
if (dead_key && (special_keys[i].vim_code0 == 'K'
1889+
|| vk == VK_TAB || vk == CAR))
1890+
{
1891+
outputDeadKey_rePost(msg);
1892+
return;
1893+
}
1894+
18251895
#ifdef FEAT_MENU
18261896
/* Check for <F10>: Windows selects the menu. When <F10> is
18271897
* mapped we want to use the mapping instead. */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ static char *(features[]) =
741741

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
1124,
744746
/**/
745747
1123,
746748
/**/

0 commit comments

Comments
 (0)