mirror of
https://github.com/ocornut/imgui.git
synced 2025-02-25 14:34:40 +01:00
Backends: Win32: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse positions over non-client area (OS decorations) when app is not focused. (#6045, #6162)
This commit is contained in:
parent
4f630b0449
commit
5d74891285
@ -34,6 +34,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 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)
|
// 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-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).
|
// 2022-09-28: Inputs: Convert WM_CHAR values with MultiByteToWideChar() when window class was registered as MBCS (not Unicode).
|
||||||
@ -84,7 +85,7 @@ struct ImGui_ImplWin32_Data
|
|||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
HWND MouseHwnd;
|
HWND MouseHwnd;
|
||||||
bool MouseTracked;
|
int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
|
||||||
int MouseButtonsDown;
|
int MouseButtonsDown;
|
||||||
INT64 Time;
|
INT64 Time;
|
||||||
INT64 TicksPerSecond;
|
INT64 TicksPerSecond;
|
||||||
@ -267,7 +268,8 @@ static void ImGui_ImplWin32_UpdateMouseData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||||
if (!io.WantSetMousePos && !bd->MouseTracked)
|
// 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)
|
||||||
{
|
{
|
||||||
POINT pos;
|
POINT pos;
|
||||||
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
||||||
@ -515,25 +517,39 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
|
case WM_NCMOUSEMOVE:
|
||||||
{
|
{
|
||||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||||
|
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||||
bd->MouseHwnd = hwnd;
|
bd->MouseHwnd = hwnd;
|
||||||
if (!bd->MouseTracked)
|
if (bd->MouseTrackedArea != area)
|
||||||
{
|
{
|
||||||
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
|
TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
|
||||||
::TrackMouseEvent(&tme);
|
TRACKMOUSEEVENT tme_track = { sizeof(tme_track), (DWORD)((area == 2) ? (TME_LEAVE | TME_NONCLIENT) : TME_LEAVE), hwnd, 0 };
|
||||||
bd->MouseTracked = true;
|
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) };
|
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||||
|
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
|
||||||
|
break;
|
||||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_MOUSELEAVE:
|
case WM_MOUSELEAVE:
|
||||||
if (bd->MouseHwnd == hwnd)
|
case WM_NCMOUSELEAVE:
|
||||||
bd->MouseHwnd = nullptr;
|
{
|
||||||
bd->MouseTracked = false;
|
const int area = (msg == WM_MOUSELEAVE) ? 1 : 2;
|
||||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
if (bd->MouseTrackedArea == area)
|
||||||
|
{
|
||||||
|
if (bd->MouseHwnd == hwnd)
|
||||||
|
bd->MouseHwnd = nullptr;
|
||||||
|
bd->MouseTrackedArea = 0;
|
||||||
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||||
|
@ -35,6 +35,14 @@ HOW TO UPDATE?
|
|||||||
VERSION 1.89.4 WIP (In Progress)
|
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)
|
VERSION 1.89.3 (Released 2023-02-14)
|
||||||
@ -50,7 +58,7 @@ Breaking Changes:
|
|||||||
- imgui_impl_sdl.h -> imgui_impl_sdl2.h
|
- imgui_impl_sdl.h -> imgui_impl_sdl2.h
|
||||||
- example_sdl_xxxx/ -> example_sdl2_xxxx/ (folders and projects)
|
- example_sdl_xxxx/ -> example_sdl2_xxxx/ (folders and projects)
|
||||||
|
|
||||||
All changes:
|
Other changes:
|
||||||
|
|
||||||
- SeparatorText(): Added SeparatorText() widget. (#1643) [@phed, @ocornut]
|
- SeparatorText(): Added SeparatorText() widget. (#1643) [@phed, @ocornut]
|
||||||
- Added to style: float SeparatorTextBorderSize.
|
- Added to style: float SeparatorTextBorderSize.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user