@ -7791,246 +7791,6 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
//-----------------------------------------------------------------------------
static void ImGui : : UpdateViewportsNewFrame ( )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( g . PlatformIO . Viewports . Size < = g . Viewports . Size ) ;
// Update Minimized status (we need it first in order to decide if we'll apply Pos/Size of the main viewport)
for ( int n = 0 ; n < g . Viewports . Size ; n + + )
{
ImGuiViewportP * viewport = g . Viewports [ n ] ;
const bool platform_funcs_available = ( n = = 0 | | viewport - > PlatformWindowCreated ) ;
if ( ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
if ( g . PlatformIO . Platform_GetWindowMinimized & & platform_funcs_available )
viewport - > PlatformWindowMinimized = g . PlatformIO . Platform_GetWindowMinimized ( viewport ) ;
}
// Create/update main viewport with current platform position and size
ImGuiViewportP * main_viewport = g . Viewports [ 0 ] ;
IM_ASSERT ( main_viewport - > ID = = IMGUI_VIEWPORT_DEFAULT_ID ) ;
IM_ASSERT ( main_viewport - > Window = = NULL ) ;
ImVec2 main_viewport_platform_pos = ImVec2 ( 0.0f , 0.0f ) ;
ImVec2 main_viewport_platform_size = g . IO . DisplaySize ;
if ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable )
main_viewport_platform_pos = main_viewport - > PlatformWindowMinimized ? main_viewport - > Pos : g . PlatformIO . Platform_GetWindowPos ( main_viewport ) ;
AddUpdateViewport ( NULL , IMGUI_VIEWPORT_DEFAULT_ID , main_viewport_platform_pos , main_viewport_platform_size , ImGuiViewportFlags_CanHostOtherWindows ) ;
g . CurrentViewport = NULL ;
g . MouseViewport = NULL ;
for ( int n = 0 ; n < g . Viewports . Size ; n + + )
{
// Erase unused viewports
ImGuiViewportP * viewport = g . Viewports [ n ] ;
viewport - > Idx = n ;
if ( n > 0 & & viewport - > LastFrameActive < g . FrameCount - 2 )
{
// Clear references to this viewport in windows (window->ViewportId becomes the master data)
for ( int window_n = 0 ; window_n < g . Windows . Size ; window_n + + )
if ( g . Windows [ window_n ] - > Viewport = = viewport )
{
g . Windows [ window_n ] - > Viewport = NULL ;
g . Windows [ window_n ] - > ViewportOwned = false ;
}
if ( viewport = = g . MouseLastHoveredViewport )
g . MouseLastHoveredViewport = NULL ;
g . Viewports . erase ( g . Viewports . Data + n ) ;
// Destroy
//IMGUI_DEBUG_LOG("Delete Viewport %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
DestroyPlatformWindow ( viewport ) ; // In most circumstances the platform window will already be destroyed here.
IM_ASSERT ( g . PlatformIO . Viewports . contains ( viewport ) = = false ) ;
IM_DELETE ( viewport ) ;
n - - ;
continue ;
}
const bool platform_funcs_available = ( n = = 0 | | viewport - > PlatformWindowCreated ) ;
if ( ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
{
// Update Position and Size (from Platform Window to ImGui) if requested.
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
if ( ! viewport - > PlatformWindowMinimized & & platform_funcs_available )
{
if ( viewport - > PlatformRequestMove )
viewport - > Pos = viewport - > LastPlatformPos = g . PlatformIO . Platform_GetWindowPos ( viewport ) ;
if ( viewport - > PlatformRequestResize )
viewport - > Size = viewport - > LastPlatformSize = g . PlatformIO . Platform_GetWindowSize ( viewport ) ;
}
// Update monitor (we'll use this info to clamp windows and save windows lost in a removed monitor)
viewport - > PlatformMonitor = ( short ) FindPlatformMonitorForRect ( viewport - > GetRect ( ) ) ;
}
// Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back.
viewport - > Alpha = 1.0f ;
// Translate imgui windows when a Host Viewport has been moved
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
ImVec2 viewport_delta = viewport - > Pos - viewport - > LastPos ;
if ( ( viewport - > Flags & ImGuiViewportFlags_CanHostOtherWindows ) & & ( viewport_delta . x ! = 0.0f | | viewport_delta . y ! = 0.0f ) )
for ( int window_n = 0 ; window_n < g . Windows . Size ; window_n + + )
if ( g . Windows [ window_n ] - > Viewport = = viewport | | ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) = = 0 )
TranslateWindow ( g . Windows [ window_n ] , viewport_delta ) ;
// Update DPI scale
float new_dpi_scale ;
if ( g . PlatformIO . Platform_GetWindowDpiScale & & platform_funcs_available )
new_dpi_scale = g . PlatformIO . Platform_GetWindowDpiScale ( viewport ) ;
else if ( viewport - > PlatformMonitor ! = - 1 )
new_dpi_scale = g . PlatformIO . Monitors [ viewport - > PlatformMonitor ] . DpiScale ;
else
new_dpi_scale = ( viewport - > DpiScale ! = 0.0f ) ? viewport - > DpiScale : 1.0f ;
if ( viewport - > DpiScale ! = 0.0f & & new_dpi_scale ! = viewport - > DpiScale )
{
float scale_factor = new_dpi_scale / viewport - > DpiScale ;
if ( g . IO . ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports )
ScaleWindowsInViewport ( viewport , scale_factor ) ;
//if (viewport == GetMainViewport())
// g.PlatformInterface.SetWindowSize(viewport, viewport->Size * scale_factor);
// Scale our window moving pivot so that the window will rescale roughly around the mouse position.
// FIXME-VIEWPORT: This currently creates a resizing feedback loop when a window is straddling a DPI transition border.
// (Minor: since our sizes do not perfectly linearly scale, deferring the click offset scale until we know the actual window scale ratio may get us slightly more precise mouse positioning.)
//if (g.MovingWindow != NULL && g.MovingWindow->Viewport == viewport)
// g.ActiveIdClickOffset = ImFloor(g.ActiveIdClickOffset * scale_factor);
}
viewport - > DpiScale = new_dpi_scale ;
}
if ( ! ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
{
g . MouseViewport = main_viewport ;
return ;
}
// Mouse handling: decide on the actual mouse viewport for this frame between the active/focused viewport and the hovered viewport.
// Note that 'viewport_hovered' should skip over any viewport that has the ImGuiViewportFlags_NoInputs flags set.
ImGuiViewportP * viewport_hovered = NULL ;
if ( g . IO . BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport )
{
viewport_hovered = g . IO . MouseHoveredViewport ? ( ImGuiViewportP * ) FindViewportByID ( g . IO . MouseHoveredViewport ) : NULL ;
if ( viewport_hovered & & ( viewport_hovered - > Flags & ImGuiViewportFlags_NoInputs ) )
{
// Back-end failed at honoring its contract if it returned a viewport with the _NoInputs flag.
IM_ASSERT ( 0 ) ;
viewport_hovered = FindViewportHoveredFromPlatformWindowStack ( g . IO . MousePos ) ;
}
}
else
{
// If the back-end doesn't know how to honor ImGuiViewportFlags_NoInputs, we do a search ourselves. Note that this search:
// A) won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
// B) uses LastFrameAsRefViewport as a flawed replacement for the last time a window was focused (we could/should fix that by introducing Focus functions in PlatformIO)
viewport_hovered = FindViewportHoveredFromPlatformWindowStack ( g . IO . MousePos ) ;
}
if ( viewport_hovered ! = NULL )
g . MouseLastHoveredViewport = viewport_hovered ;
else if ( g . MouseLastHoveredViewport = = NULL )
g . MouseLastHoveredViewport = g . Viewports [ 0 ] ;
// Update mouse reference viewport
// (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode)
if ( g . MovingWindow )
g . MouseViewport = g . MovingWindow - > Viewport ;
else
g . MouseViewport = g . MouseLastHoveredViewport ;
// When dragging something, always refer to the last hovered viewport.
// - when releasing a moving window we will revert to aiming behind (at viewport_hovered)
// - when we are between viewports, our dragged preview will tend to show in the last viewport _even_ if we don't have tooltips in their viewports (when lacking monitor info)
// - consider the case of holding on a menu item to browse child menus: even thou a mouse button is held, there's no active id because menu items only react on mouse release.
const bool is_mouse_dragging_with_an_expected_destination = g . DragDropActive ;
if ( is_mouse_dragging_with_an_expected_destination & & viewport_hovered = = NULL )
viewport_hovered = g . MouseLastHoveredViewport ;
if ( is_mouse_dragging_with_an_expected_destination | | g . ActiveId = = 0 | | ! IsAnyMouseDown ( ) )
if ( viewport_hovered ! = NULL & & viewport_hovered ! = g . MouseViewport & & ! ( viewport_hovered - > Flags & ImGuiViewportFlags_NoInputs ) )
g . MouseViewport = viewport_hovered ;
IM_ASSERT ( g . MouseViewport ! = NULL ) ;
}
// Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some)
static void ImGui : : UpdateViewportsEndFrame ( )
{
ImGuiContext & g = * GImGui ;
g . PlatformIO . MainViewport = g . Viewports [ 0 ] ;
g . PlatformIO . Viewports . resize ( 0 ) ;
for ( int i = 0 ; i < g . Viewports . Size ; i + + )
{
ImGuiViewportP * viewport = g . Viewports [ i ] ;
viewport - > LastPos = viewport - > Pos ;
if ( viewport - > LastFrameActive < g . FrameCount | | viewport - > Size . x < = 0.0f | | viewport - > Size . y < = 0.0f )
if ( i > 0 ) // Always include main viewport in the list
continue ;
if ( viewport - > Window & & ! IsWindowActiveAndVisible ( viewport - > Window ) )
continue ;
if ( i > 0 )
IM_ASSERT ( viewport - > Window ! = NULL ) ;
g . PlatformIO . Viewports . push_back ( viewport ) ;
}
g . Viewports [ 0 ] - > ClearRequestFlags ( ) ; // Clear main viewport flags because UpdatePlatformWindows() won't do it and may not even be called
}
// FIXME: We should ideally refactor the system to call this every frame (we currently don't)
ImGuiViewportP * ImGui : : AddUpdateViewport ( ImGuiWindow * window , ImGuiID id , const ImVec2 & pos , const ImVec2 & size , ImGuiViewportFlags flags )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( id ! = 0 ) ;
if ( window ! = NULL )
{
if ( g . MovingWindow & & g . MovingWindow - > RootWindow = = window )
flags | = ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_NoFocusOnAppearing ;
if ( ( window - > Flags & ImGuiWindowFlags_NoMouseInputs ) & & ( window - > Flags & ImGuiWindowFlags_NoNavInputs ) )
flags | = ImGuiViewportFlags_NoInputs ;
if ( window - > Flags & ImGuiWindowFlags_NoFocusOnAppearing )
flags | = ImGuiViewportFlags_NoFocusOnAppearing ;
}
ImGuiViewportP * viewport = ( ImGuiViewportP * ) FindViewportByID ( id ) ;
if ( viewport )
{
if ( ! viewport - > PlatformRequestMove )
viewport - > Pos = pos ;
if ( ! viewport - > PlatformRequestResize )
viewport - > Size = size ;
}
else
{
// New viewport
viewport = IM_NEW ( ImGuiViewportP ) ( ) ;
viewport - > ID = id ;
viewport - > Idx = g . Viewports . Size ;
viewport - > Pos = viewport - > LastPos = pos ;
viewport - > Size = size ;
viewport - > PlatformMonitor = ( short ) FindPlatformMonitorForRect ( viewport - > GetRect ( ) ) ;
g . Viewports . push_back ( viewport ) ;
//IMGUI_DEBUG_LOG("Add Viewport %08X (%s)\n", id, window->Name);
// We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport.
// We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
g . DrawListSharedData . ClipRectFullscreen . z = ImMax ( g . DrawListSharedData . ClipRectFullscreen . z , viewport - > Pos . x + viewport - > Size . x ) ;
g . DrawListSharedData . ClipRectFullscreen . w = ImMax ( g . DrawListSharedData . ClipRectFullscreen . w , viewport - > Pos . y + viewport - > Size . y ) ;
// Store initial DpiScale before the OS platform window creation, based on expected monitor data.
// This is so we can select an appropriate font size on the first frame of our window lifetime
if ( viewport - > PlatformMonitor ! = - 1 )
viewport - > DpiScale = g . PlatformIO . Monitors [ viewport - > PlatformMonitor ] . DpiScale ;
}
viewport - > Window = window ;
viewport - > Flags = flags ;
viewport - > LastFrameActive = g . FrameCount ;
IM_ASSERT ( window = = NULL | | viewport - > ID = = window - > ID ) ;
if ( window ! = NULL )
window - > ViewportOwned = true ;
return viewport ;
}
// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten.
static void ImGui : : UpdateSelectWindowViewport ( ImGuiWindow * window )
{
@ -8045,7 +7805,6 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
SetWindowViewport ( window , main_viewport ) ;
return ;
}
window - > ViewportOwned = false ;
// Appearing popups reset their viewport so they can inherit again
@ -8138,7 +7897,6 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
window - > Viewport = AddUpdateViewport ( window , window - > ID , window - > Pos , window - > Size , ImGuiViewportFlags_NoFocusOnAppearing ) ;
}
}
// Regular (non-child, non-popup) windows by default are also allowed to protrude
// Child windows are kept contained within their parent.
else if ( window - > ViewportAllowPlatformMonitorExtend < 0 & & ( flags & ImGuiWindowFlags_ChildWindow ) = = 0 )
@ -8146,12 +7904,11 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
// Update flags
window - > ViewportOwned = ( window = = window - > Viewport - > Window ) ;
window - > ViewportId = window - > Viewport - > ID ;
// If the OS window has a title bar, hide our imgui title bar
//if (window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration))
// window->Flags |= ImGuiWindowFlags_NoTitleBar;
window - > ViewportId = window - > Viewport - > ID ;
}
// Called by user at the end of the main loop, after EndFrame()
@ -10616,6 +10373,246 @@ static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 m
return best_candidate ;
}
static void ImGui : : UpdateViewportsNewFrame ( )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( g . PlatformIO . Viewports . Size < = g . Viewports . Size ) ;
// Update Minimized status (we need it first in order to decide if we'll apply Pos/Size of the main viewport)
for ( int n = 0 ; n < g . Viewports . Size ; n + + )
{
ImGuiViewportP * viewport = g . Viewports [ n ] ;
const bool platform_funcs_available = ( n = = 0 | | viewport - > PlatformWindowCreated ) ;
if ( ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
if ( g . PlatformIO . Platform_GetWindowMinimized & & platform_funcs_available )
viewport - > PlatformWindowMinimized = g . PlatformIO . Platform_GetWindowMinimized ( viewport ) ;
}
// Create/update main viewport with current platform position and size
ImGuiViewportP * main_viewport = g . Viewports [ 0 ] ;
IM_ASSERT ( main_viewport - > ID = = IMGUI_VIEWPORT_DEFAULT_ID ) ;
IM_ASSERT ( main_viewport - > Window = = NULL ) ;
ImVec2 main_viewport_platform_pos = ImVec2 ( 0.0f , 0.0f ) ;
ImVec2 main_viewport_platform_size = g . IO . DisplaySize ;
if ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable )
main_viewport_platform_pos = main_viewport - > PlatformWindowMinimized ? main_viewport - > Pos : g . PlatformIO . Platform_GetWindowPos ( main_viewport ) ;
AddUpdateViewport ( NULL , IMGUI_VIEWPORT_DEFAULT_ID , main_viewport_platform_pos , main_viewport_platform_size , ImGuiViewportFlags_CanHostOtherWindows ) ;
g . CurrentViewport = NULL ;
g . MouseViewport = NULL ;
for ( int n = 0 ; n < g . Viewports . Size ; n + + )
{
// Erase unused viewports
ImGuiViewportP * viewport = g . Viewports [ n ] ;
viewport - > Idx = n ;
if ( n > 0 & & viewport - > LastFrameActive < g . FrameCount - 2 )
{
// Clear references to this viewport in windows (window->ViewportId becomes the master data)
for ( int window_n = 0 ; window_n < g . Windows . Size ; window_n + + )
if ( g . Windows [ window_n ] - > Viewport = = viewport )
{
g . Windows [ window_n ] - > Viewport = NULL ;
g . Windows [ window_n ] - > ViewportOwned = false ;
}
if ( viewport = = g . MouseLastHoveredViewport )
g . MouseLastHoveredViewport = NULL ;
g . Viewports . erase ( g . Viewports . Data + n ) ;
// Destroy
//IMGUI_DEBUG_LOG("Delete Viewport %08X (%s)\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
DestroyPlatformWindow ( viewport ) ; // In most circumstances the platform window will already be destroyed here.
IM_ASSERT ( g . PlatformIO . Viewports . contains ( viewport ) = = false ) ;
IM_DELETE ( viewport ) ;
n - - ;
continue ;
}
const bool platform_funcs_available = ( n = = 0 | | viewport - > PlatformWindowCreated ) ;
if ( ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
{
// Update Position and Size (from Platform Window to ImGui) if requested.
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
if ( ! viewport - > PlatformWindowMinimized & & platform_funcs_available )
{
if ( viewport - > PlatformRequestMove )
viewport - > Pos = viewport - > LastPlatformPos = g . PlatformIO . Platform_GetWindowPos ( viewport ) ;
if ( viewport - > PlatformRequestResize )
viewport - > Size = viewport - > LastPlatformSize = g . PlatformIO . Platform_GetWindowSize ( viewport ) ;
}
// Update monitor (we'll use this info to clamp windows and save windows lost in a removed monitor)
viewport - > PlatformMonitor = ( short ) FindPlatformMonitorForRect ( viewport - > GetRect ( ) ) ;
}
// Reset alpha every frame. Users of transparency (docking) needs to request a lower alpha back.
viewport - > Alpha = 1.0f ;
// Translate imgui windows when a Host Viewport has been moved
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
ImVec2 viewport_delta = viewport - > Pos - viewport - > LastPos ;
if ( ( viewport - > Flags & ImGuiViewportFlags_CanHostOtherWindows ) & & ( viewport_delta . x ! = 0.0f | | viewport_delta . y ! = 0.0f ) )
for ( int window_n = 0 ; window_n < g . Windows . Size ; window_n + + )
if ( g . Windows [ window_n ] - > Viewport = = viewport | | ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) = = 0 )
TranslateWindow ( g . Windows [ window_n ] , viewport_delta ) ;
// Update DPI scale
float new_dpi_scale ;
if ( g . PlatformIO . Platform_GetWindowDpiScale & & platform_funcs_available )
new_dpi_scale = g . PlatformIO . Platform_GetWindowDpiScale ( viewport ) ;
else if ( viewport - > PlatformMonitor ! = - 1 )
new_dpi_scale = g . PlatformIO . Monitors [ viewport - > PlatformMonitor ] . DpiScale ;
else
new_dpi_scale = ( viewport - > DpiScale ! = 0.0f ) ? viewport - > DpiScale : 1.0f ;
if ( viewport - > DpiScale ! = 0.0f & & new_dpi_scale ! = viewport - > DpiScale )
{
float scale_factor = new_dpi_scale / viewport - > DpiScale ;
if ( g . IO . ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports )
ScaleWindowsInViewport ( viewport , scale_factor ) ;
//if (viewport == GetMainViewport())
// g.PlatformInterface.SetWindowSize(viewport, viewport->Size * scale_factor);
// Scale our window moving pivot so that the window will rescale roughly around the mouse position.
// FIXME-VIEWPORT: This currently creates a resizing feedback loop when a window is straddling a DPI transition border.
// (Minor: since our sizes do not perfectly linearly scale, deferring the click offset scale until we know the actual window scale ratio may get us slightly more precise mouse positioning.)
//if (g.MovingWindow != NULL && g.MovingWindow->Viewport == viewport)
// g.ActiveIdClickOffset = ImFloor(g.ActiveIdClickOffset * scale_factor);
}
viewport - > DpiScale = new_dpi_scale ;
}
if ( ! ( g . ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable ) )
{
g . MouseViewport = main_viewport ;
return ;
}
// Mouse handling: decide on the actual mouse viewport for this frame between the active/focused viewport and the hovered viewport.
// Note that 'viewport_hovered' should skip over any viewport that has the ImGuiViewportFlags_NoInputs flags set.
ImGuiViewportP * viewport_hovered = NULL ;
if ( g . IO . BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport )
{
viewport_hovered = g . IO . MouseHoveredViewport ? ( ImGuiViewportP * ) FindViewportByID ( g . IO . MouseHoveredViewport ) : NULL ;
if ( viewport_hovered & & ( viewport_hovered - > Flags & ImGuiViewportFlags_NoInputs ) )
{
// Back-end failed at honoring its contract if it returned a viewport with the _NoInputs flag.
IM_ASSERT ( 0 ) ;
viewport_hovered = FindViewportHoveredFromPlatformWindowStack ( g . IO . MousePos ) ;
}
}
else
{
// If the back-end doesn't know how to honor ImGuiViewportFlags_NoInputs, we do a search ourselves. Note that this search:
// A) won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
// B) uses LastFrameAsRefViewport as a flawed replacement for the last time a window was focused (we could/should fix that by introducing Focus functions in PlatformIO)
viewport_hovered = FindViewportHoveredFromPlatformWindowStack ( g . IO . MousePos ) ;
}
if ( viewport_hovered ! = NULL )
g . MouseLastHoveredViewport = viewport_hovered ;
else if ( g . MouseLastHoveredViewport = = NULL )
g . MouseLastHoveredViewport = g . Viewports [ 0 ] ;
// Update mouse reference viewport
// (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode)
if ( g . MovingWindow )
g . MouseViewport = g . MovingWindow - > Viewport ;
else
g . MouseViewport = g . MouseLastHoveredViewport ;
// When dragging something, always refer to the last hovered viewport.
// - when releasing a moving window we will revert to aiming behind (at viewport_hovered)
// - when we are between viewports, our dragged preview will tend to show in the last viewport _even_ if we don't have tooltips in their viewports (when lacking monitor info)
// - consider the case of holding on a menu item to browse child menus: even thou a mouse button is held, there's no active id because menu items only react on mouse release.
const bool is_mouse_dragging_with_an_expected_destination = g . DragDropActive ;
if ( is_mouse_dragging_with_an_expected_destination & & viewport_hovered = = NULL )
viewport_hovered = g . MouseLastHoveredViewport ;
if ( is_mouse_dragging_with_an_expected_destination | | g . ActiveId = = 0 | | ! IsAnyMouseDown ( ) )
if ( viewport_hovered ! = NULL & & viewport_hovered ! = g . MouseViewport & & ! ( viewport_hovered - > Flags & ImGuiViewportFlags_NoInputs ) )
g . MouseViewport = viewport_hovered ;
IM_ASSERT ( g . MouseViewport ! = NULL ) ;
}
// Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some)
static void ImGui : : UpdateViewportsEndFrame ( )
{
ImGuiContext & g = * GImGui ;
g . PlatformIO . MainViewport = g . Viewports [ 0 ] ;
g . PlatformIO . Viewports . resize ( 0 ) ;
for ( int i = 0 ; i < g . Viewports . Size ; i + + )
{
ImGuiViewportP * viewport = g . Viewports [ i ] ;
viewport - > LastPos = viewport - > Pos ;
if ( viewport - > LastFrameActive < g . FrameCount | | viewport - > Size . x < = 0.0f | | viewport - > Size . y < = 0.0f )
if ( i > 0 ) // Always include main viewport in the list
continue ;
if ( viewport - > Window & & ! IsWindowActiveAndVisible ( viewport - > Window ) )
continue ;
if ( i > 0 )
IM_ASSERT ( viewport - > Window ! = NULL ) ;
g . PlatformIO . Viewports . push_back ( viewport ) ;
}
g . Viewports [ 0 ] - > ClearRequestFlags ( ) ; // Clear main viewport flags because UpdatePlatformWindows() won't do it and may not even be called
}
// FIXME: We should ideally refactor the system to call this every frame (we currently don't)
ImGuiViewportP * ImGui : : AddUpdateViewport ( ImGuiWindow * window , ImGuiID id , const ImVec2 & pos , const ImVec2 & size , ImGuiViewportFlags flags )
{
ImGuiContext & g = * GImGui ;
IM_ASSERT ( id ! = 0 ) ;
if ( window ! = NULL )
{
if ( g . MovingWindow & & g . MovingWindow - > RootWindow = = window )
flags | = ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_NoFocusOnAppearing ;
if ( ( window - > Flags & ImGuiWindowFlags_NoMouseInputs ) & & ( window - > Flags & ImGuiWindowFlags_NoNavInputs ) )
flags | = ImGuiViewportFlags_NoInputs ;
if ( window - > Flags & ImGuiWindowFlags_NoFocusOnAppearing )
flags | = ImGuiViewportFlags_NoFocusOnAppearing ;
}
ImGuiViewportP * viewport = ( ImGuiViewportP * ) FindViewportByID ( id ) ;
if ( viewport )
{
if ( ! viewport - > PlatformRequestMove )
viewport - > Pos = pos ;
if ( ! viewport - > PlatformRequestResize )
viewport - > Size = size ;
}
else
{
// New viewport
viewport = IM_NEW ( ImGuiViewportP ) ( ) ;
viewport - > ID = id ;
viewport - > Idx = g . Viewports . Size ;
viewport - > Pos = viewport - > LastPos = pos ;
viewport - > Size = size ;
viewport - > PlatformMonitor = ( short ) FindPlatformMonitorForRect ( viewport - > GetRect ( ) ) ;
g . Viewports . push_back ( viewport ) ;
//IMGUI_DEBUG_LOG("Add Viewport %08X (%s)\n", id, window->Name);
// We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport.
// We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
g . DrawListSharedData . ClipRectFullscreen . z = ImMax ( g . DrawListSharedData . ClipRectFullscreen . z , viewport - > Pos . x + viewport - > Size . x ) ;
g . DrawListSharedData . ClipRectFullscreen . w = ImMax ( g . DrawListSharedData . ClipRectFullscreen . w , viewport - > Pos . y + viewport - > Size . y ) ;
// Store initial DpiScale before the OS platform window creation, based on expected monitor data.
// This is so we can select an appropriate font size on the first frame of our window lifetime
if ( viewport - > PlatformMonitor ! = - 1 )
viewport - > DpiScale = g . PlatformIO . Monitors [ viewport - > PlatformMonitor ] . DpiScale ;
}
viewport - > Window = window ;
viewport - > Flags = flags ;
viewport - > LastFrameActive = g . FrameCount ;
IM_ASSERT ( window = = NULL | | viewport - > ID = = window - > ID ) ;
if ( window ! = NULL )
window - > ViewportOwned = true ;
return viewport ;
}
//-----------------------------------------------------------------------------
// [SECTION] DOCKING