Patch 8.2.4807

9 views
Skip to first unread message

Bram Moolenaar

unread,
Apr 22, 2022, 5:46:35 PM4/22/22
to vim...@googlegroups.com

Patch 8.2.4807
Problem: Processing key eveints in Win32 GUI is not ideal.
Solution: Improve processing of key events. (closes #10155)
Files: src/gui_w32.c


*** ../vim-8.2.4806/src/gui_w32.c 2022-04-13 11:47:21.711886557 +0100
--- src/gui_w32.c 2022-04-22 22:45:08.369018686 +0100
***************
*** 824,837 ****
static void
_OnChar(
HWND hwnd UNUSED,
! UINT ch,
int cRepeat UNUSED)
{
char_u string[40];
int len = 0;

dead_key = 0;

len = char_to_string(ch, string, 40, FALSE);
if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts)
{
--- 824,862 ----
static void
_OnChar(
HWND hwnd UNUSED,
! UINT cch,
int cRepeat UNUSED)
{
char_u string[40];
int len = 0;
+ int modifiers = 0;
+ int ch = cch; // special keys are negative

dead_key = 0;

+ if (GetKeyState(VK_SHIFT) & 0x8000)
+ modifiers |= MOD_MASK_SHIFT;
+ if (GetKeyState(VK_CONTROL) & 0x8000)
+ modifiers |= MOD_MASK_CTRL;
+
+ ch = simplify_key(ch, &modifiers);
+ // remove the SHIFT modifier for keys where it's already included, e.g.,
+ // '(' and '*'
+ modifiers = may_remove_shift_modifier(modifiers, ch);
+
+ // Unify modifiers somewhat. No longer use ALT to set the 8th bit.
+ ch = extract_modifiers(ch, &modifiers, FALSE, NULL);
+ if (ch == CSI)
+ ch = K_CSI;
+
+ if (modifiers)
+ {
+ string[0] = CSI;
+ string[1] = KS_MODIFIER;
+ string[2] = modifiers;
+ add_to_input_buf(string, 3);
+ }
+
len = char_to_string(ch, string, 40, FALSE);
if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts)
{
***************
*** 858,865 ****

dead_key = 0;

- // TRACE("OnSysChar(%d, %c)\n", ch, ch);
-
// 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
// that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless
--- 883,888 ----
***************
*** 1816,1822 ****
originalMsg.lParam);
}

-
/*
* Process a single Windows message.
* If one is not available we hang until one is.
--- 1839,1844 ----
***************
*** 1833,1838 ****
--- 1855,1861 ----
#ifdef FEAT_MENU
static char_u k10[] = {K_SPECIAL, 'k', ';', 0};
#endif
+ BYTE keyboard_state[256];

GetMessageW(&msg, NULL, 0, 0);

***************
*** 1894,1911 ****
* 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;
- TranslateMessage(&msg);
- return;
}
// In modes where we are not typing, dead keys should behave
// normally
--- 1917,1926 ----
***************
*** 1926,1931 ****
--- 1941,1953 ----
add_to_input_buf(string, 1);
}

+ // This is an IME event or a synthetic keystroke, let Windows handle it.
+ if (vk == VK_PROCESSKEY || vk == VK_PACKET)
+ {
+ TranslateMessage(&msg);
+ return;
+ }
+
for (i = 0; special_keys[i].key_sym != 0; i++)
{
// ignore VK_SPACE when ALT key pressed: system menu
***************
*** 2005,2043 ****
break;
}
}
if (special_keys[i].key_sym == 0)
{
! // Some keys need C-S- where they should only need C-.
! // Ignore 0xff, Windows XP sends it when NUMLOCK has changed since
! // system startup (Helmut Stiegler, 2003 Oct 3).
! if (vk != 0xff
! && (GetKeyState(VK_CONTROL) & 0x8000)
! && !(GetKeyState(VK_SHIFT) & 0x8000)
! && !(GetKeyState(VK_MENU) & 0x8000))
{
! // CTRL-6 is '^'; Japanese keyboard maps '^' to vk == 0xDE
! if (vk == '6' || MapVirtualKey(vk, 2) == (UINT)'^')
! {
! string[0] = Ctrl_HAT;
! add_to_input_buf(string, 1);
! }
! // vk == 0xBD AZERTY for CTRL-'-', but CTRL-[ for * QWERTY!
! else if (vk == 0xBD) // QWERTY for CTRL-'-'
! {
! string[0] = Ctrl__;
! add_to_input_buf(string, 1);
! }
! // CTRL-2 is '@'; Japanese keyboard maps '@' to vk == 0xC0
! else if (vk == '2' || MapVirtualKey(vk, 2) == (UINT)'@')
! {
! string[0] = Ctrl_AT;
! add_to_input_buf(string, 1);
! }
! else
! TranslateMessage(&msg);
}
else
! TranslateMessage(&msg);
}
}
#ifdef FEAT_MBYTE_IME
--- 2027,2084 ----
break;
}
}
+
+ // Not a special key.
if (special_keys[i].key_sym == 0)
{
! WCHAR ch[8];
! int len;
! int i;
! UINT scan_code;
!
! if (GetKeyState(VK_SHIFT) & 0x8000)
! modifiers |= MOD_MASK_SHIFT;
! if (GetKeyState(VK_CONTROL) & 0x8000)
! modifiers |= MOD_MASK_CTRL;
! if (GetKeyState(VK_LMENU) & 0x8000)
! modifiers |= MOD_MASK_ALT;
!
! // Construct the state table with only a few modifiers, we don't
! // really care about the presence of Ctrl/Alt as those modifiers are
! // handled by Vim separately.
! memset(keyboard_state, 0, 256);
! if (GetKeyState(VK_SHIFT) & 0x8000)
! keyboard_state[VK_SHIFT] = 0x80;
! if (GetKeyState(VK_RMENU) & 0x8000)
{
! keyboard_state[VK_MENU] = 0x80;
! keyboard_state[VK_CONTROL] = 0x80;
! }
!
! // Translate the virtual key according to the current keyboard
! // layout.
! scan_code = MapVirtualKey(vk, MAPVK_VK_TO_VSC);
! // Convert the scan-code into a sequence of zero or more unicode
! // codepoints.
! // If this is a dead key ToUnicode returns a negative value.
! len = ToUnicode(vk, scan_code, keyboard_state, ch, ARRAY_LENGTH(ch),
! 0);
! dead_key = len < 0;
!
! if (len <= 0)
! return;
!
! // Post the message as TranslateMessage would do.
! if (msg.message == WM_KEYDOWN)
! {
! for (i = 0; i < len; i++)
! PostMessageW(msg.hwnd, WM_CHAR, ch[i], msg.lParam);
}
else
! {
! for (i = 0; i < len; i++)
! PostMessageW(msg.hwnd, WM_SYSCHAR, ch[i], msg.lParam);
! }
}
}
#ifdef FEAT_MBYTE_IME
***************
*** 3728,3735 ****
POINT pt;
int_u modifiers = 0;

- // TRACE("_OnDropFiles: %d files dropped\n", cFiles);
-
// Obtain dropped position
DragQueryPoint(hDrop, &pt);
MapWindowPoints(s_hwnd, s_textArea, &pt, 1);
--- 3769,3774 ----
***************
*** 4580,4589 ****
WPARAM wParam,
LPARAM lParam)
{
! /*
! TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
! hwnd, uMsg, wParam, lParam);
! */

HandleMouseHide(uMsg, lParam);

--- 4619,4626 ----
WPARAM wParam,
LPARAM lParam)
{
! // TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
! // hwnd, uMsg, wParam, lParam);

HandleMouseHide(uMsg, lParam);

***************
*** 4635,4654 ****
}
break;

- case WM_KEYUP:
- // handle CTRL-/
- if ((GetKeyState(VK_CONTROL) & 0x8000) != 0 && wParam == 0xBF)
- {
- char_u string[4];
-
- string[0] = CSI;
- string[1] = KS_MODIFIER;
- string[2] = MOD_MASK_CTRL;
- string[3] = 0x2F;
- add_to_input_buf(string, 4);
- }
- return 0L;
-
case WM_CHAR:
// Don't use HANDLE_MSG() for WM_CHAR, it truncates wParam to a single
// byte while we want the UTF-16 character value.
--- 4672,4677 ----
*** ../vim-8.2.4806/src/version.c 2022-04-22 21:20:22.829092772 +0100
--- src/version.c 2022-04-22 22:45:20.280996863 +0100
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 4807,
/**/

--
A day without sunshine is like, well, night.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages