diff --git a/Core.UnitTests/Core.UnitTests.csproj b/Core.UnitTests/Core.UnitTests.csproj index 91afd397..88d1a1dc 100644 --- a/Core.UnitTests/Core.UnitTests.csproj +++ b/Core.UnitTests/Core.UnitTests.csproj @@ -54,6 +54,9 @@ Core + + + - - - - - - - - ? - - - - - - - - - - - - - - - - - - - - - - - - - - - - 00:00:00.150 - - 0.5 - - - Silver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + type to search + + + + + Press tab or ↑↓ to navigate in the list + + tab or ↑↓ to navigate + + + + Press enter to open the highlighted window + + enter to open a window + + + + Press ctrl+w to close the highlighted window + + ctrl+w to close a window + + + + Press esc to dismiss the Switcheroo overlay + + esc to dismiss switcheroo + + + + + + + + + + + + + + + ? + + + + + + + + + + + + + + + + + + + + + + + + + + + + 00:00:00.150 + + 0.5 + + + Silver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Switcheroo/MainWindow.xaml.cs b/Switcheroo/MainWindow.xaml.cs index afeab7ee..c540788e 100644 --- a/Switcheroo/MainWindow.xaml.cs +++ b/Switcheroo/MainWindow.xaml.cs @@ -56,6 +56,10 @@ public partial class MainWindow : Window public static readonly RoutedUICommand SwitchToWindowCommand = new RoutedUICommand(); public static readonly RoutedUICommand ScrollListDownCommand = new RoutedUICommand(); public static readonly RoutedUICommand ScrollListUpCommand = new RoutedUICommand(); + public static readonly RoutedUICommand ScrollListPageDownCommand = new RoutedUICommand(); + public static readonly RoutedUICommand ScrollListPageUpCommand = new RoutedUICommand(); + public static readonly RoutedUICommand ScrollListHomeCommand = new RoutedUICommand(); + public static readonly RoutedUICommand ScrollListEndCommand = new RoutedUICommand(); private OptionsWindow _optionsWindow; private AboutWindow _aboutWindow; private AltTabHook _altTabHook; @@ -102,13 +106,59 @@ private void SetUpKeyBindings() { Opacity = 0; } - else if (args.SystemKey == Key.S && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + else if (args.SystemKey == Key.Q && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) { _altTabAutoSwitch = false; tb.Text = ""; tb.IsEnabled = true; tb.Focus(); } + else if (args.SystemKey == Key.D && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + _unfilteredWindowList = _unfilteredWindowList.OrderBy(x => x.FormattedProcessTitle).ToList(); + lb.DataContext = null; + lb.DataContext = _unfilteredWindowList; + } + else if (args.SystemKey == Key.D1 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(0); + } + else if (args.SystemKey == Key.D2 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(1); + } + else if (args.SystemKey == Key.D3 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(2); + } + else if (args.SystemKey == Key.D4 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(3); + } + else if (args.SystemKey == Key.D5 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(4); + } + else if (args.SystemKey == Key.D6 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(5); + } + else if (args.SystemKey == Key.D7 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(6); + } + else if (args.SystemKey == Key.D8 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(7); + } + else if (args.SystemKey == Key.D9 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(8); + } + else if (args.SystemKey == Key.D0 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt)) + { + SwitchToIndex(9); + } }; KeyUp += (sender, args) => @@ -133,6 +183,17 @@ private void SetUpKeyBindings() }; } + private void SwitchToIndex(int i) + { + if (i < lb.Items.Count) + { + lb.SelectedIndex = i; + ScrollSelectedItemIntoView(); + Switch(); + HideWindow(); + } + } + private void SetUpHotKey() { _hotkey = new HotKey(); @@ -183,6 +244,28 @@ private void SetUpNotifyIcon() new MenuItem("Exit", (s, e) => Quit()) }) }; + + _notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(NotifyIconMouseClick); + } + + void NotifyIconMouseClick(object sender, System.Windows.Forms.MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + if (Visibility != Visibility.Visible) + { + _foregroundWindow = SystemWindow.ForegroundWindow; + Show(); + Activate(); + Keyboard.Focus(tb); + LoadData(InitialFocus.NextItem); + Opacity = 1; + } + else + { + HideWindow(); + } + } } private static void RunOnStartup(MenuItem menuItem) @@ -280,11 +363,15 @@ private void LoadData(InitialFocus focus) _filteredWindowList = new ObservableCollection(_unfilteredWindowList); _windowCloser = new WindowCloser(); - foreach (var window in _unfilteredWindowList) + for (var i = 0; i < _unfilteredWindowList.Count; i++) { - window.FormattedTitle = new XamlHighlighter().Highlight(new[] {new StringPart(window.AppWindow.Title)}); - window.FormattedProcessTitle = - new XamlHighlighter().Highlight(new[] {new StringPart(window.AppWindow.ProcessTitle)}); + if (i < 10) + { + _unfilteredWindowList[i].FormattedTitle = new XamlHighlighter().Highlight(new[] { new StringPart("" + (i + 1) + " ", true) }); + } + _unfilteredWindowList[i].FormattedTitle += new XamlHighlighter().Highlight(new[] { new StringPart(_unfilteredWindowList[i].AppWindow.Title) }); + _unfilteredWindowList[i].FormattedProcessTitle = + new XamlHighlighter().Highlight(new[] { new StringPart(_unfilteredWindowList[i].AppWindow.ProcessTitle) }); } lb.DataContext = null; @@ -498,7 +585,7 @@ private void AltTabPressed(object sender, AltTabHookEventArgs e) { _altTabAutoSwitch = true; tb.IsEnabled = false; - tb.Text = "Press Alt + S to search"; + tb.Text = "Press Alt + Q to search"; } Opacity = 1; @@ -594,9 +681,12 @@ private void OnEnterPressed(object sender, ExecutedRoutedEventArgs e) e.Handled = true; } - private void ListBoxItem_MouseDoubleClick(object sender, MouseButtonEventArgs e) + private void ListBoxItem_MouseLBClick(object sender, MouseButtonEventArgs e) { - Switch(); + if (!Keyboard.Modifiers.HasFlag(ModifierKeys.Control) && !Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)) + { + Switch(); + } e.Handled = true; } @@ -683,6 +773,53 @@ private void NextItem() } } + private void ScrollListPageUp(object sender, ExecutedRoutedEventArgs e) + { + double n = NumOfVisibleRows(); + + if (lb.SelectedIndex - n >= 0) + lb.SelectedIndex = Convert.ToInt32(lb.SelectedIndex - n); + else + lb.SelectedIndex = 0; + ScrollSelectedItemIntoView(); + + e.Handled = true; + } + + private void ScrollListPageDown(object sender, ExecutedRoutedEventArgs e) + { + double n = NumOfVisibleRows(); + + if (n + lb.SelectedIndex <= lb.Items.Count - 1) + lb.SelectedIndex = Convert.ToInt32(n); + else + lb.SelectedIndex = lb.Items.Count - 1; + ScrollSelectedItemIntoView(); + + e.Handled = true; + } + + private double NumOfVisibleRows() + { + return Math.Round(lb.ActualHeight / SearchGrid.ActualHeight); + } + + private void ScrollListHome(object sender, ExecutedRoutedEventArgs e) + { + lb.SelectedIndex = 0; + ScrollSelectedItemIntoView(); + + e.Handled = true; + } + + private void ScrollListEnd(object sender, ExecutedRoutedEventArgs e) + { + lb.SelectedIndex = lb.Items.Count-1; + ScrollSelectedItemIntoView(); + + e.Handled = true; + } + private void ScrollSelectedItemIntoView() { var selectedItem = lb.SelectedItem; @@ -723,5 +860,35 @@ private enum InitialFocus NextItem, PreviousItem } + + private void MenuItem_Click_toFront(object sender, RoutedEventArgs e) + { + Switch(); + } + + private async void MenuItem_Click_toClose(object sender, RoutedEventArgs e) + { + var windows = lb.SelectedItems.Cast().ToList(); + foreach (var win in windows) + { + bool isClosed = await _windowCloser.TryCloseAsync(win); + if (isClosed) + RemoveWindow(win); + } + + if (lb.Items.Count == 0) + HideWindow(); + } + + private void MenuItem_Duplicate(object sender, RoutedEventArgs e) + { + foreach (var item in lb.SelectedItems) + { + var torun = _unfilteredWindowList[lb.SelectedIndex].AppWindow.ExecutablePath.ToString(); + System.Diagnostics.Process.Start(torun); + } + + HideWindow(); + } } -} \ No newline at end of file +}