mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-08 23:45:46 +01:00
Merge c65a3e2d6ea99de98ba0e1e06ceeda0d18e2a02b into 367b2c24f399988ddafc0bb4628da0106bcc09be
This commit is contained in:
commit
ac7cc48354
@ -31,6 +31,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-08-12: [Docking] Multi-viewport: Synchronize window manager adjustments instead of treating them as setter echoes. On X11, poll live geometry after a setter so fully rejected requests still synchronize. (#9356, #9398, #9442)
|
||||
// 2026-08-12: [Docking] Multi-viewport: Disable support on Wayland with legacy GLFW versions as global window positioning is unavailable.
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-04-21: Added a Win32-specific implementation of ImGui_ImplGlfw_GetContentScaleXXXX functions for legacy GLFW 3.2.
|
||||
// 2026-03-25: Mouse cursor is properly restored if changed by user app/code while using glfwSetInputMode(..., GLFW_CURSOR_DISABLED) or ImGuiConfigFlags_NoMouseCursorChange. Amend change from 2025-12-10.
|
||||
@ -310,6 +312,9 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window)
|
||||
static void ImGui_ImplGlfw_UpdateMonitors();
|
||||
static void ImGui_ImplGlfw_InitMultiViewportSupport();
|
||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||
#if GLFW_HAS_X11
|
||||
static void ImGui_ImplGlfw_UpdateWindowGeometryRequests();
|
||||
#endif
|
||||
|
||||
// Functions
|
||||
static bool ImGui_ImplGlfw_IsWayland()
|
||||
@ -323,10 +328,10 @@ static bool ImGui_ImplGlfw_IsWayland()
|
||||
if (strstr(version, "Wayland") == nullptr) // e.g. Ubuntu 22.04 ships with GLFW 3.3.6 compiled without Wayland
|
||||
return false;
|
||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
||||
if (glfwGetX11Display() != nullptr)
|
||||
return false;
|
||||
return glfwGetX11Display() == nullptr;
|
||||
#else
|
||||
return false; // Missing X11 native API: do not assume Wayland (keeps viewports on X11).
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -739,11 +744,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
|
||||
bool has_viewports = false;
|
||||
#ifndef __EMSCRIPTEN__
|
||||
has_viewports = true;
|
||||
#if GLFW_HAS_GETPLATFORM
|
||||
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
|
||||
has_viewports = false;
|
||||
#endif
|
||||
has_viewports = !bd->IsWayland;
|
||||
if (has_viewports)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
#endif
|
||||
@ -835,11 +836,14 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
const char* x11_module_path = "libX11.so.6";
|
||||
#endif
|
||||
bd->X11Module = dlopen(x11_module_path, RTLD_LAZY | RTLD_LOCAL);
|
||||
bd->XInternAtom = (PFN_XInternAtom)dlsym(bd->X11Module, "XInternAtom");
|
||||
bd->XChangeProperty = (PFN_XChangeProperty)dlsym(bd->X11Module, "XChangeProperty");
|
||||
bd->XChangeWindowAttributes = (PFN_XChangeWindowAttributes)dlsym(bd->X11Module, "XChangeWindowAttributes");
|
||||
bd->XFlush = (PFN_XFlush)dlsym(bd->X11Module, "XFlush");
|
||||
IM_ASSERT(bd->XInternAtom != nullptr && bd->XChangeProperty != nullptr && bd->XChangeWindowAttributes != nullptr && bd->XFlush != nullptr);
|
||||
if (bd->X11Module != nullptr)
|
||||
{
|
||||
bd->XInternAtom = (PFN_XInternAtom)dlsym(bd->X11Module, "XInternAtom");
|
||||
bd->XChangeProperty = (PFN_XChangeProperty)dlsym(bd->X11Module, "XChangeProperty");
|
||||
bd->XChangeWindowAttributes = (PFN_XChangeWindowAttributes)dlsym(bd->X11Module, "XChangeWindowAttributes");
|
||||
bd->XFlush = (PFN_XFlush)dlsym(bd->X11Module, "XFlush");
|
||||
IM_ASSERT(bd->XInternAtom != nullptr && bd->XChangeProperty != nullptr && bd->XChangeWindowAttributes != nullptr && bd->XFlush != nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1201,6 +1205,9 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
#if GLFW_HAS_X11
|
||||
ImGui_ImplGlfw_UpdateWindowGeometryRequests();
|
||||
#endif
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||
@ -1294,6 +1301,18 @@ struct ImGui_ImplGlfw_ViewportData
|
||||
bool WindowOwned;
|
||||
int IgnoreWindowPosEventFrame;
|
||||
int IgnoreWindowSizeEventFrame;
|
||||
int LastWindowPosRequest[2];
|
||||
int LastWindowSizeRequest[2];
|
||||
#if GLFW_HAS_X11
|
||||
int LastObservedWindowPos[2];
|
||||
int LastObservedWindowSize[2];
|
||||
int WindowPosMismatchFrameCount;
|
||||
int WindowSizeMismatchFrameCount;
|
||||
double WindowPosMismatchStartTime;
|
||||
double WindowSizeMismatchStartTime;
|
||||
bool WindowPosRequestPending;
|
||||
bool WindowSizeRequestPending;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
@ -1314,30 +1333,100 @@ static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
|
||||
// - on Linux it is queued and invoked during glfwPollEvents()
|
||||
// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only
|
||||
// ignore recent glfwSetWindowXXX() calls.
|
||||
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
|
||||
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int x, int y)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
{
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1);
|
||||
//data->IgnoreWindowPosEventFrame = -1;
|
||||
if (ignore_event)
|
||||
// Ignore only the latest matching setter echo. Adjusted or stale geometry requests a platform readback.
|
||||
const bool is_latest_request = (x == vd->LastWindowPosRequest[0] && y == vd->LastWindowPosRequest[1]);
|
||||
const bool is_current_viewport_pos = (x == (int)viewport->Pos.x && y == (int)viewport->Pos.y);
|
||||
#if GLFW_HAS_X11
|
||||
vd->WindowPosRequestPending = false;
|
||||
vd->WindowPosMismatchFrameCount = 0;
|
||||
vd->WindowPosMismatchStartTime = 0.0;
|
||||
#endif
|
||||
if (ignore_event && is_latest_request && is_current_viewport_pos)
|
||||
return;
|
||||
}
|
||||
viewport->PlatformRequestMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
||||
#if GLFW_HAS_X11
|
||||
static bool ImGui_ImplGlfw_UpdateWindowGeometryRequest(int value_0, int value_1, const int request[2], int observed[2], int* mismatch_frame_count, double* mismatch_start_time, bool* request_pending, double current_time)
|
||||
{
|
||||
if (value_0 == request[0] && value_1 == request[1])
|
||||
{
|
||||
*request_pending = false;
|
||||
*mismatch_frame_count = 0;
|
||||
*mismatch_start_time = 0.0;
|
||||
return false;
|
||||
}
|
||||
if (*mismatch_frame_count > 0 && value_0 == observed[0] && value_1 == observed[1])
|
||||
(*mismatch_frame_count)++;
|
||||
else
|
||||
{
|
||||
*mismatch_frame_count = 1;
|
||||
*mismatch_start_time = current_time;
|
||||
}
|
||||
observed[0] = value_0;
|
||||
observed[1] = value_1;
|
||||
if (*mismatch_frame_count < 2 || current_time - *mismatch_start_time < 0.050)
|
||||
return false;
|
||||
*request_pending = false;
|
||||
*mismatch_frame_count = 0;
|
||||
*mismatch_start_time = 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// GLFW swallows unchanged synthetic ConfigureNotify. Poll live geometry until it matches the last Set or stays rejected.
|
||||
static void ImGui_ImplGlfw_UpdateWindowGeometryRequests()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
const double current_time = glfwGetTime();
|
||||
for (int viewport_n = 1; viewport_n < platform_io.Viewports.Size; viewport_n++)
|
||||
{
|
||||
ImGuiViewport* viewport = platform_io.Viewports[viewport_n];
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd == nullptr)
|
||||
continue;
|
||||
if (vd->WindowPosRequestPending)
|
||||
{
|
||||
int x, y;
|
||||
glfwGetWindowPos(vd->Window, &x, &y);
|
||||
if (ImGui_ImplGlfw_UpdateWindowGeometryRequest(x, y, vd->LastWindowPosRequest, vd->LastObservedWindowPos, &vd->WindowPosMismatchFrameCount, &vd->WindowPosMismatchStartTime, &vd->WindowPosRequestPending, current_time))
|
||||
viewport->PlatformRequestMove = true;
|
||||
}
|
||||
if (vd->WindowSizeRequestPending)
|
||||
{
|
||||
int width, height;
|
||||
glfwGetWindowSize(vd->Window, &width, &height);
|
||||
if (ImGui_ImplGlfw_UpdateWindowGeometryRequest(width, height, vd->LastWindowSizeRequest, vd->LastObservedWindowSize, &vd->WindowSizeMismatchFrameCount, &vd->WindowSizeMismatchStartTime, &vd->WindowSizeRequestPending, current_time))
|
||||
viewport->PlatformRequestResize = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
{
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1);
|
||||
//data->IgnoreWindowSizeEventFrame = -1;
|
||||
if (ignore_event)
|
||||
// Preserve delayed setter-echo suppression only while the viewport still expects that exact size.
|
||||
const bool is_latest_request = (width == vd->LastWindowSizeRequest[0] && height == vd->LastWindowSizeRequest[1]);
|
||||
const bool is_current_viewport_size = (width == (int)viewport->Size.x && height == (int)viewport->Size.y);
|
||||
#if GLFW_HAS_X11
|
||||
vd->WindowSizeRequestPending = false;
|
||||
vd->WindowSizeMismatchFrameCount = 0;
|
||||
vd->WindowSizeMismatchStartTime = 0.0;
|
||||
#endif
|
||||
if (ignore_event && is_latest_request && is_current_viewport_size)
|
||||
return;
|
||||
}
|
||||
viewport->PlatformRequestResize = true;
|
||||
@ -1349,7 +1438,7 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
||||
static void ImGui_ImplGlfw_SetWindowFloating(ImGui_ImplGlfw_Data* bd, GLFWwindow* window)
|
||||
{
|
||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
||||
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
|
||||
if (glfwGetPlatform() == GLFW_PLATFORM_X11 && bd->XInternAtom != nullptr && bd->XChangeProperty != nullptr && bd->XChangeWindowAttributes != nullptr && bd->XFlush != nullptr)
|
||||
{
|
||||
Display* display = glfwGetX11Display();
|
||||
Window xwindow = glfwGetX11Window(window);
|
||||
@ -1499,7 +1588,22 @@ static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
|
||||
glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y);
|
||||
#if GLFW_HAS_X11
|
||||
const int request_x = (int)pos.x;
|
||||
const int request_y = (int)pos.y;
|
||||
if (request_x != vd->LastWindowPosRequest[0] || request_y != vd->LastWindowPosRequest[1])
|
||||
{
|
||||
vd->WindowPosMismatchFrameCount = 0;
|
||||
vd->WindowPosMismatchStartTime = 0.0;
|
||||
}
|
||||
vd->LastWindowPosRequest[0] = request_x;
|
||||
vd->LastWindowPosRequest[1] = request_y;
|
||||
vd->WindowPosRequestPending = true;
|
||||
#else
|
||||
vd->LastWindowPosRequest[0] = (int)pos.x;
|
||||
vd->LastWindowPosRequest[1] = (int)pos.y;
|
||||
#endif
|
||||
glfwSetWindowPos(vd->Window, vd->LastWindowPosRequest[0], vd->LastWindowPosRequest[1]);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
|
||||
@ -1521,10 +1625,28 @@ static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
int x, y, width, height;
|
||||
glfwGetWindowPos(vd->Window, &x, &y);
|
||||
glfwGetWindowSize(vd->Window, &width, &height);
|
||||
glfwSetWindowPos(vd->Window, x, y - height + size.y);
|
||||
vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
|
||||
vd->LastWindowPosRequest[0] = x;
|
||||
vd->LastWindowPosRequest[1] = (int)(y - height + size.y);
|
||||
glfwSetWindowPos(vd->Window, vd->LastWindowPosRequest[0], vd->LastWindowPosRequest[1]);
|
||||
#endif
|
||||
vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount();
|
||||
glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
||||
#if GLFW_HAS_X11
|
||||
const int request_w = (int)size.x;
|
||||
const int request_h = (int)size.y;
|
||||
if (request_w != vd->LastWindowSizeRequest[0] || request_h != vd->LastWindowSizeRequest[1])
|
||||
{
|
||||
vd->WindowSizeMismatchFrameCount = 0;
|
||||
vd->WindowSizeMismatchStartTime = 0.0;
|
||||
}
|
||||
vd->LastWindowSizeRequest[0] = request_w;
|
||||
vd->LastWindowSizeRequest[1] = request_h;
|
||||
vd->WindowSizeRequestPending = true;
|
||||
#else
|
||||
vd->LastWindowSizeRequest[0] = (int)size.x;
|
||||
vd->LastWindowSizeRequest[1] = (int)size.y;
|
||||
#endif
|
||||
glfwSetWindowSize(vd->Window, vd->LastWindowSizeRequest[0], vd->LastWindowSizeRequest[1]);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplGlfw_GetWindowFramebufferScale(ImGuiViewport* viewport)
|
||||
|
||||
@ -113,7 +113,15 @@ Other Changes:
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: fixed platform position/size requests adjusted or rejected by a window manager
|
||||
leaving Dear ImGui geometry out of sync with the native window. Active window dragging now
|
||||
continues from the platform-accepted position instead of repeatedly requesting rejected
|
||||
geometry. (#9356, #9398, #9442)
|
||||
- Backends:
|
||||
- GLFW: on X11, poll live geometry after a setter so completely rejected viewport
|
||||
requests are synchronized. (#9356, #9398, #9442)
|
||||
- GLFW: disabled multi-viewports on Wayland with legacy GLFW versions, where global window
|
||||
positioning is unavailable.
|
||||
- Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856) [@laikoken]
|
||||
- Examples:
|
||||
- SDL3+Metal, GLFW+Metal: fix multi-viewport support.
|
||||
@ -9714,4 +9722,3 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.00
|
||||
|
||||
- Initial release.
|
||||
|
||||
|
||||
67
imgui.cpp
67
imgui.cpp
@ -4334,6 +4334,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
HoveredWindowUnderMovingWindow = NULL;
|
||||
HoveredWindowBeforeClear = NULL;
|
||||
MovingWindow = NULL;
|
||||
MovingWindowClickOffset = ImVec2(-1, -1);
|
||||
WheelingWindow = NULL;
|
||||
WheelingWindowStartFrame = WheelingWindowScrolledFrame = -1;
|
||||
WheelingWindowReleaseTimer = 0.0f;
|
||||
@ -5464,6 +5465,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
|
||||
if (g.IO.ConfigNavCursorVisibleAuto)
|
||||
g.NavCursorVisible = false;
|
||||
g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - window->RootWindowDockTree->Pos;
|
||||
g.MovingWindowClickOffset = g.ActiveIdClickOffset;
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
SetActiveIdUsingAllKeyboardKeys();
|
||||
|
||||
@ -5549,7 +5551,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
||||
const bool window_disappeared = (!moving_window->WasActive && !moving_window->Active);
|
||||
if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos) && !window_disappeared)
|
||||
{
|
||||
ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
|
||||
ImVec2 pos = g.IO.MousePos - g.MovingWindowClickOffset;
|
||||
if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
|
||||
{
|
||||
SetWindowPos(moving_window, pos, ImGuiCond_Always);
|
||||
@ -17210,9 +17212,43 @@ static void ImGui::UpdateViewportsNewFrame()
|
||||
{
|
||||
// Viewport->WorkPos and WorkSize will be updated below
|
||||
if (viewport->PlatformRequestMove)
|
||||
viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport);
|
||||
{
|
||||
const ImVec2 requested_pos = viewport->LastPlatformPos;
|
||||
const ImVec2 platform_pos = g.PlatformIO.Platform_GetWindowPos(viewport);
|
||||
// Rebase only axes adjusted by the window manager. Platform coordinates are integer pixels.
|
||||
const bool platform_pos_adjusted = (ImTrunc(platform_pos.x) != ImTrunc(requested_pos.x) || ImTrunc(platform_pos.y) != ImTrunc(requested_pos.y));
|
||||
ImGuiWindow* moving_root = g.MovingWindow ? g.MovingWindow->RootWindowDockTree : NULL;
|
||||
const bool moving_owned_viewport = (moving_root && viewport->Window == moving_root && moving_root->ViewportOwned && IsMousePosValid(&g.IO.MousePos));
|
||||
if (moving_owned_viewport)
|
||||
{
|
||||
if (ImTrunc(platform_pos.x) != ImTrunc(requested_pos.x))
|
||||
g.MovingWindowClickOffset.x = g.IO.MousePos.x - platform_pos.x;
|
||||
if (ImTrunc(platform_pos.y) != ImTrunc(requested_pos.y))
|
||||
g.MovingWindowClickOffset.y = g.IO.MousePos.y - platform_pos.y;
|
||||
}
|
||||
viewport->Pos = viewport->LastPlatformPos = platform_pos;
|
||||
if (platform_pos_adjusted && viewport->Window != NULL)
|
||||
{
|
||||
viewport->Window->Pos = platform_pos;
|
||||
MarkIniSettingsDirty(viewport->Window);
|
||||
}
|
||||
if (!platform_pos_adjusted || moving_owned_viewport)
|
||||
viewport->PlatformRequestMove = false;
|
||||
}
|
||||
if (viewport->PlatformRequestResize)
|
||||
viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport);
|
||||
{
|
||||
const ImVec2 requested_size = viewport->LastPlatformSize;
|
||||
const ImVec2 platform_size = g.PlatformIO.Platform_GetWindowSize(viewport);
|
||||
const bool platform_size_adjusted = (ImTrunc(platform_size.x) != ImTrunc(requested_size.x) || ImTrunc(platform_size.y) != ImTrunc(requested_size.y));
|
||||
viewport->Size = viewport->LastPlatformSize = platform_size;
|
||||
if (platform_size_adjusted && viewport->Window != NULL)
|
||||
{
|
||||
viewport->Window->Size = viewport->Window->SizeFull = platform_size;
|
||||
MarkIniSettingsDirty(viewport->Window);
|
||||
}
|
||||
if (!platform_size_adjusted)
|
||||
viewport->PlatformRequestResize = false;
|
||||
}
|
||||
if (g.PlatformIO.Platform_GetWindowFramebufferScale != NULL)
|
||||
viewport->FramebufferScale = g.PlatformIO.Platform_GetWindowFramebufferScale(viewport);
|
||||
}
|
||||
@ -17763,15 +17799,25 @@ void ImGui::UpdatePlatformWindows()
|
||||
viewport->PlatformWindowCreated = true;
|
||||
}
|
||||
|
||||
// Consume requests applied by NewFrame(), before setters can raise synchronous callbacks.
|
||||
const bool platform_request_move = viewport->PlatformRequestMove;
|
||||
const bool platform_request_resize = viewport->PlatformRequestResize;
|
||||
viewport->PlatformRequestMove = viewport->PlatformRequestResize = false;
|
||||
|
||||
// Apply Position and Size (from ImGui to Platform/Renderer backends)
|
||||
if ((viewport->LastPlatformPos.x != viewport->Pos.x || viewport->LastPlatformPos.y != viewport->Pos.y) && !viewport->PlatformRequestMove)
|
||||
if ((viewport->LastPlatformPos.x != viewport->Pos.x || viewport->LastPlatformPos.y != viewport->Pos.y) && !platform_request_move)
|
||||
{
|
||||
g.PlatformIO.Platform_SetWindowPos(viewport, viewport->Pos);
|
||||
if ((viewport->LastPlatformSize.x != viewport->Size.x || viewport->LastPlatformSize.y != viewport->Size.y) && !viewport->PlatformRequestResize)
|
||||
viewport->LastPlatformPos = viewport->Pos;
|
||||
}
|
||||
if ((viewport->LastPlatformSize.x != viewport->Size.x || viewport->LastPlatformSize.y != viewport->Size.y) && !platform_request_resize)
|
||||
{
|
||||
g.PlatformIO.Platform_SetWindowSize(viewport, viewport->Size);
|
||||
viewport->LastPlatformSize = viewport->Size;
|
||||
}
|
||||
if ((viewport->LastRendererSize.x != viewport->Size.x || viewport->LastRendererSize.y != viewport->Size.y) && g.PlatformIO.Renderer_SetWindowSize)
|
||||
g.PlatformIO.Renderer_SetWindowSize(viewport, viewport->Size);
|
||||
viewport->LastPlatformPos = viewport->Pos;
|
||||
viewport->LastPlatformSize = viewport->LastRendererSize = viewport->Size;
|
||||
viewport->LastRendererSize = viewport->Size;
|
||||
|
||||
// Update title bar (if it changed)
|
||||
if (ImGuiWindow* window_for_title = GetWindowForTitleDisplay(viewport->Window))
|
||||
@ -17808,8 +17854,10 @@ void ImGui::UpdatePlatformWindows()
|
||||
g.PlatformIO.Platform_ShowWindow(viewport);
|
||||
}
|
||||
|
||||
// Clear request flags
|
||||
viewport->ClearRequestFlags();
|
||||
// Position/size requests raised synchronously above need to survive until the next NewFrame().
|
||||
// Close requests keep their previous lifetime and are consumed once per platform update.
|
||||
viewport->PlatformRequestClose = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -19259,6 +19307,7 @@ static void ImGui::DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWind
|
||||
IM_ASSERT(node->WantMouseMove == true);
|
||||
StartMouseMovingWindow(window);
|
||||
g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - node->Pos;
|
||||
g.MovingWindowClickOffset = g.ActiveIdClickOffset;
|
||||
g.MovingWindow = window; // If we are docked into a non moveable root window, StartMouseMovingWindow() won't set g.MovingWindow. Override that decision.
|
||||
node->WantMouseMove = false;
|
||||
}
|
||||
|
||||
@ -2498,6 +2498,7 @@ struct ImGuiContext
|
||||
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
|
||||
ImGuiWindow* HoveredWindowBeforeClear; // Window the mouse is hovering. Filled even with _NoMouse. This is currently useful for multi-context compositors.
|
||||
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree.
|
||||
ImVec2 MovingWindowClickOffset; // Click offset used to position MovingWindow. May be rebased when a platform window manager adjusts our requested position.
|
||||
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
|
||||
ImVec2 WheelingWindowRefMousePos;
|
||||
int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
|
||||
|
||||
@ -11014,6 +11014,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
g.MovingWindow = docked_window;
|
||||
SetActiveID(g.MovingWindow->MoveId, g.MovingWindow);
|
||||
g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min;
|
||||
g.MovingWindowClickOffset = g.ActiveIdClickOffset;
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
SetActiveIdUsingAllKeyboardKeys();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user