CLOSE_SLATE_MAINFRAME

CLOSE_SLATE_MAINFRAME

#Overview

name: CLOSE_SLATE_MAINFRAME

This variable is created as a Console Variable (cvar).

It is referenced in 6 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of CLOSE_SLATE_MAINFRAME is to initiate the process of closing the main editor window in Unreal Engine 5. It is primarily used in the context of shutting down the editor or switching projects.

This setting variable is primarily utilized by the MainFrame module and the UnrealEd subsystem. Based on the callsites, it’s clear that it’s an integral part of the editor’s shutdown process.

The value of this variable is not set directly. Instead, it’s used as a command string that is added to the engine’s deferred commands queue (GEngine->DeferredCommands). This queue is processed at a later time, allowing for safe execution of potentially disruptive operations.

CLOSE_SLATE_MAINFRAME interacts with other parts of the engine, particularly:

  1. The MainFrame module, which handles the actual closing of the editor.
  2. The engine’s deferred command system (GEngine->DeferredCommands).

Developers should be aware of several important aspects when using this variable:

  1. It’s not instantaneous - the command is queued for later execution.
  2. It’s used in various scenarios, including user-initiated exits, project switching, and programmatic shutdown requests.
  3. It’s platform-specific in some cases, with special handling on Mac systems.

Best practices for using this variable include:

  1. Use it when you need to safely close the editor, especially in situations where immediate shutdown might be unsafe.
  2. Always add it to the deferred commands queue rather than trying to execute it directly.
  3. Be aware that adding this command doesn’t guarantee immediate editor closure - the engine will process it when it’s safe to do so.
  4. Consider the state of the engine (e.g., if it’s saving packages or garbage collecting) before adding this command.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameActions.cpp:574

Scope (from outer to inner):

file
function     void FMainFrameActionCallbacks::Exit

Source code excerpt:

	//       (such as MainFrame) to become unloaded out from underneath the code pointer.  We'll shut down
	//       as soon as it's safe to do so.
	GEngine->DeferredCommands.Add( TEXT("CLOSE_SLATE_MAINFRAME"));
}


bool FMainFrameActionCallbacks::Undo_CanExecute()
{
	return GUnrealEd->Trans->CanUndo() && FSlateApplication::Get().IsNormalExecution();

#Loc: <Workspace>/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameHandler.h:78

Scope (from outer to inner):

file
class        class FMainFrameHandler : public TSharedFromThis<FMainFrameHandler>
function     bool CanCloseEditor

Source code excerpt:


			// Defer the call RequestCloseEditor() till next tick.
			GEngine->DeferredCommands.AddUnique( TEXT("CLOSE_SLATE_MAINFRAME") );

			// Cannot exit right now.
			return false;
		}
		else if (GIsSavingPackage || IsGarbageCollecting() || IsLoading() || GIsSlowTask)
		{

#Loc: <Workspace>/Engine/Source/Editor/MainFrame/Private/Frame/MainFrameHandler.h:91

Scope (from outer to inner):

file
class        class FMainFrameHandler : public TSharedFromThis<FMainFrameHandler>
function     bool CanCloseEditor

Source code excerpt:


			// Defer the call RequestCloseEditor() till next tick.
			GEngine->DeferredCommands.AddUnique( TEXT("CLOSE_SLATE_MAINFRAME") );

			// Cannot exit right now.
			return false;
		}
		else
		{

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:5712

Scope (from outer to inner):

file
function     bool UEditorEngine::Exec_Editor

Source code excerpt:

		return true;
	}
	else if( FParse::Command(&Str,TEXT("CLOSE_SLATE_MAINFRAME")) )
	{
		IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
		MainFrameModule.RequestCloseEditor();
		return true;
	}
	//----------------------------------------------------------------------------------

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdMisc.cpp:1837

Scope (from outer to inner):

file
function     void FUnrealEdMisc::SwitchProject

Source code excerpt:


		// Close the editor.  This will prompt the user to save changes.  If they hit cancel, we abort the project switch
		GEngine->DeferredCommands.Add( TEXT("CLOSE_SLATE_MAINFRAME"));
	}
	else
	{
		ClearPendingProjectName();
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/Mac/LaunchMac.cpp:162

Scope: file

Source code excerpt:

				else
				{
					GEngine->DeferredCommands.Add(TEXT("CLOSE_SLATE_MAINFRAME"));
				}
			}
			else
			{
				GEngine->DeferredCommands.Add(TEXT("EXIT"));
			}
		}
	}, @[ NSDefaultRunLoopMode ], false);
}

- (IBAction)showAboutWindow:(id)Sender
{
#if WITH_EDITOR
	GameThreadCall(^{
		if (FModuleManager::Get().IsModuleLoaded(TEXT("MainFrame")))
		{
			FModuleManager::GetModuleChecked<IMainFrameModule>(TEXT("MainFrame")).ShowAboutWindow();
		}
	}, @[ NSDefaultRunLoopMode ], false);
#else
	[NSApp orderFrontStandardAboutPanel:Sender];
#endif
}

#if WITH_EDITOR
- (IBAction)showPreferencesWindow:(id)Sender
{
	GameThreadCall(^{
		if (FModuleManager::Get().IsModuleLoaded(TEXT("Settings")))
		{
			FModuleManager::LoadModuleChecked<ISettingsModule>("Settings").ShowViewer(FName("Editor"), FName("General"), FName("Appearance"));
		}
	}, @[ NSDefaultRunLoopMode ], false);
}
#endif

//handler for the quit apple event used by the Dock menu
- (void)handleQuitEvent:(NSAppleEventDescriptor*)Event withReplyEvent:(NSAppleEventDescriptor*)ReplyEvent
{
    [self requestQuit:self];
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)Sender;
{
	if(!IsEngineExitRequested() || ([NSThread gameThread] && [NSThread gameThread] != [NSThread mainThread]))
	{
		if (!IsEngineExitRequested())
		{
			[self requestQuit:self];
		}
		return NSTerminateLater;
	}
	else
	{
		return NSTerminateNow;
	}
}

- (void) applicationWillTerminate:(NSNotification*)notification
{
	FTaskTagScope::SetTagStaticInit();
}

- (void) runGameThread:(id)Arg
{
	bool bIsBuildMachine = false;
#if !UE_BUILD_SHIPPING
	if (FParse::Param(*GSavedCommandLine, TEXT("BUILDMACHINE")))
	{
		bIsBuildMachine = true;
	}
#endif
	
#if UE_BUILD_DEBUG
	if( true && !GAlwaysReportCrash )
#else
	if( FPlatformMisc::IsDebuggerPresent() && !GAlwaysReportCrash )
#endif
	{