Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Flow.Launcher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
Left="{Binding Settings.WindowLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Loaded="OnLoaded"
LocationChanged="OnLocationChanged"
Opacity="{Binding MainWindowOpacity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
PreviewKeyDown="OnKeyDown"
PreviewKeyUp="OnKeyUp"
PreviewMouseMove="OnPreviewMouseMove"
Expand Down
49 changes: 28 additions & 21 deletions Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
};

// QueryTextBox.Text change detection (modified to only work when character count is 1 or higher)
QueryTextBox.TextChanged += (sender, e) => UpdateClockPanelVisibility();
QueryTextBox.TextChanged += (s, e) => UpdateClockPanelVisibility();

// Detecting ContextMenu.Visibility changes
DependencyPropertyDescriptor
Expand Down Expand Up @@ -351,15 +351,13 @@ private void OnKeyDown(object sender, KeyEventArgs e)
_viewModel.LoadContextMenuCommand.Execute(null);
e.Handled = true;
}

break;
case Key.Left:
if (!_viewModel.QueryResultsSelected() && QueryTextBox.CaretIndex == 0)
{
_viewModel.EscCommand.Execute(null);
e.Handled = true;
}

break;
case Key.Back:
if (specialKeyState.CtrlPressed)
Expand All @@ -378,7 +376,6 @@ private void OnKeyDown(object sender, KeyEventArgs e)
}
}
}

break;
default:
break;
Expand Down Expand Up @@ -864,16 +861,18 @@ private void WindowAnimation()
private void UpdateClockPanelVisibility()
{
if (QueryTextBox == null || ContextMenu == null || History == null || ClockPanel == null)
{
return;
}

// ✅ Initialize animation length & duration
var animationLength = _settings.AnimationSpeed switch
{
AnimationSpeeds.Slow => 560,
AnimationSpeeds.Medium => 360,
AnimationSpeeds.Fast => 160,
_ => _settings.CustomAnimationLength
};

var animationDuration = TimeSpan.FromMilliseconds(animationLength * 2 / 3);

// ✅ Conditions for showing ClockPanel (No query input & ContextMenu, History are closed)
Expand All @@ -890,15 +889,21 @@ private void UpdateClockPanelVisibility()
}

// ✅ 2. When ContextMenu is closed, keep it Hidden if there's text in the query (remember previous state)
if (ContextMenu.Visibility != Visibility.Visible && QueryTextBox.Text.Length > 0)
else if (QueryTextBox.Text.Length > 0)
{
_viewModel.ClockPanelVisibility = Visibility.Hidden;
_viewModel.ClockPanelOpacity = 0.0;
return;
}

// ✅ Prevent multiple animations
if (_isClockPanelAnimating)
{
return;
}

// ✅ 3. When hiding ClockPanel (apply fade-out animation)
if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible && !_isClockPanelAnimating)
if ((!shouldShowClock) && _viewModel.ClockPanelVisibility == Visibility.Visible)
{
_isClockPanelAnimating = true;

Expand All @@ -920,32 +925,32 @@ private void UpdateClockPanelVisibility()
}

// ✅ 4. When showing ClockPanel (apply fade-in animation)
else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible && !_isClockPanelAnimating)
else if (shouldShowClock && _viewModel.ClockPanelVisibility != Visibility.Visible)
{
_isClockPanelAnimating = true;

Application.Current.Dispatcher.Invoke(() =>
_viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first

var fadeIn = new DoubleAnimation
{
_viewModel.ClockPanelVisibility = Visibility.Visible; // ✅ Set Visibility to Visible first
From = 0.0,
To = 1.0,
Duration = animationDuration,
FillBehavior = FillBehavior.HoldEnd
};

var fadeIn = new DoubleAnimation
{
From = 0.0,
To = 1.0,
Duration = animationDuration,
FillBehavior = FillBehavior.HoldEnd
};

fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;
ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
}, DispatcherPriority.Render);
fadeIn.Completed += (s, e) => _isClockPanelAnimating = false;

ClockPanel.BeginAnimation(OpacityProperty, fadeIn);
}
}

private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1.0)
{
if (style == null)
{
return defaultOpacity;
}

foreach (Setter setter in style.Setters.Cast<Setter>())
{
Expand All @@ -961,7 +966,9 @@ private static double GetOpacityFromStyle(Style style, double defaultOpacity = 1
private static Thickness GetThicknessFromStyle(Style style, Thickness defaultThickness)
{
if (style == null)
{
return defaultThickness;
}

foreach (Setter setter in style.Setters.Cast<Setter>())
{
Expand Down
15 changes: 9 additions & 6 deletions Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -753,8 +753,7 @@ private ResultsViewModel SelectedResults

public Visibility ProgressBarVisibility { get; set; }
public Visibility MainWindowVisibility { get; set; }
public double MainWindowOpacity { get; set; } = 1;


// This is to be used for determining the visibility status of the mainwindow instead of MainWindowVisibility
// because it is more accurate and reliable representation than using Visibility as a condition check
public bool MainWindowVisibilityStatus { get; set; } = true;
Expand Down Expand Up @@ -1454,9 +1453,11 @@ public bool ShouldIgnoreHotkeys()

public void Show()
{
// Invoke on UI thread
Application.Current.Dispatcher.Invoke(() =>
{
if (Application.Current.MainWindow is MainWindow mainWindow)
// When application is exitting, the Application.Current will be null
if (Application.Current?.MainWindow is MainWindow mainWindow)
{
// 📌 Remove DWM Cloak (Make the window visible normally)
Win32Helper.DWMSetCloakForWindow(mainWindow, false);
Expand All @@ -1481,10 +1482,10 @@ public void Show()

// Update WPF properties
MainWindowVisibility = Visibility.Visible;
MainWindowOpacity = 1;
MainWindowVisibilityStatus = true;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = true });

// Switch keyboard layout
if (StartWithEnglishMode)
{
Win32Helper.SwitchToEnglishKeyboardLayout(true);
Expand Down Expand Up @@ -1527,9 +1528,11 @@ public async void Hide()
break;
}

// Invoke on UI thread
Application.Current.Dispatcher.Invoke(() =>
{
if (Application.Current.MainWindow is MainWindow mainWindow)
// When application is exitting, the Application.Current will be null
if (Application.Current?.MainWindow is MainWindow mainWindow)
{
// Set clock and search icon opacity
var opacity = Settings.UseAnimation ? 0.0 : 1.0;
Expand All @@ -1549,6 +1552,7 @@ public async void Hide()
}
}, DispatcherPriority.Render);

// Switch keyboard layout
if (StartWithEnglishMode)
{
Win32Helper.RestorePreviousKeyboardLayout();
Expand All @@ -1558,7 +1562,6 @@ public async void Hide()
await Task.Delay(50);

// Update WPF properties
//MainWindowOpacity = 0;
MainWindowVisibilityStatus = false;
MainWindowVisibility = Visibility.Collapsed;
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
Expand Down
Loading