Skip to content

Fix freezing with gpu #3384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private void OnSourceInitialized(object sender, EventArgs e)
Win32Helper.HideFromAltTab(this);
Win32Helper.DisableControlBox(this);
}

private async void OnLoaded(object sender, RoutedEventArgs _)
{
// Check first launch
Expand Down Expand Up @@ -236,6 +236,7 @@ private async void OnLoaded(object sender, RoutedEventArgs _)
DependencyPropertyDescriptor
.FromProperty(VisibilityProperty, typeof(StackPanel)) // History는 StackPanel이라고 가정
.AddValueChanged(History, (s, e) => UpdateClockPanelVisibility());
_viewModel.ClearAllCacheModes(this);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emmmm, can I know all UIElement in all the window be clear cache? Thank you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the settings window (secondary window) also have its cachemode=null? For now, separate from this PR, I tried settingwindow the cache mode of all UI elements in both the main window and the settings window to Null in code, but it didn’t resolve the issue.

Copy link

@lindexi lindexi Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onesounds What worries me is that elements are added dynamically, and they are added after loading. And as my test, removing all the CacheMode can fix dotnet/wpf#2158 issues. If you can sure all the CacheMode be removed, I think may be you meet the other issues, not the dotnet/wpf#2158

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onesounds Can I ask any other try update?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't go well. Since we're using ModernWpf, I thought that instead of creating and building a new NuGet package to remove all the resources used by ModernWpf, I should find and remove them in the code — and I tried that, but it didn't work. I can’t tell if I’m doing it right, so I discussed it with Copilot and confirmed through debug code that all the caches were cleared, but even then, I’m not sure if it really worked correctly.

I also tested a few suggestions from cyclonring, but they all failed. The only thing that almost worked was an idea I came up with — showing the first window again at the moment of a "system change" (which removed the freezing of the settings window). But during testing, a focus loss situation. When the first window is hidden in this case, it causes the first window itself to freeze instead. I ended up giving up on this task because I discovered that the first window itself freezes as a result. #3378

I’ve asked my team members for help with this a few times, but no one seems interested. It feels like programmers tend to dislike this kind of work — the kind that doesn’t have a clear logic or defined answer and requires a lot of trial and error over a long period. Everyone seems to think it would be better and easier to just abandon WPF and move to something else. From my experience, I know that it's not that easy — which is why I want to find a solution within WPF.

In any case, I think it would be better if someone more capable than me took over this task and asked you questions. (The person you're talking to — me — is more of a designer and doesn’t really know much about programming.)

@Flow-Launcher/team

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClearAllCacheModes cannot bring any difference.

@Jack251970 I not sure this issus is same as dotnet/wpf#2158 . Maybe other case cause the freeze render issues.

Copy link
Contributor Author

@onesounds onesounds Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jack251970 This issue basically comes down to the fact that the freeze gets lifted when the primary window is shown. So the behavior you're describing is actually expected. What’s happening is that when the primary window is hidden, something keeps trying to render to it, and that’s causing the second window (in our case, the settings window) to crash.

Sorry for my confusion. I mean the second window starts to work when I brought main window with hotkey.

Open FL -> Sleep -> Unlock -> Open settings window (Freeze) -> Open main window with hotkey (Settings window starts to render)

You're basically saying the same thing I described. After the lock screen, the settings window freezes, and then when the first window is shown, the settings window becomes active again. That's the basic structure of the changes I made in my initial PR. So you had told me, "There's an issue where the window is being shown," right? So I said something like, "This PR resolves the issue when the window is shown, so the fix is based on that behavior — therefore, it's not fair to consider the fact that the window is being shown as a problem."

Copy link
Member

@Jack251970 Jack251970 Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClearAllCacheModes cannot bring any difference.

@Jack251970 I not sure this issus is same as dotnet/wpf#2158 . Maybe other case cause the freeze render issues.

Calling ClearAllCaches cannot find any UI elements with image caches. I am also not sure if this issue related to dotnet/wpf#2158.

Copy link

@lindexi lindexi Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jack251970 and @onesounds Can you make sure that no new elements with BitmapCache are added after OnLoaded? Thank you.

As #3384 (comment) , what worries me is that elements are added dynamically, and they are added after loading.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jack251970 and @onesounds Can you make sure that no new elements with BitmapCache are added after OnLoaded? Thank you.

As #3384 (comment) , what worries me is that elements are added dynamically, and they are added after loading.

For second window, I do think there are any elements added dynamically. For main window, I think there could be some dynamically added elements if we change query text. But even if we do not change query text, the freezing issue still exists.

}

private async void OnClosing(object sender, CancelEventArgs e)
Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher/SettingWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ private void OnLoaded(object sender, RoutedEventArgs e)
RefreshMaximizeRestoreButton();
// Fix (workaround) for the window freezes after lock screen (Win+L) or sleep
// https://stackoverflow.com/questions/4951058/software-rendering-mode-wpf
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
HwndTarget hwndTarget = hwndSource.CompositionTarget;
hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here
//HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
//HwndTarget hwndTarget = hwndSource.CompositionTarget;
//hwndTarget.RenderMode = RenderMode.SoftwareOnly; // Must use software only render mode here

InitializePosition();
}
Expand Down
34 changes: 34 additions & 0 deletions Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Input;
using System.Linq;
Expand Down Expand Up @@ -1428,7 +1429,36 @@ public bool ShouldIgnoreHotkeys()
#endregion

#region Public Methods
public void ClearAllCacheModes(DependencyObject element)
{
if (element == null)
return;

// 현재 요소의 CacheMode를 확인하고 제거
if (element is UIElement uiElement && uiElement.CacheMode != null)
{
string elementName = GetElementName(uiElement);
Debug.WriteLine($"CacheMode 제거: {elementName} - CacheMode 타입: {uiElement.CacheMode.GetType().Name}");
uiElement.CacheMode = null;
}

// 모든 자식 요소에 대해 재귀적으로 CacheMode 제거
int childCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(element, i);
ClearAllCacheModes(child);
}
}
private string GetElementName(UIElement element)
{
// 요소의 이름 가져오기 시도
if (element is FrameworkElement fe && !string.IsNullOrEmpty(fe.Name))
return fe.Name;

// 이름이 없으면 타입 반환
return element.GetType().Name;
}
public void Show()
{
Application.Current.Dispatcher.Invoke(() =>
Expand All @@ -1442,6 +1472,7 @@ public void Show()
mainWindow.ClockPanel.Visibility = Visibility.Visible;
//mainWindow.SearchIcon.Visibility = Visibility.Visible;
SearchIconVisibility = Visibility.Visible;
ClearAllCacheModes(mainWindow);
}

// Update WPF properties
Expand All @@ -1454,8 +1485,11 @@ public void Show()
{
Win32Helper.SwitchToEnglishKeyboardLayout(true);
}

});
}



#pragma warning disable VSTHRD100 // Avoid async void methods

Expand Down
Loading