mirror of
https://github.com/ocornut/imgui.git
synced 2025-01-31 12:03:49 +01:00
Viewports: Setting focus from Platform/OS sets corresponding focus at Dear ImGui level. (#6299)
This commit is contained in:
parent
ee5ce36745
commit
dcb6335bfe
@ -153,6 +153,8 @@ Other changes:
|
|||||||
|
|
||||||
Docking+Viewports Branch:
|
Docking+Viewports Branch:
|
||||||
|
|
||||||
|
- Viewports: Setting focus from Platform/OS (e.g. via decoration, or Alt-Tab) sets corresponding
|
||||||
|
focus at Dear ImGui level (generally last focused window in the viewport). (#6299)
|
||||||
- Docking: Fixed using GetItemXXX() or IsItemXXX() functions after a DockSpace(). (#6217)
|
- Docking: Fixed using GetItemXXX() or IsItemXXX() functions after a DockSpace(). (#6217)
|
||||||
- Backends: GLFW: Fixed key modifiers handling on secondary viewports. (#6248, #6034) [@aiekick]
|
- Backends: GLFW: Fixed key modifiers handling on secondary viewports. (#6248, #6034) [@aiekick]
|
||||||
- Backends: GLFW: Fixed Emscripten erroneously enabling multi-viewport support, leading to assert. (#5683)
|
- Backends: GLFW: Fixed Emscripten erroneously enabling multi-viewport support, leading to assert. (#5683)
|
||||||
@ -423,7 +425,7 @@ Other changes:
|
|||||||
|
|
||||||
Docking+Viewports Branch:
|
Docking+Viewports Branch:
|
||||||
|
|
||||||
- Viewport: Fixed collapsed windows setting ImGuiViewportFlags_NoRendererClear without
|
- Viewports: Fixed collapsed windows setting ImGuiViewportFlags_NoRendererClear without
|
||||||
making title bar color opaque, leading to potential texture/fb garbage being visible.
|
making title bar color opaque, leading to potential texture/fb garbage being visible.
|
||||||
Right now as we don't fully support transparent viewports (#2766), so we turn that
|
Right now as we don't fully support transparent viewports (#2766), so we turn that
|
||||||
'TitleBgCollapsed' color opaque just lke we do for 'WindowBG' on uncollapsed windows.
|
'TitleBgCollapsed' color opaque just lke we do for 'WindowBG' on uncollapsed windows.
|
||||||
|
45
imgui.cpp
45
imgui.cpp
@ -4799,7 +4799,7 @@ void ImGui::NewFrame()
|
|||||||
|
|
||||||
// Closing the focused window restore focus to the first active root window in descending z-order
|
// Closing the focused window restore focus to the first active root window in descending z-order
|
||||||
if (g.NavWindow && !g.NavWindow->WasActive)
|
if (g.NavWindow && !g.NavWindow->WasActive)
|
||||||
FocusTopMostWindowUnderOne(NULL, NULL);
|
FocusTopMostWindowUnderOne(NULL, NULL, NULL);
|
||||||
|
|
||||||
// No window should be open at the beginning of the frame.
|
// No window should be open at the beginning of the frame.
|
||||||
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
|
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
|
||||||
@ -7495,7 +7495,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
|||||||
BringWindowToDisplayFront(display_front_window);
|
BringWindowToDisplayFront(display_front_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
|
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
int start_idx = g.WindowsFocusOrder.Size - 1;
|
int start_idx = g.WindowsFocusOrder.Size - 1;
|
||||||
@ -7515,17 +7515,20 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind
|
|||||||
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
||||||
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
||||||
IM_ASSERT(window == window->RootWindow);
|
IM_ASSERT(window == window->RootWindow);
|
||||||
if (window != ignore_window && window->WasActive)
|
if (window == ignore_window || !window->WasActive)
|
||||||
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
continue;
|
||||||
{
|
if (filter_viewport != NULL && window->Viewport != filter_viewport)
|
||||||
// FIXME-DOCK: This is failing (lagging by one frame) for docked windows.
|
continue;
|
||||||
// If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B.
|
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
||||||
// We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update)
|
{
|
||||||
// to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself?
|
// FIXME-DOCK: This is failing (lagging by one frame) for docked windows.
|
||||||
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
|
// If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B.
|
||||||
FocusWindow(focus_window);
|
// We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update)
|
||||||
return;
|
// to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself?
|
||||||
}
|
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
|
||||||
|
FocusWindow(focus_window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FocusWindow(NULL);
|
FocusWindow(NULL);
|
||||||
}
|
}
|
||||||
@ -10895,7 +10898,7 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
|
|||||||
if (focus_window && !focus_window->WasActive && popup_window)
|
if (focus_window && !focus_window->WasActive && popup_window)
|
||||||
{
|
{
|
||||||
// Fallback
|
// Fallback
|
||||||
FocusTopMostWindowUnderOne(popup_window, NULL);
|
FocusTopMostWindowUnderOne(popup_window, NULL, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -12596,6 +12599,8 @@ static void ImGui::NavUpdateWindowing()
|
|||||||
// Apply final focus
|
// Apply final focus
|
||||||
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
|
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
|
||||||
{
|
{
|
||||||
|
// FIXME: Many actions here could be part of a higher-level/reused function. Why aren't they in FocusWindow()
|
||||||
|
// Investigate for each of them: ClearActiveID(), NavRestoreHighlightAfterMove(), NavRestoreLastChildNavWindow(), ClosePopupsOverWindow(), NavInitWindow()
|
||||||
ImGuiViewport* previous_viewport = g.NavWindow ? g.NavWindow->Viewport : NULL;
|
ImGuiViewport* previous_viewport = g.NavWindow ? g.NavWindow->Viewport : NULL;
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
NavRestoreHighlightAfterMove();
|
NavRestoreHighlightAfterMove();
|
||||||
@ -14490,6 +14495,10 @@ void ImGui::UpdatePlatformWindows()
|
|||||||
if (focused_viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
|
if (focused_viewport->LastFrontMostStampCount != g.ViewportFrontMostStampCount)
|
||||||
focused_viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
|
focused_viewport->LastFrontMostStampCount = ++g.ViewportFrontMostStampCount;
|
||||||
g.PlatformLastFocusedViewportId = focused_viewport->ID;
|
g.PlatformLastFocusedViewportId = focused_viewport->ID;
|
||||||
|
if (focused_viewport->Window != NULL)
|
||||||
|
FocusWindow(NavRestoreLastChildNavWindow(focused_viewport->Window));
|
||||||
|
else
|
||||||
|
FocusTopMostWindowUnderOne(NULL, NULL, focused_viewport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19151,11 +19160,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
memcpy(viewports.Data, g.Viewports.Data, g.Viewports.size_in_bytes());
|
memcpy(viewports.Data, g.Viewports.Data, g.Viewports.size_in_bytes());
|
||||||
if (viewports.Size > 1)
|
if (viewports.Size > 1)
|
||||||
ImQsort(viewports.Data, viewports.Size, sizeof(ImGuiViewport*), ViewportComparerByFrontMostStampCount);
|
ImQsort(viewports.Data, viewports.Size, sizeof(ImGuiViewport*), ViewportComparerByFrontMostStampCount);
|
||||||
for (int i = 0; i < viewports.Size; i++)
|
for (ImGuiViewportP* viewport : viewports)
|
||||||
BulletText("Viewport #%d, ID: 0x%08X, FrontMostStampCount = %08d, Window: \"%s\"", viewports[i]->Idx, viewports[i]->ID, viewports[i]->LastFrontMostStampCount, viewports[i]->Window ? viewports[i]->Window->Name : "N/A");
|
BulletText("Viewport #%d, ID: 0x%08X, FrontMostStampCount = %08d, PlatformFocused = %s, Window: \"%s\"",
|
||||||
|
viewport->Idx, viewport->ID, viewport->LastFrontMostStampCount,
|
||||||
|
(g.PlatformIO.Platform_GetWindowFocus && viewport->PlatformWindowCreated) ? (g.PlatformIO.Platform_GetWindowFocus(viewport) ? "1" : "0") : "N/A",
|
||||||
|
viewport->Window ? viewport->Window->Name : "N/A");
|
||||||
TreePop();
|
TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < g.Viewports.Size; i++)
|
for (int i = 0; i < g.Viewports.Size; i++)
|
||||||
DebugNodeViewport(g.Viewports[i]);
|
DebugNodeViewport(g.Viewports[i]);
|
||||||
TreePop();
|
TreePop();
|
||||||
|
@ -2976,7 +2976,7 @@ namespace ImGui
|
|||||||
|
|
||||||
// Windows: Display Order and Focus Order
|
// Windows: Display Order and Focus Order
|
||||||
IMGUI_API void FocusWindow(ImGuiWindow* window);
|
IMGUI_API void FocusWindow(ImGuiWindow* window);
|
||||||
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window);
|
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport);
|
||||||
IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window);
|
IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window);
|
||||||
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window);
|
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window);
|
||||||
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window);
|
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window);
|
||||||
|
@ -7088,7 +7088,7 @@ void ImGui::EndMainMenuBar()
|
|||||||
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
|
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
|
||||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL);
|
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL);
|
||||||
|
|
||||||
End();
|
End();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user