@ -946,7 +946,8 @@ const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbi
static ImGuiViewportP * AddUpdateViewport ( ImGuiWindow * window , ImGuiID id , const ImVec2 & platform_pos , const ImVec2 & size , ImGuiViewportFlags flags ) ;
static void UpdateViewportsNewFrame ( ) ;
static void UpdateViewportsEndFrame ( ) ;
static void UpdateSelectWindowViewport ( ImGuiWindow * window ) ;
static void WindowSelectViewport ( ImGuiWindow * window ) ;
static void WindowSyncOwnedViewport ( ImGuiWindow * window , ImGuiWindow * parent_window_in_stack ) ;
static bool UpdateTryMergeWindowIntoHostViewport ( ImGuiWindow * window , ImGuiViewportP * host_viewport ) ;
static bool UpdateTryMergeWindowIntoHostViewports ( ImGuiWindow * window ) ;
static bool GetWindowAlwaysWantOwnViewport ( ImGuiWindow * window ) ;
@ -6315,7 +6316,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// SELECT VIEWPORT
// We need to do this before using any style/font sizes, as viewport with a different DPI may affect font sizes.
UpdateSelectWindow Viewport( window ) ;
WindowSelect Viewport( window ) ;
SetCurrentViewport ( window , window - > Viewport ) ;
window - > FontDpiScale = ( g . IO . ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts ) ? window - > Viewport - > DpiScale : 1.0f ;
SetCurrentWindow ( window ) ;
@ -6447,85 +6448,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetCurrentWindow ( window ) ;
}
bool viewport_rect_changed = false ;
if ( window - > ViewportOwned )
{
// Synchronize window --> viewport in most situations
// Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM
if ( window - > Viewport - > PlatformRequestMove )
{
window - > Pos = window - > Viewport - > Pos ;
MarkIniSettingsDirty ( window ) ;
}
else if ( memcmp ( & window - > Viewport - > Pos , & window - > Pos , sizeof ( window - > Pos ) ) ! = 0 )
{
viewport_rect_changed = true ;
window - > Viewport - > Pos = window - > Pos ;
}
if ( window - > Viewport - > PlatformRequestResize )
{
window - > Size = window - > SizeFull = window - > Viewport - > Size ;
MarkIniSettingsDirty ( window ) ;
}
else if ( memcmp ( & window - > Viewport - > Size , & window - > Size , sizeof ( window - > Size ) ) ! = 0 )
{
viewport_rect_changed = true ;
window - > Viewport - > Size = window - > Size ;
}
window - > Viewport - > UpdateWorkRect ( ) ;
// The viewport may have changed monitor since the global update in UpdateViewportsNewFrame()
// Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect.
if ( viewport_rect_changed )
UpdateViewportPlatformMonitor ( window - > Viewport ) ;
// Update common viewport flags
const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear ;
ImGuiViewportFlags viewport_flags = window - > Viewport - > Flags & ~ viewport_flags_to_clear ;
const bool is_modal = ( flags & ImGuiWindowFlags_Modal ) ! = 0 ;
const bool is_short_lived_floating_window = ( flags & ( ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup ) ) ! = 0 ;
if ( flags & ImGuiWindowFlags_Tooltip )
viewport_flags | = ImGuiViewportFlags_TopMost ;
if ( ( g . IO . ConfigViewportsNoTaskBarIcon | | is_short_lived_floating_window ) & & ! is_modal )
viewport_flags | = ImGuiViewportFlags_NoTaskBarIcon ;
if ( g . IO . ConfigViewportsNoDecoration | | is_short_lived_floating_window )
viewport_flags | = ImGuiViewportFlags_NoDecoration ;
// Not correct to set modal as topmost because:
// - Because other popups can be stacked above a modal (e.g. combo box in a modal)
// - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost"
//if (flags & ImGuiWindowFlags_Modal)
// viewport_flags |= ImGuiViewportFlags_TopMost;
// For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
// won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
// Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
// but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
if ( is_short_lived_floating_window & & ! is_modal )
viewport_flags | = ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick ;
// We can overwrite viewport flags using ImGuiWindowClass (advanced users)
// We don't default to the main viewport because.
if ( window - > WindowClass . ParentViewportId )
window - > Viewport - > ParentViewportId = window - > WindowClass . ParentViewportId ;
else if ( ( flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip ) ) & & parent_window_in_stack )
window - > Viewport - > ParentViewportId = parent_window_in_stack - > Viewport - > ID ;
else
window - > Viewport - > ParentViewportId = g . IO . ConfigViewportsNoDefaultParent ? 0 : IMGUI_VIEWPORT_DEFAULT_ID ;
if ( window - > WindowClass . ViewportFlagsOverrideSet )
viewport_flags | = window - > WindowClass . ViewportFlagsOverrideSet ;
if ( window - > WindowClass . ViewportFlagsOverrideClear )
viewport_flags & = ~ window - > WindowClass . ViewportFlagsOverrideClear ;
// We can also tell the backend that clearing the platform window won't be necessary,
// as our window background is filling the viewport and we have disabled BgAlpha.
// FIXME: Work on support for per-viewport transparency (#2766)
if ( ! ( flags & ImGuiWindowFlags_NoBackground ) )
viewport_flags | = ImGuiViewportFlags_NoRendererClear ;
window - > Viewport - > Flags = viewport_flags ;
}
WindowSyncOwnedViewport ( window , parent_window_in_stack ) ;
// Calculate the range of allowed position for that window (to be movable and visible past safe area padding)
// When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect.
@ -11409,7 +11333,8 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
// - UpdateViewportsNewFrame() [Internal]
// - UpdateViewportsEndFrame() [Internal]
// - AddUpdateViewport() [Internal]
// - UpdateSelectWindowViewport() [Internal]
// - WindowSelectViewport() [Internal]
// - WindowSyncOwnedViewport() [Internal]
// - UpdatePlatformWindows()
// - RenderPlatformWindowsDefault()
// - FindPlatformMonitorForPos() [Internal]
@ -11425,6 +11350,7 @@ ImGuiViewport* ImGui::GetMainViewport()
return g . Viewports [ 0 ] ;
}
// FIXME: This leaks access to viewports not listed in PlatformIO.Viewports[]. Problematic? (#4236)
ImGuiViewport * ImGui : : FindViewportByID ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
@ -11856,7 +11782,7 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
}
// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten.
static void ImGui : : UpdateSelectWindow Viewport( ImGuiWindow * window )
static void ImGui : : WindowSelect Viewport( ImGuiWindow * window )
{
ImGuiContext & g = * GImGui ;
ImGuiWindowFlags flags = window - > Flags ;
@ -11983,6 +11909,89 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
// window->Flags |= ImGuiWindowFlags_NoTitleBar;
}
void ImGui : : WindowSyncOwnedViewport ( ImGuiWindow * window , ImGuiWindow * parent_window_in_stack )
{
ImGuiContext & g = * GImGui ;
bool viewport_rect_changed = false ;
// Synchronize window --> viewport in most situations
// Synchronize viewport -> window in case the platform window has been moved or resized from the OS/WM
if ( window - > Viewport - > PlatformRequestMove )
{
window - > Pos = window - > Viewport - > Pos ;
MarkIniSettingsDirty ( window ) ;
}
else if ( memcmp ( & window - > Viewport - > Pos , & window - > Pos , sizeof ( window - > Pos ) ) ! = 0 )
{
viewport_rect_changed = true ;
window - > Viewport - > Pos = window - > Pos ;
}
if ( window - > Viewport - > PlatformRequestResize )
{
window - > Size = window - > SizeFull = window - > Viewport - > Size ;
MarkIniSettingsDirty ( window ) ;
}
else if ( memcmp ( & window - > Viewport - > Size , & window - > Size , sizeof ( window - > Size ) ) ! = 0 )
{
viewport_rect_changed = true ;
window - > Viewport - > Size = window - > Size ;
}
window - > Viewport - > UpdateWorkRect ( ) ;
// The viewport may have changed monitor since the global update in UpdateViewportsNewFrame()
// Either a SetNextWindowPos() call in the current frame or a SetWindowPos() call in the previous frame may have this effect.
if ( viewport_rect_changed )
UpdateViewportPlatformMonitor ( window - > Viewport ) ;
// Update common viewport flags
const ImGuiViewportFlags viewport_flags_to_clear = ImGuiViewportFlags_TopMost | ImGuiViewportFlags_NoTaskBarIcon | ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoRendererClear ;
ImGuiViewportFlags viewport_flags = window - > Viewport - > Flags & ~ viewport_flags_to_clear ;
ImGuiWindowFlags window_flags = window - > Flags ;
const bool is_modal = ( window_flags & ImGuiWindowFlags_Modal ) ! = 0 ;
const bool is_short_lived_floating_window = ( window_flags & ( ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup ) ) ! = 0 ;
if ( window_flags & ImGuiWindowFlags_Tooltip )
viewport_flags | = ImGuiViewportFlags_TopMost ;
if ( ( g . IO . ConfigViewportsNoTaskBarIcon | | is_short_lived_floating_window ) & & ! is_modal )
viewport_flags | = ImGuiViewportFlags_NoTaskBarIcon ;
if ( g . IO . ConfigViewportsNoDecoration | | is_short_lived_floating_window )
viewport_flags | = ImGuiViewportFlags_NoDecoration ;
// Not correct to set modal as topmost because:
// - Because other popups can be stacked above a modal (e.g. combo box in a modal)
// - ImGuiViewportFlags_TopMost is currently handled different in backends: in Win32 it is "appear top most" whereas in GLFW and SDL it is "stay topmost"
//if (flags & ImGuiWindowFlags_Modal)
// viewport_flags |= ImGuiViewportFlags_TopMost;
// For popups and menus that may be protruding out of their parent viewport, we enable _NoFocusOnClick so that clicking on them
// won't steal the OS focus away from their parent window (which may be reflected in OS the title bar decoration).
// Setting _NoFocusOnClick would technically prevent us from bringing back to front in case they are being covered by an OS window from a different app,
// but it shouldn't be much of a problem considering those are already popups that are closed when clicking elsewhere.
if ( is_short_lived_floating_window & & ! is_modal )
viewport_flags | = ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoFocusOnClick ;
// We can overwrite viewport flags using ImGuiWindowClass (advanced users)
if ( window - > WindowClass . ParentViewportId )
window - > Viewport - > ParentViewportId = window - > WindowClass . ParentViewportId ;
else if ( ( window_flags & ( ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip ) ) & & parent_window_in_stack )
window - > Viewport - > ParentViewportId = parent_window_in_stack - > Viewport - > ID ;
else
window - > Viewport - > ParentViewportId = g . IO . ConfigViewportsNoDefaultParent ? 0 : IMGUI_VIEWPORT_DEFAULT_ID ;
if ( window - > WindowClass . ViewportFlagsOverrideSet )
viewport_flags | = window - > WindowClass . ViewportFlagsOverrideSet ;
if ( window - > WindowClass . ViewportFlagsOverrideClear )
viewport_flags & = ~ window - > WindowClass . ViewportFlagsOverrideClear ;
// We can also tell the backend that clearing the platform window won't be necessary,
// as our window background is filling the viewport and we have disabled BgAlpha.
// FIXME: Work on support for per-viewport transparency (#2766)
if ( ! ( window_flags & ImGuiWindowFlags_NoBackground ) )
viewport_flags | = ImGuiViewportFlags_NoRendererClear ;
window - > Viewport - > Flags = viewport_flags ;
}
// Called by user at the end of the main loop, after EndFrame()
// This will handle the creation/update of all OS windows via function defined in the ImGuiPlatformIO api.
void ImGui : : UpdatePlatformWindows ( )