public void Toggle(bool open, int durationMs) { var stepDelayMs = Settings.Instance.ToggleAnimationFrameTimeMs == 0 ? 15 : Settings.Instance.ToggleAnimationFrameTimeMs; var stepCount = durationMs / stepDelayMs; if (stepCount <= 0) { stepCount = 1; } var screen = GetScreenWithCursor(); // Close if (!open) { Log.Information("Close"); User32.ShowWindow(_process.MainWindowHandle, NCmdShow.RESTORE); User32.SetForegroundWindow(_process.MainWindowHandle); for (int i = stepCount - 1; i >= 0; i--) { var bounds = GetBounds(screen, stepCount, i); User32.MoveWindow(_process.MainWindowHandle, bounds.X, bounds.Y, bounds.Width, bounds.Height, true); Task.Delay(TimeSpan.FromMilliseconds(stepDelayMs)).GetAwaiter().GetResult(); } // Minimize, so the last window gets focus User32.ShowWindow(_process.MainWindowHandle, NCmdShow.MINIMIZE); // Hide, so the terminal windows doesn't linger on the desktop User32.ShowWindow(_process.MainWindowHandle, NCmdShow.HIDE); } // Open else { Log.Information("Open"); FocusTracker.FocusGained(_process); User32.ShowWindow(_process.MainWindowHandle, NCmdShow.RESTORE); User32.SetForegroundWindow(_process.MainWindowHandle); for (int i = 1; i <= stepCount; i++) { var bounds = GetBounds(screen, stepCount, i); User32.MoveWindow(_process.MainWindowHandle, bounds.X, bounds.Y, bounds.Width, bounds.Height, true); Task.Delay(TimeSpan.FromMilliseconds(stepDelayMs)).GetAwaiter().GetResult(); } if (Settings.Instance.VerticalScreenCoverage >= 100 && Settings.Instance.HorizontalScreenCoverage >= 100) { User32.ShowWindow(_process.MainWindowHandle, NCmdShow.MAXIMIZE); } } }
public void Toggle(bool open, int durationMs) { var animationFn = _animTypeProvider.GetAnimationFunction(); var frameTimeMs = QSettings.Instance.ToggleAnimationFrameTimeMs; Log.Information(open ? "Open" : "Close"); // Notify focus tracker if (open) { FocusTracker.FocusGained(Process); } Process.BringToForeground(); var screen = _scrBoundsProvider.GetTargetScreenBounds(); // Used to accurately measure how far we are in the animation var stopwatch = new Stopwatch(); stopwatch.Start(); // Run the open/close animation while (stopwatch.ElapsedMilliseconds < durationMs) { var deltaMs = (float)stopwatch.ElapsedMilliseconds; // Asynchronously start the timer for this frame (unless frameTimeMs is 0) var frameTimer = (frameTimeMs == 0) ? new TaskAwaiter() : Task.Delay(TimeSpan.FromMilliseconds(frameTimeMs)).GetAwaiter() ; // Render the next frame of animation var linearProgress = open ? (deltaMs / durationMs) : (1.0 - (deltaMs / durationMs)) ; var intermediateBounds = _termBoundsProvider.GetTerminalBounds(screen, animationFn(linearProgress)); Process.MoveWindow(bounds: intermediateBounds); if (frameTimeMs > 0) { frameTimer.GetResult(); // Wait for the timer to end } } stopwatch.Stop(); // To ensure sure we end up in exactly the correct final position var finalBounds = _termBoundsProvider.GetTerminalBounds(screen, open ? 1.0 : 0.0); Process.MoveWindow(bounds: finalBounds); if (open) { // If vertical- and horizontal screen coverage is set to 100, maximize the window to make it actually fullscreen if (QSettings.Instance.MaximizeAfterToggle && QSettings.Instance.VerticalScreenCoverage >= 100 && QSettings.Instance.HorizontalScreenCoverage >= 100) { Process.SetWindowState(WindowShowStyle.Maximize); } } else { // Minimize first, so the last window gets focus Process.SetWindowState(WindowShowStyle.Minimize); // Then hide, so the terminal windows doesn't linger on the desktop if (QSettings.Instance.TaskbarIconVisibility == TaskBarIconVisibility.AlwaysHidden || QSettings.Instance.TaskbarIconVisibility == TaskBarIconVisibility.WhenTerminalVisible) { Process.SetWindowState(WindowShowStyle.Hide); } } }
public void Toggle(bool open, int durationMs) { var animationFn = AnimationFunction(Settings.Instance.ToggleAnimationType); var frameTimeMs = Settings.Instance.ToggleAnimationFrameTimeMs; Log.Information(open?"Open":"Close"); if (open) { FocusTracker.FocusGained(_process); } var screen = GetScreenWithCursor(); User32.ShowWindow(_process.MainWindowHandle, NCmdShow.RESTORE); User32.SetForegroundWindow(_process.MainWindowHandle); // Used to accurately measure how far we are in the animation Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); TimeSpan ts = stopWatch.Elapsed; var curMs = ts.TotalMilliseconds; // Run the open/close animation while (curMs < durationMs) { // Asynchronously start the timer for this frame (unless frameTimeMs is 0) TaskAwaiter frameTimer = (frameTimeMs == 0)? new TaskAwaiter(): Task.Delay(TimeSpan.FromMilliseconds(frameTimeMs)).GetAwaiter(); // Render the next frame of animation var animationX = open ? (curMs / durationMs) : (1.0 - (curMs / durationMs)); var bounds = GetBounds(screen, animationFn(animationX)); User32.MoveWindow(_process.MainWindowHandle, bounds.X, bounds.Y, bounds.Width, bounds.Height, true); User32.ThrowIfError(); ts = stopWatch.Elapsed; curMs = (double)ts.TotalMilliseconds; if (frameTimeMs != 0) { frameTimer.GetResult(); // Wait for the timer to end } } stopWatch.Stop(); // To ensure sure we end up in exactly the correct final position var finalBounds = GetBounds(screen, open?1.0:0.0); User32.MoveWindow(_process.MainWindowHandle, finalBounds.X, finalBounds.Y, finalBounds.Width, finalBounds.Height, true); User32.ThrowIfError(); if (open) { if (Settings.Instance.VerticalScreenCoverage >= 100 && Settings.Instance.HorizontalScreenCoverage >= 100) { User32.ShowWindow(_process.MainWindowHandle, NCmdShow.MAXIMIZE); } } else { // Minimize, so the last window gets focus User32.ShowWindow(_process.MainWindowHandle, NCmdShow.MINIMIZE); // Hide, so the terminal windows doesn't linger on the desktop User32.ShowWindow(_process.MainWindowHandle, NCmdShow.HIDE); } }