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

Remove Xaml from windows crate #1836

Merged
merged 2 commits into from
Jun 21, 2022
Merged

Remove Xaml from windows crate #1836

merged 2 commits into from
Jun 21, 2022

Conversation

kennykerr
Copy link
Collaborator

Much like the windows-sys crate (#1797), the windows crate no longer includes the Xaml APIs by default since they are largely unusable anyway and take up a lot of space. Xaml is designed squarely for C# developers and there are currently no plans to provide a Rust-friendly version of Xaml (microsoft/microsoft-ui-xaml#2488). This just removes Xaml's WinRT APIs to reduce the overall size of the windows crate.

@Alovchin91
Copy link
Contributor

Hi @kennykerr, I wonder what would that mean for Windows App SDK and particularly WinUI 3 support? C++/WinRT can author WinUI 3 apps, so I guess it's not entirely a C#-only story 🤔

@kennykerr
Copy link
Collaborator Author

Hi kennykerr, I wonder what would that mean for Windows App SDK and particularly WinUI 3 support?

Those are not Windows APIs and are thus not included in the windows crate. Experimental support for those APIs is provided by windows-app-rs. Of course, the windows crate still provides the underlying type system support to even make that possible.

C++/WinRT can author WinUI 3 apps, so I guess it's not entirely a C#-only story 🤔

C# is what Xaml is designed for. C++/WinRT goes to great lengths to support Xaml and act like C# in many ways to try and smooth things over, but even then the developer experience is a far cry from that of C#.

@kennykerr kennykerr merged commit b8d83c2 into master Jun 21, 2022
@kennykerr kennykerr deleted the sans-xaml branch June 21, 2022 14:59
@mwcampbell
Copy link

@kennykerr Would you consider bringing back this projection as a separate crate? There may be big missing features, like the ability to subclass XAML elements, and it may be necessary to construct the UI purely in code rather than markup. But some app developers may tolerate these problems in order to produce a native, memory-efficient (because Windows.UI.Xaml.dll is already in the working set of any Windows 10+ machine) UI that's also modern (i.e. not GDI-based).

Of course, another option would be to implement the UI in C++ using C++/WinRT, then bridge between that and Rust using something like the cxx crate. But bridging languages always adds complexity, and some developers (myself included) may prefer the tedium of constructing a UI purely in code over the complexity of bridging languages.

@riverar
Copy link
Collaborator

riverar commented Jun 22, 2022

Inbox WinRT Xaml is in maintenence mode, I wouldn't recommend it for any new development. WinUI Xaml is going to be the new normal and is accessible via the windows-app crate. That said, I recognize that WinUI Xaml is also not fully usable yet (in any language) leaving devs in a bit of a pickle.

@mwcampbell
Copy link

I think discouraging app developers from using in-box WinRT XAML is a mistake. It's one of two UI frameworks that are already loaded into memory on every Windows 10+ machine, the other one being Win32 (meaning specifically user32 and GDI). At some point, Edge's WebView2 might achieve that status as well, but it's not there yet. Some of us want to develop UIs that have minimal memory footprint. But GDI+user32 has its own drawbacks, that might even be noticeable to the user, particularly on high-DPI and touch machines.

@riverar
Copy link
Collaborator

riverar commented Jun 22, 2022

A separate crate is definitely do'able, but it's not clear yet if there's any real demand for this. (WinRT XAML is near rock bottom in terms of usage across the Windows Development community and effectively zero in the Rust community. WinForms and WPF are the top two UI frameworks in use today.)

@MRahilly
Copy link

MRahilly commented Jun 28, 2022

WinRT core app remains. App support without the cabling tangle that Xaml brings from .NET.

@ghost
Copy link

ghost commented Jul 13, 2022

Would it be possible to restore XAML support to this crate until such time as the separate WinRT XAML crate is ready, so as to not break existing codebases which wish to obtain the latest fixes? This decision leaves multiple projects at my organization stuck with poor options like not getting patches or maintaining a fork.

@kennykerr
Copy link
Collaborator Author

@mattelkinsTC Please open an issue or email me and help me understand the value proposition. Although I plumbed in support for the Xaml type system, my impression is that Xaml is not a viable option but I'm happy to hear otherwise. I just don't have any data to show that anyone is seriously using Xaml with Rust.

@youknowone
Copy link

Hi, I don't think we would ever it for end user production, but we are depending on UI::Xaml for our in-house utility. We decide to stick on 0.37.0 for a while not to break it.

@sotanakamura
Copy link

sotanakamura commented May 20, 2023

@kennykerr How about accessing Xaml API without Xaml? You can use all WinUI 3 controls in C++ without Xaml in the way shown in here. What you need is application implementing IXamlMetadataProvider which provide types of built-in WinUI 3 controls through XamlControlsXamlMetaDataProvider. It is needed to instantiate XamlControlsResources providing WinUI 3 theme. I think you can do the same thing in Rust.

@riverar You are probably understanding what I mentioned above. What was the problem of accessing Xaml API without Xaml? I am interested in the result of the experiment you did.

I checked xaml sample in Rust, but I couldn' t find XamlControlsXamlMetaDataProvider

@sotanakamura
Copy link

The following sample program can show a ColorPicker control with WinUI 3 theme even though it is considered as impossible in microsoft/windows-app-rs#50 (comment). The sample is here. I can run it by debugging in VS code with CodeLLBD. When I run it with cargo run, it crashed.

This approach allow us to use all WinUI 3 controls with Fluent design. It makes us happy.

I have no experience of Rust, so I cannot do any more, but you can do it well because you know Rust well. Please try it!

use std::cell::RefCell;
use windows::core::IInspectable;
use windows::core::implement;
use windows::Foundation::Collections::IVector;
use windows::UI::Xaml::Interop::TypeName;
use windows_app::bootstrap;
use windows_app::Microsoft::UI::Xaml::Application;
use windows_app::Microsoft::UI::Xaml::IApplicationOverrides;
use windows_app::Microsoft::UI::Xaml::IApplicationOverrides_Impl;
use windows_app::Microsoft::UI::Xaml::ApplicationInitializationCallback;
use windows_app::Microsoft::UI::Xaml::Markup::IXamlMetadataProvider_Impl;
use windows_app::Microsoft::UI::Xaml::Window;
use windows_app::Microsoft::UI::Xaml::ResourceDictionary;
use windows_app::Microsoft::UI::Xaml::LaunchActivatedEventArgs;
use windows_app::Microsoft::UI::Xaml::Controls::XamlControlsResources;
use windows_app::Microsoft::UI::Xaml::Controls::ColorPicker;
use windows_app::Microsoft::UI::Xaml::Controls::RatingControl;
use windows_app::Microsoft::UI::Xaml::Controls::ToggleSplitButton;
use windows_app::Microsoft::UI::Xaml::Markup::XmlnsDefinition;
use windows_app::Microsoft::UI::Xaml::Markup::IXamlMetadataProvider;
use windows_app::Microsoft::UI::Xaml::XamlTypeInfo::XamlControlsXamlMetaDataProvider;

#[implement(IApplicationOverrides,IXamlMetadataProvider)]
struct App {
    window: RefCell<Option<Window>>,
    provider: XamlControlsXamlMetaDataProvider
}

#[allow(non_snake_case)]
impl App {
    fn new() -> windows::core::Result<App> {
        let app = App {
            window: RefCell::new(None),
            provider: XamlControlsXamlMetaDataProvider::new()?
        };
        Ok(app)
    }
}

impl IApplicationOverrides_Impl for App {
    fn OnLaunched(&self, _: &Option<LaunchActivatedEventArgs>) -> windows::core::Result<()> {
        Application::Current()?.Resources()?.MergedDictionaries()?.Append(XamlControlsResources::new()?);
        let window = Window::new()?;
        window.SetContent(ColorPicker::new()?);

        let result = window.Activate();
        *self.window.borrow_mut() = Some(window);
        result
    }
}

impl IXamlMetadataProvider_Impl for App{
    fn GetXamlType(&self,r#type: &TypeName,) ->  windows::core::Result<windows_app::Microsoft::UI::Xaml::Markup::IXamlType> {
        self.provider.GetXamlType(r#type)
    }
    
    fn GetXamlTypeByFullName(&self,fullname: &windows::core::HSTRING,) ->  windows::core::Result<windows_app::Microsoft::UI::Xaml::Markup::IXamlType> {
        self.provider.GetXamlTypeByFullName(fullname)
    }
    
    fn GetXmlnsDefinitions(&self,) ->  windows::core::Result<windows::core::Array<XmlnsDefinition>> {
        self.provider.GetXmlnsDefinitions()
    }
}

fn main() -> windows::core::Result<()> {
    bootstrap::initialize()?;

    Application::Start(ApplicationInitializationCallback::new(|_| {
        let _ = Application::compose(App::new()?)?;
        Ok(())
    }))?;

    bootstrap::uninitialize()
}

@kennykerr
Copy link
Collaborator Author

I'm familiar - I wrote a C++ prototype years ago here https://github.com/kennykerr/binding and demoed it here
https://youtu.be/X41j_gzSwOY?t=2661

It just isn't very practical or efficient without improvements to Xaml itself.

@sotanakamura
Copy link

It just isn't very practical or efficient without improvements to Xaml itself.

I agree with you, but we cannot wait for it. Please remain the option to create WinUI 3 apps without Xaml. I think Xaml integration will be improved in the future and the way will change (C++/WinRT still uses IDL for UIs and it will be removed in the future as shown in your demo). The accessing WinUI APIs directly from code won't change in the future because it is stable. We can enjoy with WinUI 3 in that way until Xaml improvements will come.

@riverar
Copy link
Collaborator

riverar commented May 20, 2023

Hi @sotanakamura,

@kennykerr [...] What you need is application implementing IXamlMetadataProvider which provide types of built-in WinUI 3 controls through XamlControlsXamlMetaDataProvider. It is needed to instantiate XamlControlsResources providing WinUI 3 theme. I think you can do the same thing in Rust.

@riverar You are probably understanding what I mentioned above. What was the problem of accessing Xaml API without Xaml? I am interested in the result of the experiment you did.

We quickly discovered that implementing IXamlMetadataProvider and instantiating XamlControlsXamlMetaDataProvider was not enough. WinUI has undocumented behavior and makes undocumented assumptions about its host process. (XAML only truly supports MSBuild+C#.) Finding and adjusting for those quirks--that changed between WinUI 3 releases--through trial and error was wasting everyone's time.

For example: One day, a control would appear to be working, only to later crash in the WinUI stack. I would then spend days and weeks, without source code access, trying to understand why. We would then tweak the crate and repeat. It became clear that it was an unsustainable process and the crate would never move beyond a science experiment without XAML team involvement. Those teams have refused to get involved. And the Windows App SDK team has also yet to deliver on their promise of WinUI 3 source code, making it difficult for the community to pick up this work.

The following sample program can show a ColorPicker control with WinUI 3 theme even though it is considered as impossible in microsoft/windows-app-rs#50 (comment). The sample is here. I can run it by debugging in VS code with CodeLLBD. When I run it with cargo run, it crashed.

No one said it was "impossible".

One possible reason for your crash is that your executable has an incomplete fusion manifest. This is not supported by the Windows App Runtime and the app will never truly work correctly. We did add support in both the windows and windows-app crates to accomidate the WinRT activation scheme used...

I think the sustainable 🌿 way forward is to throw away XAML and build on top of DirectComposition. That's a gargantuian effort and not something folks are working on at this time. (I can't officially speak for what Microsoft is working on internally, but I can assure you it's not this.)

@sotanakamura
Copy link

@riverar Thank you for providing many information. I just enjoyed experimenting it. I would apologize if sharing the sample will occur confusion and wasting a time.

Windows Runtime API should be used from any language. I think it is good WinUI api is used eaily from any language. If Xaml disturb it, I am sad. I hope it will be good in the future in some way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants