mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 19:42:43 +00:00
Merge pull request #92415 from bruvzg/win_mod_keys
[Windows] Use current keyboard state instead of saved values for modifier keys.
This commit is contained in:
commit
d30456fea8
@ -3595,6 +3595,30 @@ void DisplayServerWindows::popup_close(WindowID p_window) {
|
||||
}
|
||||
}
|
||||
|
||||
BitField<DisplayServerWindows::WinKeyModifierMask> DisplayServerWindows::_get_mods() const {
|
||||
BitField<WinKeyModifierMask> mask;
|
||||
static unsigned char keyboard_state[256];
|
||||
if (GetKeyboardState((PBYTE)&keyboard_state)) {
|
||||
if ((keyboard_state[VK_LSHIFT] & 0x80) || (keyboard_state[VK_RSHIFT] & 0x80)) {
|
||||
mask.set_flag(WinKeyModifierMask::SHIFT);
|
||||
}
|
||||
if ((keyboard_state[VK_LCONTROL] & 0x80) || (keyboard_state[VK_RCONTROL] & 0x80)) {
|
||||
mask.set_flag(WinKeyModifierMask::CTRL);
|
||||
}
|
||||
if ((keyboard_state[VK_LMENU] & 0x80) || (keyboard_state[VK_RMENU] & 0x80)) {
|
||||
mask.set_flag(WinKeyModifierMask::ALT);
|
||||
}
|
||||
if ((keyboard_state[VK_RMENU] & 0x80)) {
|
||||
mask.set_flag(WinKeyModifierMask::ALT_GR);
|
||||
}
|
||||
if ((keyboard_state[VK_LWIN] & 0x80) || (keyboard_state[VK_RWIN] & 0x80)) {
|
||||
mask.set_flag(WinKeyModifierMask::META);
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
LRESULT DisplayServerWindows::MouseProc(int code, WPARAM wParam, LPARAM lParam) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
@ -3850,7 +3874,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
if (((lParam >> 16) <= 0) && !engine->is_project_manager_hint() && !engine->is_editor_hint() && !GLOBAL_GET("application/run/enable_alt_space_menu")) {
|
||||
return 0;
|
||||
}
|
||||
if (!alt_mem || !(GetAsyncKeyState(VK_SPACE) & (1 << 15))) {
|
||||
if (!_get_mods().has_flag(WinKeyModifierMask::ALT) || !(GetAsyncKeyState(VK_SPACE) & (1 << 15))) {
|
||||
return 0;
|
||||
}
|
||||
SendMessage(windows[window_id].hWnd, WM_SYSKEYUP, VK_SPACE, 0);
|
||||
@ -3936,20 +3960,22 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
|
||||
RAWINPUT *raw = (RAWINPUT *)lpb;
|
||||
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
if (raw->header.dwType == RIM_TYPEKEYBOARD) {
|
||||
if (raw->data.keyboard.VKey == VK_SHIFT) {
|
||||
// If multiple Shifts are held down at the same time,
|
||||
// Windows natively only sends a KEYUP for the last one to be released.
|
||||
if (raw->data.keyboard.Flags & RI_KEY_BREAK) {
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0) {
|
||||
if (!mods.has_flag(WinKeyModifierMask::SHIFT)) {
|
||||
// A Shift is released, but another Shift is still held
|
||||
ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
|
||||
|
||||
KeyEvent ke;
|
||||
ke.shift = false;
|
||||
ke.alt = alt_mem;
|
||||
ke.control = control_mem;
|
||||
ke.meta = meta_mem;
|
||||
ke.altgr = mods.has_flag(WinKeyModifierMask::ALT_GR);
|
||||
ke.alt = mods.has_flag(WinKeyModifierMask::ALT);
|
||||
ke.control = mods.has_flag(WinKeyModifierMask::CTRL);
|
||||
ke.meta = mods.has_flag(WinKeyModifierMask::META);
|
||||
ke.uMsg = WM_KEYUP;
|
||||
ke.window_id = window_id;
|
||||
|
||||
@ -3966,9 +3992,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
mm.instantiate();
|
||||
|
||||
mm->set_window_id(window_id);
|
||||
mm->set_ctrl_pressed(control_mem);
|
||||
mm->set_shift_pressed(shift_mem);
|
||||
mm->set_alt_pressed(alt_mem);
|
||||
mm->set_ctrl_pressed(mods.has_flag(WinKeyModifierMask::CTRL));
|
||||
mm->set_shift_pressed(mods.has_flag(WinKeyModifierMask::SHIFT));
|
||||
mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
|
||||
mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
|
||||
|
||||
mm->set_pressure((raw->data.mouse.ulButtons & RI_MOUSE_LEFT_BUTTON_DOWN) ? 1.0f : 0.0f);
|
||||
|
||||
@ -4063,12 +4090,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
break;
|
||||
}
|
||||
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
Ref<InputEventMouseMotion> mm;
|
||||
mm.instantiate();
|
||||
mm->set_window_id(window_id);
|
||||
mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0);
|
||||
mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0);
|
||||
mm->set_alt_pressed(alt_mem);
|
||||
mm->set_ctrl_pressed(mods.has_flag(WinKeyModifierMask::CTRL));
|
||||
mm->set_shift_pressed(mods.has_flag(WinKeyModifierMask::SHIFT));
|
||||
mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
|
||||
mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
|
||||
|
||||
mm->set_pressure(windows[window_id].last_pressure);
|
||||
mm->set_tilt(windows[window_id].last_tilt);
|
||||
@ -4213,9 +4242,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
}
|
||||
mm->set_pen_inverted(pen_info.penFlags & (PEN_FLAG_INVERTED | PEN_FLAG_ERASER));
|
||||
|
||||
mm->set_ctrl_pressed(GetKeyState(VK_CONTROL) < 0);
|
||||
mm->set_shift_pressed(GetKeyState(VK_SHIFT) < 0);
|
||||
mm->set_alt_pressed(alt_mem);
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
mm->set_ctrl_pressed(mods.has_flag(WinKeyModifierMask::CTRL));
|
||||
mm->set_shift_pressed(mods.has_flag(WinKeyModifierMask::SHIFT));
|
||||
mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
|
||||
mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
|
||||
|
||||
mm->set_button_mask(last_button_state);
|
||||
|
||||
@ -4318,12 +4349,15 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
if (receiving_window_id == INVALID_WINDOW_ID) {
|
||||
receiving_window_id = window_id;
|
||||
}
|
||||
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
Ref<InputEventMouseMotion> mm;
|
||||
mm.instantiate();
|
||||
mm->set_window_id(receiving_window_id);
|
||||
mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0);
|
||||
mm->set_shift_pressed((wParam & MK_SHIFT) != 0);
|
||||
mm->set_alt_pressed(alt_mem);
|
||||
mm->set_ctrl_pressed(mods.has_flag(WinKeyModifierMask::CTRL));
|
||||
mm->set_shift_pressed(mods.has_flag(WinKeyModifierMask::SHIFT));
|
||||
mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
|
||||
mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
|
||||
|
||||
if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
|
||||
// Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not updated recently.
|
||||
@ -4512,10 +4546,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
}
|
||||
}
|
||||
|
||||
mb->set_ctrl_pressed((wParam & MK_CONTROL) != 0);
|
||||
mb->set_shift_pressed((wParam & MK_SHIFT) != 0);
|
||||
mb->set_alt_pressed(alt_mem);
|
||||
// mb->is_alt_pressed()=(wParam&MK_MENU)!=0;
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
mb->set_ctrl_pressed(mods.has_flag(WinKeyModifierMask::CTRL));
|
||||
mb->set_shift_pressed(mods.has_flag(WinKeyModifierMask::SHIFT));
|
||||
mb->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
|
||||
mb->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
|
||||
|
||||
if (mb->is_pressed()) {
|
||||
last_button_state.set_flag(mouse_button_to_mask(mb->get_button_index()));
|
||||
} else {
|
||||
@ -4691,19 +4727,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN: {
|
||||
if (wParam == VK_SHIFT) {
|
||||
shift_mem = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN);
|
||||
}
|
||||
if (wParam == VK_CONTROL) {
|
||||
control_mem = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN);
|
||||
}
|
||||
if (wParam == VK_MENU) {
|
||||
alt_mem = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN);
|
||||
if (lParam & (1 << 24)) {
|
||||
gr_mem = alt_mem;
|
||||
}
|
||||
}
|
||||
|
||||
if (windows[window_id].ime_suppress_next_keyup && (uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP)) {
|
||||
windows[window_id].ime_suppress_next_keyup = false;
|
||||
break;
|
||||
@ -4714,7 +4737,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
|
||||
if (mouse_mode == MOUSE_MODE_CAPTURED) {
|
||||
// When SetCapture is used, ALT+F4 hotkey is ignored by Windows, so handle it ourselves
|
||||
if (wParam == VK_F4 && alt_mem && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) {
|
||||
if (wParam == VK_F4 && _get_mods().has_flag(WinKeyModifierMask::ALT) && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)) {
|
||||
_send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST);
|
||||
}
|
||||
}
|
||||
@ -4722,13 +4745,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
}
|
||||
case WM_CHAR: {
|
||||
ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
|
||||
const BitField<WinKeyModifierMask> &mods = _get_mods();
|
||||
|
||||
// Make sure we don't include modifiers for the modifier key itself.
|
||||
KeyEvent ke;
|
||||
ke.shift = (wParam != VK_SHIFT) ? shift_mem : false;
|
||||
ke.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
|
||||
ke.control = (wParam != VK_CONTROL) ? control_mem : false;
|
||||
ke.meta = meta_mem;
|
||||
ke.shift = mods.has_flag(WinKeyModifierMask::SHIFT);
|
||||
ke.alt = mods.has_flag(WinKeyModifierMask::ALT);
|
||||
ke.altgr = mods.has_flag(WinKeyModifierMask::ALT_GR);
|
||||
ke.control = mods.has_flag(WinKeyModifierMask::CTRL);
|
||||
ke.meta = mods.has_flag(WinKeyModifierMask::META);
|
||||
ke.uMsg = uMsg;
|
||||
ke.window_id = window_id;
|
||||
|
||||
@ -4899,10 +4923,6 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id) {
|
||||
WindowData &wd = windows[p_window_id];
|
||||
if (wd.activate_state == WA_ACTIVE || wd.activate_state == WA_CLICKACTIVE) {
|
||||
last_focused_window = p_window_id;
|
||||
alt_mem = false;
|
||||
control_mem = false;
|
||||
shift_mem = false;
|
||||
gr_mem = false;
|
||||
_set_mouse_mode_impl(mouse_mode);
|
||||
if (!IsIconic(wd.hWnd)) {
|
||||
SetFocus(wd.hWnd);
|
||||
@ -4914,7 +4934,6 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id) {
|
||||
track_mouse_leave_event(wd.hWnd);
|
||||
// Release capture unconditionally because it can be set due to dragging, in addition to captured mode.
|
||||
ReleaseCapture();
|
||||
alt_mem = false;
|
||||
wd.window_focused = false;
|
||||
_send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
|
||||
}
|
||||
@ -4985,7 +5004,7 @@ void DisplayServerWindows::_process_key_events() {
|
||||
k->set_physical_keycode(physical_keycode);
|
||||
k->set_key_label(key_label);
|
||||
k->set_unicode(fix_unicode(unicode));
|
||||
if (k->get_unicode() && gr_mem) {
|
||||
if (k->get_unicode() && ke.altgr) {
|
||||
k->set_alt_pressed(false);
|
||||
k->set_ctrl_pressed(false);
|
||||
}
|
||||
@ -5061,7 +5080,7 @@ void DisplayServerWindows::_process_key_events() {
|
||||
}
|
||||
k->set_unicode(fix_unicode(unicode));
|
||||
}
|
||||
if (k->get_unicode() && gr_mem) {
|
||||
if (k->get_unicode() && ke.altgr) {
|
||||
k->set_alt_pressed(false);
|
||||
k->set_ctrl_pressed(false);
|
||||
}
|
||||
@ -5527,11 +5546,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
|
||||
drop_events = false;
|
||||
key_event_pos = 0;
|
||||
|
||||
alt_mem = false;
|
||||
gr_mem = false;
|
||||
shift_mem = false;
|
||||
control_mem = false;
|
||||
meta_mem = false;
|
||||
hInstance = static_cast<OS_Windows *>(OS::get_singleton())->get_hinstance();
|
||||
|
||||
pressrc = 0;
|
||||
|
@ -337,7 +337,7 @@ class DisplayServerWindows : public DisplayServer {
|
||||
|
||||
struct KeyEvent {
|
||||
WindowID window_id;
|
||||
bool alt, shift, control, meta;
|
||||
bool alt, shift, control, meta, altgr;
|
||||
UINT uMsg;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
@ -478,11 +478,6 @@ class DisplayServerWindows : public DisplayServer {
|
||||
|
||||
MouseMode mouse_mode;
|
||||
int restore_mouse_trails = 0;
|
||||
bool alt_mem = false;
|
||||
bool gr_mem = false;
|
||||
bool shift_mem = false;
|
||||
bool control_mem = false;
|
||||
bool meta_mem = false;
|
||||
BitField<MouseButtonMask> last_button_state;
|
||||
bool use_raw_input = false;
|
||||
bool drop_events = false;
|
||||
@ -519,6 +514,15 @@ class DisplayServerWindows : public DisplayServer {
|
||||
LRESULT _handle_early_window_message(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
Point2i _get_screens_origin() const;
|
||||
|
||||
enum class WinKeyModifierMask {
|
||||
ALT_GR = (1 << 1),
|
||||
SHIFT = (1 << 2),
|
||||
ALT = (1 << 3),
|
||||
META = (1 << 4),
|
||||
CTRL = (1 << 5),
|
||||
};
|
||||
BitField<WinKeyModifierMask> _get_mods() const;
|
||||
|
||||
Error _file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb);
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user