public static void SetFullscreen(bool fullscreen, bool showTopToolbar, Vector2 fullscreenAtPosition) { var originallyFocusedEditorWin = EditorWindow.focusedWindow; var originallyFocusedEditorWinType = originallyFocusedEditorWin == null ? null : originallyFocusedEditorWin.GetType(); var fullscreenState = GetWindowFullscreenState(); bool wasFullscreen = fullscreenState.IsFullscreen; fullscreenState.ShowTopToolbar = showTopToolbar; fullscreenState.originalContainerWindow = (ScriptableObject)FindOriginalContainerWindow(); fullscreenState.containerWindow = (ScriptableObject)FindContainerWindow(); object mainWindow = FindMainWindow(); bool inOriginalContainer = fullscreenState.containerWindow == fullscreenState.originalContainerWindow; var screenBounds = EditorDisplay.ClosestToPoint(fullscreenAtPosition).Bounds; if (fullscreen) { fullscreenState.ScreenBounds = screenBounds; fullscreenState.FullscreenAtPosition = fullscreenAtPosition; if (!wasFullscreen) { var wasMaximized = maximized; if (wasMaximized) { ToggleMaximize(); } fullscreenState.PreFullscreenPosition = position; fullscreenState.PreFullscreenMinSize = minSize; fullscreenState.PreFullscreenMaxSize = maxSize; fullscreenState.PreFullscreenMaximized = wasMaximized; } } if (fullscreen && !showTopToolbar) { object fsContainerWindow; if (inOriginalContainer) { fsContainerWindow = ScriptableObject.CreateInstance(FS.containerWindowType); } else { fsContainerWindow = fullscreenState.containerWindow; } //Custom toolbar //int toolbarHeight = 18; //fullscreenState.EditorWin = MainWindowMenu.Create(new Rect(newPos.xMin, newPos.yMin, newPos.width, toolbarHeight)); //newPos.yMin += toolbarHeight; //Put the main view into the fullscreen container window containerMainView.SetValue(fsContainerWindow, mainWindow, null); inOriginalContainer = false; containerPosition.SetValue(fsContainerWindow, screenBounds, null); containerShow.Invoke(fsContainerWindow, new object[] { 3, false, true }); SetMinMaxSizes(screenBounds.size, screenBounds.size); containerPosition.SetValue(fsContainerWindow, screenBounds, null); MethodInfo displayAllViews = FS.containerWindowType.GetMethod("DisplayAllViews", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new System.Type[] { }, null); displayAllViews.Invoke(fsContainerWindow, null); fullscreenState.containerWindow = (ScriptableObject)fsContainerWindow; fullscreenState.IsFullscreen = true; } else { if (fullscreenState.EditorWin != null) { fullscreenState.EditorWin.Close(); } if (!inOriginalContainer) { //Reset main view back to original container view containerMainViewField.SetValue(fullscreenState.originalContainerWindow, null); containerMainView.SetValue(fullscreenState.originalContainerWindow, mainWindow, null); try { containerMainViewField.SetValue(fullscreenState.containerWindow, null); containerClose.Invoke(fullscreenState.containerWindow, null); } catch (System.Exception e) { if (FS.LogNonFatalErrors) { Debug.LogException(e); } } fullscreenState.containerWindow = fullscreenState.originalContainerWindow; fullscreenState.IsFullscreen = false; inOriginalContainer = true; } if (fullscreen) { //Set fullscreen with toolbar var newPos = screenBounds; newPos.yMin += topToolbarHeight; position = newPos; SetMinMaxSizes(newPos.size, newPos.size); position = newPos; if (position.x != newPos.x) { //Position didn't set correctly, so must be maximized fullscreenState.PreFullscreenMaximized = true; ToggleMaximize(); position = newPos; } fullscreenState.IsFullscreen = true; } } if (!fullscreen && inOriginalContainer && wasFullscreen) { //Reset position position = fullscreenState.PreFullscreenPosition; SetMinMaxSizes(fullscreenState.PreFullscreenMinSize, fullscreenState.PreFullscreenMaxSize); position = fullscreenState.PreFullscreenPosition; PropertyInfo pos = FS.viewType.GetProperty("position", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); pos.SetValue(FindMainWindow(), fullscreenState.PreFullscreenPosition, null); fullscreenState.IsFullscreen = false; //Save and reload temporary layout, to fix resizable main window var fsSaveToLayout = new Dictionary <FS.WindowFullscreenState, bool>(); var allWinStates = FS.fullscreenState.window.ToArray(); foreach (var state in allWinStates) { if (state.EditorWin != null) { fsSaveToLayout.Add(state, state.EditorWin.GetSaveToLayout()); state.EditorWin.SetSaveToLayout(true); } } FS.SaveFullscreenState(); WindowLayoutUtility.SaveProjectLayout("PostFullscreenLayout.dwlt"); foreach (var state in fsSaveToLayout) { if (state.Key.EditorWin != null) { state.Key.EditorWin.SetSaveToLayout(state.Value); } } WindowLayoutUtility.LoadProjectLayout("PostFullscreenLayout.dwlt"); Focus(); position = fullscreenState.PreFullscreenPosition; //Reset position position = fullscreenState.PreFullscreenPosition; if (fullscreenState.PreFullscreenMaximized != maximized) { ToggleMaximize(); } FS.LoadFullscreenState(); } FS.SaveFullscreenState(); FS.TriggerFullscreenEvent(mainWindow, FS.mainWindowType, fullscreenAtPosition, fullscreen); if (EditorWindow.focusedWindow == null) { if (originallyFocusedEditorWin != null) { originallyFocusedEditorWin.Focus(); } else if (originallyFocusedEditorWinType != null) { EditorWindow.FocusWindowIfItsOpen(originallyFocusedEditorWinType); } } }
public static void SetFullscreen(bool fullscreen, bool showTopToolbar, Vector2 fullscreenAtPosition, bool disableUpdatePrePos) { var fullscreenState = GetWindowFullscreenState(); var fullscreenOnDisplay = EditorDisplay.ClosestToPoint(fullscreenAtPosition); var screenBounds = fullscreenOnDisplay.Bounds; #if UNITY_EDITOR_OSX if (fullscreenOnDisplay.Locked) { FS.RunAfterDisplayNotLocked(fullscreenAtPosition, () => SetFullscreen(fullscreen, showTopToolbar, fullscreenAtPosition, disableUpdatePrePos)); return; } #endif var originallyFocusedEditorWin = EditorWindow.focusedWindow; var originallyFocusedEditorWinType = originallyFocusedEditorWin == null ? null : originallyFocusedEditorWin.GetType(); object mainWindow = null; #if UNITY_EDITOR_OSX bool wasFullscreen = SystemDisplay.MainWindowIsFullscreen(); //If toggling the top toolbar, don't update pre positions. bool updatePrePos = fullscreen && !wasFullscreen && !disableUpdatePrePos; windowController = IntPtr.Zero; if (fullscreen) { fullscreenState.ScreenBounds = screenBounds; fullscreenState.FullscreenAtPosition = fullscreenAtPosition; } if (updatePrePos) { fullscreenState.PreFullscreenPosition = position; fullscreenState.PreFullscreenMinSize = minSize; fullscreenState.PreFullscreenMaxSize = maxSize; } var prePos = fullscreenState.PreFullscreenPosition; if (prePos.width < 100 || prePos.height < 100 || prePos.width < fullscreenState.PreFullscreenMinSize.x || prePos.height < fullscreenState.PreFullscreenMinSize.y) { prePos = new Rect(prePos.x, prePos.y, Mathf.Max(fullscreenState.PreFullscreenMinSize.x, 300), Mathf.Max(fullscreenState.PreFullscreenMinSize.y, 300)); //Make sure size is valid } if (fullscreen && !screenBounds.Contains(position.center)) { if (wasFullscreen) { //Exit fullscreen because we are fullscreen on another screen fullscreen = false; } else { //Move to the correct screen SystemDisplay.SetMainWindowPosition((int)screenBounds.xMin, (int)screenBounds.yMin, (int)screenBounds.width, (int)screenBounds.height); } } if (fullscreen != wasFullscreen) { windowController = SystemDisplay.ToggleFullscreenMainWindow((int)prePos.xMin, (int)prePos.yMin, (int)prePos.width, (int)prePos.height); if (!fullscreen) { if (fullscreenState.ScreenBounds.Contains(prePos)) { position = prePos; //Setting the position here first (even though still haven't finished exiting fullscreen) updates the docked window sizes so the shrinking animation is smoother. } else { var intermediatePos = fullscreenState.PreFullscreenPosition.CenterRectInBounds(fullscreenState.ScreenBounds); position = intermediatePos; //Can't move screen yet because still fullscreen, so use an intermediate pos. } //Restore position once the fullscreen has finished exiting if (windowController != IntPtr.Zero) { fullscreenOnDisplay.Locked = true; EditorApplication.update += CheckForFinishExitingFullscreen; numChecksForFinishExiting = 0; } } else { fullscreenOnDisplay.Locked = true; FS.RunAfter(() => { return(false); }, () => { fullscreenOnDisplay.Locked = false; fullscreenState.currentlyRestoringFromState = false; FS.SaveFullscreenState(); }, 50, true); } } fullscreenState.IsFullscreen = fullscreen; FS.SaveFullscreenState(); #else bool wasFullscreen = fullscreenState.IsFullscreen; fullscreenState.ShowTopToolbar = showTopToolbar; fullscreenState.originalContainerWindow = (ScriptableObject)FindOriginalContainerWindow(); fullscreenState.containerWindow = (ScriptableObject)FindContainerWindow(); mainWindow = FindMainWindow(); bool inOriginalContainer = fullscreenState.containerWindow == fullscreenState.originalContainerWindow; #if UNITY_2018_2_OR_NEWER var pixelsPerPoint = GetPixelsPerPointAtPosition(fullscreenAtPosition); screenBounds.width /= pixelsPerPoint; screenBounds.height /= pixelsPerPoint; #endif if (fullscreen) { fullscreenState.ScreenBounds = screenBounds; fullscreenState.FullscreenAtPosition = fullscreenAtPosition; if (!wasFullscreen) { var wasMaximized = maximized; if (wasMaximized) { ToggleMaximize(); } fullscreenState.PreFullscreenPosition = position; fullscreenState.PreFullscreenMinSize = minSize; fullscreenState.PreFullscreenMaxSize = maxSize; fullscreenState.PreFullscreenMaximized = wasMaximized; if (inOriginalContainer) { SystemDisplay.SaveMainWindowStyleInState(fullscreenState); } } } if (fullscreen && !showTopToolbar) { object fsContainerWindow; if (inOriginalContainer) { fsContainerWindow = ScriptableObject.CreateInstance(FS.ContainerWindowType); } else { fsContainerWindow = fullscreenState.containerWindow; } //Put the main view into the fullscreen container window containerMainView.SetValue(fsContainerWindow, mainWindow, null); inOriginalContainer = false; containerPosition.SetValue(fsContainerWindow, screenBounds, null); if (containerShow.GetParameters().Length == 3) { containerShow.Invoke(fsContainerWindow, new object[] { 3, false, true }); } else if (containerShow.GetParameters().Length == 4) { containerShow.Invoke(fsContainerWindow, new object[] { 3, false, true, true }); //4 parameters since Unity 2018 } SetMinMaxSizes(screenBounds.size, screenBounds.size); containerPosition.SetValue(fsContainerWindow, screenBounds, null); MethodInfo displayAllViews = FS.ContainerWindowType.GetMethod("DisplayAllViews", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new System.Type[] { }, null); displayAllViews.Invoke(fsContainerWindow, null); fullscreenState.containerWindow = (ScriptableObject)fsContainerWindow; fullscreenState.IsFullscreen = true; } else { if (fullscreenState.EditorWin != null) { fullscreenState.EditorWin.Close(); } if (!inOriginalContainer) { //Reset main view back to original container view containerMainViewField.SetValue(fullscreenState.originalContainerWindow, null); containerMainView.SetValue(fullscreenState.originalContainerWindow, mainWindow, null); try { containerMainViewField.SetValue(fullscreenState.containerWindow, null); containerClose.Invoke(fullscreenState.containerWindow, null); } catch (System.Exception e) { if (EWFDebugging.Enabled) { Debug.LogException(e); EWFDebugging.LogError(e.Message); } } fullscreenState.containerWindow = fullscreenState.originalContainerWindow; fullscreenState.IsFullscreen = false; inOriginalContainer = true; } if (fullscreen) { //Set fullscreen with toolbar var newPos = screenBounds; newPos.yMin += topToolbarHeight; position = newPos; SetMinMaxSizes(newPos.size, newPos.size); position = newPos; if (position.x != newPos.x) { //Position didn't set correctly, so must be maximized fullscreenState.PreFullscreenMaximized = true; ToggleMaximize(); position = newPos; } fullscreenState.IsFullscreen = true; } } if (!fullscreen && inOriginalContainer && wasFullscreen) { //Reset position var prePos = fullscreenState.PreFullscreenPosition; position = prePos; fullscreenState.IsFullscreen = false; position = fullscreenState.PreFullscreenPosition; SetMinMaxSizes(fullscreenState.PreFullscreenMinSize, fullscreenState.PreFullscreenMaxSize); position = fullscreenState.PreFullscreenPosition; PropertyInfo pos = FS.ViewType.GetProperty("position", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); pos.SetValue(FindMainWindow(), fullscreenState.PreFullscreenPosition, null); fullscreenState.IsFullscreen = false; SystemDisplay.LoadMainWindowStyleInState(fullscreenState, true); TriggerOnResizedAll(); Focus(); position = fullscreenState.PreFullscreenPosition; //Reset position position = fullscreenState.PreFullscreenPosition; if (fullscreenState.PreFullscreenMaximized != maximized) { ToggleMaximize(); } } fullscreenState.currentlyRestoringFromState = false; FS.SaveFullscreenState(); #endif //All platforms FS.TriggerFullscreenEvent(mainWindow, FS.MainWindowType, fullscreenAtPosition, fullscreen); if (EditorWindow.focusedWindow == null) { if (originallyFocusedEditorWin != null) { originallyFocusedEditorWin.Focus(); } else if (originallyFocusedEditorWinType != null) { EditorWindow.FocusWindowIfItsOpen(originallyFocusedEditorWinType); } } }
/// <summary> Make the EditorWindow fullscreen, or return to how it was. Opens the fullscreen window on the screen at a specified position. </summary> public static void SetFullscreen(this EditorWindow editorWindow, bool setFullscreen, Vector2 atPosition) { Type windowType = editorWindow.GetWindowType(); var fullscreenState = EditorFullscreenState.FindWindowState(editorWindow); CursorLockMode currentCursorLockMode = Cursor.lockState; if (setFullscreen == false) { if (fullscreenState.EditorWin != null) { if (fullscreenState.CloseOnExitFullscreen) { //Close the window editorWindow.Close(); } else { //Restore the window editorWindow.SetBorderlessPosition(fullscreenState.PreFullscreenPosition); fullscreenState.EditorWin.minSize = fullscreenState.PreFullscreenMinSize; fullscreenState.EditorWin.maxSize = fullscreenState.PreFullscreenMaxSize; fullscreenState.EditorWin.position = fullscreenState.PreFullscreenPosition; if (editorWindow.maximized != fullscreenState.PreFullscreenMaximized) { editorWindow.maximized = fullscreenState.PreFullscreenMaximized; } } } if (editorWindow.GetWindowType() == FS.gameViewType) { Unsupported.SetAllowCursorLock(false); //Unlock the cursor when exiting game fullscreen } if (fullscreenState.UnfocusedGameViewOnEnteringFullscreen == true) { //Refocus the first docked game view var gameView = GetDockedGameView(editorWindow, false); if (gameView != null) { gameView.Focus(); } } } else { if (!fullscreenState.IsFullscreen) { fullscreenState.PreFullscreenPosition = editorWindow.position; fullscreenState.PreFullscreenPosition.y -= FS.windowTopPadding; fullscreenState.PreFullscreenMinSize = editorWindow.minSize; fullscreenState.PreFullscreenMaxSize = editorWindow.maxSize; fullscreenState.PreFullscreenMaximized = editorWindow.maximized; } editorWindow.SetWindowTitle("FULLSCREEN_WINDOW_" + editorWindow.GetInstanceID(), true); if (!editorWindow.IsFullscreen()) { editorWindow.maximized = false; if (fullscreenState.ShowTopTabs) { editorWindow.Show(); } else { editorWindow.ShowWithMode(ShowMode.PopupMenu); editorWindow.SetSaveToLayout(true); } fullscreenState.FullscreenAtPosition = atPosition; editorWindow.SetBorderlessPosition(new Rect(atPosition.x, atPosition.y, 100, 100)); } else if (fullscreenState.IsFullscreen) { //If already fullscreen, resize slightly to make sure the taskbar gets covered (E.g. when loading fullscreen state on startup) var tempBounds = editorWindow.position; tempBounds.yMax -= 1; editorWindow.SetBorderlessPosition(tempBounds); } fullscreenState.ScreenBounds = editorWindow.MakeFullscreenWindow(!fullscreenState.ShowTopToolbar, atPosition); editorWindow.ExitFullscreenForOtherWindowsOnScreen(atPosition); fullscreenState.WindowName = editorWindow.name; fullscreenState.EditorWin = editorWindow; fullscreenState.IsFullscreen = true; //Usability improvement for Unity bug where only one visible game window accepts input. (Unfocus docked game views if opening fullscreen view on the same screen.) try { var gameView = GetDockedGameView(editorWindow, true); if (gameView != null) { bool onSameDisplay = EditorDisplay.ClosestToPoint(gameView.position.center).Bounds.Contains(atPosition); var hostView = gameView.GetHostView(); if (onSameDisplay && hostView != null && FS.dockAreaType != null) { FieldInfo m_Panes = FS.dockAreaType.GetField("m_Panes", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var dockAreaPanes = (List <EditorWindow>)m_Panes.GetValue(hostView); foreach (var sibling in dockAreaPanes) { if (sibling.GetType() != FS.gameViewType) { sibling.Focus(); //Focus the first non-game sibling of the docked game view fullscreenState.UnfocusedGameViewOnEnteringFullscreen = true; break; } } } } } catch (System.Exception e) { if (FS.LogNonFatalErrors) { Debug.LogException(e); } } editorWindow.Focus(); Cursor.lockState = currentCursorLockMode; //Ensure that the cursor lock mode remains the same when entering fullscreen } FS.SaveFullscreenState(); FS.TriggerFullscreenEvent(editorWindow, windowType, atPosition, setFullscreen); }