Skip to content

Commit 9be5938

Browse files
authored
Merge pull request #3606 from onesounds/FixWindowSnap
Fix issues related to window maximization and Snap behavior
2 parents 86ca41a + 5aebf3f commit 9be5938

File tree

2 files changed

+88
-10
lines changed

2 files changed

+88
-10
lines changed

Flow.Launcher.Core/Resource/Theme.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,15 @@ private void SetBlurForWindow(string theme, BackdropTypes backdropType)
671671
windowBorderStyle.Setters.Remove(windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property.Name == "Background"));
672672
windowBorderStyle.Setters.Add(new Setter(Border.BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
673673
}
674-
674+
675+
// For themes with blur enabled, the window border is rendered by the system, so it's treated as a simple rectangle regardless of thickness.
676+
//(This is to avoid issues when the window is forcibly changed to a rectangular shape during snap scenarios.)
677+
var cornerRadiusSetter = windowBorderStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property == Border.CornerRadiusProperty);
678+
if (cornerRadiusSetter != null)
679+
cornerRadiusSetter.Value = new CornerRadius(0);
680+
else
681+
windowBorderStyle.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(0)));
682+
675683
// Apply the blur effect
676684
Win32Helper.DWMSetBackdropForWindow(mainWindow, backdropType);
677685
ColorizeWindow(theme, backdropType);

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,52 @@ private void OnPreviewMouseMove(object sender, MouseEventArgs e)
465465

466466
private void OnMouseDown(object sender, MouseButtonEventArgs e)
467467
{
468-
if (e.ChangedButton == MouseButton.Left) DragMove();
468+
if (e.ChangedButton == MouseButton.Left)
469+
{
470+
try
471+
{
472+
if (WindowState == WindowState.Maximized)
473+
{
474+
// Calculate ratio based on maximized window dimensions
475+
double maxWidth = this.ActualWidth;
476+
double maxHeight = this.ActualHeight;
477+
var mousePos = e.GetPosition(this);
478+
double xRatio = mousePos.X / maxWidth;
479+
double yRatio = mousePos.Y / maxHeight;
480+
481+
// Current monitor information
482+
var screen = Screen.FromHandle(new WindowInteropHelper(this).Handle);
483+
var workingArea = screen.WorkingArea;
484+
var screenLeftTop = Win32Helper.TransformPixelsToDIP(this, workingArea.X, workingArea.Y);
485+
486+
// Switch to Normal state
487+
WindowState = WindowState.Normal;
488+
489+
Dispatcher.BeginInvoke(new Action(() =>
490+
{
491+
double normalWidth = Width;
492+
double normalHeight = Height;
493+
494+
// Apply ratio based on the difference between maximized and normal window sizes
495+
Left = screenLeftTop.X + (maxWidth - normalWidth) * xRatio;
496+
Top = screenLeftTop.Y + (maxHeight - normalHeight) * yRatio;
497+
498+
if (Mouse.LeftButton == MouseButtonState.Pressed)
499+
{
500+
DragMove();
501+
}
502+
}), DispatcherPriority.ApplicationIdle);
503+
}
504+
else
505+
{
506+
DragMove();
507+
}
508+
}
509+
catch (InvalidOperationException)
510+
{
511+
// Ignored - can occur if drag operation is already in progress
512+
}
513+
}
469514
}
470515

471516
#endregion
@@ -490,18 +535,25 @@ private async void OnContextMenusForSettingsClick(object sender, RoutedEventArgs
490535

491536
#region Window WndProc
492537

493-
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
494-
{
495-
if (msg == Win32Helper.WM_ENTERSIZEMOVE)
496-
{
497-
_initialWidth = (int)Width;
538+
private const int WM_NCLBUTTONDBLCLK = 0x00A3;
539+
private const int WM_SYSCOMMAND = 0x0112;
540+
private const int SC_MAXIMIZE = 0xF030;
541+
private const int SC_RESTORE = 0xF120;
542+
private const int SC_MINIMIZE = 0xF020;
543+
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
544+
{
545+
if (msg == Win32Helper.WM_ENTERSIZEMOVE)
546+
{
547+
_initialWidth = (int)Width;
498548
_initialHeight = (int)Height;
499-
500549
handled = true;
501550
}
502551
else if (msg == Win32Helper.WM_EXITSIZEMOVE)
503552
{
504-
if (_initialHeight != (int)Height)
553+
//Prevent updating the number of results when the window height is below the height of a single result item.
554+
//This situation occurs not only when the user manually resizes the window, but also when the window is released from a side snap, as the OS automatically adjusts the window height.
555+
//(Without this check, releasing from a snap can cause the window height to hit the minimum, resulting in only 2 results being shown.)
556+
if (_initialHeight != (int)Height && Height> (_settings.WindowHeightSize + _settings.ItemHeightSize))
505557
{
506558
if (!_settings.KeepMaxResults)
507559
{
@@ -527,6 +579,11 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
527579

528580
SizeToContent = SizeToContent.Height;
529581
}
582+
else
583+
{
584+
// Update height when exiting maximized snap state.
585+
SizeToContent = SizeToContent.Height;
586+
}
530587

531588
if (_initialWidth != (int)Width)
532589
{
@@ -541,7 +598,20 @@ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref b
541598

542599
handled = true;
543600
}
544-
601+
if (msg == WM_NCLBUTTONDBLCLK)
602+
{
603+
SizeToContent = SizeToContent.Height;
604+
handled = true;
605+
}
606+
else if (msg == WM_SYSCOMMAND)
607+
{
608+
int command = wParam.ToInt32() & 0xFFF0;
609+
if (command == SC_MAXIMIZE || command == SC_MINIMIZE)
610+
{
611+
SizeToContent = SizeToContent.Height;
612+
handled = true;
613+
}
614+
}
545615
return IntPtr.Zero;
546616
}
547617

0 commit comments

Comments
 (0)