mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-13 12:59:02 +08:00
Backends: GLFW: moved WndProc hook to bottom of file + rename a field. (#6889)
No functional change in this commit.
This commit is contained in:
parent
ff534b0d0a
commit
17bfafda55
@ -162,7 +162,7 @@ struct ImGui_ImplGlfw_Data
|
|||||||
GLFWcharfun PrevUserCallbackChar;
|
GLFWcharfun PrevUserCallbackChar;
|
||||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WNDPROC GlfwWndProc;
|
WNDPROC PrevWndProc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
@ -494,48 +494,7 @@ static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEven
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
|
||||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|
||||||
{
|
|
||||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
|
||||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
|
||||||
return ImGuiMouseSource_Pen;
|
|
||||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
|
||||||
return ImGuiMouseSource_TouchScreen;
|
|
||||||
return ImGuiMouseSource_Mouse;
|
|
||||||
}
|
|
||||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
|
||||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
|
||||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
|
||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
|
||||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
|
||||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
|
||||||
break;
|
|
||||||
|
|
||||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
|
||||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
|
||||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
|
||||||
case WM_NCHITTEST:
|
|
||||||
{
|
|
||||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
|
||||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
|
||||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
|
||||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
|
||||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
|
||||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
|
||||||
return HTTRANSPARENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return ::CallWindowProc(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||||
@ -672,8 +631,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
|
|
||||||
// Windows: register a WndProc hook so we can intercept some messages.
|
// Windows: register a WndProc hook so we can intercept some messages.
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||||
IM_ASSERT(bd->GlfwWndProc != nullptr);
|
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -713,11 +672,11 @@ void ImGui_ImplGlfw_Shutdown()
|
|||||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||||
|
|
||||||
// Windows: register a WndProc hook so we can intercept some messages.
|
// Windows: restore our WndProc hook
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
|
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||||
bd->GlfwWndProc = nullptr;
|
bd->PrevWndProc = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
@ -1102,7 +1061,7 @@ static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
|||||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
||||||
IM_ASSERT(bd->GlfwWndProc == (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC));
|
IM_ASSERT(bd->PrevWndProc == (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC));
|
||||||
::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1290,6 +1249,54 @@ static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
|
||||||
|
#ifdef _WIN32
|
||||||
|
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||||
|
{
|
||||||
|
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||||
|
return ImGuiMouseSource_Pen;
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||||
|
return ImGuiMouseSource_TouchScreen;
|
||||||
|
return ImGuiMouseSource_Mouse;
|
||||||
|
}
|
||||||
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||||
|
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||||
|
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||||
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||||
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||||
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||||
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||||
|
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||||
|
break;
|
||||||
|
|
||||||
|
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||||
|
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||||
|
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||||
|
case WM_NCHITTEST:
|
||||||
|
{
|
||||||
|
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||||
|
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||||
|
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||||
|
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||||
|
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||||
|
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||||
|
return HTTRANSPARENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return ::CallWindowProc(bd->PrevWndProc, hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
#endif // #ifdef _WIN32
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user