|
@@ -18,6 +18,7 @@
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
#endif
|
|
|
#include <windows.h>
|
|
|
+#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
|
|
#include <tchar.h>
|
|
|
#include <dwmapi.h>
|
|
|
|
|
@@ -33,6 +34,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|
|
|
|
|
// CHANGELOG
|
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
|
+// 2022-01-12: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
|
|
|
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
|
|
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
|
|
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
|
@@ -240,38 +242,31 @@ static void ImGui_ImplWin32_UpdateKeyModifiers()
|
|
|
io.AddKeyModsEvent(key_mods);
|
|
|
}
|
|
|
|
|
|
-static void ImGui_ImplWin32_UpdateMousePos()
|
|
|
+static void ImGui_ImplWin32_UpdateMouseData()
|
|
|
{
|
|
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
IM_ASSERT(bd->hWnd != 0);
|
|
|
|
|
|
- const ImVec2 mouse_pos_prev = io.MousePos;
|
|
|
- io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
|
-
|
|
|
- // Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
|
|
|
- HWND focused_window = ::GetForegroundWindow();
|
|
|
- HWND hovered_window = bd->MouseHwnd;
|
|
|
- HWND mouse_window = NULL;
|
|
|
- if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd)))
|
|
|
- mouse_window = hovered_window;
|
|
|
- else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd)))
|
|
|
- mouse_window = focused_window;
|
|
|
- if (mouse_window == NULL)
|
|
|
- return;
|
|
|
-
|
|
|
- // Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
|
|
- if (io.WantSetMousePos)
|
|
|
+ const bool is_app_focused = (::GetForegroundWindow() == bd->hWnd);
|
|
|
+ if (is_app_focused)
|
|
|
{
|
|
|
- POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
|
|
|
- if (::ClientToScreen(bd->hWnd, &pos))
|
|
|
- ::SetCursorPos(pos.x, pos.y);
|
|
|
- }
|
|
|
+ // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
|
|
+ if (io.WantSetMousePos)
|
|
|
+ {
|
|
|
+ POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
|
|
+ if (::ClientToScreen(bd->hWnd, &pos))
|
|
|
+ ::SetCursorPos(pos.x, pos.y);
|
|
|
+ }
|
|
|
|
|
|
- // Set Dear ImGui mouse position from OS position
|
|
|
- POINT pos;
|
|
|
- if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos))
|
|
|
- io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
|
|
+ // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
|
|
+ if (!io.WantSetMousePos && !bd->MouseTracked)
|
|
|
+ {
|
|
|
+ POINT pos;
|
|
|
+ if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
|
|
+ io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Gamepad navigation mapping
|
|
@@ -341,15 +336,15 @@ void ImGui_ImplWin32_NewFrame()
|
|
|
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
|
|
|
bd->Time = current_time;
|
|
|
|
|
|
+ // Update OS mouse position
|
|
|
+ ImGui_ImplWin32_UpdateMouseData();
|
|
|
+
|
|
|
// Process workarounds for known Windows key handling issues
|
|
|
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
|
|
|
|
|
// Update key modifiers
|
|
|
ImGui_ImplWin32_UpdateKeyModifiers();
|
|
|
|
|
|
- // Update OS mouse position
|
|
|
- ImGui_ImplWin32_UpdateMousePos();
|
|
|
-
|
|
|
// Update OS mouse cursor with the cursor requested by imgui
|
|
|
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
|
|
if (bd->LastMouseCursor != mouse_cursor)
|
|
@@ -517,11 +512,13 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|
|
::TrackMouseEvent(&tme);
|
|
|
bd->MouseTracked = true;
|
|
|
}
|
|
|
+ io.MousePos = ImVec2((float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam));
|
|
|
break;
|
|
|
case WM_MOUSELEAVE:
|
|
|
if (bd->MouseHwnd == hwnd)
|
|
|
bd->MouseHwnd = NULL;
|
|
|
bd->MouseTracked = false;
|
|
|
+ io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
|
break;
|
|
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
|
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
|
@@ -535,8 +532,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|
|
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
|
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
|
|
|
::SetCapture(hwnd);
|
|
|
- io.MouseDown[button] = true;
|
|
|
bd->MouseButtonsDown |= 1 << button;
|
|
|
+ io.MouseDown[button] = true;
|
|
|
return 0;
|
|
|
}
|
|
|
case WM_LBUTTONUP:
|
|
@@ -549,10 +546,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|
|
if (msg == WM_RBUTTONUP) { button = 1; }
|
|
|
if (msg == WM_MBUTTONUP) { button = 2; }
|
|
|
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
|
|
- io.MouseDown[button] = false;
|
|
|
bd->MouseButtonsDown &= ~(1 << button);
|
|
|
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
|
|
|
::ReleaseCapture();
|
|
|
+ io.MouseDown[button] = false;
|
|
|
return 0;
|
|
|
}
|
|
|
case WM_MOUSEWHEEL:
|