From 4d336038ce99b30bf1585ddcc934c37b2a78716e Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sun, 12 Feb 2023 18:27:05 -0800 Subject: [PATCH] Win32: Auto-Raise and -Focus Windows on Hover On the Windows platform, raise windows and give them focus as the mouse hovers over them. This allows keyboard shortcuts for the area under the mouse without having to click the window caption to make them active. --- intern/ghost/intern/GHOST_SystemWin32.cpp | 34 ++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 9fc69dabe00..2a9186ba1ae 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1826,7 +1826,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, uint msg, WPARAM wParam, if (!window->m_mousePresent) { WINTAB_PRINTF("HWND %p mouse enter\n", window->getHWND()); TRACKMOUSEEVENT tme = {sizeof(tme)}; - tme.dwFlags = TME_LEAVE; + /* Request WM_MOUSELEAVE message when the cursor leaves the client area, and + * WM_MOUSEHOVER message after 50ms when in the client area. */ + tme.dwFlags = TME_LEAVE | TME_HOVER; + tme.dwHoverTime = 50; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); window->m_mousePresent = true; @@ -1843,6 +1846,35 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, uint msg, WPARAM wParam, break; } + case WM_MOUSEHOVER: { + /* Mouse Tracking is now off. TrackMouseEvent restarts in MouseMove. */ + window->m_mousePresent = false; + + /* Auto-focus only occurs within Blender windows, not with _other_ applications. */ + HWND old_hwnd = ::GetFocus(); + if (hwnd != old_hwnd) { + HWND new_parent = ::GetParent(hwnd); + HWND old_parent = ::GetParent(old_hwnd); + if (hwnd == old_parent || old_hwnd == new_parent) { + /* Child to its parent, parent to its child. */ + ::SetFocus(hwnd); + } + else if (new_parent != HWND_DESKTOP && new_parent == old_parent) { + /* Between siblings of same parent. */ + ::SetFocus(hwnd); + } + else if (!new_parent && !old_parent) { + /* Between main windows that don't overlap. */ + RECT new_rect, old_rect, dest_rect; + ::GetWindowRect(hwnd, &new_rect); + ::GetWindowRect(old_hwnd, &old_rect); + if (!IntersectRect(&dest_rect, &new_rect, &old_rect)) { + ::SetFocus(hwnd); + } + } + } + break; + } case WM_MOUSEWHEEL: { /* The WM_MOUSEWHEEL message is sent to the focus window * when the mouse wheel is rotated. The DefWindowProc -- 2.30.2