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); } } }
/// <summary> /// Initializes a new instance of the <see cref="ImageButton" /> class. /// </summary> public FocusVisualizer() { DefaultStyleKey = typeof(FocusVisualizer); new PropertyChangeEventSource <Thickness>(this, "BorderThickness").ValueChanged += this.OnBorderThicknessChanged; new PropertyChangeEventSource <Brush>(this, "BorderBrush").ValueChanged += this.OnBorderBrushChanged; this.Loaded += OnLoaded; this.Unloaded += OnUnloaded; this.FocusTracker = new FocusTracker(); this.FocusTracker.FocusChanged += OnFocusChanged; _focusedElement = FocusManager.GetFocusedElement() as UIElement; }
/// <summary> /// private Constructor /// </summary> private SelectAction() { this.FocusTracker = new FocusTracker(SetCandidateElement); this.MouseTracker = new MouseTracker(SetCandidateElement); this.TreeTracker = new TreeTracker(this.SetCandidateElement, this); }
public Toggler(string[] args) { _args = args ?? Array.Empty <string>(); // Always on top if (QSettings.Instance.AlwaysOnTop) { Process.SetAlwaysOnTop(); } // Taskbar icon visibility QSettings.Get(s => { Process.ToggleTaskbarIconVisibility(s.TaskbarIconVisibility != TaskBarIconVisibility.AlwaysHidden); }); // Used to keep track of the current toggle state. // The terminal is always assumed to be open on app start. var isOpen = true; // Register hotkeys QSettings.Get(s => { if (s.Hotkeys == null) { return; // Hotkeys not loaded yet } _registeredHotKeys.ForEach(hk => HotKeyManager.UnregisterHotKey(hk)); _registeredHotKeys.Clear(); s.Hotkeys.ForEach(hk => { Log.Information($"Registering hot key {hk.Modifiers} + {hk.Key}"); var reg = HotKeyManager.RegisterHotKey(hk.Key, hk.Modifiers); _registeredHotKeys.Add(reg); }); }); QSettings.Get(s => { _termBoundsProvider = s.ToggleMode switch { ToggleMode.Move => new MovingTerminalBoundsProvider(), _ => new ResizingTerminalBoundsProvider() }; }); // Hide on focus lost FocusTracker.OnFocusLost += (s, a) => { if (QSettings.Instance.HideOnFocusLost && isOpen) { isOpen = false; Toggle(false, 0); } }; // Toggle on hotkey(s) HotKeyManager.HotKeyPressed += (s, a) => { if (FocusTracker.HotKeySuppressedForCurrentFocusedProcess()) { return; } if (QSettings.Instance.DisableWhenActiveAppIsInFullscreen && ActiveWindowIsInFullscreen()) { return; } isOpen = !isOpen; Toggle(isOpen, QSettings.Instance.ToggleDurationMs); }; // Start hidden? if (QSettings.Instance.StartHidden) { Toggle(isOpen = false, 0); } // Otherwise, call toggle once to setup the correct size and position else { Toggle(isOpen = true, 0); } }
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); } }