comparison src/gui_w32.c @ 28586:3fd992496509 v8.2.4817

patch 8.2.4817: Win32 GUI: modifiers are not always used Commit: https://github.com/vim/vim/commit/45684c6ec458c43e20db0b2f5f19ce000d34dbd5 Author: LemonBoy <thatlemon@gmail.com> Date: Sun Apr 24 15:46:42 2022 +0100 patch 8.2.4817: Win32 GUI: modifiers are not always used Problem: Win32 GUI: modifiers are not always used. Solution: Handle more modifiers. (closes https://github.com/vim/vim/issues/10269)
author Bram Moolenaar <Bram@vim.org>
date Sun, 24 Apr 2022 17:00:02 +0200
parents 7c96d7924ea5
children 8ea5468f9b5a
comparison
equal deleted inserted replaced
28585:d2e063c391ff 28586:3fd992496509
816 } 816 }
817 817
818 return len; 818 return len;
819 } 819 }
820 820
821 static int
822 get_active_modifiers(void)
823 {
824 int modifiers = 0;
825
826 if (GetKeyState(VK_CONTROL) & 0x8000)
827 modifiers |= MOD_MASK_CTRL;
828 if (GetKeyState(VK_SHIFT) & 0x8000)
829 modifiers |= MOD_MASK_SHIFT;
830 if (GetKeyState(VK_MENU) & 0x8000)
831 modifiers |= MOD_MASK_ALT;
832 // Windows handles Ctrl + Alt as AltGr, in that case no modifier is actually
833 // pressed.
834 if ((modifiers & (MOD_MASK_CTRL | MOD_MASK_ALT)) ==
835 (MOD_MASK_CTRL | MOD_MASK_ALT))
836 modifiers &= ~(MOD_MASK_CTRL | MOD_MASK_ALT);
837
838 return modifiers;
839 }
840
821 /* 841 /*
822 * Key hit, add it to the input buffer. 842 * Key hit, add it to the input buffer.
823 */ 843 */
824 static void 844 static void
825 _OnChar( 845 _OnChar(
827 UINT cch, 847 UINT cch,
828 int cRepeat UNUSED) 848 int cRepeat UNUSED)
829 { 849 {
830 char_u string[40]; 850 char_u string[40];
831 int len = 0; 851 int len = 0;
832 int modifiers = 0; 852 int modifiers;
833 int ch = cch; // special keys are negative 853 int ch = cch; // special keys are negative
834 854
835 dead_key = 0; 855 dead_key = 0;
836 856
837 if (GetKeyState(VK_SHIFT) & 0x8000) 857 modifiers = get_active_modifiers();
838 modifiers |= MOD_MASK_SHIFT;
839 if (GetKeyState(VK_CONTROL) & 0x8000)
840 modifiers |= MOD_MASK_CTRL;
841 858
842 ch = simplify_key(ch, &modifiers); 859 ch = simplify_key(ch, &modifiers);
843 // remove the SHIFT modifier for keys where it's already included, e.g., 860 // remove the SHIFT modifier for keys where it's already included, e.g.,
844 // '(' and '*' 861 // '(' and '*'
845 modifiers = may_remove_shift_modifier(modifiers, ch); 862 modifiers = may_remove_shift_modifier(modifiers, ch);
885 902
886 // OK, we have a character key (given by ch) which was entered with the 903 // OK, we have a character key (given by ch) which was entered with the
887 // ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note 904 // ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
888 // that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless 905 // that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless
889 // CAPSLOCK is pressed) at this point. 906 // CAPSLOCK is pressed) at this point.
890 modifiers = MOD_MASK_ALT; 907 modifiers = get_active_modifiers();
891 if (GetKeyState(VK_SHIFT) & 0x8000)
892 modifiers |= MOD_MASK_SHIFT;
893 if (GetKeyState(VK_CONTROL) & 0x8000)
894 modifiers |= MOD_MASK_CTRL;
895
896 ch = simplify_key(ch, &modifiers); 908 ch = simplify_key(ch, &modifiers);
897 // remove the SHIFT modifier for keys where it's already included, e.g., 909 // remove the SHIFT modifier for keys where it's already included, e.g.,
898 // '(' and '*' 910 // '(' and '*'
899 modifiers = may_remove_shift_modifier(modifiers, ch); 911 modifiers = may_remove_shift_modifier(modifiers, ch);
900 912
1915 /* 1927 /*
1916 * If a dead key was pressed and the user presses VK_SPACE, 1928 * If a dead key was pressed and the user presses VK_SPACE,
1917 * VK_BACK, or VK_ESCAPE it means that he actually wants to deal 1929 * VK_BACK, or VK_ESCAPE it means that he actually wants to deal
1918 * with the dead char now, so do nothing special and let Windows 1930 * with the dead char now, so do nothing special and let Windows
1919 * handle it. 1931 * handle it.
1932 *
1933 * Note that VK_SPACE combines with the dead_key's character and
1934 * only one WM_CHAR will be generated by TranslateMessage(), in
1935 * the two other cases two WM_CHAR will be generated: the dead
1936 * char and VK_BACK or VK_ESCAPE. That is most likely what the
1937 * user expects.
1920 */ 1938 */
1921 if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE)) 1939 if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
1922 { 1940 {
1923 dead_key = 0; 1941 dead_key = 0;
1942 TranslateMessage(&msg);
1943 return;
1924 } 1944 }
1925 // In modes where we are not typing, dead keys should behave 1945 // In modes where we are not typing, dead keys should behave
1926 // normally 1946 // normally
1927 else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE))) 1947 else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
1928 { 1948 {
1974 && gui.menu_is_active 1994 && gui.menu_is_active
1975 && check_map(k10, State, FALSE, TRUE, FALSE, 1995 && check_map(k10, State, FALSE, TRUE, FALSE,
1976 NULL, NULL) == NULL) 1996 NULL, NULL) == NULL)
1977 break; 1997 break;
1978 #endif 1998 #endif
1979 if (GetKeyState(VK_SHIFT) & 0x8000) 1999 modifiers = get_active_modifiers();
1980 modifiers |= MOD_MASK_SHIFT;
1981 /*
1982 * Don't use caps-lock as shift, because these are special keys
1983 * being considered here, and we only want letters to get
1984 * shifted -- webb
1985 */
1986 /*
1987 if (GetKeyState(VK_CAPITAL) & 0x0001)
1988 modifiers ^= MOD_MASK_SHIFT;
1989 */
1990 if (GetKeyState(VK_CONTROL) & 0x8000)
1991 modifiers |= MOD_MASK_CTRL;
1992 if (GetKeyState(VK_MENU) & 0x8000)
1993 modifiers |= MOD_MASK_ALT;
1994 2000
1995 if (special_keys[i].vim_code1 == NUL) 2001 if (special_keys[i].vim_code1 == NUL)
1996 key = special_keys[i].vim_code0; 2002 key = special_keys[i].vim_code0;
1997 else 2003 else
1998 key = TO_SPECIAL(special_keys[i].vim_code0, 2004 key = TO_SPECIAL(special_keys[i].vim_code0,
2034 WCHAR ch[8]; 2040 WCHAR ch[8];
2035 int len; 2041 int len;
2036 int i; 2042 int i;
2037 UINT scan_code; 2043 UINT scan_code;
2038 2044
2039 if (GetKeyState(VK_SHIFT) & 0x8000)
2040 modifiers |= MOD_MASK_SHIFT;
2041 if (GetKeyState(VK_CONTROL) & 0x8000)
2042 modifiers |= MOD_MASK_CTRL;
2043 if (GetKeyState(VK_LMENU) & 0x8000)
2044 modifiers |= MOD_MASK_ALT;
2045
2046 // Construct the state table with only a few modifiers, we don't 2045 // Construct the state table with only a few modifiers, we don't
2047 // really care about the presence of Ctrl/Alt as those modifiers are 2046 // really care about the presence of Ctrl/Alt as those modifiers are
2048 // handled by Vim separately. 2047 // handled by Vim separately.
2049 memset(keyboard_state, 0, 256); 2048 memset(keyboard_state, 0, 256);
2050 if (GetKeyState(VK_SHIFT) & 0x8000) 2049 if (GetKeyState(VK_SHIFT) & 0x8000)
2051 keyboard_state[VK_SHIFT] = 0x80; 2050 keyboard_state[VK_SHIFT] = 0x80;
2052 if (GetKeyState(VK_CAPITAL) & 0x0001) 2051 if (GetKeyState(VK_CAPITAL) & 0x0001)
2053 keyboard_state[VK_CAPITAL] = 0x01; 2052 keyboard_state[VK_CAPITAL] = 0x01;
2054 if (GetKeyState(VK_RMENU) & 0x8000) 2053 // Alt-Gr is synthesized as Alt + Ctrl.
2054 if ((GetKeyState(VK_MENU) & 0x8000) &&
2055 (GetKeyState(VK_CONTROL) & 0x8000))
2055 { 2056 {
2056 keyboard_state[VK_MENU] = 0x80; 2057 keyboard_state[VK_MENU] = 0x80;
2057 keyboard_state[VK_CONTROL] = 0x80; 2058 keyboard_state[VK_CONTROL] = 0x80;
2058 } 2059 }
2059 2060
3793 3794
3794 DragFinish(hDrop); 3795 DragFinish(hDrop);
3795 3796
3796 if (fnames != NULL) 3797 if (fnames != NULL)
3797 { 3798 {
3798 if ((GetKeyState(VK_SHIFT) & 0x8000) != 0) 3799 int kbd_modifiers = get_active_modifiers();
3800
3801 if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
3799 modifiers |= MOUSE_SHIFT; 3802 modifiers |= MOUSE_SHIFT;
3800 if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) 3803 if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
3801 modifiers |= MOUSE_CTRL; 3804 modifiers |= MOUSE_CTRL;
3802 if ((GetKeyState(VK_MENU) & 0x8000) != 0) 3805 if ((kbd_modifiers & MOD_MASK_ALT) != 0)
3803 modifiers |= MOUSE_ALT; 3806 modifiers |= MOUSE_ALT;
3804 3807
3805 gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles); 3808 gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
3806 3809
3807 s_need_activate = TRUE; 3810 s_need_activate = TRUE;