mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Fix Window Positioning with Multiple Montiors
Co-authored-by: onesounds <onesound@oooz.net>
This commit is contained in:
parent
d2e63ab437
commit
b96a69a5b6
3 changed files with 109 additions and 12 deletions
|
|
@ -293,6 +293,10 @@ namespace Flow.Launcher.Infrastructure.UserSettings
|
|||
|
||||
public double WindowLeft { get; set; }
|
||||
public double WindowTop { get; set; }
|
||||
public double PreviousScreenWidth { get; set; }
|
||||
public double PreviousScreenHeight { get; set; }
|
||||
public double PreviousDpiX { get; set; }
|
||||
public double PreviousDpiY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom left position on selected monitor
|
||||
|
|
|
|||
|
|
@ -711,8 +711,26 @@ namespace Flow.Launcher
|
|||
{
|
||||
if (_settings.SearchWindowScreen == SearchWindowScreens.RememberLastLaunchLocation)
|
||||
{
|
||||
Top = _settings.WindowTop;
|
||||
var previousScreenWidth = _settings.PreviousScreenWidth;
|
||||
var previousScreenHeight = _settings.PreviousScreenHeight;
|
||||
GetDpi(out var previousDpiX, out var previousDpiY);
|
||||
|
||||
_settings.PreviousScreenWidth = SystemParameters.VirtualScreenWidth;
|
||||
_settings.PreviousScreenHeight = SystemParameters.VirtualScreenHeight;
|
||||
GetDpi(out var currentDpiX, out var currentDpiY);
|
||||
|
||||
if (previousScreenWidth != 0 && previousScreenHeight != 0 &&
|
||||
previousDpiX != 0 && previousDpiY != 0 &&
|
||||
(previousScreenWidth != SystemParameters.VirtualScreenWidth ||
|
||||
previousScreenHeight != SystemParameters.VirtualScreenHeight ||
|
||||
previousDpiX != currentDpiX || previousDpiY != currentDpiY))
|
||||
{
|
||||
AdjustPositionForResolutionChange();
|
||||
return;
|
||||
}
|
||||
|
||||
Left = _settings.WindowLeft;
|
||||
Top = _settings.WindowTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -725,27 +743,73 @@ namespace Flow.Launcher
|
|||
break;
|
||||
case SearchWindowAligns.CenterTop:
|
||||
Left = HorizonCenter(screen);
|
||||
Top = 10;
|
||||
Top = VerticalTop(screen);
|
||||
break;
|
||||
case SearchWindowAligns.LeftTop:
|
||||
Left = HorizonLeft(screen);
|
||||
Top = 10;
|
||||
Top = VerticalTop(screen);
|
||||
break;
|
||||
case SearchWindowAligns.RightTop:
|
||||
Left = HorizonRight(screen);
|
||||
Top = 10;
|
||||
Top = VerticalTop(screen);
|
||||
break;
|
||||
case SearchWindowAligns.Custom:
|
||||
Left = Win32Helper.TransformPixelsToDIP(this,
|
||||
screen.WorkingArea.X + _settings.CustomWindowLeft, 0).X;
|
||||
Top = Win32Helper.TransformPixelsToDIP(this, 0,
|
||||
screen.WorkingArea.Y + _settings.CustomWindowTop).Y;
|
||||
var customLeft = Win32Helper.TransformPixelsToDIP(this,
|
||||
screen.WorkingArea.X + _settings.CustomWindowLeft, 0);
|
||||
var customTop = Win32Helper.TransformPixelsToDIP(this, 0,
|
||||
screen.WorkingArea.Y + _settings.CustomWindowTop);
|
||||
Left = customLeft.X;
|
||||
Top = customTop.Y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustPositionForResolutionChange()
|
||||
{
|
||||
var screenWidth = SystemParameters.VirtualScreenWidth;
|
||||
var screenHeight = SystemParameters.VirtualScreenHeight;
|
||||
GetDpi(out var currentDpiX, out var currentDpiY);
|
||||
|
||||
var previousLeft = _settings.WindowLeft;
|
||||
var previousTop = _settings.WindowTop;
|
||||
GetDpi(out var previousDpiX, out var previousDpiY);
|
||||
|
||||
var widthRatio = screenWidth / _settings.PreviousScreenWidth;
|
||||
var heightRatio = screenHeight / _settings.PreviousScreenHeight;
|
||||
var dpiXRatio = currentDpiX / previousDpiX;
|
||||
var dpiYRatio = currentDpiY / previousDpiY;
|
||||
|
||||
var newLeft = previousLeft * widthRatio * dpiXRatio;
|
||||
var newTop = previousTop * heightRatio * dpiYRatio;
|
||||
|
||||
var screenLeft = SystemParameters.VirtualScreenLeft;
|
||||
var screenTop = SystemParameters.VirtualScreenTop;
|
||||
|
||||
var maxX = screenLeft + screenWidth - ActualWidth;
|
||||
var maxY = screenTop + screenHeight - ActualHeight;
|
||||
|
||||
Left = Math.Max(screenLeft, Math.Min(newLeft, maxX));
|
||||
Top = Math.Max(screenTop, Math.Min(newTop, maxY));
|
||||
}
|
||||
|
||||
private void GetDpi(out double dpiX, out double dpiY)
|
||||
{
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
if (source != null && source.CompositionTarget != null)
|
||||
{
|
||||
var matrix = source.CompositionTarget.TransformToDevice;
|
||||
dpiX = 96 * matrix.M11;
|
||||
dpiY = 96 * matrix.M22;
|
||||
}
|
||||
else
|
||||
{
|
||||
dpiX = 96;
|
||||
dpiY = 96;
|
||||
}
|
||||
}
|
||||
|
||||
private Screen SelectedScreen()
|
||||
{
|
||||
Screen screen;
|
||||
|
|
@ -806,6 +870,13 @@ namespace Flow.Launcher
|
|||
return left;
|
||||
}
|
||||
|
||||
public double VerticalTop(Screen screen)
|
||||
{
|
||||
var dip1 = Win32Helper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y);
|
||||
var top = dip1.Y + 10;
|
||||
return top;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Window Animation
|
||||
|
|
|
|||
|
|
@ -137,18 +137,40 @@ public partial class SettingWindow
|
|||
|
||||
if (previousTop == null || previousLeft == null || !IsPositionValid(previousTop.Value, previousLeft.Value))
|
||||
{
|
||||
Top = WindowTop();
|
||||
Left = WindowLeft();
|
||||
SetWindowPosition(WindowTop(), WindowLeft());
|
||||
}
|
||||
else
|
||||
{
|
||||
Top = previousTop.Value;
|
||||
Left = previousLeft.Value;
|
||||
var left = _settings.SettingWindowLeft.Value;
|
||||
var top = _settings.SettingWindowTop.Value;
|
||||
AdjustWindowPosition(ref top, ref left);
|
||||
SetWindowPosition(top, left);
|
||||
}
|
||||
|
||||
WindowState = _settings.SettingWindowState;
|
||||
}
|
||||
|
||||
private void SetWindowPosition(double top, double left)
|
||||
{
|
||||
// Ensure window does not exceed screen boundaries
|
||||
top = Math.Max(top, SystemParameters.VirtualScreenTop);
|
||||
left = Math.Max(left, SystemParameters.VirtualScreenLeft);
|
||||
top = Math.Min(top, SystemParameters.VirtualScreenHeight - ActualHeight);
|
||||
left = Math.Min(left, SystemParameters.VirtualScreenWidth - ActualWidth);
|
||||
|
||||
Top = top;
|
||||
Left = left;
|
||||
}
|
||||
|
||||
private void AdjustWindowPosition(ref double top, ref double left)
|
||||
{
|
||||
// Adjust window position if it exceeds screen boundaries
|
||||
top = Math.Max(top, SystemParameters.VirtualScreenTop);
|
||||
left = Math.Max(left, SystemParameters.VirtualScreenLeft);
|
||||
top = Math.Min(top, SystemParameters.VirtualScreenHeight - ActualHeight);
|
||||
left = Math.Min(left, SystemParameters.VirtualScreenWidth - ActualWidth);
|
||||
}
|
||||
|
||||
private static bool IsPositionValid(double top, double left)
|
||||
{
|
||||
foreach (var screen in Screen.AllScreens)
|
||||
|
|
|
|||
Loading…
Reference in a new issue