Skip to content

Proposal: A ThousandIslands Window for Easy Interoperability and Migration #10050

@softworkz

Description

@softworkz

Proposal: ThousandIslands Window

TL/DR

This is about hosting Win32 Islands like WinForms, WPF, ActiveX, ATL, MFC inside a WinUI3 application.

Primer

About "Modernize your applications with WinUI3"

This tag line can be found on many different places these days and I'm inclined to say that - per se - it's a good one.
But once you follow, you always get to the same kind of suggestions, which are about using XAML islands for integrating newly developed WinUI3 content/controls in existing applications. Each time I come across those topics, it appears kind of alienating to me, because it doesn't quite match reality. There are basically two ways for migrating to a new UI framework:

  1. Switch to the new framework and include legacy elements (until migrated)
    🡆 The typical mainstream way
  2. Stick to the legacy framework and include some elements done in the new framework
    🡆 Makes sense for niche cases only

I won't elaborate further on this classification for now, other than this: "modernizing" usually implies getting a fresh new look and this cannot only be achieved with (1), not with (2). When you put effort into some migration effort, you typically want some visual advancements and with (2), you just create visual weirdness.

Developer Acceptance and Adoption

I can only wonder why the focus on migration paths is so strongly fixated on (2).
Surely, XAML Islands are a good thing and also a useful building block for (1). but as of now, I am seeing ZERO effort on enabling (1) in any way.

And that's weird, because I think this is among the top blockers (if not THE top blocking reason) for delopers migrating to WinUI3:

"Can we integrate our existing UI components (win32, WinForms, WPF) when we migrate to WinUI3?"

As long as the answer is "no", I don't think that WinUI3 will ever achieve a level of adoption that is even close to the other frameworks.

 

The Current Situation

Many developers have tried to include Win32 windows in WinUI3 applications already - and failed. At least eventually at the point where it comes to input processing: it's possible to show something in a child window but it's not possible to get input working properly (keyboard, mouse, pointer).

Why is that so?

First, we need to understand how XAML islands are working: A XAML Island is basically a Win32 window in which the XAML content is sited. To build a XAML Island, you create a Win32 window first and then you use DesktopWindowXamlSource to have your XAML rendered (and available for interaction) inside that Win32 window.
This allows to host one or more XAML Islands inside another application - in a way that it's cooperative with regards to input focus management and input processing. You can switch input focus back and forther between non-WinUI3 XAML content, XAML content and from one to another XAML content. This functionality already exists (InputFocusController.

So what's wrong, why can't we use that to embed arbitrary Win32 controls in our WinUI3 app?

The Culprit: Microsoft.UI.Xaml.Window

When we create a default plain WinUI3 application (as of WASDK 1.6), we get the following window hierarchy:

image

A WinUI3 window forms a ContentIsland itself (you can retrieve it like this: ContentIsland.FindAllForCompositor(this.Compositor).First()).
And as we have learned: A content island consists of a hWnd window and a DesktopChildSiteBridge as a child. And that's the important part:

The DesktopChildSiteBridge IS NOT the XAML island.
The XAML island is the top-level window itself (WinUIDesktopWin32WindowClass).

And here it becomes clear why all those attempts of adding custom Win32 windows as children of the window never worked out well:

This way, you are essentially putting content INSIDE an existing island and hence it's no wonder that none of the interoperability mechanisms is working.

The Proposal: Microsoft.UI.Xaml.MultiIslandWindow

The MultiIslandWindow class should be very similar to the existing Window class, just with some important differences:

  • The XAML desktop island is not rooted directly to the AppWindow
    Instead, there's an intermediate Win32 window (direct child of the AppWindow, same size) for hosting the XAML content
  • Large parts of the subclassing (window message processing) that JupiterWindow is currently performing on the AppWindow is performed on the intermediate Win32 window instead, so that the AppWindow will no longer block input messages flowing to (non-WinUI3) child windows
    (I say "large parts", because certain processing like activation, closing, non-client messages might need to remain to be done on the AppWindow directly)

This will essentially allow developers to include ContentIslands from other sources and UI frameworks in a WinUI3 application.

 

Follow-Up Proposals

  • Extending APIs to manage ContentSites with non-xaml content
    for example with InputFocusController
  • Provide a HwndHost XAML control for easy integration in your XAML layouts
    (that content will just "fly above" the XAML content)
  • Possible derivatives of the HwndHost control:
    • WinFormsHost control
    • WpfContentHost control
  • Provide a XamlIslandHost XAML control for including a XamlIsland in a XAML layout
    (this will in turn allow to have XAML content "above" some other Hwnd content)

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature proposalNew feature proposalneeds-triageIssue needs to be triaged by the area owners

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions