diff --git a/Common/Input/InputState.h b/Common/Input/InputState.h index 4a0a5a331e..2edb14210e 100644 --- a/Common/Input/InputState.h +++ b/Common/Input/InputState.h @@ -180,6 +180,11 @@ struct KeyInput { int unicodeChar; // for KEY_CHAR }; int flags; + + // Used by mousewheel events. The delta is packed in the upper 16 bits of flags. + int Delta() const { + return flags >> 16; + } }; struct AxisInput { diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 1f7da023ff..05a48d3f05 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -1413,6 +1413,7 @@ bool TriggerButton::Touch(const TouchInput &input) { down_ |= 1 << input.id; } } + if (input.flags & TOUCH_MOVE) { if (contains) down_ |= 1 << input.id; diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 97ab21bbe5..7ef52538d4 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -195,7 +195,11 @@ static void UpdateScreenDPI(SDL_Window *window) { SDL_GL_GetDrawableSize(window, &drawable_width, NULL); else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) SDL_Vulkan_GetDrawableSize(window, &drawable_width, NULL); - + else { + // If we add SDL support for more platforms, we'll end up here. + g_DesktopDPI = 1.0f; + return; + } // Round up a little otherwise there would be a gap sometimes // in fractional scaling g_DesktopDPI = ((float) drawable_width + 1.0f) / window_width; @@ -729,7 +733,7 @@ struct InputStateTracker { } } - bool mouseDown; + int mouseDown; // bitflags bool mouseCaptured; }; @@ -943,7 +947,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta switch (event.button.button) { case SDL_BUTTON_LEFT: { - inputTracker->mouseDown = true; + inputTracker->mouseDown |= 1; TouchInput input{}; input.x = mx; input.y = my; @@ -957,6 +961,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta break; case SDL_BUTTON_RIGHT: { + inputTracker->mouseDown |= 2; TouchInput input{}; input.x = mx; input.y = my; @@ -1018,21 +1023,22 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta break; } case SDL_MOUSEMOTION: - if (inputTracker->mouseDown) { + { TouchInput input{}; input.x = mx; input.y = my; input.flags = TOUCH_MOVE | TOUCH_MOUSE; + input.buttons = inputTracker->mouseDown; input.id = 0; NativeTouch(input); + NativeMouseDelta(event.motion.xrel, event.motion.yrel); + break; } - NativeMouseDelta(event.motion.xrel, event.motion.yrel); - break; case SDL_MOUSEBUTTONUP: switch (event.button.button) { case SDL_BUTTON_LEFT: { - inputTracker->mouseDown = false; + inputTracker->mouseDown &= ~1; TouchInput input{}; input.x = mx; input.y = my; @@ -1045,6 +1051,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta break; case SDL_BUTTON_RIGHT: { + inputTracker->mouseDown &= ~2; // Right button only emits mouse move events. This is weird, // but consistent with Windows. Needs cleanup. TouchInput input{}; diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index 1ad0e9eb8f..30371171f4 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -46,8 +46,6 @@ public: // This can be called on a thread. void LoadSamplesOnThread(); private: - bool samplesLoaded_ = false; - std::mutex mutex_; std::vector queue_; std::vector plays_; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index ea8612c5de..c8bd8ba10d 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -1149,8 +1149,8 @@ void TouchTestScreen::touch(const TouchInput &touch) { found = true; } } - if (!found) { - WARN_LOG(Log::System, "Move without touch down: %d", touch.id); + if (!found && touch.buttons) { + WARN_LOG(Log::System, "Move with buttons %d without touch down: %d", touch.buttons, touch.id); } } if (touch.flags & TOUCH_UP) { diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index bacff3426c..ab00f6c495 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -680,19 +680,18 @@ namespace MainWindow float y = (float)cursorY * g_display.dpi_scale_y; WindowsRawInput::SetMousePos(x, y); - if (wParam & (MK_LBUTTON | MK_RBUTTON)) { - TouchInput touch{}; - touch.flags = TOUCH_MOVE | TOUCH_MOUSE; - if (wParam & MK_LBUTTON) { - touch.buttons |= 1; - } - if (wParam & MK_RBUTTON) { - touch.buttons |= 2; - } - touch.x = x; - touch.y = y; - NativeTouch(touch); + // Mouse moves now happen also when no button is pressed. + TouchInput touch{}; + touch.flags = TOUCH_MOVE | TOUCH_MOUSE; + if (wParam & MK_LBUTTON) { + touch.buttons |= 1; } + if (wParam & MK_RBUTTON) { + touch.buttons |= 2; + } + touch.x = x; + touch.y = y; + NativeTouch(touch); } break; diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 0227675d48..d5d4726b83 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -156,6 +156,7 @@ namespace WindowsRawInput { { VK_OEM_5, NKCODE_BACKSLASH }, { VK_OEM_6, NKCODE_RIGHT_BRACKET }, { VK_OEM_7, NKCODE_APOSTROPHE }, + { VK_OEM_8, NKCODE_GRAVE }, // Key left of 1 (above Q) on a lot of layouts. { VK_RETURN, NKCODE_ENTER }, { VK_APPS, NKCODE_MENU }, // Context menu key, let's call this "menu". { VK_PAUSE, NKCODE_BREAK }, diff --git a/ext/imgui/imgui_impl_platform.cpp b/ext/imgui/imgui_impl_platform.cpp index 0bd33d25d9..62344d2c76 100644 --- a/ext/imgui/imgui_impl_platform.cpp +++ b/ext/imgui/imgui_impl_platform.cpp @@ -11,9 +11,24 @@ void ImGui_ImplPlatform_KeyEvent(const KeyInput &key) { ImGuiIO& io = ImGui::GetIO(); if (key.flags & KEY_DOWN) { - ImGuiKey keyCode = KeyCodeToImGui(key.keyCode); - if (keyCode != ImGuiKey_None) { - io.AddKeyEvent(keyCode, true); + // Specially handle scroll events and any other special keys. + switch (key.keyCode) { + case NKCODE_EXT_MOUSEWHEEL_UP: + io.AddMouseWheelEvent(0, key.Delta() * 0.010f); + break; + case NKCODE_EXT_MOUSEWHEEL_DOWN: + io.AddMouseWheelEvent(0, -key.Delta() * 0.010f); + break; + default: + { + ImGuiKey keyCode = KeyCodeToImGui(key.keyCode); + if (keyCode == ImGuiKey_None) { + WARN_LOG(Log::System, "Unmapped ImGui keycode conversion from %d", key.keyCode); + } else { + io.AddKeyEvent(keyCode, true); + } + break; + } } } if (key.flags & KEY_UP) { @@ -103,7 +118,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_MOVE_END: return ImGuiKey_End; case NKCODE_INSERT: return ImGuiKey_Insert; - // Numeric keys + // Numeric keys case NKCODE_0: return ImGuiKey_0; case NKCODE_1: return ImGuiKey_1; case NKCODE_2: return ImGuiKey_2; @@ -115,7 +130,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_8: return ImGuiKey_8; case NKCODE_9: return ImGuiKey_9; - // Letter keys + // Letter keys case NKCODE_A: return ImGuiKey_A; case NKCODE_B: return ImGuiKey_B; case NKCODE_C: return ImGuiKey_C; @@ -143,7 +158,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_Y: return ImGuiKey_Y; case NKCODE_Z: return ImGuiKey_Z; - // Symbols + // Symbols case NKCODE_COMMA: return ImGuiKey_Comma; case NKCODE_PERIOD: return ImGuiKey_Period; case NKCODE_MINUS: return ImGuiKey_Minus; @@ -156,7 +171,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_SLASH: return ImGuiKey_Slash; case NKCODE_GRAVE: return ImGuiKey_GraveAccent; - // Function keys + // Function keys case NKCODE_F1: return ImGuiKey_F1; case NKCODE_F2: return ImGuiKey_F2; case NKCODE_F3: return ImGuiKey_F3; @@ -170,7 +185,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_F11: return ImGuiKey_F11; case NKCODE_F12: return ImGuiKey_F12; - // Keypad + // Keypad case NKCODE_NUMPAD_0: return ImGuiKey_Keypad0; case NKCODE_NUMPAD_1: return ImGuiKey_Keypad1; case NKCODE_NUMPAD_2: return ImGuiKey_Keypad2; @@ -188,7 +203,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter; case NKCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual; - // Lock keys + // Lock keys case NKCODE_NUM_LOCK: return ImGuiKey_NumLock; case NKCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;