summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gui_w48.c108
-rw-r--r--src/version.c2
2 files changed, 91 insertions, 19 deletions
diff --git a/src/gui_w48.c b/src/gui_w48.c
index ef288e1e6..1f3822be9 100644
--- a/src/gui_w48.c
+++ b/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.
+ *
+ * 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)
*
- * 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.
+ * - 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. */
diff --git a/src/version.c b/src/version.c
index 09176eb54..a1eb08399 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1124,
+/**/
1123,
/**/
1122,