Skip to content

Commit 4042231

Browse files
committed
Fix blink issue when fast trigering show/hide
1 parent 7587178 commit 4042231

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
using System.Windows.Media;
2828
using System.Windows.Interop;
2929
using Windows.Win32;
30+
using Microsoft.VisualBasic.Devices;
31+
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
32+
using Window = System.Windows.Window;
3033

3134
namespace Flow.Launcher
3235
{
@@ -46,6 +49,11 @@ public partial class MainWindow
4649
private MediaPlayer animationSoundWMP;
4750
private SoundPlayer animationSoundWPF;
4851

52+
//For Window Animations
53+
private Storyboard clocksb;
54+
private Storyboard iconsb;
55+
private Storyboard windowsb;
56+
4957
#endregion
5058

5159
public MainWindow(Settings settings, MainViewModel mainVM)
@@ -476,6 +484,19 @@ private void InitProgressbarAnimation()
476484
isProgressBarStoryboardPaused = true;
477485
}
478486

487+
public void ResetAnimation()
488+
{
489+
// 애니메이션 중지
490+
clocksb?.Stop(ClockPanel);
491+
iconsb?.Stop(SearchIcon);
492+
windowsb?.Stop(FlowMainWindow);
493+
494+
// UI 요소 상태 초기화
495+
ClockPanel.Margin = new Thickness(0, 0, ClockPanel.Margin.Right, 0);
496+
ClockPanel.Opacity = 0;
497+
SearchIcon.Opacity = 0;
498+
}
499+
479500
public void WindowAnimator()
480501
{
481502
if (_animating)
@@ -485,11 +506,10 @@ public void WindowAnimator()
485506
_animating = true;
486507
UpdatePosition();
487508

488-
Storyboard windowsb = new Storyboard();
489-
Storyboard clocksb = new Storyboard();
490-
Storyboard iconsb = new Storyboard();
491-
CircleEase easing = new CircleEase();
492-
easing.EasingMode = EasingMode.EaseInOut;
509+
windowsb = new Storyboard();
510+
clocksb = new Storyboard();
511+
iconsb = new Storyboard();
512+
CircleEase easing = new CircleEase { EasingMode = EasingMode.EaseInOut };
493513

494514
var animationLength = _settings.AnimationSpeed switch
495515
{
@@ -501,19 +521,21 @@ public void WindowAnimator()
501521

502522
var WindowOpacity = new DoubleAnimation
503523
{
504-
From = 0,
524+
From = 1,
505525
To = 1,
506526
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
507527
FillBehavior = FillBehavior.Stop
508528
};
509529

530+
// 📌 항상 같은 위치에서 시작하도록 `_originalTop`을 사용
510531
var WindowMotion = new DoubleAnimation
511532
{
512-
From = Top,
513-
To = Top,
533+
From = Top + 10, // 원래 위치에서 10px 내려온 후
534+
To = Top, // 다시 원래 위치로 이동
514535
Duration = TimeSpan.FromMilliseconds(animationLength * 2 / 3),
515536
FillBehavior = FillBehavior.Stop
516537
};
538+
517539
var IconMotion = new DoubleAnimation
518540
{
519541
From = 12,
@@ -529,16 +551,17 @@ public void WindowAnimator()
529551
To = 1,
530552
EasingFunction = easing,
531553
Duration = TimeSpan.FromMilliseconds(animationLength),
532-
FillBehavior = FillBehavior.Stop
554+
FillBehavior = FillBehavior.HoldEnd
533555
};
534-
double TargetIconOpacity = SearchIcon.Opacity; // Animation Target Opacity from Style
556+
557+
double TargetIconOpacity = SearchIcon.Opacity;
535558
var IconOpacity = new DoubleAnimation
536559
{
537560
From = 0,
538-
To = TargetIconOpacity,
561+
To = 1,
539562
EasingFunction = easing,
540563
Duration = TimeSpan.FromMilliseconds(animationLength),
541-
FillBehavior = FillBehavior.Stop
564+
FillBehavior = FillBehavior.HoldEnd
542565
};
543566

544567
double right = ClockPanel.Margin.Right;
@@ -548,18 +571,29 @@ public void WindowAnimator()
548571
To = new Thickness(0, 0, right, 0),
549572
EasingFunction = easing,
550573
Duration = TimeSpan.FromMilliseconds(animationLength),
551-
FillBehavior = FillBehavior.Stop
574+
FillBehavior = FillBehavior.HoldEnd
552575
};
553576

577+
// 애니메이션 타겟 설정
554578
Storyboard.SetTargetProperty(ClockOpacity, new PropertyPath(OpacityProperty));
579+
Storyboard.SetTarget(ClockOpacity, ClockPanel);
580+
555581
Storyboard.SetTargetName(thicknessAnimation, "ClockPanel");
556582
Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(MarginProperty));
583+
557584
Storyboard.SetTarget(WindowOpacity, this);
558585
Storyboard.SetTargetProperty(WindowOpacity, new PropertyPath(Window.OpacityProperty));
586+
587+
Storyboard.SetTarget(WindowMotion, this);
559588
Storyboard.SetTargetProperty(WindowMotion, new PropertyPath(Window.TopProperty));
589+
590+
Storyboard.SetTarget(IconMotion, SearchIcon);
560591
Storyboard.SetTargetProperty(IconMotion, new PropertyPath(TopProperty));
592+
593+
Storyboard.SetTarget(IconOpacity, SearchIcon);
561594
Storyboard.SetTargetProperty(IconOpacity, new PropertyPath(OpacityProperty));
562595

596+
// 스토리보드에 애니메이션 추가
563597
clocksb.Children.Add(thicknessAnimation);
564598
clocksb.Children.Add(ClockOpacity);
565599
windowsb.Children.Add(WindowOpacity);
@@ -569,7 +603,6 @@ public void WindowAnimator()
569603

570604
windowsb.Completed += (_, _) => _animating = false;
571605
_settings.WindowLeft = Left;
572-
_settings.WindowTop = Top;
573606
isArrowKeyPressed = false;
574607

575608
if (QueryTextBox.Text.Length == 0)
@@ -581,6 +614,8 @@ public void WindowAnimator()
581614
windowsb.Begin(FlowMainWindow);
582615
}
583616

617+
618+
584619
private void InitSoundEffects()
585620
{
586621
if (_settings.WMPInstalled)

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,11 +1393,15 @@ public void Show()
13931393
});
13941394
}
13951395

1396-
public async void Hide()
1396+
public void Hide()
13971397
{
1398-
lastHistoryIndex = 1;
1398+
// MainWindow 인스턴스를 가져와서 애니메이션 초기화
1399+
if (Application.Current.MainWindow is MainWindow mainWindow)
1400+
{
1401+
mainWindow.ResetAnimation(); // 애니메이션 강제 리셋
1402+
}
13991403

1400-
// Trick for no delay
1404+
lastHistoryIndex = 1;
14011405
MainWindowOpacity = 0;
14021406

14031407
if (ExternalPreviewVisible)
@@ -1408,7 +1412,6 @@ public async void Hide()
14081412
SelectedResults = Results;
14091413
}
14101414

1411-
// 📌 모든 LastQueryMode에서 텍스트 필드 즉시 업데이트 + 강제 UI 갱신
14121415
Application.Current.Dispatcher.Invoke(() =>
14131416
{
14141417
switch (Settings.LastQueryMode)
@@ -1437,18 +1440,17 @@ public async void Hide()
14371440
break;
14381441
}
14391442

1440-
// 📌 UI 강제 갱신
14411443
Application.Current.MainWindow.UpdateLayout();
1442-
}, DispatcherPriority.Render); // UI 스레드에서 즉시 실행
1444+
}, DispatcherPriority.Render);
14431445

1444-
// 📌 창 숨김 처리 (텍스트 변경 후)
14451446
MainWindowVisibilityStatus = false;
14461447
MainWindowVisibility = Visibility.Collapsed;
14471448
VisibilityChanged?.Invoke(this, new VisibilityChangedEventArgs { IsVisible = false });
14481449
}
14491450

14501451

14511452

1453+
14521454
/// <summary>
14531455
/// Checks if Flow Launcher should ignore any hotkeys
14541456
/// </summary>

0 commit comments

Comments
 (0)