diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 8c1d7d74f..11f66c8af 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -252,6 +252,7 @@ namespace Flow.Launcher.Infrastructure.Image image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.UriSource = new Uri(path); + image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile; image.EndInit(); return image; } diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 2ab97e8ae..27afff5b6 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -203,7 +203,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings } public bool LeaveCmdOpen { get; set; } public bool HideWhenDeactive { get; set; } = true; - public bool RememberLastLaunchLocation { get; set; } + public SearchWindowPositions SearchWindowPosition { get; set; } = SearchWindowPositions.MouseScreenCenter; public bool IgnoreHotkeysOnFullscreen { get; set; } public HttpProxy Proxy { get; set; } = new HttpProxy(); @@ -229,4 +229,12 @@ namespace Flow.Launcher.Infrastructure.UserSettings Light, Dark } + public enum SearchWindowPositions + { + RememberLastLaunchLocation, + MouseScreenCenter, + MouseScreenCenterTop, + MouseScreenLeftTop, + MouseScreenRightTop + } } diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index f429586ce..c4341288f 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -50,7 +50,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 66cc911ee..813a44527 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -83,6 +83,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -114,4 +115,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Flow.Launcher/Images/app_missing_img.png b/Flow.Launcher/Images/app_missing_img.png index b86c29ac9..27e366bbc 100644 Binary files a/Flow.Launcher/Images/app_missing_img.png and b/Flow.Launcher/Images/app_missing_img.png differ diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index a8cdc0d93..1cff70a97 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -23,6 +23,8 @@ Text Game Mode Suspend the use of Hotkeys. + Position Reset + Reset search window position Flow Launcher Settings @@ -33,7 +35,13 @@ Error setting launch on startup Hide Flow Launcher when focus is lost Do not show new version notifications + Search Window Position Remember last launch location + Remember Last Location + Mouse Focused Screen - Center + Mouse Focused Screen - Center Top + Mouse Focused Screen - Left Top + Mouse Focused Screen - Right Top Language Last Query Style Show/Hide previous results when Flow Launcher is reactivated. @@ -41,6 +49,7 @@ Select last Query Empty last Query Maximum results shown + You can also quickly adjust this by using CTRL+Plus and CTRL+Minus. Ignore hotkeys in fullscreen mode Disable Flow Launcher activation when a full screen application is active (Recommended for games). Default File Manager @@ -133,6 +142,7 @@ Query window shadow effect Shadow effect has a substantial usage of GPU. Not recommended if your computer performance is limited. Window Width Size + You can also quickly adjust this by using Ctrl+[ and Ctrl+]. Use Segoe Fluent Icons Use Segoe Fluent Icons for query results where supported diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index 3b57e7a70..bb5c28b0a 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -81,6 +81,26 @@ + + + + + + @@ -182,21 +183,40 @@ namespace Flow.Launcher case nameof(Settings.Hotkey): UpdateNotifyIconText(); break; + case nameof(Settings.WindowLeft): + Left = _settings.WindowLeft; + break; + case nameof(Settings.WindowTop): + Top = _settings.WindowTop; + break; } }; } private void InitializePosition() { - if (_settings.RememberLastLaunchLocation) + switch (_settings.SearchWindowPosition) { - Top = _settings.WindowTop; - Left = _settings.WindowLeft; - } - else - { - Left = WindowLeft(); - Top = WindowTop(); + case SearchWindowPositions.RememberLastLaunchLocation: + Top = _settings.WindowTop; + Left = _settings.WindowLeft; + break; + case SearchWindowPositions.MouseScreenCenter: + Left = HorizonCenter(); + Top = VerticalCenter(); + break; + case SearchWindowPositions.MouseScreenCenterTop: + Left = HorizonCenter(); + Top = 10; + break; + case SearchWindowPositions.MouseScreenLeftTop: + Left = 10; + Top = 10; + break; + case SearchWindowPositions.MouseScreenRightTop: + Left = HorizonRight(); + Top = 10; + break; } } @@ -205,8 +225,9 @@ namespace Flow.Launcher var menu = contextMenu; ((MenuItem)menu.Items[1]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayOpen") + " (" + _settings.Hotkey + ")"; ((MenuItem)menu.Items[2]).Header = InternationalizationManager.Instance.GetTranslation("GameMode"); - ((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); - ((MenuItem)menu.Items[4]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); + ((MenuItem)menu.Items[3]).Header = InternationalizationManager.Instance.GetTranslation("PositionReset"); + ((MenuItem)menu.Items[4]).Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings"); + ((MenuItem)menu.Items[5]).Header = InternationalizationManager.Instance.GetTranslation("iconTrayExit"); } private void InitializeNotifyIcon() @@ -232,6 +253,10 @@ namespace Flow.Launcher { Header = InternationalizationManager.Instance.GetTranslation("GameMode") }; + var positionreset = new MenuItem + { + Header = InternationalizationManager.Instance.GetTranslation("PositionReset") + }; var settings = new MenuItem { Header = InternationalizationManager.Instance.GetTranslation("iconTraySettings") @@ -243,12 +268,15 @@ namespace Flow.Launcher open.Click += (o, e) => _viewModel.ToggleFlowLauncher(); gamemode.Click += (o, e) => ToggleGameMode(); + positionreset.Click += (o, e) => PositionReset(); settings.Click += (o, e) => App.API.OpenSettingDialog(); exit.Click += (o, e) => Close(); contextMenu.Items.Add(header); contextMenu.Items.Add(open); gamemode.ToolTip = InternationalizationManager.Instance.GetTranslation("GameModeToolTip"); + positionreset.ToolTip = InternationalizationManager.Instance.GetTranslation("PositionResetToolTip"); contextMenu.Items.Add(gamemode); + contextMenu.Items.Add(positionreset); contextMenu.Items.Add(settings); contextMenu.Items.Add(exit); @@ -295,10 +323,17 @@ namespace Flow.Launcher _viewModel.GameModeStatus = true; } } + private async void PositionReset() + { + _viewModel.Show(); + await Task.Delay(300); // If don't give a time, Positioning will be weird. + Left = HorizonCenter(); + Top = VerticalCenter(); + } private void InitProgressbarAnimation() { var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 150, - new Duration(new TimeSpan(0, 0, 0, 0, 1600))); + new Duration(new TimeSpan(0, 0, 0, 0, 1600))); var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth + 50, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); @@ -402,6 +437,8 @@ namespace Flow.Launcher private async void OnDeactivated(object sender, EventArgs e) { + _settings.WindowLeft = Left; + _settings.WindowTop = Top; //This condition stops extra hide call when animator is on, // which causes the toggling to occasional hide instead of show. if (_viewModel.MainWindowVisibilityStatus) @@ -423,24 +460,14 @@ namespace Flow.Launcher { if (_animating) return; - - if (_settings.RememberLastLaunchLocation) - { - Left = _settings.WindowLeft; - Top = _settings.WindowTop; - } - else - { - Left = WindowLeft(); - Top = WindowTop(); - } + InitializePosition(); } private void OnLocationChanged(object sender, EventArgs e) { if (_animating) return; - if (_settings.RememberLastLaunchLocation) + if (_settings.SearchWindowPosition == SearchWindowPositions.RememberLastLaunchLocation) { _settings.WindowLeft = Left; _settings.WindowTop = Top; @@ -459,8 +486,8 @@ namespace Flow.Launcher _viewModel.Show(); } } - - public double WindowLeft() + + public double HorizonCenter() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); @@ -469,7 +496,7 @@ namespace Flow.Launcher return left; } - public double WindowTop() + public double VerticalCenter() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y); @@ -478,12 +505,22 @@ namespace Flow.Launcher return top; } + public double HorizonRight() + { + var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); + var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); + var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0); + var left = (dip2.X - ActualWidth) - 10; + return left; + } + /// /// Register up and down key /// todo: any way to put this in xaml ? /// private void OnKeyDown(object sender, KeyEventArgs e) { + var specialKeyState = GlobalHotkey.CheckModifiers(); switch (e.Key) { case Key.Down: @@ -518,8 +555,13 @@ namespace Flow.Launcher e.Handled = true; } break; + case Key.F12: + if (specialKeyState.CtrlPressed) + { + ToggleGameMode(); + } + break; case Key.Back: - var specialKeyState = GlobalHotkey.CheckModifiers(); if (specialKeyState.CtrlPressed) { if (_viewModel.SelectedIsFromQueryResults() diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml index 9cad84069..b1a3bfbdd 100644 --- a/Flow.Launcher/SettingWindow.xaml +++ b/Flow.Launcher/SettingWindow.xaml @@ -684,12 +684,25 @@ - + - + - + + +  + @@ -817,11 +830,13 @@ BorderThickness="0" Style="{DynamicResource SettingGroupBox}"> - + + + + + @@ -352,6 +356,55 @@ namespace Flow.Launcher.ViewModel } } + + [RelayCommand] + private void IncreaseWidth() + { + if (MainWindowWidth + 100 > 1920 || _settings.WindowSize == 1920) + { + _settings.WindowSize = 1920; + } + else + { + _settings.WindowSize += 100; + _settings.WindowLeft -= 50; + } + OnPropertyChanged(); + } + + [RelayCommand] + private void DecreaseWidth() + { + if (MainWindowWidth - 100 < 400 || _settings.WindowSize == 400) + { + _settings.WindowSize = 400; + } + else + { + _settings.WindowLeft += 50; + _settings.WindowSize -= 100; + } + OnPropertyChanged(); + } + + [RelayCommand] + private void IncreaseMaxResult() + { + if (_settings.MaxResultsToShow == 17) + return; + + _settings.MaxResultsToShow += 1; + } + + [RelayCommand] + private void DecreaseMaxResult() + { + if (_settings.MaxResultsToShow == 2) + return; + + _settings.MaxResultsToShow -= 1; + } + /// /// we need move cursor to end when we manually changed query /// but we don't want to move cursor to end when query is updated from TextBox @@ -427,7 +480,11 @@ namespace Flow.Launcher.ViewModel public Visibility SearchIconVisibility { get; set; } - public double MainWindowWidth => Settings.WindowSize; + public double MainWindowWidth + { + get => _settings.WindowSize; + set => _settings.WindowSize = value; + } public string PluginIconPath { get; set; } = null; diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index da7258f0d..2a7f7b010 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -41,6 +41,9 @@ namespace Flow.Launcher.ViewModel case nameof(Settings.ActivateTimes): OnPropertyChanged(nameof(ActivatedTimes)); break; + case nameof(Settings.WindowSize): + OnPropertyChanged(nameof(WindowWidthSize)); + break; } }; } @@ -382,6 +385,31 @@ namespace Flow.Launcher.ViewModel } } + + + public class SearchWindowPosition + { + public string Display { get; set; } + public SearchWindowPositions Value { get; set; } + } + + public List SearchWindowPositions + { + get + { + List modes = new List(); + var enums = (SearchWindowPositions[])Enum.GetValues(typeof(SearchWindowPositions)); + foreach (var e in enums) + { + var key = $"SearchWindowPosition{e}"; + var display = _translater.GetTranslation(key); + var m = new SearchWindowPosition { Display = display, Value = e, }; + modes.Add(m); + } + return modes; + } + } + public List TimeFormatList { get; set; } = new List() { "hh:mm", diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj index 0fe809926..e65e7d497 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj @@ -62,7 +62,7 @@ - + \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Images/ControlPanel_Small.png b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Images/ControlPanel_Small.png index 8a8a41aeb..0897fd788 100644 Binary files a/Plugins/Flow.Launcher.Plugin.WindowsSettings/Images/ControlPanel_Small.png and b/Plugins/Flow.Launcher.Plugin.WindowsSettings/Images/ControlPanel_Small.png differ diff --git a/global.json b/global.json index 5e94f4b05..6ff5b35d3 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.100", - "rollForward": "latestFeature" + "version": "6.0.*", + "rollForward": "latestPatch" } } \ No newline at end of file