Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_glfw.cpp
#	backends/imgui_impl_osx.h
#	backends/imgui_impl_osx.mm
#	backends/imgui_impl_sdl.cpp
#	backends/imgui_impl_win32.cpp
This commit is contained in:
ocornut 2022-01-13 18:36:23 +01:00
commit 0647ba3bad
20 changed files with 326 additions and 211 deletions

View File

@ -414,8 +414,6 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
}; };
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro)); bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
#if ALLEGRO_HAS_CLIPBOARD #if ALLEGRO_HAS_CLIPBOARD
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText; io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText; io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;

View File

@ -13,7 +13,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer.

View File

@ -13,7 +13,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.

View File

@ -22,7 +22,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer. // 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.

View File

@ -13,7 +13,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1. // 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)

View File

@ -20,7 +20,8 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback().
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API. // 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API.
// 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback(). // 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback().
@ -111,6 +112,7 @@ struct ImGui_ImplGlfw_Data
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
GLFWwindowfocusfun PrevUserCallbackWindowFocus; GLFWwindowfocusfun PrevUserCallbackWindowFocus;
GLFWcursorposfun PrevUserCallbackCursorPos;
GLFWcursorenterfun PrevUserCallbackCursorEnter; GLFWcursorenterfun PrevUserCallbackCursorEnter;
GLFWmousebuttonfun PrevUserCallbackMousebutton; GLFWmousebuttonfun PrevUserCallbackMousebutton;
GLFWscrollfun PrevUserCallbackScroll; GLFWscrollfun PrevUserCallbackScroll;
@ -336,16 +338,37 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
io.AddFocusEvent(focused != 0); io.AddFocusEvent(focused != 0);
} }
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
{
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorPos != NULL && window == bd->Window)
bd->PrevUserCallbackCursorPos(window, x, y);
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
int window_x, window_y;
glfwGetWindowPos(window, &window_x, &window_y);
x += window_x;
y += window_y;
}
io.MousePos = ImVec2((float)x, (float)y);
}
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
{ {
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
if (bd->PrevUserCallbackCursorEnter != NULL && window == bd->Window) if (bd->PrevUserCallbackCursorEnter != NULL && window == bd->Window)
bd->PrevUserCallbackCursorEnter(window, entered); bd->PrevUserCallbackCursorEnter(window, entered);
ImGuiIO& io = ImGui::GetIO();
if (entered) if (entered)
bd->MouseWindow = window; bd->MouseWindow = window;
if (!entered && bd->MouseWindow == window) if (!entered && bd->MouseWindow == window)
{
bd->MouseWindow = NULL; bd->MouseWindow = NULL;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
}
} }
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
@ -424,6 +447,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
bd->InstalledCallbacks = true; bd->InstalledCallbacks = true;
bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback); bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback);
bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback); bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback);
bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback);
bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
@ -475,6 +499,7 @@ void ImGui_ImplGlfw_Shutdown()
{ {
glfwSetWindowFocusCallback(bd->Window, bd->PrevUserCallbackWindowFocus); glfwSetWindowFocusCallback(bd->Window, bd->PrevUserCallbackWindowFocus);
glfwSetCursorEnterCallback(bd->Window, bd->PrevUserCallbackCursorEnter); glfwSetCursorEnterCallback(bd->Window, bd->PrevUserCallbackCursorEnter);
glfwSetCursorPosCallback(bd->Window, bd->PrevUserCallbackCursorPos);
glfwSetMouseButtonCallback(bd->Window, bd->PrevUserCallbackMousebutton); glfwSetMouseButtonCallback(bd->Window, bd->PrevUserCallbackMousebutton);
glfwSetScrollCallback(bd->Window, bd->PrevUserCallbackScroll); glfwSetScrollCallback(bd->Window, bd->PrevUserCallbackScroll);
glfwSetKeyCallback(bd->Window, bd->PrevUserCallbackKey); glfwSetKeyCallback(bd->Window, bd->PrevUserCallbackKey);
@ -490,61 +515,52 @@ void ImGui_ImplGlfw_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
static void ImGui_ImplGlfw_UpdateMousePosAndButtons() static void ImGui_ImplGlfw_UpdateMouseData()
{ {
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
const ImVec2 mouse_pos_prev = io.MousePos;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
// Update mouse buttons const ImVec2 mouse_pos_prev = io.MousePos;
// (if a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame) int mouse_buttons_mask = 0x00;
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
io.MouseDown[i] = bd->MouseJustPressed[i] || glfwGetMouseButton(bd->Window, i) != 0;
bd->MouseJustPressed[i] = false;
}
for (int n = 0; n < platform_io.Viewports.Size; n++) for (int n = 0; n < platform_io.Viewports.Size; n++)
{ {
ImGuiViewport* viewport = platform_io.Viewports[n]; ImGuiViewport* viewport = platform_io.Viewports[n];
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle; GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
const bool focused = true; const bool is_window_focused = true;
#else #else
const bool focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0; const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
#endif #endif
GLFWwindow* mouse_window = (bd->MouseWindow == window || focused) ? window : NULL; if (is_window_focused)
// Update mouse buttons
if (focused)
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0;
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// (When multi-viewports are enabled, all Dear ImGui positions are same as OS positions)
if (io.WantSetMousePos && focused)
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
// Set Dear ImGui mouse position from OS position
if (mouse_window != NULL)
{ {
double mouse_x, mouse_y; // Update mouse button mask (applied below)
glfwGetCursorPos(mouse_window, &mouse_x, &mouse_y); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (glfwGetMouseButton(window, i) != 0)
mouse_buttons_mask |= (1 << i);
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
if (io.WantSetMousePos)
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
if (bd->MouseWindow == NULL)
{ {
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) double mouse_x, mouse_y;
int window_x, window_y; glfwGetCursorPos(window, &mouse_x, &mouse_y);
glfwGetWindowPos(window, &window_x, &window_y); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
io.MousePos = ImVec2((float)mouse_x + window_x, (float)mouse_y + window_y); {
} // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
else // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
{ int window_x, window_y;
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) glfwGetWindowPos(window, &window_x, &window_y);
mouse_x += window_x;
mouse_y += window_y;
}
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
} }
} }
@ -566,6 +582,14 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons()
io.MouseHoveredViewport = viewport->ID; io.MouseHoveredViewport = viewport->ID;
#endif #endif
} }
// Update mouse buttons
// (if a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame)
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
io.MouseDown[i] = bd->MouseJustPressed[i] || (mouse_buttons_mask & (1 << i)) != 0;
bd->MouseJustPressed[i] = false;
}
} }
static void ImGui_ImplGlfw_UpdateMouseCursor() static void ImGui_ImplGlfw_UpdateMouseCursor()
@ -701,10 +725,8 @@ void ImGui_ImplGlfw_NewFrame()
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
// Update key modifiers
ImGui_ImplGlfw_UpdateKeyModifiers(); ImGui_ImplGlfw_UpdateKeyModifiers();
ImGui_ImplGlfw_UpdateMouseData();
ImGui_ImplGlfw_UpdateMousePosAndButtons();
ImGui_ImplGlfw_UpdateMouseCursor(); ImGui_ImplGlfw_UpdateMouseCursor();
// Update game controllers (if enabled and available) // Update game controllers (if enabled and available)
@ -800,6 +822,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
// Install GLFW callbacks for secondary viewports // Install GLFW callbacks for secondary viewports
glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback); glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback);
glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback); glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback);
glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback);
glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback); glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback);
glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback); glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback);
glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback); glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback);

View File

@ -37,8 +37,9 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
// GLFW callbacks // GLFW callbacks
// - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's previously installed callbacks, if any. // - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's previously installed callbacks, if any.
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those function yourself from your own GLFW callbacks. // - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those function yourself from your own GLFW callbacks.
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);

View File

@ -20,7 +20,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)

View File

@ -15,7 +15,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers. // 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions. // 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader. // 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader.

View File

@ -7,6 +7,7 @@
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: IME support.
// Issues: // Issues:
// [ ] Platform: Multi-viewport / platform windows. // [ ] Platform: Multi-viewport / platform windows.

View File

@ -7,6 +7,7 @@
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: IME support.
// Issues: // Issues:
// [ ] Platform: Multi-viewport / platform windows. // [ ] Platform: Multi-viewport / platform windows.
@ -24,6 +25,7 @@
// 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)
// 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys. // 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys.
// 2021-12-13: Add game controller support. // 2021-12-13: Add game controller support.
@ -56,6 +58,7 @@ static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
static ImGuiKeyModFlags g_KeyModifiers = ImGuiKeyModFlags_None; static ImGuiKeyModFlags g_KeyModifiers = ImGuiKeyModFlags_None;
static ImFocusObserver* g_FocusObserver = nil; static ImFocusObserver* g_FocusObserver = nil;
static KeyEventResponder* g_KeyEventResponder = nil; static KeyEventResponder* g_KeyEventResponder = nil;
static NSTextInputContext* g_InputContext = nil;
// Undocumented methods for creating cursors. // Undocumented methods for creating cursors.
@interface NSCursor() @interface NSCursor()
@ -93,6 +96,29 @@ static double GetMachAbsoluteTimeInSeconds()
@end @end
@implementation KeyEventResponder @implementation KeyEventResponder
{
float _posX;
float _posY;
NSRect _imeRect;
}
#pragma mark - Public
- (void)setImePosX:(float)posX imePosY:(float)posY
{
_posX = posX;
_posY = posY;
}
- (void)updateImePosWithView:(NSView *)view
{
NSWindow *window = view.window;
if (!window)
return;
NSRect contentRect = [window contentRectForFrameRect:window.frame];
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
_imeRect = [window convertRectToScreen:rect];
}
- (void)viewDidMoveToWindow - (void)viewDidMoveToWindow
{ {
@ -147,7 +173,7 @@ static double GetMachAbsoluteTimeInSeconds()
- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange
{ {
return NSZeroRect; return _imeRect;
} }
- (BOOL)hasMarkedText - (BOOL)hasMarkedText
@ -392,6 +418,7 @@ bool ImGui_ImplOSX_Init(NSView* view)
// Add the NSTextInputClient to the view hierarchy, // Add the NSTextInputClient to the view hierarchy,
// to receive keyboard events and translate them to input text. // to receive keyboard events and translate them to input text.
g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect]; g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
g_InputContext = [[NSTextInputContext alloc] initWithClient:g_KeyEventResponder];
[view addSubview:g_KeyEventResponder]; [view addSubview:g_KeyEventResponder];
// Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down). // Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down).
@ -403,6 +430,21 @@ bool ImGui_ImplOSX_Init(NSView* view)
return event; return event;
}]; }];
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
{
if (data->WantVisible)
{
[g_InputContext activate];
}
else
{
[g_InputContext discardMarkedText];
[g_InputContext invalidateCharacterCoordinates];
[g_InputContext deactivate];
}
[g_KeyEventResponder setImePosX:data->InputPos.x imePosY:data->InputPos.y + data->InputLineHeight];
};
return true; return true;
} }
@ -501,6 +543,13 @@ static void ImGui_ImplOSX_UpdateKeyModifiers()
io.AddKeyModsEvent(g_KeyModifiers); io.AddKeyModsEvent(g_KeyModifiers);
} }
static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
{
ImGuiIO& io = ImGui::GetIO();
if (io.WantTextInput)
[g_KeyEventResponder updateImePosWithView:view];
}
void ImGui_ImplOSX_NewFrame(NSView* view) void ImGui_ImplOSX_NewFrame(NSView* view)
{ {
// Setup display size // Setup display size
@ -525,6 +574,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
ImGui_ImplOSX_UpdateKeyModifiers(); ImGui_ImplOSX_UpdateKeyModifiers();
ImGui_ImplOSX_UpdateMouseCursorAndButtons(); ImGui_ImplOSX_UpdateMouseCursorAndButtons();
ImGui_ImplOSX_UpdateGamepads(); ImGui_ImplOSX_UpdateGamepads();
ImGui_ImplOSX_UpdateImePosWithView(view);
} }
bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
@ -605,9 +655,10 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if ([event isARepeat]) if ([event isARepeat])
return io.WantCaptureKeyboard; return io.WantCaptureKeyboard;
int key_code = (int)[event keyCode];
ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code); ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
io.AddKeyEvent(key, event.type == NSEventTypeKeyDown); io.AddKeyEvent(key, event.type == NSEventTypeKeyDown);
io.SetKeyEventNativeData(key, (int)[event keyCode], -1); // To support legacy indexing (<1.87 user code) io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
return io.WantCaptureKeyboard; return io.WantCaptureKeyboard;
} }

View File

@ -20,7 +20,9 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST. // 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+) // 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
@ -85,6 +87,7 @@ struct ImGui_ImplSDL2_Data
{ {
SDL_Window* Window; SDL_Window* Window;
Uint64 Time; Uint64 Time;
int MouseButtonsDown;
bool MousePressed[3]; bool MousePressed[3];
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
char* ClipboardTextData; char* ClipboardTextData;
@ -248,7 +251,20 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
switch (event->type) switch (event->type)
{ {
case SDL_MOUSEWHEEL: case SDL_MOUSEMOTION:
{
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
int window_x, window_y;
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
mouse_pos.x += window_x;
mouse_pos.y += window_y;
}
io.MousePos = mouse_pos;
return true;
}
case SDL_MOUSEWHEEL:
{ {
if (event->wheel.x > 0) io.MouseWheelH += 1; if (event->wheel.x > 0) io.MouseWheelH += 1;
if (event->wheel.x < 0) io.MouseWheelH -= 1; if (event->wheel.x < 0) io.MouseWheelH -= 1;
@ -256,45 +272,55 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
if (event->wheel.y < 0) io.MouseWheel -= 1; if (event->wheel.y < 0) io.MouseWheel -= 1;
return true; return true;
} }
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{ {
if (event->button.button == SDL_BUTTON_LEFT) { bd->MousePressed[0] = true; } int mouse_button = -1;
if (event->button.button == SDL_BUTTON_RIGHT) { bd->MousePressed[1] = true; } if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
if (event->button.button == SDL_BUTTON_MIDDLE) { bd->MousePressed[2] = true; } if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
if (mouse_button != -1)
break;
if (event->type == SDL_MOUSEBUTTONDOWN)
bd->MousePressed[mouse_button] = true;
bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
return true; return true;
} }
case SDL_TEXTINPUT: case SDL_TEXTINPUT:
{ {
io.AddInputCharactersUTF8(event->text.text); io.AddInputCharactersUTF8(event->text.text);
return true; return true;
} }
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym); ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN)); io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
return true; return true;
} }
// Multi-viewport support case SDL_WINDOWEVENT:
case SDL_WINDOWEVENT: {
Uint8 window_event = event->window.event; Uint8 window_event = event->window.event;
if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED || window_event == SDL_WINDOWEVENT_FOCUS_GAINED || window_event == SDL_WINDOWEVENT_FOCUS_LOST) if (window_event == SDL_WINDOWEVENT_LEAVE)
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID))) io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
{ if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
if (window_event == SDL_WINDOWEVENT_CLOSE) io.AddFocusEvent(true);
viewport->PlatformRequestClose = true; else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
if (window_event == SDL_WINDOWEVENT_MOVED) io.AddFocusEvent(false);
viewport->PlatformRequestMove = true; if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED)
if (window_event == SDL_WINDOWEVENT_RESIZED) if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID)))
viewport->PlatformRequestResize = true; {
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) if (window_event == SDL_WINDOWEVENT_CLOSE)
io.AddFocusEvent(true); viewport->PlatformRequestClose = true;
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) if (window_event == SDL_WINDOWEVENT_MOVED)
io.AddFocusEvent(false); viewport->PlatformRequestMove = true;
return true; if (window_event == SDL_WINDOWEVENT_RESIZED)
} viewport->PlatformRequestResize = true;
break; return true;
}
return true;
}
} }
return false; return false;
} }
@ -427,77 +453,60 @@ void ImGui_ImplSDL2_Shutdown()
} }
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4. // This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
static void ImGui_ImplSDL2_UpdateMousePosAndButtons() static void ImGui_ImplSDL2_UpdateMouseData()
{ {
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImVec2 mouse_pos_prev = io.MousePos; // We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
SDL_CaptureMouse(bd->MouseButtonsDown != 0 ? SDL_TRUE : SDL_FALSE);
SDL_Window* focused_window = SDL_GetKeyboardFocus();
const bool is_app_focused = (bd->Window == focused_window);
#else
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
#endif
if (is_app_focused)
{
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos)
{
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y);
else
#endif
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
}
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
{
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
int mouse_x, mouse_y, window_x, window_y;
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
{
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
mouse_x -= window_x;
mouse_y -= window_y;
}
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
}
}
// We don't support ImGuiBackendFlags_HasMouseHoveredViewport
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
// Update mouse buttons // Update buttons
int mouse_x_local, mouse_y_local; Uint32 mouse_buttons = SDL_GetMouseState(NULL, NULL);
Uint32 mouse_buttons = SDL_GetMouseState(&mouse_x_local, &mouse_y_local);
io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false; bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false;
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
SDL_Window* focused_window = SDL_GetKeyboardFocus();
SDL_Window* hovered_window = SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH ? SDL_GetMouseFocus() : NULL; // This is better but is only reliably useful with SDL 2.0.5+ and SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH.
SDL_Window* mouse_window = NULL;
if (hovered_window && (bd->Window == hovered_window || ImGui::FindViewportByPlatformHandle((void*)hovered_window)))
mouse_window = hovered_window;
else if (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window)))
mouse_window = focused_window;
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
SDL_CaptureMouse(ImGui::IsAnyMouseDown() ? SDL_TRUE : SDL_FALSE);
#else
// SDL 2.0.3 and non-windowed systems: single-viewport only
SDL_Window* mouse_window = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) ? bd->Window : NULL;
#endif
if (mouse_window == NULL)
return;
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if (io.WantSetMousePos)
{
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
SDL_WarpMouseGlobal((int)mouse_pos_prev.x, (int)mouse_pos_prev.y);
else
#endif
SDL_WarpMouseInWindow(bd->Window, (int)mouse_pos_prev.x, (int)mouse_pos_prev.y);
}
// Set Dear ImGui mouse position from OS position + get buttons. (this is the common behavior)
if (bd->MouseCanUseGlobalState)
{
int mouse_x_global, mouse_y_global;
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
io.MousePos = ImVec2((float)mouse_x_global, (float)mouse_y_global);
}
else
{
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
// Unlike local position obtained earlier this will be valid when straying out of bounds.
int window_x, window_y;
SDL_GetWindowPosition(mouse_window, &window_x, &window_y);
io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
}
}
else
{
io.MousePos = ImVec2((float)mouse_x_local, (float)mouse_y_local);
}
} }
static void ImGui_ImplSDL2_UpdateMouseCursor() static void ImGui_ImplSDL2_UpdateMouseCursor()
@ -625,10 +634,8 @@ void ImGui_ImplSDL2_NewFrame()
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
// Update key modifiers
ImGui_ImplSDL2_UpdateKeyModifiers(); ImGui_ImplSDL2_UpdateKeyModifiers();
ImGui_ImplSDL2_UpdateMouseData();
ImGui_ImplSDL2_UpdateMousePosAndButtons();
ImGui_ImplSDL2_UpdateMouseCursor(); ImGui_ImplSDL2_UpdateMouseCursor();
// Update game controllers (if enabled and available) // Update game controllers (if enabled and available)

View File

@ -24,7 +24,7 @@
// 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame. // 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize. // 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.

View File

@ -314,8 +314,8 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1); wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1);
// Bind shader and vertex buffers // Bind shader and vertex buffers
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize); wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize); wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState); wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL); wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);

View File

@ -19,6 +19,7 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#include <windows.h> #include <windows.h>
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
#include <tchar.h> #include <tchar.h>
#include <dwmapi.h> #include <dwmapi.h>
@ -34,7 +35,9 @@ 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)
// 2021-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-01-12: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness. // 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages. // 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
@ -81,6 +84,7 @@ struct ImGui_ImplWin32_Data
HWND hWnd; HWND hWnd;
HWND MouseHwnd; HWND MouseHwnd;
bool MouseTracked; bool MouseTracked;
int MouseButtonsDown;
INT64 Time; INT64 Time;
INT64 TicksPerSecond; INT64 TicksPerSecond;
ImGuiMouseCursor LastMouseCursor; ImGuiMouseCursor LastMouseCursor;
@ -256,54 +260,41 @@ static void ImGui_ImplWin32_UpdateKeyModifiers()
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports) // This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
// Because of that, it is a little more complicated than your typical single-viewport binding code! // Because of that, it is a little more complicated than your typical single-viewport binding code!
static void ImGui_ImplWin32_UpdateMousePos() static void ImGui_ImplWin32_UpdateMouseData()
{ {
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(bd->hWnd != 0); IM_ASSERT(bd->hWnd != 0);
const ImVec2 mouse_pos_prev = io.MousePos;
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
io.MouseHoveredViewport = 0;
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
HWND focused_window = ::GetForegroundWindow();
HWND hovered_window = bd->MouseHwnd;
HWND mouse_window = NULL;
if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)hovered_window)))
mouse_window = hovered_window;
else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window)))
mouse_window = focused_window;
if (mouse_window == NULL)
return;
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// (When multi-viewports are enabled, all Dear ImGui positions are same as OS positions)
if (io.WantSetMousePos)
{
POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0)
::ClientToScreen(mouse_window, &pos);
::SetCursorPos(pos.x, pos.y);
}
// Set Dear ImGui mouse position from OS position
POINT mouse_screen_pos; POINT mouse_screen_pos;
if (!::GetCursorPos(&mouse_screen_pos)) bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
return;
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) HWND focused_window = ::GetForegroundWindow();
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
if (is_app_focused)
{ {
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
// This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same. // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
io.MousePos = ImVec2((float)mouse_screen_pos.x, (float)mouse_screen_pos.y); if (io.WantSetMousePos)
} {
else POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
{ if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0)
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) ::ClientToScreen(focused_window, &pos);
// This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE. ::SetCursorPos(pos.x, pos.y);
POINT mouse_client_pos = mouse_screen_pos; }
::ScreenToClient(bd->hWnd, &mouse_client_pos);
io.MousePos = ImVec2((float)mouse_client_pos.x, (float)mouse_client_pos.y); // (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
if (!io.WantSetMousePos && !bd->MouseTracked && has_mouse_screen_pos)
{
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
// (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
// (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
POINT mouse_pos = mouse_screen_pos;
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
::ScreenToClient(bd->hWnd, &mouse_pos);
io.MousePos = ImVec2((float)mouse_pos.x, (float)mouse_pos.y);
}
} }
// (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering. // (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
@ -312,10 +303,12 @@ static void ImGui_ImplWin32_UpdateMousePos()
// - This is _regardless_ of whether another viewport is focused or being dragged from. // - This is _regardless_ of whether another viewport is focused or being dragged from.
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, imgui will ignore this field and infer the information by relying on the // If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, imgui will ignore this field and infer the information by relying on the
// rectangles and last focused time of every viewports it knows about. It will be unaware of foreign windows that may be sitting between or over your windows. // rectangles and last focused time of every viewports it knows about. It will be unaware of foreign windows that may be sitting between or over your windows.
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos)) io.MouseHoveredViewport = 0;
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd)) if (has_mouse_screen_pos)
if ((viewport->Flags & ImGuiViewportFlags_NoInputs) == 0) // FIXME: We still get our NoInputs window with WM_NCHITTEST/HTTRANSPARENT code when decorated? if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
io.MouseHoveredViewport = viewport->ID; if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
if ((viewport->Flags & ImGuiViewportFlags_NoInputs) == 0) // FIXME: We still get our NoInputs window with WM_NCHITTEST/HTTRANSPARENT code when decorated?
io.MouseHoveredViewport = viewport->ID;
} }
// Gamepad navigation mapping // Gamepad navigation mapping
@ -415,15 +408,15 @@ void ImGui_ImplWin32_NewFrame()
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond; io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
bd->Time = current_time; bd->Time = current_time;
// Update OS mouse position
ImGui_ImplWin32_UpdateMouseData();
// Process workarounds for known Windows key handling issues // Process workarounds for known Windows key handling issues
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(); ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
// Update key modifiers // Update key modifiers
ImGui_ImplWin32_UpdateKeyModifiers(); ImGui_ImplWin32_UpdateKeyModifiers();
// Update OS mouse position
ImGui_ImplWin32_UpdateMousePos();
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
if (bd->LastMouseCursor != mouse_cursor) if (bd->LastMouseCursor != mouse_cursor)
@ -583,6 +576,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
switch (msg) switch (msg)
{ {
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
{
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
bd->MouseHwnd = hwnd; bd->MouseHwnd = hwnd;
if (!bd->MouseTracked) if (!bd->MouseTracked)
@ -591,11 +585,17 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
::TrackMouseEvent(&tme); ::TrackMouseEvent(&tme);
bd->MouseTracked = true; bd->MouseTracked = true;
} }
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
::ClientToScreen(hwnd, &mouse_pos);
io.MousePos = ImVec2((float)mouse_pos.x, (float)mouse_pos.y);
break; break;
}
case WM_MOUSELEAVE: case WM_MOUSELEAVE:
if (bd->MouseHwnd == hwnd) if (bd->MouseHwnd == hwnd)
bd->MouseHwnd = NULL; bd->MouseHwnd = NULL;
bd->MouseTracked = false; bd->MouseTracked = false;
io.MousePos = ImVec2(-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:
@ -607,8 +607,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
::SetCapture(hwnd); ::SetCapture(hwnd);
bd->MouseButtonsDown |= 1 << button;
io.MouseDown[button] = true; io.MouseDown[button] = true;
return 0; return 0;
} }
@ -622,9 +623,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (msg == WM_RBUTTONUP) { button = 1; } if (msg == WM_RBUTTONUP) { button = 1; }
if (msg == WM_MBUTTONUP) { button = 2; } if (msg == WM_MBUTTONUP) { button = 2; }
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
io.MouseDown[button] = false; bd->MouseButtonsDown &= ~(1 << button);
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
::ReleaseCapture(); ::ReleaseCapture();
io.MouseDown[button] = false;
return 0; return 0;
} }
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:

View File

@ -133,6 +133,10 @@ Breaking Changes:
- io.AddKeyEvent() will later be turned into a trickling IO queue (for all inputs) to handle very low framerate better. (#2525, #2787, #3383) - io.AddKeyEvent() will later be turned into a trickling IO queue (for all inputs) to handle very low framerate better. (#2525, #2787, #3383)
- io.SetKeyEventNativeData() include native keycode/scancode which will later be exposed. (#3141, #2959) - io.SetKeyEventNativeData() include native keycode/scancode which will later be exposed. (#3141, #2959)
- Renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. (#2625) - Renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. (#2625)
- Backends: GLFW: backend now uses glfwSetCursorPosCallback().
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: nothing to do. is already done for you.
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callback
using glfwSetCursorPosCallback() and forward it to the backend function ImGui_ImplGlfw_CursorPosCallback().
- Commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019) - Commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019)
- ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen() - ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen()
- ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x - ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x
@ -162,7 +166,12 @@ Other Changes:
- Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. - Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every
other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625) other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
- Backends: GLFW: Update mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured.
- Backends: Win32: Update mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured.
- Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. - Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
- Backends: SDL: Update mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured.
- Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
- Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd] - Backends: Allegro5, GLFW, GLUT, SDL, OSX, Win32, Android: Updated to use io.AddKeyEvent() with full key range. (#2625) [@thedmd]
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk] - Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers. It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.
@ -170,6 +179,9 @@ Other Changes:
Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
- Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but - Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but
can theorically be created by user code manipulating a ImDrawList. (#4857) can theorically be created by user code manipulating a ImDrawList. (#4857)
- Backends: OSX: Added basic Platform IME support. (#3108, #2598) [@liuliu]
- Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and
wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev]
Docking+Viewports Branch: Docking+Viewports Branch:

View File

@ -8020,6 +8020,8 @@ const char* ImGui::GetKeyName(ImGuiKey key)
#endif #endif
if (key == ImGuiKey_None) if (key == ImGuiKey_None)
return "None"; return "None";
if (!IsNamedKey(key))
return "Unknown";
return GKeyNames[key - ImGuiKey_NamedKey_BEGIN]; return GKeyNames[key - ImGuiKey_NamedKey_BEGIN];
} }
@ -8168,6 +8170,7 @@ bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID; return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID;
} }
// [WILL OBSOLETE] This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid.
bool ImGui::IsAnyMouseDown() bool ImGui::IsAnyMouseDown()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -8225,6 +8228,13 @@ void ImGui::CaptureMouseFromApp(bool capture)
g.WantCaptureMouseNextFrame = capture ? 1 : 0; g.WantCaptureMouseNextFrame = capture ? 1 : 0;
} }
static const char* GetInputSourceName(ImGuiInputSource source)
{
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" };
IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT);
return input_source_names[source];
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ERROR CHECKING // [SECTION] ERROR CHECKING
@ -10357,6 +10367,18 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
} }
} }
const char* ImGui::GetNavInputName(ImGuiNavInput n)
{
static const char* names[] =
{
"Activate", "Cancel", "Input", "Menu", "DpadLeft", "DpadRight", "DpadUp", "DpadDown", "LStickLeft", "LStickRight", "LStickUp", "LStickDown",
"FocusPrev", "FocusNext", "TweakSlow", "TweakFast", "KeyLeft", "KeyRight", "KeyUp", "KeyDown"
};
IM_ASSERT(IM_ARRAYSIZE(names) == ImGuiNavInput_COUNT);
IM_ASSERT(n >= 0 && n < ImGuiNavInput_COUNT);
return names[n];
}
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode) float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -17602,8 +17624,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Misc Details // Misc Details
if (TreeNode("Internal state")) if (TreeNode("Internal state"))
{ {
const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
Text("WINDOWING"); Text("WINDOWING");
Indent(); Indent();
Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
@ -17616,7 +17636,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("ITEMS"); Text("ITEMS");
Indent(); Indent();
Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]); Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, GetInputSourceName(g.ActiveIdSource));
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
int active_id_using_key_input_count = 0; int active_id_using_key_input_count = 0;
@ -17631,7 +17651,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Indent(); Indent();
Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL");
Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer);
Text("NavInputSource: %s", input_source_names[g.NavInputSource]); Text("NavInputSource: %s", GetInputSourceName(g.NavInputSource));
Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId); Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId);
Text("NavActivateFlags: %04X", g.NavActivateFlags); Text("NavActivateFlags: %04X", g.NavActivateFlags);

View File

@ -65,7 +65,7 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.87 WIP" #define IMGUI_VERSION "1.87 WIP"
#define IMGUI_VERSION_NUM 18604 #define IMGUI_VERSION_NUM 18605
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -940,7 +940,7 @@ namespace ImGui
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0). IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block. IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
IMGUI_API bool IsAnyMouseDown(); // is any mouse button held? IMGUI_API bool IsAnyMouseDown(); // [WILL OBSOLETE] is any mouse button held? This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid.
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves) IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves)
IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)
@ -1585,8 +1585,7 @@ enum ImGuiNavInput_
ImGuiNavInput_KeyRight_, // Move right ImGuiNavInput_KeyRight_, // Move right
ImGuiNavInput_KeyUp_, // Move up ImGuiNavInput_KeyUp_, // Move up
ImGuiNavInput_KeyDown_, // Move down ImGuiNavInput_KeyDown_, // Move down
ImGuiNavInput_COUNT, ImGuiNavInput_COUNT
ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyLeft_
}; };
// Configuration flags stored in io.ConfigFlags. Set by user/application. // Configuration flags stored in io.ConfigFlags. Set by user/application.

View File

@ -6091,7 +6091,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
namespace ImGui { IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); } namespace ImGui { IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); }
// Demo helper function to select among loaded fonts. // Demo helper function to select among loaded fonts.
// Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one. // Here we use the regular BeginCombo()/EndCombo() api which is the more flexible one.
void ImGui::ShowFontSelector(const char* label) void ImGui::ShowFontSelector(const char* label)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();

View File

@ -453,7 +453,7 @@ static inline float ImLengthSqr(const ImVec2& lhs)
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)(f); } static inline float ImFloor(float f) { return (float)(int)(f); }
static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
@ -2811,6 +2811,7 @@ namespace ImGui
IMGUI_API void NavMoveRequestCancel(); IMGUI_API void NavMoveRequestCancel();
IMGUI_API void NavMoveRequestApplyResult(); IMGUI_API void NavMoveRequestApplyResult();
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API const char* GetNavInputName(ImGuiNavInput n);
IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode);
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);