microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.32k stars 676 forks source link

How to remove the flickering of WinUI3 Window on resizing #5148

Open selastingeorge opened 3 years ago

selastingeorge commented 3 years ago

I am new to WinUI3, I have created a sample app and when I resize it, there is a flickering in window, In WPF it was able to fix this flickering issue. but on winUI3 it is not working, is there any way to fix it.

I know that The Content Rendered in the window is created by Direct Composition and all the contents are hosted as a child window in a parent window, and i usually adjust WndProc to adjust the flickering some how I was not even able to override the wndPoc like i did for wpf, is there any way to fix this flickering.

Here is the screenshot of the issue:

Animation

codendone commented 3 years ago

We're currently working on fixing this. The plan is that instead of having that background color always be white it will instead be white or black depending on the value of Window.Content.RequestedTheme.

selastingeorge commented 3 years ago

The How can i get access to the WndProc, will sub classing work ? Why is it not possible to create a transparent window, i just added used the SetWindowCompositionAttribute() and set it to INVALID_STATE, usually it creates the same effect as the WS_EX_NOREDIRECTIONBITMAP in WPF but in Win UI some white background is covering the window,.

float34 commented 3 years ago

@codendone So instead of properly synchronizing the rendering with window sizing events you simply want to hide the issue by coloring? How will it help to eliminate the obvious title bar buttons flicker?

niels9001 commented 3 years ago

Agree with @torquerrr - and what if there's a custom image / gradient background set? This doesn't sound like an actual solution to the problem..

selastingeorge commented 3 years ago

When i checked the window with Spy++ i found that the child window hosted inside the parent is uses class Microsoft.UI.Hosting.Experimental.ContentWindowBridge, when i checked the caption of window this shows DesktopWindowBridge, which points me to other classes their in which one (Microsoft.UI.Hosting.Experimental.ExpSystemVisualBridge) has background property, will it be helpful, these are undocumented and i don't know what it does ?

And Check out these : image

Here the Child window uses WS_EX_NOREDIRECTIONBITMAP Which means the Child window draws a background using Direct Composition and the Window actually doesn't have a background.

llothar commented 3 years ago

We're currently working on fixing this. The plan is that instead of having that background color always be white it will instead be white or black depending on the value of Window.Content.RequestedTheme.

Thats a hack but it's not a solution, why is it rendered when not ready? The window resize is already delayed from the mouse dragging, so why not just syncing it. Windows is the only OS where this still happens. A simple color theme will not help if a sidebar is jumping around like a cat in heat.

selastingeorge commented 3 years ago

We're currently working on fixing this. The plan is that instead of having that background color always be white it will instead be white or black depending on the value of Window.Content.RequestedTheme.

Thats a hack but it's not a solution, why is it rendered when not ready? The window resize is already delayed from the mouse dragging, so why not just syncing it. Windows is the only OS where this still happens. A simple color theme will not happen when the sidebar at that location is jumping around like a cat in heat.

I have used Windows.UI.Composition wpf samples, those windows were also having the flickering but i was able to fix it by setting the window style to none and allow transparency to true. i think it won't work here.

Here is a sample wpf app: Animation

float34 commented 3 years ago

@SelastinGeorge Seems to be the same issue as https://github.com/microsoft/microsoft-ui-xaml/issues/2506. It is a long standing problem with how Windows handles the window resize. You can read how bad it actually is here. I don't expect it to be fixed ever.

selastingeorge commented 3 years ago

Actually i fixed the flickering issue in WPF by overriding the WndProc. Responding to WM_NCCALCSIZE with any RECT smaller than the window solves the problem. But i don't know it will work on child windows

codendone commented 3 years ago

Lots of good discussion on this thread. I agree with comments that setting a better background color is an incomplete solution, but as @torquerrr said, handling resize well in Windows is difficult. Windows has code to attempt to synchronize window frame redraw with when the app content has finished drawing, but that synchronization code requires Windows to know when the app is finished drawing. WinUI3 draws all app content into a swapchain, which Windows intentionally never synchronizes to favor performance of the swapchain. Window resize is a case where synchronization might be desirable. I think this needs to be investigated, but supporting synchronized resize would be significant work and likely requires an OS update.

Because of all that, a better background color will at least reduce the visible flicker for dark theme apps without waiting for a full synchronized resize solution.

selastingeorge commented 3 years ago

I Know this is not the question i should ask in this thread, but it's just a small doubt ,I was also trying to implement transparent background and acrylic effect also in win ui3, i was able to implement both in Win32 using the DWMThumbnail API, but the DWM Thumbnail Api Outputs the Content Behind Window on to IDCompositionVisual2 , is there any way to convert it to Microsoft.UI.Composition.Visual

Here is the demo screen shot:

image

Here the Position i marked using Red Rectangle is not caused by WS_EX_NOREDIRECTIONBITMAP, its dwm thumbnail based, After blurring it will be:

image

If I could get these visual to Microsoft.UI.Composition.Visual, I might be able to bring back Transparency+ Acrylic to win UI 3, I believe So.

float34 commented 3 years ago

@codendone As far as I know default Windows 10 apps (News, Maps, Photos) use DirectComposition API, and they don't have the resize issue being discussed. Why WinUI 3 draws to swapchain (with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL/DXGI_SWAP_EFFECT_FLIP_DISCARD I guess?) instead? To cover the needs of both 2D apps and 3D games (which need maximum performance)?

codendone commented 3 years ago

@torquerrr WinUI 3 uses Microsoft.UI.Composition, which is part of Project Reunion, rather than Windows.UI.Composition. Using Microsoft.UI.Composition means we can update it when desired, just like we can with the XAML code of WinUI 3, and that those updates are available on all OS versions supported by Project Reunion, rather than only being on the latest OS version.

float34 commented 3 years ago

@codendone So, do we need to add "feature-request" label or close it and all relevant stories?

codendone commented 3 years ago

We should keep this active, and I think just an issue is fine here. This is being tracked internally as a feature due to its cost and complexity.

etkramer commented 3 years ago

Definitely with everyone else in this thread, syncing the clear color with the Windows theme is not a solution. The proposed hack would look just as bad as it does now if the page:

a. Uses a background color that doesn't perfectly match the windows theme or b. has content anywhere near the edges

chausner commented 2 years ago

The plan is that instead of having that background color always be white it will instead be white or black depending on the value of Window.Content.RequestedTheme.

I agree with the others that this seems a poor workaround at best. Still, a workaround that makes these artifacts less noticeable is better than no fix at all, at least until a proper fix is available. It would be good, however, to be able to set a custom color for this instead of having white/black hardcoded. My app, for example, uses an orange background, so neither white nor black looks good.

nathanAjacobs commented 2 years ago

Is there an update on this? This is turning me away from wanting to use WinUI 3.

castorix commented 2 years ago

Is there an update on this? This is turning me away from wanting to use WinUI 3.

There is no more flickering :

WinUI3_Resize

wangwenx190 commented 2 years ago

We should keep this active, and I think just an issue is fine here. This is being tracked internally as a feature due to its cost and complexity.

@codendone May I ask the current status of this internal ticket? Is it ever been worked on since it's created?

wangwenx190 commented 2 years ago

Is there an update on this? This is turning me away from wanting to use WinUI 3.

There is no more flickering :

WinUI3_Resize

@castorix That looks a lot better, but can you verify whether the content still flickers or not if you remove the whole window frame (by not modifying the non-client area and returning 0 directly in WM_NCCALCSIZE) ? And from your video it looks like the contents are jumping around because of window resizing, that's really not nice.

castorix commented 2 years ago

@castorix That looks a lot better, but can you verify whether the content still flickers or not if you remove the whole window frame (by not modifying the non-client area and returning 0 directly in WM_NCCALCSIZE) ? And from your video it looks like the contents are jumping around because of window resizing, that's really not nice.

If I remove the frame by subclassing it, the result is the same (I can only resize once as there is no more sizing border...) But the jumping content is clearly not good (if I test resising with WPF for example with also a centered button, it is smoother)

nathanAjacobs commented 2 years ago

There is no more flickering :

https://user-images.githubusercontent.com/37193095/171750464-b4368a38-6a0e-43ad-8ff9-2ac98b23692c.mp4

@castorix I definitely have flickering...

I'm pretty sure the only reason you do not see flickering is because you are using a theme with a dark background and your background is set to black.

I could be wrong, but could this be solved by adding a Background property to the Window control? It currently does not have one.

wangwenx190 commented 2 years ago

@nathanAjacobs You can try the WS_EX_NOREDIRECTIONBITMAP style, enabling that style will cause your window doesn't have a background at all (it won't affect the window frame and the title bar), so the flicker may be removed. But that style is only supported on window creation time, that is, when you call the CreateWindow function. If you try to enable or disable that style after the window has been created, it will have no effect.

nathanAjacobs commented 2 years ago

@nathanAjacobs You can try the WS_EX_NOREDIRECTIONBITMAP style, enabling that style will cause your window doesn't have a background at all (it won't affect the window frame and the title bar), so the flicker may be removed. But that style is only supported on window creation time, that is, when you call the CreateWindow function. If you try to enable or disable that style after the window has been created, it will have no effect.

I'm working in a C# project, so I'm not sure I can even try that. WPF and UWP do not have this problem. This issue prevents any app from using a custom background color that doesn't match close enough to the current system theme. I feel like this issue needs to be properly addressed sooner than later if they want people to adopt WinUI 3 over other frameworks.

selastingeorge commented 2 years ago

@nathanAjacobs You can try the WS_EX_NOREDIRECTIONBITMAP style, enabling that style will cause your window doesn't have a background at all (it won't affect the window frame and the title bar), so the flicker may be removed. But that style is only supported on window creation time, that is, when you call the CreateWindow function. If you try to enable or disable that style after the window has been created, it will have no effect.

But there is a possible way to achieve the same effect using setwindowcompositionattribute(), using ACCENT_INVALID_STATE gives us a transparent window which has same behaviour as WS_EX_NOREDIRECTIONBITMAP.

castorix commented 2 years ago

I'm pretty sure the only reason you do not see flickering is because you are using a theme with a dark background and your background is set to black.

I could be wrong, but could this be solved by adding a Background property to the Window control? It currently does not have one.

I use the standard Dark Theme on Windows 10 (21H1) You can change the background color in WM_ERASEBKGND, like I did in some samples I posted, but it is just a workaround

selastingeorge commented 2 years ago

Actually you can remove the complete background, like this:

image

Try this :

https://github.com/microsoft/microsoft-ui-xaml/issues/1247#issuecomment-653373428

castorix commented 2 years ago

They added a background in 1.1.0 stable version. (which breaks transparency which could be done with ULW_COLORKEY as it is drawn over...) ...which does not solve the problem if you use another background color :

Flickering

nathanAjacobs commented 2 years ago

It's pretty surprising that this issue is still present in 1.1.0 stable release, however I managed to solve it with some help from castorix's interop code in his demo sample from the transparency issue thread.

I basically made a BetterWindow class which inherits from Window that handles all the Win32 interop and added Background, MinWidth, and MinHeight properties to it. Unfortunately, the Background property cannot be bound to a ThemeResource via XAML. I think it's because Window doesn't inherit from DependencyObject, but I'm not entirely sure. It basically just means if you desire the Background property to respect theme changes it has to be handled from code behind. Also, the BetterWindow class I made doesn't support Window transparency, but I'm sure that can be added if you need it.

There's another flickering issue, but I believe it's unrelated to this flickering issue on the edge of windows. You can notice when resizing the window at certain sizes, that the window's content disappears completely for a split second.

I will post the demo project to a repo and link it here shortly, but here is a video of my results in the meantime:

https://user-images.githubusercontent.com/37193095/173190803-f6bf979e-7ae7-4530-9fea-132586895dea.mp4

castorix commented 2 years ago

2022-06-11.09-23-47_Trim_Trim_Trim.mp4

Did you test the resizing from left side, which still flickers with custom colors in my tests ? I made other tests and I could remove this flickering by handling WM_NCCALCSIZE instead of WM_SIZE... but I replaced the default Swapchain with my own Swapchain (with CreateSwapChainForComposition) for the test (so XAML is not drawn anymore, just what I draw in my Swapchain...), by using the method in this article DXGI Flip Model Flickering During Live Resize

nathanAjacobs commented 2 years ago

Did you test the resizing from left side, which still flickers with custom colors in my tests ? I made other tests and I could remove this flickering by handling WM_NCCALCSIZE instead of WM_SIZE... but I replaced the default Swapchain with my own Swapchain (with CreateSwapChainForComposition) for the test (so XAML is not drawn anymore, just what I draw in my Swapchain...), by using the method in this article DXGI Flip Model Flickering During Live Resize

There is no flickering with custom colors when resizing from the left side for me. Although the content repositioning is more jittery when resizing from the left size for some reason.

Here is the link to the repo: https://github.com/nathanAjacobs/WindowBackgroundDemoWinUI3

I would really like to see a Background property added to the Window class in the framework itself, that way all this extra workaround isn't required. It would also be nice if it was able to be bound to a ThemeResource brush.

castorix commented 2 years ago

Yes, the idea is to erase the background with the same color as the current background, to hide the flickering I think that's why they added a black/white background, depending on the Theme

If a border is added, the flickering is visible (but usually, nobody adds a border to a main window...) :

Background_Resize_Border

nathanAjacobs commented 2 years ago

Did you test the resizing from left side, which still flickers with custom colors in my tests ? I made other tests and I could remove this flickering by handling WM_NCCALCSIZE instead of WM_SIZE... but I replaced the default Swapchain with my own Swapchain (with CreateSwapChainForComposition) for the test (so XAML is not drawn anymore, just what I draw in my Swapchain...), by using the method in this article DXGI Flip Model Flickering During Live Resize

So I ended up retesting, and there is a chance of a flicker still, but it is rare and I have to move my mouse really fast when resizing the window:

https://user-images.githubusercontent.com/37193095/173201013-9755f70d-b073-49e2-931d-269a46c940ba.mp4

flicker

The jittery movement of the content when resizing from the left side, in addition to the content popping in and out occasionally is definitely more jarring.

https://user-images.githubusercontent.com/37193095/173201075-e5c87af2-9f3c-495d-8778-f04dd13f237c.mp4

MattBDev commented 2 years ago

I can't believe that this issue still exists. I consider it a major regression from UWP apps which handle resizing without a problem. This issue should be marked as a bug instead of a question since this shouldn't be the intended behavior. Apps should resize smoothly without any flickering.

Lightczx commented 1 year ago

Workarounds not doing well when using the 1.1 MicaBackdrop/SystemBackdrop feature. Since it is not solid, filling color when resizing really helps nothing.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 5 days.

xStrom commented 1 year ago

The issue isn't stale.

llothar commented 1 year ago

The issue isn't stale.

Windows is stale at the moment, at least it taste like this.

JJBrychell commented 1 year ago

The "partial" fix has been completed and a more comprehensive fix has been added to the backlog so changing this to a feature proposal.

AndyHTML2012 commented 9 months ago

@JJBrychell any update on when this might be fixed in WinUI3?

wuyang26 commented 9 months ago

WPF will also encounter the same problem in custom windows,However, setting NonClientFrameEdges="Bottom" in Windows Chrome eliminates flickering issues: `

`
Sebbe909 commented 8 months ago

@farran 100%. Windows is the cripple handicapped kid from the block. It's terrible. MS, but in particular Windows, is a complete joke compared to any other OS nowadays. How did Satya Nadella ever think this (and related stuff, like W11 in general) was ready to ship considering the horrible UX/UI experience? No wonder Panos Panay left the building.

Remember the time where Vista was able to render Aero blur effect real time without any lag or crazy stuff whatsoever. This was almost 20(!!) years ago. Now, on high end hardware, you can literally see the Acrylic effect being drawn over the window background when resizing, has Explorer.exe trouble to load up the UI instantly, renewed Task Manager which feels like a slow responsive pile of garbage, etc. etc...

It's a total utter mess.

Not surprising as senior and experienced devs move up the ladder (and bail) and most of the dev is supposedly done by junior (medior at most) devs in India. And I hear India is known for high quality software development.

But yeah, MS is only a startup right.

Yes I'm frustrated, because all MS does is near to nothing to improve the overall performance. From time to time they seem to check out the feedback hub to see which unneeded bloated feature they should add in the next "major update". Awesome idea to let the gamer kids tell MS what should be important.

the-homer-inline4

Just my 2ct.

Neme12 commented 6 months ago

This issue doesn't happen for built-in apps on Windows 11 like File Explorer or Notepad, even though they seem like they're in WinUI by the style. Also, they open much quicker than a WinUI app. Maybe they're actually written in something completely different? That would support https://github.com/microsoft/microsoft-ui-xaml/discussions/9417

EDIT: Oh, actually they do, I can see that when resizing via the top or left sides rather than the bottom or right sides, where I don't notice it.

(see this video from 2013).

Wow, this looks out of this world to me, since I'm used to Windows. This certainly doesn't happen for any app on Windows. I think I'll switch OS 😄

Lightczx commented 6 months ago

This issue doesn't happen for built-in apps on Windows 11 like File Explorer or Notepad

File Explorer do have flickers, since it's HWND + Xaml island

AndyHTML2012 commented 6 months ago

This issue has been open since 2021 and is still one of the most noticeable visual bugs in WinUI3.

JamasChuang94 commented 6 months ago

有更新吗?这让我不再想使用 WinUI 3。

不再有闪烁:

WinUI3_调整大小 WinUI3_调整大小

This only solves the problem of solid colors, but the system acrylic and Mica backgrounds will still flicker. How do I resolve rendering issues with SDK1.5?

mominshaikhdevs commented 2 months ago

@codendone has this issue been fixed at the OS level yet? what's the latest update on this?

codendone commented 2 months ago

@mominshaikhdevs There has been a little progress, but no ETA currently. See http://aka.ms/winappsdk/plans for the overall roadmap.

holecekp commented 6 days ago

The same issue is also in .NET MAUI (based on WinUI3). Old Xamarin.Forms (UWP) did not have this issue and resizing is smoother there.