mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Fix blink issue when fast trigering show/hide
This commit is contained in:
parent
758717848c
commit
4042231fb3
2 changed files with 58 additions and 21 deletions
|
|
@ -27,6 +27,9 @@ using DataObject = System.Windows.DataObject;
|
|||
using System.Windows.Media;
|
||||
using System.Windows.Interop;
|
||||
using Windows.Win32;
|
||||
using Microsoft.VisualBasic.Devices;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||
using Window = System.Windows.Window;
|
||||
|
||||
namespace Flow.Launcher
|
||||
{
|
||||
|
|
@ -46,6 +49,11 @@ namespace Flow.Launcher
|
|||
private MediaPlayer animationSoundWMP;
|
||||
private SoundPlayer animationSoundWPF;
|
||||
|
||||
//For Window Animations
|
||||
private Storyboard clocksb;
|
||||
private Storyboard iconsb;
|
||||
private Storyboard windowsb;
|
||||
|
||||
#endregion
|
||||
|
||||
public MainWindow(Settings settings, MainViewModel mainVM)
|
||||
|
|
@ -476,6 +484,19 @@ namespace Flow.Launcher
|
|||
isProgressBarStoryboardPaused = true;
|
||||
}
|
||||
|
||||
public void ResetAnimation()
|
||||
{
|
||||
// 애니메이션 중지
|
||||
clocksb?.Stop(ClockPanel);
|
||||
iconsb?.Stop(SearchIcon);
|
||||
windowsb?.Stop(FlowMainWindow);
|
||||
|
||||
// UI 요소 상태 초기화
|
||||
ClockPanel.Margin = new Thickness(0, 0, ClockPanel.Margin.Right, 0);
|
||||
ClockPanel.Opacity = 0;
|
||||
SearchIcon.Opacity = 0;
|
||||
}
|
||||
|
||||
public void WindowAnimator()
|
||||
{
|
||||
if (_animating)
|
||||
|
|
@ -485,11 +506,10 @@ namespace Flow.Launcher
|
|||
_animating = true;
|
||||
UpdatePosition();
|
||||
|
||||
Storyboard windowsb = new Storyboard();
|
||||
Storyboard clocksb = new Storyboard();
|
||||
Storyboard iconsb = new Storyboard();
|
||||
CircleEase easing = new CircleEase();
|
||||
easing.EasingMode = EasingMode.EaseInOut;
|
||||
windowsb = new Storyboard();
|
||||
clocksb = new Storyboard();
|
||||
iconsb = new Storyboard();
|
||||
CircleEase easing = new CircleEase { EasingMode = EasingMode.EaseInOut };
|
||||
|
||||
var animationLength = _settings.AnimationSpeed switch
|
||||
{
|
||||
|
|
@ -501,19 +521,21 @@ namespace Flow.Launcher
|
|||
|
||||
var WindowOpacity = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
From = 1,
|
||||
To = 1,
|
||||
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
// 📌 항상 같은 위치에서 시작하도록 `_originalTop`을 사용
|
||||
var WindowMotion = new DoubleAnimation
|
||||
{
|
||||
From = Top,
|
||||
To = Top,
|
||||
From = Top + 10, // 원래 위치에서 10px 내려온 후
|
||||
To = Top, // 다시 원래 위치로 이동
|
||||
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
};
|
||||
|
||||
var IconMotion = new DoubleAnimation
|
||||
{
|
||||
From = 12,
|
||||
|
|
@ -529,16 +551,17 @@ namespace Flow.Launcher
|
|||
To = 1,
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromMilliseconds(animationLength),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
FillBehavior = FillBehavior.HoldEnd
|
||||
};
|
||||
double TargetIconOpacity = SearchIcon.Opacity; // Animation Target Opacity from Style
|
||||
|
||||
double TargetIconOpacity = SearchIcon.Opacity;
|
||||
var IconOpacity = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = TargetIconOpacity,
|
||||
To = 1,
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromMilliseconds(animationLength),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
FillBehavior = FillBehavior.HoldEnd
|
||||
};
|
||||
|
||||
double right = ClockPanel.Margin.Right;
|
||||
|
|
@ -548,18 +571,29 @@ namespace Flow.Launcher
|
|||
To = new Thickness(0, 0, right, 0),
|
||||
EasingFunction = easing,
|
||||
Duration = TimeSpan.FromMilliseconds(animationLength),
|
||||
FillBehavior = FillBehavior.Stop
|
||||
FillBehavior = FillBehavior.HoldEnd
|
||||
};
|
||||
|
||||
// 애니메이션 타겟 설정
|
||||
Storyboard.SetTargetProperty(ClockOpacity, new PropertyPath(OpacityProperty));
|
||||
Storyboard.SetTarget(ClockOpacity, ClockPanel);
|
||||
|
||||
Storyboard.SetTargetName(thicknessAnimation, "ClockPanel");
|
||||
Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(MarginProperty));
|
||||
|
||||
Storyboard.SetTarget(WindowOpacity, this);
|
||||
Storyboard.SetTargetProperty(WindowOpacity, new PropertyPath(Window.OpacityProperty));
|
||||
|
||||
Storyboard.SetTarget(WindowMotion, this);
|
||||
Storyboard.SetTargetProperty(WindowMotion, new PropertyPath(Window.TopProperty));
|
||||
|
||||
Storyboard.SetTarget(IconMotion, SearchIcon);
|
||||
Storyboard.SetTargetProperty(IconMotion, new PropertyPath(TopProperty));
|
||||
|
||||
Storyboard.SetTarget(IconOpacity, SearchIcon);
|
||||
Storyboard.SetTargetProperty(IconOpacity, new PropertyPath(OpacityProperty));
|
||||
|
||||
// 스토리보드에 애니메이션 추가
|
||||
clocksb.Children.Add(thicknessAnimation);
|
||||
clocksb.Children.Add(ClockOpacity);
|
||||
windowsb.Children.Add(WindowOpacity);
|
||||
|
|
@ -569,7 +603,6 @@ namespace Flow.Launcher
|
|||
|
||||
windowsb.Completed += (_, _) => _animating = false;
|
||||
_settings.WindowLeft = Left;
|
||||
_settings.WindowTop = Top;
|
||||
isArrowKeyPressed = false;
|
||||
|
||||
if (QueryTextBox.Text.Length == 0)
|
||||
|
|
@ -581,6 +614,8 @@ namespace Flow.Launcher
|
|||
windowsb.Begin(FlowMainWindow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void InitSoundEffects()
|
||||
{
|
||||
if (_settings.WMPInstalled)
|
||||
|
|
|
|||
|
|
@ -1393,11 +1393,15 @@ namespace Flow.Launcher.ViewModel
|
|||
});
|
||||
}
|
||||
|
||||
public async void Hide()
|
||||
public void Hide()
|
||||
{
|
||||
lastHistoryIndex = 1;
|
||||
// MainWindow 인스턴스를 가져와서 애니메이션 초기화
|
||||
if (Application.Current.MainWindow is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.ResetAnimation(); // 애니메이션 강제 리셋
|
||||
}
|
||||
|
||||
// Trick for no delay
|
||||
lastHistoryIndex = 1;
|
||||
MainWindowOpacity = 0;
|
||||
|
||||
if (ExternalPreviewVisible)
|
||||
|
|
@ -1408,7 +1412,6 @@ namespace Flow.Launcher.ViewModel
|
|||
SelectedResults = Results;
|
||||
}
|
||||
|
||||
// 📌 모든 LastQueryMode에서 텍스트 필드 즉시 업데이트 + 강제 UI 갱신
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
switch (Settings.LastQueryMode)
|
||||
|
|
@ -1437,11 +1440,9 @@ namespace Flow.Launcher.ViewModel
|
|||
break;
|
||||
}
|
||||
|
||||
// 📌 UI 강제 갱신
|
||||
Application.Current.MainWindow.UpdateLayout();
|
||||
}, DispatcherPriority.Render); // UI 스레드에서 즉시 실행
|
||||
}, DispatcherPriority.Render);
|
||||
|
||||
// 📌 창 숨김 처리 (텍스트 변경 후)
|
||||
MainWindowVisibilityStatus = false;
|
||||
MainWindowVisibility = Visibility.Collapsed;
|
||||
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
|
||||
|
|
@ -1449,6 +1450,7 @@ namespace Flow.Launcher.ViewModel
|
|||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if Flow Launcher should ignore any hotkeys
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Reference in a new issue