diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 870aef504..e7d3c51c6 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -36,6 +36,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162) // 2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463) // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode). @@ -91,7 +92,7 @@ struct ImGui_ImplWin32_Data { HWND hWnd; HWND MouseHwnd; - bool MouseTracked; + int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area int MouseButtonsDown; INT64 Time; INT64 TicksPerSecond; @@ -290,7 +291,8 @@ static void ImGui_ImplWin32_UpdateMouseData() } // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured) - if (!io.WantSetMousePos && !bd->MouseTracked && has_mouse_screen_pos) + // This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE + if (!io.WantSetMousePos && bd->MouseTrackedArea == 0 && has_mouse_screen_pos) { // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) // (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.) @@ -587,27 +589,42 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA switch (msg) { case WM_MOUSEMOVE: + case WM_NCMOUSEMOVE: { // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events + const int area = (msg == WM_MOUSEMOVE) ? 1 : 2; bd->MouseHwnd = hwnd; - if (!bd->MouseTracked) + if (bd->MouseTrackedArea != area) { - TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 }; - ::TrackMouseEvent(&tme); - bd->MouseTracked = true; + TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 }; + TRACKMOUSEEVENT tme_track = { sizeof(tme_track), (DWORD)((area == 2) ? (TME_LEAVE | TME_NONCLIENT) : TME_LEAVE), hwnd, 0 }; + if (bd->MouseTrackedArea != 0) + ::TrackMouseEvent(&tme_cancel); + ::TrackMouseEvent(&tme_track); + bd->MouseTrackedArea = area; } POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) }; - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + bool want_absolute_pos = (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != 0; + if (msg == WM_MOUSEMOVE && want_absolute_pos) // WM_MOUSEMOVE are client-relative coordinates. ::ClientToScreen(hwnd, &mouse_pos); + if (msg == WM_NCMOUSEMOVE && !want_absolute_pos) // WM_NCMOUSEMOVE are absolute coordinates. + ::ScreenToClient(hwnd, &mouse_pos); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); break; } case WM_MOUSELEAVE: - if (bd->MouseHwnd == hwnd) - bd->MouseHwnd = nullptr; - bd->MouseTracked = false; - io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + case WM_NCMOUSELEAVE: + { + const int area = (msg == WM_MOUSELEAVE) ? 1 : 2; + if (bd->MouseTrackedArea == area) + { + if (bd->MouseHwnd == hwnd) + bd->MouseHwnd = nullptr; + bd->MouseTrackedArea = 0; + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + } break; + } case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d04d59de2..d79f39e96 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -98,6 +98,18 @@ Other changes: Note that Linux/Mac still have inconsistent support for multi-viewports. If you want to help see https://github.com/ocornut/imgui/issues/2117. +----------------------------------------------------------------------- + VERSION 1.89.4 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking Changes: + +Other changes: + +- Backends: Win32: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse positions over + non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162) + + ----------------------------------------------------------------------- VERSION 1.89.3 (Released 2023-02-14) ----------------------------------------------------------------------- @@ -112,7 +124,7 @@ Breaking Changes: - imgui_impl_sdl.h -> imgui_impl_sdl2.h - example_sdl_xxxx/ -> example_sdl2_xxxx/ (folders and projects) -All changes: +Other changes: - SeparatorText(): Added SeparatorText() widget. (#1643) [@phed, @ocornut] - Added to style: float SeparatorTextBorderSize. diff --git a/imgui.cpp b/imgui.cpp index 4691e8ea6..4f0744a13 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 40451a172..bfe8fe56a 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (headers) // Help: @@ -22,8 +22,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') -#define IMGUI_VERSION "1.89.3" -#define IMGUI_VERSION_NUM 18930 +#define IMGUI_VERSION "1.89.4 WIP" +#define IMGUI_VERSION_NUM 18931 #define IMGUI_HAS_TABLE #define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 19c4051f4..189336418 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 53a125a0a..c97bae479 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index db17cf67f..85f93d89e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index ce5213e0c..6b273f6da 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 34f33f899..53b43d3ac 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.3 +// dear imgui, v1.89.4 WIP // (widgets code) /* diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 17700f16e..69417d7b1 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -52,7 +52,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used -#pragma GCC diagnostic ignored "-Wsubobject-linkage" // warning: 'xxxx' has a field ‘xxxx’ whose type uses the anonymous namespace +#pragma GCC diagnostic ignored "-Wsubobject-linkage" // warning: 'xxxx' has a field 'xxxx' whose type uses the anonymous namespace #endif //-------------------------------------------------------------------------