Skip to content

WinUIBackend: Sheets have default padding #660

Description

@stackotter

#658 implemented support for sheets in WinUIBackend. It explicitly left this issue as a future direction.

The issue is that ContentDialogs have default 24 pixel padding all the way around their content. To remove that padding, we must set the ContentDialogPadding theme resource to a custom thickness value, which sounds simple in theory, but is rather tricky in practice due to swift-winrt limitations.

The main swift-winrt limitation is that it can't properly box arbitrary value types. It attempts to (with AnyWrapper) but its existing implementation doesn't appear to work for types other than those that can be directly represented by an IPropertyValue object. I've spent many many hours attempting to solve that limitation, but so far I've come up empty handed.

Latest attempt

I've posted a half-baked implementation on the stackotter/remove_winui_sheet_padding branch.

The changes on that branch rely on some handwritten swift-winui changes as well (which should eventually be addressed in the swift-winrt projections generator). They don't appear to be working yet, but the basic idea is there;

diff --git a/Sources/WinUI/Generated/WinUI+Generics.swift b/Sources/WinUI/Generated/WinUI+Generics.swift
index 71b516b..a5a9a69 100644
--- a/Sources/WinUI/Generated/WinUI+Generics.swift
+++ b/Sources/WinUI/Generated/WinUI+Generics.swift
@@ -10600,8 +10600,25 @@ internal class IMapAny_Any: WindowsFoundation.IInspectable {
         var result: boolean = 0
         let keyWrapper = __ABI_.AnyWrapper(key)
         let _key = try! keyWrapper?.toABI { $0 }
-        let valueWrapper = __ABI_.AnyWrapper(value)
-        let _value = try! valueWrapper?.toABI { $0 }
+        let _value: UnsafeMutablePointer<C_IInspectable>?
+        if let value {
+            print("\(value), \(type(of: value))")
+            print("\(value is IWinRTObject)")
+        }
+        var valueWrapper: Any?
+        if let value, let object = value as? IWinRTObject {
+            print("Using IWinRTObject ABI")
+            _value = object.thisPtr.pUnk.borrow.withMemoryRebound(
+                to: C_IInspectable.self,
+                capacity: 1
+            ) { $0 }
+        } else {
+            print("Using AnyWrapper")
+            print("\(type(of: value))")
+            let wrapper = __ABI_.AnyWrapper(value)
+            _value = try! wrapper?.toABI { $0 }
+            valueWrapper = wrapper
+        }
         _ = try perform(as: __x_ABI_C__FIMap_2_IInspectable_IInspectable.self) { pThis in
             try CHECKED(pThis.pointee.lpVtbl.pointee.Insert(pThis, _key, _value, &result))
         }
diff --git a/Sources/WindowsFoundation/Generated/Support/IINSPECTABLE.swift b/Sources/WindowsFoundation/Generated/Support/IINSPECTABLE.swift
index 9419096..341e64a 100644
--- a/Sources/WindowsFoundation/Generated/Support/IINSPECTABLE.swift
+++ b/Sources/WindowsFoundation/Generated/Support/IINSPECTABLE.swift
@@ -47,7 +47,7 @@ public enum __ABI_ {
     public class AnyWrapper : WinRTWrapperBase<C_IInspectable, AnyObject> {
       public init?(_ swift: Any?) {
         guard let swift else { return nil }
-         if let propertyValue = PropertyValue.createFrom(swift) {
+        if let propertyValue = PropertyValue.createFrom(swift) {^M
           let abi: UnsafeMutablePointer<C_IInspectable> = RawPointer(propertyValue)
           super.init(abi.pointee, propertyValue)
         } else {
@@ -138,4 +138,4 @@ extension ComposableImpl where CABI == C_IInspectable {
     let vtblPtr = withUnsafeMutablePointer(to: &__ABI_.IInspectableVTable) { $0 }
     return .init(lpVtbl: vtblPtr)
   }
-}
\ No newline at end of file
+}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions