Skip to content
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

Regression in 11.1 Beta2 and RC1 concerning EmbeddableControlRoot's EmbeddableWindow implementation on Windows #16048

Open
fitdev opened this issue Jun 17, 2024 · 5 comments · Fixed by fitdev/Avalonia#1 · May be fixed by #16051

Comments

@fitdev
Copy link
Contributor

fitdev commented Jun 17, 2024

Describe the bug

If Avalonia is hosted inside a Windows app, like WinForms for example, then whenever user interacts with Avalonia's content embedded in the EmbeddableControlRoot, the containing app window (i.e. WinForms main window) loses focus.

To Reproduce

Just use EmbeddableControlRoot directly or via WinFormsAvaloniaControlHost to see this behavior.

Expected behavior

The containing parent window should not lose focus when user interacts with Avalonia embedded via EmbeddableControlRoot.

Avalonia version

11.1

OS

Windows

Additional context

After some investigation turns out the actual EmbeddableWindow implementation used by EmbeddableControlRoot to create a native Windows window does NOT set WS_CHILD style:

Screenshot_20240618_000557

Once that style is added manually (via, for instance User32's SetWindowLong API) everything works fine.

So it seems, that the code for creating embedded windows on Windows should be reviewed, especially within the Interop context.

@fitdev fitdev added the bug label Jun 17, 2024
@maxkatz6
Copy link
Member

This line is responsible for attaching embeddable control to the parent: https://github.com/AvaloniaUI/Avalonia/blob/master/src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs#L60

It never really did set CHILD style on parent though, so regression must come from something else. On other hand, this style would make sense anyway.

@timunie
Copy link
Contributor

timunie commented Jun 18, 2024

@fitdev a PR is welcome if you know how to improve it.

@fitdev
Copy link
Contributor Author

fitdev commented Jun 18, 2024

It never really did set CHILD style on parent though, so regression must come from something else. On other hand, this style would make sense anyway.

I know, in fact I was using own implementation of WinFormsAvaloniaControlHost, so it is not WinFormsAvaloniaControlHost that is the culprit.

The real cause is that the "embedded window" created by EmbeddableControlRoot's constructor through IWindowingPlatform.CreateEmbeddableWindow() implemented in Win32Platform.CreateEmbeddableWindow via EmbeddedWindowImpl does not set correct styles, as expected by Windows OS for the embedding use case.

I am not Windows expert by any means, so don't really know which styles and/or extended styles should be set for such a case. But, WS_CHILD should certainly be one of them and solves this issue. Strange: it seems the style does get set in the EmbeddedWindowImpl.CreateWindowOverride, but for some reason it does not translate into actual window instance having that style in either Beta 2 or RC1.

@fitdev
Copy link
Contributor Author

fitdev commented Jun 18, 2024

After some more digging, the culprit seems in the WindowImpl.UpdateWindowProperties which unconditionally does this WindowStyles style = WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_OVERLAPPEDWINDOW | WindowStyles.WS_CLIPSIBLINGS; and then modifies that style, without taking into account the already existing style (i.e. throws away WS_CHILD that was set by EmbeddedWindowImpl.CreateWindowOverride.

The WindowImpl.UpdateWindowProperties itself is called through:
Win32Platform.CreateEmbeddableWindow
WindowImpl.Show
WindowImpl.ShowWindow

So, the bottom line is that this gets screwed up in the WindowImpl.UpdateWindowProperties routine which does not preserve the initially correctly set WS_CHILD flag. So someone who owns this area should look into how best to pass the information to the UpdateWindowProperties that it should preserve certain window styles (perhaps via WindowProperties struct, a field, a parameter, or a check within the routine itself)

fitdev added a commit to fitdev/Avalonia that referenced this issue Jun 18, 2024
Restore WS_CHILD window style for embedded windows.
Should fix: AvaloniaUI#16048
@fitdev
Copy link
Contributor Author

fitdev commented Jun 18, 2024

Submitted PR. Can someone review it please? @timunie , @maxkatz6

@fitdev fitdev linked a pull request Jun 18, 2024 that will close this issue
3 tasks
@fitdev fitdev reopened this Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants