1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-02-02 20:47:23 +01:00

Refactor: moved Window Focus related functions to a dedicated section.

This commit is contained in:
ocornut 2025-01-08 14:22:37 +01:00
parent bbbdc70f26
commit 2b8545684c

522
imgui.cpp
View File

@ -85,6 +85,7 @@ CODE
// [SECTION] SCROLLING // [SECTION] SCROLLING
// [SECTION] TOOLTIPS // [SECTION] TOOLTIPS
// [SECTION] POPUPS // [SECTION] POPUPS
// [SECTION] WINDOW FOCUS
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
// [SECTION] DRAG AND DROP // [SECTION] DRAG AND DROP
// [SECTION] LOGGING/CAPTURING // [SECTION] LOGGING/CAPTURING
@ -1202,6 +1203,10 @@ namespace ImGui
// Item // Item
static void ItemHandleShortcut(ImGuiID id); static void ItemHandleShortcut(ImGuiID id);
// Window Focus
static int FindWindowFocusIndex(ImGuiWindow* window);
static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags);
// Navigation // Navigation
static void NavUpdate(); static void NavUpdate();
static void NavUpdateWindowing(); static void NavUpdateWindowing();
@ -1222,7 +1227,6 @@ static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
static void NavRestoreLayer(ImGuiNavLayer layer); static void NavRestoreLayer(ImGuiNavLayer layer);
static int FindWindowFocusIndex(ImGuiWindow* window);
// Error Checking and Debug Tools // Error Checking and Debug Tools
static void ErrorCheckNewFrameSanityChecks(); static void ErrorCheckNewFrameSanityChecks();
@ -6171,29 +6175,6 @@ static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settin
window->Collapsed = settings->Collapsed; window->Collapsed = settings->Collapsed;
} }
static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags)
{
ImGuiContext& g = *GImGui;
const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0 && ((new_flags & ImGuiWindowFlags_Popup) == 0 || (new_flags & ImGuiWindowFlags_ChildMenu) != 0);
const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild;
if ((just_created || child_flag_changed) && !new_is_explicit_child)
{
IM_ASSERT(!g.WindowsFocusOrder.contains(window));
g.WindowsFocusOrder.push_back(window);
window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1);
}
else if (!just_created && child_flag_changed && new_is_explicit_child)
{
IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window);
for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++)
g.WindowsFocusOrder[n]->FocusOrder--;
g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder);
window->FocusOrder = -1;
}
window->IsExplicitChild = new_is_explicit_child;
}
static void InitOrLoadWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) static void InitOrLoadWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings)
{ {
// Initial window state with e.g. default/arbitrary window position // Initial window state with e.g. default/arbitrary window position
@ -7777,176 +7758,6 @@ void ImGui::End()
SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window); SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window);
} }
void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(window == window->RootWindow);
const int cur_order = window->FocusOrder;
IM_ASSERT(g.WindowsFocusOrder[cur_order] == window);
if (g.WindowsFocusOrder.back() == window)
return;
const int new_order = g.WindowsFocusOrder.Size - 1;
for (int n = cur_order; n < new_order; n++)
{
g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1];
g.WindowsFocusOrder[n]->FocusOrder--;
IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n);
}
g.WindowsFocusOrder[new_order] = window;
window->FocusOrder = (short)new_order;
}
void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* current_front_window = g.Windows.back();
if (current_front_window == window || current_front_window->RootWindow == window) // Cheap early out (could be better)
return;
for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window
if (g.Windows[i] == window)
{
memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*));
g.Windows[g.Windows.Size - 1] = window;
break;
}
}
void ImGui::BringWindowToDisplayBack(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (g.Windows[0] == window)
return;
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i] == window)
{
memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*));
g.Windows[0] = window;
break;
}
}
void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window)
{
IM_ASSERT(window != NULL && behind_window != NULL);
ImGuiContext& g = *GImGui;
window = window->RootWindow;
behind_window = behind_window->RootWindow;
int pos_wnd = FindWindowDisplayIndex(window);
int pos_beh = FindWindowDisplayIndex(behind_window);
if (pos_wnd < pos_beh)
{
size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*);
memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes);
g.Windows[pos_beh - 1] = window;
}
else
{
size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*);
memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes);
g.Windows[pos_beh] = window;
}
}
int ImGui::FindWindowDisplayIndex(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
return g.Windows.index_from_ptr(g.Windows.find(window));
}
// Moving window to front of display and set focus (which happens to be back of our sorted list)
void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
{
ImGuiContext& g = *GImGui;
// Modal check?
if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case.
if (ImGuiWindow* blocking_modal = FindBlockingModal(window))
{
// This block would typically be reached in two situations:
// - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag.
// - User clicking on void or anything behind a modal while a modal is open (window == NULL)
IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "<NULL>", blocking_modal->Name);
if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?)
ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals
return;
}
// Find last focused child (if any) and focus it instead.
if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL)
window = NavRestoreLastChildNavWindow(window);
// Apply focus
if (g.NavWindow != window)
{
SetNavWindow(window);
if (window && g.NavHighlightItemUnderNav)
g.NavMousePosDirty = true;
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
g.NavLayer = ImGuiNavLayer_Main;
SetNavFocusScope(window ? window->NavRootFocusScopeId : 0);
g.NavIdIsAlive = false;
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
// Close popups if any
ClosePopupsOverWindow(window, false);
}
// Move the root window to the top of the pile
IM_ASSERT(window == NULL || window->RootWindow != NULL);
ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; // NB: In docking branch this is window->RootWindowDockStop
ImGuiWindow* display_front_window = window ? window->RootWindow : NULL;
// Steal active widgets. Some of the cases it triggers includes:
// - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run.
// - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId)
if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window)
if (!g.ActiveIdNoClearOnFocusLoss)
ClearActiveID();
// Passing NULL allow to disable keyboard focus
if (!window)
return;
// Bring to front
BringWindowToFocusFront(focus_front_window);
if (((window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
BringWindowToDisplayFront(display_front_window);
}
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags)
{
ImGuiContext& g = *GImGui;
IM_UNUSED(filter_viewport); // Unused in master branch.
int start_idx = g.WindowsFocusOrder.Size - 1;
if (under_this_window != NULL)
{
// Aim at root window behind us, if we are in a child window that's our own root (see #4640)
int offset = -1;
while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow)
{
under_this_window = under_this_window->ParentWindow;
offset = 0;
}
start_idx = FindWindowFocusIndex(under_this_window) + offset;
}
for (int i = start_idx; i >= 0; i--)
{
// 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];
if (window == ignore_window || !window->WasActive)
continue;
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
{
FocusWindow(window, flags);
return;
}
}
FocusWindow(NULL, flags);
}
// Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only. // Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only.
void ImGui::SetCurrentFont(ImFont* font) void ImGui::SetCurrentFont(ImFont* font)
{ {
@ -8216,28 +8027,6 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
return true; return true;
} }
bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* ref_window = g.NavWindow;
ImGuiWindow* cur_window = g.CurrentWindow;
if (ref_window == NULL)
return false;
if (flags & ImGuiFocusedFlags_AnyWindow)
return true;
IM_ASSERT(cur_window); // Not inside a Begin()/End()
const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0;
if (flags & ImGuiHoveredFlags_RootWindow)
cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy);
if (flags & ImGuiHoveredFlags_ChildWindows)
return IsWindowChildOf(ref_window, cur_window, popup_hierarchy);
else
return (ref_window == cur_window);
}
float ImGui::GetWindowWidth() float ImGui::GetWindowWidth()
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
@ -8385,24 +8174,6 @@ void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond)
SetWindowCollapsed(window, collapsed, cond); SetWindowCollapsed(window, collapsed, cond);
} }
void ImGui::SetWindowFocus()
{
FocusWindow(GImGui->CurrentWindow);
}
void ImGui::SetWindowFocus(const char* name)
{
if (name)
{
if (ImGuiWindow* window = FindWindowByName(name))
FocusWindow(window);
}
else
{
FocusWindow(NULL);
}
}
void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -8460,12 +8231,6 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond)
g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always;
} }
void ImGui::SetNextWindowFocus()
{
ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus;
}
void ImGui::SetNextWindowBgAlpha(float alpha) void ImGui::SetNextWindowBgAlpha(float alpha)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -12148,6 +11913,273 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
return window->Pos; return window->Pos;
} }
//-----------------------------------------------------------------------------
// [SECTION] WINDOW FOCUS
//----------------------------------------------------------------------------
// - SetWindowFocus()
// - SetNextWindowFocus()
// - IsWindowFocused()
// - UpdateWindowInFocusOrderList() [Internal]
// - BringWindowToFocusFront() [Internal]
// - BringWindowToDisplayFront() [Internal]
// - BringWindowToDisplayBack() [Internal]
// - BringWindowToDisplayBehind() [Internal]
// - FindWindowDisplayIndex() [Internal]
// - FocusWindow() [Internal]
// - FocusTopMostWindowUnderOne() [Internal]
//-----------------------------------------------------------------------------
void ImGui::SetWindowFocus()
{
FocusWindow(GImGui->CurrentWindow);
}
void ImGui::SetWindowFocus(const char* name)
{
if (name)
{
if (ImGuiWindow* window = FindWindowByName(name))
FocusWindow(window);
}
else
{
FocusWindow(NULL);
}
}
void ImGui::SetNextWindowFocus()
{
ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus;
}
// Similar to IsWindowHovered()
bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* ref_window = g.NavWindow;
ImGuiWindow* cur_window = g.CurrentWindow;
if (ref_window == NULL)
return false;
if (flags & ImGuiFocusedFlags_AnyWindow)
return true;
IM_ASSERT(cur_window); // Not inside a Begin()/End()
const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0;
if (flags & ImGuiHoveredFlags_RootWindow)
cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy);
if (flags & ImGuiHoveredFlags_ChildWindows)
return IsWindowChildOf(ref_window, cur_window, popup_hierarchy);
else
return (ref_window == cur_window);
}
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
IM_UNUSED(g);
int order = window->FocusOrder;
IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking)
IM_ASSERT(g.WindowsFocusOrder[order] == window);
return order;
}
static void ImGui::UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags)
{
ImGuiContext& g = *GImGui;
const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0 && ((new_flags & ImGuiWindowFlags_Popup) == 0 || (new_flags & ImGuiWindowFlags_ChildMenu) != 0);
const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild;
if ((just_created || child_flag_changed) && !new_is_explicit_child)
{
IM_ASSERT(!g.WindowsFocusOrder.contains(window));
g.WindowsFocusOrder.push_back(window);
window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1);
}
else if (!just_created && child_flag_changed && new_is_explicit_child)
{
IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window);
for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++)
g.WindowsFocusOrder[n]->FocusOrder--;
g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder);
window->FocusOrder = -1;
}
window->IsExplicitChild = new_is_explicit_child;
}
void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(window == window->RootWindow);
const int cur_order = window->FocusOrder;
IM_ASSERT(g.WindowsFocusOrder[cur_order] == window);
if (g.WindowsFocusOrder.back() == window)
return;
const int new_order = g.WindowsFocusOrder.Size - 1;
for (int n = cur_order; n < new_order; n++)
{
g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1];
g.WindowsFocusOrder[n]->FocusOrder--;
IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n);
}
g.WindowsFocusOrder[new_order] = window;
window->FocusOrder = (short)new_order;
}
// Note technically focus related but rather adjacent and close to BringWindowToFocusFront()
void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* current_front_window = g.Windows.back();
if (current_front_window == window || current_front_window->RootWindow == window) // Cheap early out (could be better)
return;
for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window
if (g.Windows[i] == window)
{
memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*));
g.Windows[g.Windows.Size - 1] = window;
break;
}
}
void ImGui::BringWindowToDisplayBack(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (g.Windows[0] == window)
return;
for (int i = 0; i < g.Windows.Size; i++)
if (g.Windows[i] == window)
{
memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*));
g.Windows[0] = window;
break;
}
}
void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window)
{
IM_ASSERT(window != NULL && behind_window != NULL);
ImGuiContext& g = *GImGui;
window = window->RootWindow;
behind_window = behind_window->RootWindow;
int pos_wnd = FindWindowDisplayIndex(window);
int pos_beh = FindWindowDisplayIndex(behind_window);
if (pos_wnd < pos_beh)
{
size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*);
memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes);
g.Windows[pos_beh - 1] = window;
}
else
{
size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*);
memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes);
g.Windows[pos_beh] = window;
}
}
int ImGui::FindWindowDisplayIndex(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
return g.Windows.index_from_ptr(g.Windows.find(window));
}
// Moving window to front of display and set focus (which happens to be back of our sorted list)
void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
{
ImGuiContext& g = *GImGui;
// Modal check?
if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case.
if (ImGuiWindow* blocking_modal = FindBlockingModal(window))
{
// This block would typically be reached in two situations:
// - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag.
// - User clicking on void or anything behind a modal while a modal is open (window == NULL)
IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "<NULL>", blocking_modal->Name);
if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?)
ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals
return;
}
// Find last focused child (if any) and focus it instead.
if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL)
window = NavRestoreLastChildNavWindow(window);
// Apply focus
if (g.NavWindow != window)
{
SetNavWindow(window);
if (window && g.NavHighlightItemUnderNav)
g.NavMousePosDirty = true;
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
g.NavLayer = ImGuiNavLayer_Main;
SetNavFocusScope(window ? window->NavRootFocusScopeId : 0);
g.NavIdIsAlive = false;
g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
// Close popups if any
ClosePopupsOverWindow(window, false);
}
// Move the root window to the top of the pile
IM_ASSERT(window == NULL || window->RootWindow != NULL);
ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; // NB: In docking branch this is window->RootWindowDockStop
ImGuiWindow* display_front_window = window ? window->RootWindow : NULL;
// Steal active widgets. Some of the cases it triggers includes:
// - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run.
// - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId)
if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window)
if (!g.ActiveIdNoClearOnFocusLoss)
ClearActiveID();
// Passing NULL allow to disable keyboard focus
if (!window)
return;
// Bring to front
BringWindowToFocusFront(focus_front_window);
if (((window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
BringWindowToDisplayFront(display_front_window);
}
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags)
{
ImGuiContext& g = *GImGui;
IM_UNUSED(filter_viewport); // Unused in master branch.
int start_idx = g.WindowsFocusOrder.Size - 1;
if (under_this_window != NULL)
{
// Aim at root window behind us, if we are in a child window that's our own root (see #4640)
int offset = -1;
while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow)
{
under_this_window = under_this_window->ParentWindow;
offset = 0;
}
start_idx = FindWindowFocusIndex(under_this_window) + offset;
}
for (int i = start_idx; i >= 0; i--)
{
// 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];
if (window == ignore_window || !window->WasActive)
continue;
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
{
FocusWindow(window, flags);
return;
}
}
FocusWindow(NULL, flags);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -13504,16 +13536,6 @@ static void ImGui::NavUpdateCreateWrappingRequest()
NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags); NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags);
} }
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
IM_UNUSED(g);
int order = window->FocusOrder;
IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking)
IM_ASSERT(g.WindowsFocusOrder[order] == window);
return order;
}
// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) // Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext)
// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically. // Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically.
// If you want a window to never be focused, you may use the e.g. NoInputs flag. // If you want a window to never be focused, you may use the e.g. NoInputs flag.