diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
index bfd7e4b87..d7b29aa46 100644
--- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
+++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs
@@ -195,6 +195,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings
public double WindowLeft { get; set; }
public double WindowTop { get; set; }
+ public double CustomWindowLeft { get; set; } = 0;
+ public double CustomWindowTop { get; set; } = 0;
public int MaxResultsToShow { get; set; } = 5;
public int ActivateTimes { get; set; }
@@ -227,7 +229,9 @@ namespace Flow.Launcher.Infrastructure.UserSettings
}
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;
- public SearchWindowPositions SearchWindowPosition { get; set; } = SearchWindowPositions.MouseScreenCenter;
+
+ public SearchWindowScreens SearchWindowScreen { get; set; } = SearchWindowScreens.RememberLastLaunchLocation;
+ public SearchWindowAligns SearchWindowAlign { get; set; } = SearchWindowAligns.Center;
public bool IgnoreHotkeysOnFullscreen { get; set; }
public HttpProxy Proxy { get; set; } = new HttpProxy();
@@ -253,12 +257,19 @@ namespace Flow.Launcher.Infrastructure.UserSettings
Light,
Dark
}
- public enum SearchWindowPositions
+ public enum SearchWindowScreens
{
RememberLastLaunchLocation,
- MouseScreenCenter,
- MouseScreenCenterTop,
- MouseScreenLeftTop,
- MouseScreenRightTop
+ MouseScreen,
+ PrimaryScreen,
+ SecondaryScreen,
+ CustomPosition
+ }
+ public enum SearchWindowAligns
+ {
+ Center,
+ CenterTop,
+ LeftTop,
+ RightTop
}
}
diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml
index 9e86d9305..a39adac54 100644
--- a/Flow.Launcher/Languages/en.xaml
+++ b/Flow.Launcher/Languages/en.xaml
@@ -38,11 +38,15 @@
Hide Flow Launcher when focus is lost
Do not show new version notifications
Search Window Position
- Remember Last Position
- Mouse Focused Screen - Center
- Mouse Focused Screen - Center Top
- Mouse Focused Screen - Left Top
- Mouse Focused Screen - Right Top
+ Remember Last Position
+ Mouse Focused Monitor
+ Primary Monitor
+ Secondary Monitor
+ Custom Position
+ Center
+ Center Top
+ Left Top
+ Right Top
Language
Last Query Style
Show/Hide previous results when Flow Launcher is reactivated.
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 550648b24..a465345be 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -24,6 +24,7 @@ using System.Windows.Threading;
using System.Windows.Data;
using ModernWpf.Controls;
using Key = System.Windows.Input.Key;
+using System.Threading;
namespace Flow.Launcher
{
@@ -201,29 +202,39 @@ namespace Flow.Launcher
private void InitializePosition()
{
- switch (_settings.SearchWindowPosition)
+ if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
{
- 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;
+ Top = _settings.WindowTop;
+ Left = _settings.WindowLeft;
}
+ else if (_settings.SearchWindowScreen == SearchWindowScreens.CustomPosition)
+ {
+ Top = _settings.CustomWindowTop;
+ Left = _settings.CustomWindowLeft;
+ }
+ else
+ {
+ switch (_settings.SearchWindowAlign)
+ {
+ case SearchWindowAligns.Center:
+ Left = HorizonCenter();
+ Top = VerticalCenter();
+ break;
+ case SearchWindowAligns.CenterTop:
+ Left = HorizonCenter();
+ Top = 10;
+ break;
+ case SearchWindowAligns.LeftTop:
+ Left = HorizonLeft();
+ Top = 10;
+ break;
+ case SearchWindowAligns.RightTop:
+ Left = HorizonRight();
+ Top = 10;
+ break;
+ }
+ }
+
}
private void UpdateNotifyIconText()
@@ -503,7 +514,7 @@ namespace Flow.Launcher
{
if (_animating)
return;
- if (_settings.SearchWindowPosition == SearchWindowPositions.RememberLastLaunchLocation)
+ if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
{
_settings.WindowLeft = Left;
_settings.WindowTop = Top;
@@ -523,9 +534,32 @@ namespace Flow.Launcher
}
}
+ public Screen SelectedScreen()
+ {
+ if (_settings.SearchWindowScreen == SearchWindowScreens.MouseScreen)
+ {
+ var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
+ return screen;
+ }
+ else if (_settings.SearchWindowScreen == SearchWindowScreens.PrimaryScreen)
+ {
+ var screen = Screen.PrimaryScreen;
+ return screen;
+ }
+ else if (_settings.SearchWindowScreen == SearchWindowScreens.SecondaryScreen)
+ {
+ var screen = Screen.AllScreens[1];
+ return screen;
+ }
+ else
+ {
+ var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
+ return screen;
+ }
+ }
public double HorizonCenter()
{
- var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
+ var screen = SelectedScreen();
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
var left = (dip2.X - ActualWidth) / 2 + dip1.X;
@@ -534,7 +568,7 @@ namespace Flow.Launcher
public double VerticalCenter()
{
- var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
+ var screen = SelectedScreen();
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height);
var top = (dip2.Y - QueryTextBox.ActualHeight) / 4 + dip1.Y;
@@ -543,10 +577,19 @@ namespace Flow.Launcher
public double HorizonRight()
{
- var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position);
+ var screen = SelectedScreen();
var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
- var left = (dip2.X - ActualWidth) - 10;
+ var left = (dip1.X + dip2.X - ActualWidth) - 10;
+ return left;
+ }
+
+ public double HorizonLeft()
+ {
+ var screen = SelectedScreen();
+ var dip1 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0);
+ var dip2 = WindowsInteropHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0);
+ var left = dip1.X + 10;
return left;
}
diff --git a/Flow.Launcher/SettingWindow.xaml b/Flow.Launcher/SettingWindow.xaml
index 07f23ff6a..4a16e9610 100644
--- a/Flow.Launcher/SettingWindow.xaml
+++ b/Flow.Launcher/SettingWindow.xaml
@@ -698,17 +698,70 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
index 37587ce59..7e3060384 100644
--- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
+++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs
@@ -22,6 +22,7 @@ using Flow.Launcher.Plugin.SharedModels;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.Input;
using System.Globalization;
+using static Flow.Launcher.ViewModel.SettingWindowViewModel;
namespace Flow.Launcher.ViewModel
{
@@ -463,23 +464,50 @@ namespace Flow.Launcher.ViewModel
}
}
- public class SearchWindowPosition
+ public class SearchWindowScreen
{
public string Display { get; set; }
- public SearchWindowPositions Value { get; set; }
+ public SearchWindowScreens Value { get; set; }
}
- public List SearchWindowPositions
+ public List SearchWindowScreens
{
get
{
- List modes = new List();
- var enums = (SearchWindowPositions[])Enum.GetValues(typeof(SearchWindowPositions));
+ List modes = new List();
+ var enums = (SearchWindowScreens[])Enum.GetValues(typeof(SearchWindowScreens));
foreach (var e in enums)
{
- var key = $"SearchWindowPosition{e}";
+ var key = $"SearchWindowScreen{e}";
var display = _translater.GetTranslation(key);
- var m = new SearchWindowPosition
+ var m = new SearchWindowScreen
+ {
+ Display = display,
+ Value = e,
+ };
+ modes.Add(m);
+ }
+ return modes;
+ }
+ }
+
+ public class SearchWindowAlign
+ {
+ public string Display { get; set; }
+ public SearchWindowAligns Value { get; set; }
+ }
+
+ public List SearchWindowAligns
+ {
+ get
+ {
+ List modes = new List();
+ var enums = (SearchWindowAligns[])Enum.GetValues(typeof(SearchWindowAligns));
+ foreach (var e in enums)
+ {
+ var key = $"SearchWindowAlign{e}";
+ var display = _translater.GetTranslation(key);
+ var m = new SearchWindowAlign
{
Display = display, Value = e,
};