fix: ImGui hover jumps while cursor captured (RMB look / MMB orbit)

With GLFW_CURSOR_DISABLED the official GLFW backend keeps feeding
virtual unbounded cursor coords to ImGui each frame, so hover state
wanders across hidden panels while the physical cursor is invisible.
Append a "mouse left the window" pos event before ImGui::NewFrame
whenever the cursor is captured - ImGui treats the frame as mouseless.
This commit is contained in:
2026-10-04 15:00:29 +08:00
parent 230df67db7
commit 97408e506c
2 changed files with 9 additions and 1 deletions
+1
View File
@@ -68,6 +68,7 @@ namespace Engine {
// 生命周期保证:Application 成员序中 ImGuiLayer 在 Renderer 之后声明 // 生命周期保证:Application 成员序中 ImGuiLayer 在 Renderer 之后声明
//(先析构),因此 Device 引用在整个层生命周期内有效 //(先析构),因此 Device 引用在整个层生命周期内有效
Device& m_Device; Device& m_Device;
Window& m_Window; // 光标捕获状态查询(NewFrame hover 门控)
vk::DescriptorPool m_Pool; vk::DescriptorPool m_Pool;
bool m_Enabled = true; bool m_Enabled = true;
ImTextureID m_SceneTextures[kMaxFramesInFlight]{}; ImTextureID m_SceneTextures[kMaxFramesInFlight]{};
+8 -1
View File
@@ -24,7 +24,7 @@ namespace Engine {
} }
ImGuiLayer::ImGuiLayer(Window& window, Renderer& renderer) ImGuiLayer::ImGuiLayer(Window& window, Renderer& renderer)
: m_Device(renderer.GetDevice()) : m_Device(renderer.GetDevice()), m_Window(window)
{ {
Device& device = renderer.GetDevice(); Device& device = renderer.GetDevice();
@@ -133,6 +133,13 @@ namespace Engine {
{ {
ImGui_ImplVulkan_NewFrame(); ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
// 光标捕获期间(RMB 自由视角 / MMB 环绕,GLFW_CURSOR_DISABLED),
// 官方后端每帧喂的虚拟无界坐标没有屏幕语义——hover 会随移动在
// 面板间乱窜("鼠标被隐藏但 UI 被 hover")。在 NewFrame 处理
// 事件前追加"鼠标离开"事件清空 hover,ImGui 本帧视为无鼠标
if (m_Window.IsCursorCaptured()) {
ImGui::GetIO().AddMousePosEvent(-FLT_MAX, -FLT_MAX);
}
ImGui::NewFrame(); ImGui::NewFrame();
} }