-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Win32 backend: can't hover over nonclient areas when window does not have focus #6045
Comments
It doesn't seem trivial to handle seems how WM_MOUSELEAVE are occasionally triggered after WM_NCMOUSEMOVE. I came up with this: Add case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE:
{
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
bd->MouseHwnd = hwnd;
bd->MouseInClientArea = (msg == WM_MOUSEMOVE);
if (!bd->MouseTracked)
{
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
::TrackMouseEvent(&tme);
bd->MouseTracked = true;
}
POINT pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &pos) == FALSE) // WM_NCMOUSEMOVE are provided in screen coordinates.
break;
io.AddMousePosEvent((float)pos.x, (float)pos.y);
break;
}
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
if (bd->MouseInClientArea == (msg == WM_MOUSELEAVE))
{
if (bd->MouseHwnd == hwnd)
bd->MouseHwnd = nullptr;
bd->MouseTracked = false;
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
}
break; I would however need to test it more thoroughly, and with multi-viewports. |
In handling WM_NCMOUSEMOVE I think you want Getting WM_MOUSELEAVE after the first WM_NCMOUSEMOVE is unfortunate but not the end of the world. Otherwise I believe this works. One idea is to cancel the outstanding track mouse event ( |
@ocornut your code above works perfectly with the addition of
|
That didn't look right. When unfocused we don't always get leave events there. I think I worked it our right always sending a cancel request when changing area. cc @BobbyAnguelov would be good if you can confirm it works with vanilla backend and without your custom msg handler. |
Works in both the minimal example I created and in Esoterica. |
…positions over non-client area (OS decorations) when app is not focused. (ocornut#6045, ocornut#6162)
Version: 1.88
Branch: master/viewport/docking
Back-ends: imgui_impl_win32.cpp
Compiler: vs2022
Operating System: Windows 11
imgui buttons that are part of the nonclient area of the window behave correctly only when the window has focus:
When creating a frameless window with owner draw captions you can use imgui buttons for min/max/close buttons, by appropriately processing WM_NCHITTEST on the button regions. This works fine when the window has focus (is foreground). In this case AddMousePosEvent is not called from ImGui_ImplWin32_WndProcHandler's WM_MOUSEMOVE handler since they are considered nonclient areas. Instead, AddMousePosEvent is called from
ImGui_ImplWin32_UpdateMouseData(). However, UpdateMouseData checks first that the window has focus, so that when the window does not have focus AddMousePosEvent is never called and hover tests fail.
ImGui_ImplWin32_WndProcHandler should probably handle WM_NCMOUSEMOVE as well as WM_MOUSEMOVE.
The text was updated successfully, but these errors were encountered: