Mercurial > vim
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; |