diff --git a/src/Uno.UI.Runtime.Skia.X11/DBus/Desktop.DBus.cs b/src/Uno.UI.Runtime.Skia.X11/DBus/Desktop.DBus.cs new file mode 100644 index 000000000000..89d592815de9 --- /dev/null +++ b/src/Uno.UI.Runtime.Skia.X11/DBus/Desktop.DBus.cs @@ -0,0 +1,2465 @@ +// Generated using `dotnet dbus codegen --protocol-api --bus session --service org.freedesktop.portal.Desktop` +// and `dotnet dbus codegen --protocol-api /usr/share/dbus-1/interfaces/org.freedesktop.portal.Request.xml` +// then copying the relevant parts of the latter into the former. +// Arch Linux's xdg-desktop-portal package v1.18.4-1 +// tmds.dbus.tool 0.21.2 + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Tmds.DBus.Protocol; + +namespace Uno.WinUI.Runtime.Skia.X11.DBus +{ + // From https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html#signals + enum Response : uint + { + Success = 0, + UserCancelled = 1, + Other = 2 + } + + record InhibitProperties + { + public uint Version { get; set; } = default!; + } + partial class Inhibit : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Inhibit"; + public Inhibit(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task InhibitAsync(string window, uint flags, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sua{sv}", + member: "Inhibit"); + writer.WriteString(window); + writer.WriteUInt32(flags); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task CreateMonitorAsync(string window, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "CreateMonitor"); + writer.WriteString(window); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task QueryEndResponseAsync(ObjectPath sessionHandle) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "o", + member: "QueryEndResponse"); + writer.WriteObjectPath(sessionHandle); + return writer.CreateMessage(); + } + } + public ValueTask WatchStateChangedAsync(Action State)> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "StateChanged", (Message m, object? s) => ReadMessage_oaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static InhibitProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static InhibitProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new InhibitProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record LocationProperties + { + public uint Version { get; set; } = default!; + } + partial class Location : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Location"; + public Location(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task CreateSessionAsync(Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "a{sv}", + member: "CreateSession"); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task StartAsync(ObjectPath sessionHandle, string parentWindow, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "osa{sv}", + member: "Start"); + writer.WriteObjectPath(sessionHandle); + writer.WriteString(parentWindow); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public ValueTask WatchLocationUpdatedAsync(Action Location)> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "LocationUpdated", (Message m, object? s) => ReadMessage_oaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static LocationProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static LocationProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new LocationProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record NotificationProperties + { + public uint Version { get; set; } = default!; + } + partial class Notification : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Notification"; + public Notification(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task AddNotificationAsync(string id, Dictionary notification) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "AddNotification"); + writer.WriteString(id); + writer.WriteDictionary(notification); + return writer.CreateMessage(); + } + } + public Task RemoveNotificationAsync(string id) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "s", + member: "RemoveNotification"); + writer.WriteString(id); + return writer.CreateMessage(); + } + } + public ValueTask WatchActionInvokedAsync(Action handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "ActionInvoked", (Message m, object? s) => ReadMessage_ssav(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static NotificationProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static NotificationProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new NotificationProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record AccountProperties + { + public uint Version { get; set; } = default!; + } + partial class Account : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Account"; + public Account(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task GetUserInformationAsync(string window, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "GetUserInformation"); + writer.WriteString(window); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static AccountProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static AccountProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new AccountProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record NetworkMonitorProperties + { + public uint Version { get; set; } = default!; + } + partial class NetworkMonitor : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.NetworkMonitor"; + public NetworkMonitor(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task GetAvailableAsync() + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_b(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + member: "GetAvailable"); + return writer.CreateMessage(); + } + } + public Task GetMeteredAsync() + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_b(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + member: "GetMetered"); + return writer.CreateMessage(); + } + } + public Task GetConnectivityAsync() + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_u(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + member: "GetConnectivity"); + return writer.CreateMessage(); + } + } + public Task> GetStatusAsync() + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_aesv(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + member: "GetStatus"); + return writer.CreateMessage(); + } + } + public Task CanReachAsync(string hostname, uint port) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_b(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "su", + member: "CanReach"); + writer.WriteString(hostname); + writer.WriteUInt32(port); + return writer.CreateMessage(); + } + } + public ValueTask WatchChangedAsync(Action handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "changed", handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static NetworkMonitorProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static NetworkMonitorProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new NetworkMonitorProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record PrintProperties + { + public uint Version { get; set; } = default!; + } + partial class Print : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Print"; + public Print(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task PrintAsync(string parentWindow, string title, System.Runtime.InteropServices.SafeHandle fd, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssha{sv}", + member: "Print"); + writer.WriteString(parentWindow); + writer.WriteString(title); + writer.WriteHandle(fd); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task PreparePrintAsync(string parentWindow, string title, Dictionary settings, Dictionary pageSetup, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssa{sv}a{sv}a{sv}", + member: "PreparePrint"); + writer.WriteString(parentWindow); + writer.WriteString(title); + writer.WriteDictionary(settings); + writer.WriteDictionary(pageSetup); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static PrintProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static PrintProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new PrintProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record SettingsProperties + { + public uint Version { get; set; } = default!; + } + partial class Settings : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Settings"; + public Settings(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task>> ReadAllAsync(string[] namespaces) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_aesaesv(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "as", + member: "ReadAll"); + writer.WriteArray(namespaces); + return writer.CreateMessage(); + } + } + public Task ReadAsync(string @namespace, string key) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_v(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ss", + member: "Read"); + writer.WriteString(@namespace); + writer.WriteString(key); + return writer.CreateMessage(); + } + } + public Task ReadOneAsync(string @namespace, string key) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_v(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ss", + member: "ReadOne"); + writer.WriteString(@namespace); + writer.WriteString(key); + return writer.CreateMessage(); + } + } + public ValueTask WatchSettingChangedAsync(Action handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "SettingChanged", (Message m, object? s) => ReadMessage_ssv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static SettingsProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static SettingsProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new SettingsProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record GameModeProperties + { + public bool Active { get; set; } = default!; + public uint Version { get; set; } = default!; + } + partial class GameMode : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.GameMode"; + public GameMode(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task QueryStatusAsync(int pid) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "i", + member: "QueryStatus"); + writer.WriteInt32(pid); + return writer.CreateMessage(); + } + } + public Task RegisterGameAsync(int pid) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "i", + member: "RegisterGame"); + writer.WriteInt32(pid); + return writer.CreateMessage(); + } + } + public Task UnregisterGameAsync(int pid) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "i", + member: "UnregisterGame"); + writer.WriteInt32(pid); + return writer.CreateMessage(); + } + } + public Task QueryStatusByPidAsync(int target, int requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ii", + member: "QueryStatusByPid"); + writer.WriteInt32(target); + writer.WriteInt32(requester); + return writer.CreateMessage(); + } + } + public Task RegisterGameByPidAsync(int target, int requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ii", + member: "RegisterGameByPid"); + writer.WriteInt32(target); + writer.WriteInt32(requester); + return writer.CreateMessage(); + } + } + public Task UnregisterGameByPidAsync(int target, int requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ii", + member: "UnregisterGameByPid"); + writer.WriteInt32(target); + writer.WriteInt32(requester); + return writer.CreateMessage(); + } + } + public Task QueryStatusByPIDFdAsync(System.Runtime.InteropServices.SafeHandle target, System.Runtime.InteropServices.SafeHandle requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "hh", + member: "QueryStatusByPIDFd"); + writer.WriteHandle(target); + writer.WriteHandle(requester); + return writer.CreateMessage(); + } + } + public Task RegisterGameByPIDFdAsync(System.Runtime.InteropServices.SafeHandle target, System.Runtime.InteropServices.SafeHandle requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "hh", + member: "RegisterGameByPIDFd"); + writer.WriteHandle(target); + writer.WriteHandle(requester); + return writer.CreateMessage(); + } + } + public Task UnregisterGameByPIDFdAsync(System.Runtime.InteropServices.SafeHandle target, System.Runtime.InteropServices.SafeHandle requester) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_i(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "hh", + member: "UnregisterGameByPIDFd"); + writer.WriteHandle(target); + writer.WriteHandle(requester); + return writer.CreateMessage(); + } + } + public Task GetActiveAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "Active"), (Message m, object? s) => ReadMessage_v_b(m, (DesktopObject)s!), this); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static GameModeProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "Active": invalidated.Add("Active"); break; + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static GameModeProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new GameModeProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "Active": + reader.ReadSignature("b"u8); + props.Active = reader.ReadBool(); + changedList?.Add("Active"); + break; + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record MemoryMonitorProperties + { + public uint Version { get; set; } = default!; + } + partial class MemoryMonitor : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.MemoryMonitor"; + public MemoryMonitor(DesktopService service, ObjectPath path) : base(service, path) + { } + public ValueTask WatchLowMemoryWarningAsync(Action handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "LowMemoryWarning", (Message m, object? s) => ReadMessage_y(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static MemoryMonitorProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static MemoryMonitorProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new MemoryMonitorProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record OpenURIProperties + { + public uint Version { get; set; } = default!; + } + partial class OpenURI : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.OpenURI"; + public OpenURI(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task OpenURIAsync(string parentWindow, string uri, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssa{sv}", + member: "OpenURI"); + writer.WriteString(parentWindow); + writer.WriteString(uri); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task OpenFileAsync(string parentWindow, System.Runtime.InteropServices.SafeHandle fd, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sha{sv}", + member: "OpenFile"); + writer.WriteString(parentWindow); + writer.WriteHandle(fd); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task OpenDirectoryAsync(string parentWindow, System.Runtime.InteropServices.SafeHandle fd, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sha{sv}", + member: "OpenDirectory"); + writer.WriteString(parentWindow); + writer.WriteHandle(fd); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static OpenURIProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static OpenURIProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new OpenURIProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record RealtimeProperties + { + public int MaxRealtimePriority { get; set; } = default!; + public int MinNiceLevel { get; set; } = default!; + public long RTTimeUSecMax { get; set; } = default!; + public uint Version { get; set; } = default!; + } + partial class Realtime : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Realtime"; + public Realtime(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task MakeThreadRealtimeWithPIDAsync(ulong process, ulong thread, uint priority) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ttu", + member: "MakeThreadRealtimeWithPID"); + writer.WriteUInt64(process); + writer.WriteUInt64(thread); + writer.WriteUInt32(priority); + return writer.CreateMessage(); + } + } + public Task MakeThreadHighPriorityWithPIDAsync(ulong process, ulong thread, int priority) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "tti", + member: "MakeThreadHighPriorityWithPID"); + writer.WriteUInt64(process); + writer.WriteUInt64(thread); + writer.WriteInt32(priority); + return writer.CreateMessage(); + } + } + public Task GetMaxRealtimePriorityAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "MaxRealtimePriority"), (Message m, object? s) => ReadMessage_v_i(m, (DesktopObject)s!), this); + public Task GetMinNiceLevelAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "MinNiceLevel"), (Message m, object? s) => ReadMessage_v_i(m, (DesktopObject)s!), this); + public Task GetRTTimeUSecMaxAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "RTTimeUSecMax"), (Message m, object? s) => ReadMessage_v_x(m, (DesktopObject)s!), this); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static RealtimeProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "MaxRealtimePriority": invalidated.Add("MaxRealtimePriority"); break; + case "MinNiceLevel": invalidated.Add("MinNiceLevel"); break; + case "RTTimeUSecMax": invalidated.Add("RTTimeUSecMax"); break; + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static RealtimeProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new RealtimeProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "MaxRealtimePriority": + reader.ReadSignature("i"u8); + props.MaxRealtimePriority = reader.ReadInt32(); + changedList?.Add("MaxRealtimePriority"); + break; + case "MinNiceLevel": + reader.ReadSignature("i"u8); + props.MinNiceLevel = reader.ReadInt32(); + changedList?.Add("MinNiceLevel"); + break; + case "RTTimeUSecMax": + reader.ReadSignature("x"u8); + props.RTTimeUSecMax = reader.ReadInt64(); + changedList?.Add("RTTimeUSecMax"); + break; + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record DynamicLauncherProperties + { + public uint SupportedLauncherTypes { get; set; } = default!; + public uint Version { get; set; } = default!; + } + partial class DynamicLauncher : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.DynamicLauncher"; + public DynamicLauncher(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task InstallAsync(string token, string desktopFileId, string desktopEntry, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sssa{sv}", + member: "Install"); + writer.WriteString(token); + writer.WriteString(desktopFileId); + writer.WriteString(desktopEntry); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task PrepareInstallAsync(string parentWindow, string name, VariantValue iconV, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssva{sv}", + member: "PrepareInstall"); + writer.WriteString(parentWindow); + writer.WriteString(name); + writer.WriteVariant(iconV); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task RequestInstallTokenAsync(string name, VariantValue iconV, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_s(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sva{sv}", + member: "RequestInstallToken"); + writer.WriteString(name); + writer.WriteVariant(iconV); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task UninstallAsync(string desktopFileId, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "Uninstall"); + writer.WriteString(desktopFileId); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetDesktopEntryAsync(string desktopFileId) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_s(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "s", + member: "GetDesktopEntry"); + writer.WriteString(desktopFileId); + return writer.CreateMessage(); + } + } + public Task<(VariantValue IconV, string IconFormat, uint IconSize)> GetIconAsync(string desktopFileId) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_vsu(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "s", + member: "GetIcon"); + writer.WriteString(desktopFileId); + return writer.CreateMessage(); + } + } + public Task LaunchAsync(string desktopFileId, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "Launch"); + writer.WriteString(desktopFileId); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetSupportedLauncherTypesAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "SupportedLauncherTypes"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static DynamicLauncherProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "SupportedLauncherTypes": invalidated.Add("SupportedLauncherTypes"); break; + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static DynamicLauncherProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new DynamicLauncherProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "SupportedLauncherTypes": + reader.ReadSignature("u"u8); + props.SupportedLauncherTypes = reader.ReadUInt32(); + changedList?.Add("SupportedLauncherTypes"); + break; + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record CameraProperties + { + public bool IsCameraPresent { get; set; } = default!; + public uint Version { get; set; } = default!; + } + partial class Camera : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Camera"; + public Camera(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task AccessCameraAsync(Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "a{sv}", + member: "AccessCamera"); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task OpenPipeWireRemoteAsync(Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_h(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "a{sv}", + member: "OpenPipeWireRemote"); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetIsCameraPresentAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "IsCameraPresent"), (Message m, object? s) => ReadMessage_v_b(m, (DesktopObject)s!), this); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static CameraProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "IsCameraPresent": invalidated.Add("IsCameraPresent"); break; + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static CameraProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new CameraProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "IsCameraPresent": + reader.ReadSignature("b"u8); + props.IsCameraPresent = reader.ReadBool(); + changedList?.Add("IsCameraPresent"); + break; + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record DeviceProperties + { + public uint Version { get; set; } = default!; + } + partial class Device : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Device"; + public Device(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task AccessDeviceAsync(uint pid, string[] devices, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "uasa{sv}", + member: "AccessDevice"); + writer.WriteUInt32(pid); + writer.WriteArray(devices); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static DeviceProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static DeviceProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new DeviceProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record PowerProfileMonitorProperties + { + public bool PowerSaverEnabled { get; set; } = default!; + public uint Version { get; set; } = default!; + } + partial class PowerProfileMonitor : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.PowerProfileMonitor"; + public PowerProfileMonitor(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task GetPowerSaverEnabledAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "power-saver-enabled"), (Message m, object? s) => ReadMessage_v_b(m, (DesktopObject)s!), this); + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static PowerProfileMonitorProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "power-saver-enabled": invalidated.Add("PowerSaverEnabled"); break; + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static PowerProfileMonitorProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new PowerProfileMonitorProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "power-saver-enabled": + reader.ReadSignature("b"u8); + props.PowerSaverEnabled = reader.ReadBool(); + changedList?.Add("PowerSaverEnabled"); + break; + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record EmailProperties + { + public uint Version { get; set; } = default!; + } + partial class Email : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Email"; + public Email(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task ComposeEmailAsync(string parentWindow, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "sa{sv}", + member: "ComposeEmail"); + writer.WriteString(parentWindow); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static EmailProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static EmailProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new EmailProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record TrashProperties + { + public uint Version { get; set; } = default!; + } + partial class Trash : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Trash"; + public Trash(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task TrashFileAsync(System.Runtime.InteropServices.SafeHandle fd) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_u(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "h", + member: "TrashFile"); + writer.WriteHandle(fd); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static TrashProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static TrashProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new TrashProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record ProxyResolverProperties + { + public uint Version { get; set; } = default!; + } + partial class ProxyResolver : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.ProxyResolver"; + public ProxyResolver(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task LookupAsync(string uri) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_as(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "s", + member: "Lookup"); + writer.WriteString(uri); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static ProxyResolverProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static ProxyResolverProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new ProxyResolverProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + record FileChooserProperties + { + public uint Version { get; set; } = default!; + } + partial class FileChooser : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.FileChooser"; + public FileChooser(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task OpenFileAsync(string parentWindow, string title, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssa{sv}", + member: "OpenFile"); + writer.WriteString(parentWindow); + writer.WriteString(title); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task SaveFileAsync(string parentWindow, string title, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssa{sv}", + member: "SaveFile"); + writer.WriteString(parentWindow); + writer.WriteString(title); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task SaveFilesAsync(string parentWindow, string title, Dictionary options) + { + return this.Connection.CallMethodAsync(CreateMessage(), (Message m, object? s) => ReadMessage_o(m, (DesktopObject)s!), this); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + signature: "ssa{sv}", + member: "SaveFiles"); + writer.WriteString(parentWindow); + writer.WriteString(title); + writer.WriteDictionary(options); + return writer.CreateMessage(); + } + } + public Task GetVersionAsync() + => this.Connection.CallMethodAsync(CreateGetPropertyMessage(__Interface, "version"), (Message m, object? s) => ReadMessage_v_u(m, (DesktopObject)s!), this); + public Task GetPropertiesAsync() + { + return this.Connection.CallMethodAsync(CreateGetAllPropertiesMessage(__Interface), (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), this); + static FileChooserProperties ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadProperties(ref reader); + } + } + public ValueTask WatchPropertiesChangedAsync(Action> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + { + return base.WatchPropertiesChangedAsync(__Interface, (Message m, object? s) => ReadMessage(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + static PropertyChanges ReadMessage(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadString(); // interface + List changed = new(), invalidated = new(); + return new PropertyChanges(ReadProperties(ref reader, changed), ReadInvalidated(ref reader), changed.ToArray()); + } + static string[] ReadInvalidated(ref Reader reader) + { + List? invalidated = null; + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.String); + while (reader.HasNext(arrayEnd)) + { + invalidated ??= new(); + var property = reader.ReadString(); + switch (property) + { + case "version": invalidated.Add("Version"); break; + } + } + return invalidated?.ToArray() ?? Array.Empty(); + } + } + private static FileChooserProperties ReadProperties(ref Reader reader, List? changedList = null) + { + var props = new FileChooserProperties(); + ArrayEnd arrayEnd = reader.ReadArrayStart(DBusType.Struct); + while (reader.HasNext(arrayEnd)) + { + var property = reader.ReadString(); + switch (property) + { + case "version": + reader.ReadSignature("u"u8); + props.Version = reader.ReadUInt32(); + changedList?.Add("Version"); + break; + default: + reader.ReadVariantValue(); + break; + } + } + return props; + } + } + partial class DesktopService + { + public Tmds.DBus.Protocol.Connection Connection { get; } + public string Destination { get; } + public DesktopService(Tmds.DBus.Protocol.Connection connection, string destination) + => (Connection, Destination) = (connection, destination); + public Inhibit CreateInhibit(ObjectPath path) => new Inhibit(this, path); + public Location CreateLocation(ObjectPath path) => new Location(this, path); + public Notification CreateNotification(ObjectPath path) => new Notification(this, path); + public Account CreateAccount(ObjectPath path) => new Account(this, path); + public NetworkMonitor CreateNetworkMonitor(ObjectPath path) => new NetworkMonitor(this, path); + public Print CreatePrint(ObjectPath path) => new Print(this, path); + public Settings CreateSettings(ObjectPath path) => new Settings(this, path); + public GameMode CreateGameMode(ObjectPath path) => new GameMode(this, path); + public MemoryMonitor CreateMemoryMonitor(ObjectPath path) => new MemoryMonitor(this, path); + public OpenURI CreateOpenURI(ObjectPath path) => new OpenURI(this, path); + public Realtime CreateRealtime(ObjectPath path) => new Realtime(this, path); + public DynamicLauncher CreateDynamicLauncher(ObjectPath path) => new DynamicLauncher(this, path); + public Camera CreateCamera(ObjectPath path) => new Camera(this, path); + public Device CreateDevice(ObjectPath path) => new Device(this, path); + public PowerProfileMonitor CreatePowerProfileMonitor(ObjectPath path) => new PowerProfileMonitor(this, path); + public Email CreateEmail(ObjectPath path) => new Email(this, path); + public Trash CreateTrash(ObjectPath path) => new Trash(this, path); + public ProxyResolver CreateProxyResolver(ObjectPath path) => new ProxyResolver(this, path); + public FileChooser CreateFileChooser(ObjectPath path) => new FileChooser(this, path); + + public Request CreateRequest(ObjectPath path) => new Request(this, path); + } + partial class Request : DesktopObject + { + private const string __Interface = "org.freedesktop.portal.Request"; + public Request(DesktopService service, ObjectPath path) : base(service, path) + { } + public Task CloseAsync() + { + return this.Connection.CallMethodAsync(CreateMessage()); + MessageBuffer CreateMessage() + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: __Interface, + member: "Close"); + return writer.CreateMessage(); + } + } + public ValueTask WatchResponseAsync(Action Results)> handler, bool emitOnCapturedContext = true, ObserverFlags flags = ObserverFlags.None) + => base.WatchSignalAsync(Service.Destination, __Interface, Path, "Response", (Message m, object? s) => ReadMessage_uaesv(m, (DesktopObject)s!), handler, emitOnCapturedContext, flags); + } + class DesktopObject + { + public DesktopService Service { get; } + public ObjectPath Path { get; } + protected Tmds.DBus.Protocol.Connection Connection => Service.Connection; + protected DesktopObject(DesktopService service, ObjectPath path) + => (Service, Path) = (service, path); + protected MessageBuffer CreateGetPropertyMessage(string @interface, string property) + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: "org.freedesktop.DBus.Properties", + signature: "ss", + member: "Get"); + writer.WriteString(@interface); + writer.WriteString(property); + return writer.CreateMessage(); + } + protected MessageBuffer CreateGetAllPropertiesMessage(string @interface) + { + var writer = this.Connection.GetMessageWriter(); + writer.WriteMethodCallHeader( + destination: Service.Destination, + path: Path, + @interface: "org.freedesktop.DBus.Properties", + signature: "s", + member: "GetAll"); + writer.WriteString(@interface); + return writer.CreateMessage(); + } + protected ValueTask WatchPropertiesChangedAsync(string @interface, MessageValueReader> reader, Action> handler, bool emitOnCapturedContext, ObserverFlags flags) + { + var rule = new MatchRule + { + Type = MessageType.Signal, + Sender = Service.Destination, + Path = Path, + Interface = "org.freedesktop.DBus.Properties", + Member = "PropertiesChanged", + Arg0 = @interface + }; + return this.Connection.AddMatchAsync(rule, reader, + (Exception? ex, PropertyChanges changes, object? rs, object? hs) => ((Action>)hs!).Invoke(ex, changes), + this, handler, emitOnCapturedContext, flags); + } + public ValueTask WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, MessageValueReader reader, Action handler, bool emitOnCapturedContext, ObserverFlags flags) + { + var rule = new MatchRule + { + Type = MessageType.Signal, + Sender = sender, + Path = path, + Member = signal, + Interface = @interface + }; + return this.Connection.AddMatchAsync(rule, reader, + (Exception? ex, TArg arg, object? rs, object? hs) => ((Action)hs!).Invoke(ex, arg), + this, handler, emitOnCapturedContext, flags); + } + public ValueTask WatchSignalAsync(string sender, string @interface, ObjectPath path, string signal, Action handler, bool emitOnCapturedContext, ObserverFlags flags) + { + var rule = new MatchRule + { + Type = MessageType.Signal, + Sender = sender, + Path = path, + Member = signal, + Interface = @interface + }; + return this.Connection.AddMatchAsync(rule, (Message message, object? state) => null!, + (Exception? ex, object v, object? rs, object? hs) => ((Action)hs!).Invoke(ex), this, handler, emitOnCapturedContext, flags); + } + protected static ObjectPath ReadMessage_o(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadObjectPath(); + } + protected static (ObjectPath, Dictionary) ReadMessage_oaesv(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + var arg0 = reader.ReadObjectPath(); + var arg1 = reader.ReadDictionaryOfStringToVariantValue(); + return (arg0, arg1); + } + protected static uint ReadMessage_v_u(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadSignature("u"u8); + return reader.ReadUInt32(); + } + protected static (string, string, VariantValue[]) ReadMessage_ssav(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + var arg0 = reader.ReadString(); + var arg1 = reader.ReadString(); + var arg2 = reader.ReadArrayOfVariantValue(); + return (arg0, arg1, arg2); + } + protected static bool ReadMessage_b(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadBool(); + } + protected static uint ReadMessage_u(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadUInt32(); + } + protected static Dictionary ReadMessage_aesv(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadDictionaryOfStringToVariantValue(); + } + protected static Dictionary> ReadMessage_aesaesv(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return ReadType_aesaesv(ref reader); + } + protected static VariantValue ReadMessage_v(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadVariantValue(); + } + protected static (string, string, VariantValue) ReadMessage_ssv(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + var arg0 = reader.ReadString(); + var arg1 = reader.ReadString(); + var arg2 = reader.ReadVariantValue(); + return (arg0, arg1, arg2); + } + protected static int ReadMessage_i(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadInt32(); + } + protected static bool ReadMessage_v_b(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadSignature("b"u8); + return reader.ReadBool(); + } + protected static byte ReadMessage_y(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadByte(); + } + protected static int ReadMessage_v_i(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadSignature("i"u8); + return reader.ReadInt32(); + } + protected static long ReadMessage_v_x(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + reader.ReadSignature("x"u8); + return reader.ReadInt64(); + } + protected static string ReadMessage_s(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadString(); + } + protected static (VariantValue, string, uint) ReadMessage_vsu(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + var arg0 = reader.ReadVariantValue(); + var arg1 = reader.ReadString(); + var arg2 = reader.ReadUInt32(); + return (arg0, arg1, arg2); + } + protected static System.Runtime.InteropServices.SafeHandle ReadMessage_h(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadHandle()!; + } + protected static string[] ReadMessage_as(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + return reader.ReadArrayOfString(); + } + protected static (uint, Dictionary) ReadMessage_uaesv(Message message, DesktopObject _) + { + var reader = message.GetBodyReader(); + var arg0 = reader.ReadUInt32(); + var arg1 = reader.ReadDictionaryOfStringToVariantValue(); + return (arg0, arg1); + } + protected static Dictionary> ReadType_aesaesv(ref Reader reader) + { + Dictionary> dictionary = new(); + ArrayEnd dictEnd = reader.ReadDictionaryStart(); + while (reader.HasNext(dictEnd)) + { + var key = reader.ReadString(); + var value = reader.ReadDictionaryOfStringToVariantValue(); + dictionary[key] = value; + } + return dictionary; + } + } + class PropertyChanges + { + public PropertyChanges(TProperties properties, string[] invalidated, string[] changed) + => (Properties, Invalidated, Changed) = (properties, invalidated, changed); + public TProperties Properties { get; } + public string[] Invalidated { get; } + public string[] Changed { get; } + public bool HasChanged(string property) => Array.IndexOf(Changed, property) != -1; + public bool IsInvalidated(string property) => Array.IndexOf(Invalidated, property) != -1; + } +} diff --git a/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalDesktop.cs b/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalDesktop.cs deleted file mode 100644 index 13c9d5360187..000000000000 --- a/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalDesktop.cs +++ /dev/null @@ -1,745 +0,0 @@ -// Generated using `dotnet dbus codegen --bus session --service org.freedesktop.portal.Desktop` -// tmds.dbus.tool 0.16.0 -#nullable disable -#pragma warning disable CA1805 - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using Tmds.DBus; - -[assembly: InternalsVisibleTo(Connection.DynamicAssemblyName)] -namespace Uno.WinUI.Runtime.Skia.X11.Dbus -{ - [DBusInterface("org.freedesktop.portal.Inhibit")] - internal interface IInhibit : IDBusObject - { - Task InhibitAsync(string Window, uint Flags, IDictionary Options); - Task CreateMonitorAsync(string Window, IDictionary Options); - Task QueryEndResponseAsync(ObjectPath SessionHandle); - Task WatchStateChangedAsync(Action<(ObjectPath sessionHandle, IDictionary state)> handler, Action onError = null); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class InhibitProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class InhibitExtensions - { - public static Task GetVersionAsync(this IInhibit o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Location")] - internal interface ILocation : IDBusObject - { - Task CreateSessionAsync(IDictionary Options); - Task StartAsync(ObjectPath SessionHandle, string ParentWindow, IDictionary Options); - Task WatchLocationUpdatedAsync(Action<(ObjectPath sessionHandle, IDictionary location)> handler, Action onError = null); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class LocationProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class LocationExtensions - { - public static Task GetVersionAsync(this ILocation o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Account")] - internal interface IAccount : IDBusObject - { - Task GetUserInformationAsync(string Window, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class AccountProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class AccountExtensions - { - public static Task GetVersionAsync(this IAccount o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Notification")] - interface INotification : IDBusObject - { - Task AddNotificationAsync(string Id, IDictionary Notification); - Task RemoveNotificationAsync(string Id); - Task WatchActionInvokedAsync(Action<(string id, string action, object[] parameter)> handler, Action onError = null); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class NotificationProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class NotificationExtensions - { - public static Task GetVersionAsync(this INotification o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.NetworkMonitor")] - internal interface INetworkMonitor : IDBusObject - { - Task GetAvailableAsync(); - Task GetMeteredAsync(); - Task GetConnectivityAsync(); - Task> GetStatusAsync(); - Task CanReachAsync(string Hostname, uint Port); - Task WatchchangedAsync(Action handler, Action onError = null); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class NetworkMonitorProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class NetworkMonitorExtensions - { - public static Task GetVersionAsync(this INetworkMonitor o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Print")] - internal interface IPrint : IDBusObject - { - Task PrintAsync(string ParentWindow, string Title, CloseSafeHandle Fd, IDictionary Options); - Task PreparePrintAsync(string ParentWindow, string Title, IDictionary Settings, IDictionary PageSetup, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class PrintProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class PrintExtensions - { - public static Task GetVersionAsync(this IPrint o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.GameMode")] - internal interface IGameMode : IDBusObject - { - Task QueryStatusAsync(int Pid); - Task RegisterGameAsync(int Pid); - Task UnregisterGameAsync(int Pid); - Task QueryStatusByPidAsync(int Target, int Requester); - Task RegisterGameByPidAsync(int Target, int Requester); - Task UnregisterGameByPidAsync(int Target, int Requester); - Task QueryStatusByPIDFdAsync(CloseSafeHandle Target, CloseSafeHandle Requester); - Task RegisterGameByPIDFdAsync(CloseSafeHandle Target, CloseSafeHandle Requester); - Task UnregisterGameByPIDFdAsync(CloseSafeHandle Target, CloseSafeHandle Requester); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class GameModeProperties - { - private bool _Active = default(bool); - public bool Active - { - get - { - return _Active; - } - - set - { - _Active = (value); - } - } - - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class GameModeExtensions - { - public static Task GetActiveAsync(this IGameMode o) => o.GetAsync("Active"); - public static Task GetVersionAsync(this IGameMode o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.MemoryMonitor")] - internal interface IMemoryMonitor : IDBusObject - { - Task WatchLowMemoryWarningAsync(Action handler, Action onError = null); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class MemoryMonitorProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class MemoryMonitorExtensions - { - public static Task GetVersionAsync(this IMemoryMonitor o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.OpenURI")] - internal interface IOpenURI : IDBusObject - { - Task OpenURIAsync(string ParentWindow, string Uri, IDictionary Options); - Task OpenFileAsync(string ParentWindow, CloseSafeHandle Fd, IDictionary Options); - Task OpenDirectoryAsync(string ParentWindow, CloseSafeHandle Fd, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class OpenURIProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class OpenURIExtensions - { - public static Task GetVersionAsync(this IOpenURI o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Realtime")] - internal interface IRealtime : IDBusObject - { - Task MakeThreadRealtimeWithPIDAsync(ulong Process, ulong Thread, uint Priority); - Task MakeThreadHighPriorityWithPIDAsync(ulong Process, ulong Thread, int Priority); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class RealtimeProperties - { - private int _MaxRealtimePriority = default(int); - public int MaxRealtimePriority - { - get - { - return _MaxRealtimePriority; - } - - set - { - _MaxRealtimePriority = (value); - } - } - - private int _MinNiceLevel = default(int); - public int MinNiceLevel - { - get - { - return _MinNiceLevel; - } - - set - { - _MinNiceLevel = (value); - } - } - - private long _RTTimeUSecMax = default(long); - public long RTTimeUSecMax - { - get - { - return _RTTimeUSecMax; - } - - set - { - _RTTimeUSecMax = (value); - } - } - - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class RealtimeExtensions - { - public static Task GetMaxRealtimePriorityAsync(this IRealtime o) => o.GetAsync("MaxRealtimePriority"); - public static Task GetMinNiceLevelAsync(this IRealtime o) => o.GetAsync("MinNiceLevel"); - public static Task GetRTTimeUSecMaxAsync(this IRealtime o) => o.GetAsync("RTTimeUSecMax"); - public static Task GetVersionAsync(this IRealtime o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.DynamicLauncher")] - internal interface IDynamicLauncher : IDBusObject - { - Task InstallAsync(string Token, string DesktopFileId, string DesktopEntry, IDictionary Options); - Task PrepareInstallAsync(string ParentWindow, string Name, object IconV, IDictionary Options); - Task RequestInstallTokenAsync(string Name, object IconV, IDictionary Options); - Task UninstallAsync(string DesktopFileId, IDictionary Options); - Task GetDesktopEntryAsync(string DesktopFileId); - Task<(object iconV, string iconFormat, uint iconSize)> GetIconAsync(string DesktopFileId); - Task LaunchAsync(string DesktopFileId, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class DynamicLauncherProperties - { - private uint _SupportedLauncherTypes = default(uint); - public uint SupportedLauncherTypes - { - get - { - return _SupportedLauncherTypes; - } - - set - { - _SupportedLauncherTypes = (value); - } - } - - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class DynamicLauncherExtensions - { - public static Task GetSupportedLauncherTypesAsync(this IDynamicLauncher o) => o.GetAsync("SupportedLauncherTypes"); - public static Task GetVersionAsync(this IDynamicLauncher o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Camera")] - internal interface ICamera : IDBusObject - { - Task AccessCameraAsync(IDictionary Options); - Task OpenPipeWireRemoteAsync(IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class CameraProperties - { - private bool _IsCameraPresent = default(bool); - public bool IsCameraPresent - { - get - { - return _IsCameraPresent; - } - - set - { - _IsCameraPresent = (value); - } - } - - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class CameraExtensions - { - public static Task GetIsCameraPresentAsync(this ICamera o) => o.GetAsync("IsCameraPresent"); - public static Task GetVersionAsync(this ICamera o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Device")] - internal interface IDevice : IDBusObject - { - Task AccessDeviceAsync(uint Pid, string[] Devices, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class DeviceProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class DeviceExtensions - { - public static Task GetVersionAsync(this IDevice o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.PowerProfileMonitor")] - internal interface IPowerProfileMonitor : IDBusObject - { - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class PowerProfileMonitorProperties - { - private bool _power_saver_enabled = default(bool); - public bool PowerSaverEnabled - { - get - { - return _power_saver_enabled; - } - - set - { - _power_saver_enabled = (value); - } - } - - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class PowerProfileMonitorExtensions - { - public static Task GetPowerSaverEnabledAsync(this IPowerProfileMonitor o) => o.GetAsync("power-saver-enabled"); - public static Task GetVersionAsync(this IPowerProfileMonitor o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Email")] - internal interface IEmail : IDBusObject - { - Task ComposeEmailAsync(string ParentWindow, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class EmailProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class EmailExtensions - { - public static Task GetVersionAsync(this IEmail o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.Trash")] - internal interface ITrash : IDBusObject - { - Task TrashFileAsync(CloseSafeHandle Fd); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class TrashProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class TrashExtensions - { - public static Task GetVersionAsync(this ITrash o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.ProxyResolver")] - internal interface IProxyResolver : IDBusObject - { - Task LookupAsync(string Uri); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class ProxyResolverProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class ProxyResolverExtensions - { - public static Task GetVersionAsync(this IProxyResolver o) => o.GetAsync("version"); - } - - [DBusInterface("org.freedesktop.portal.FileChooser")] - internal interface IFileChooser : IDBusObject - { - Task OpenFileAsync(string ParentWindow, string Title, IDictionary Options); - Task SaveFileAsync(string ParentWindow, string Title, IDictionary Options); - Task SaveFilesAsync(string ParentWindow, string Title, IDictionary Options); - Task GetAsync(string prop); - Task GetAllAsync(); - Task SetAsync(string prop, object val); - Task WatchPropertiesAsync(Action handler); - } - - [Dictionary] - internal class FileChooserProperties - { - private uint _version = default(uint); - public uint Version - { - get - { - return _version; - } - - set - { - _version = (value); - } - } - } - - internal static class FileChooserExtensions - { - public static Task GetVersionAsync(this IFileChooser o) => o.GetAsync("version"); - } -} diff --git a/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalRequest.cs b/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalRequest.cs deleted file mode 100644 index c05cfb763e4b..000000000000 --- a/src/Uno.UI.Runtime.Skia.X11/DBus/OrgFreedesktopPortalRequest.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Generated using `dotnet dbus codegen /usr/share/dbus-1/interfaces/org.freedesktop.portal.Request.xml` -// tmds.dbus.tool 0.16.0 -#nullable disable - -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using Tmds.DBus; - -[assembly: InternalsVisibleTo(Connection.DynamicAssemblyName)] -namespace Uno.WinUI.Runtime.Skia.X11.Dbus -{ - [DBusInterface("org.freedesktop.portal.Request")] - internal interface IRequest : IDBusObject - { - Task CloseAsync(); - Task WatchResponseAsync(Action<(Response Response, IDictionary results)> handler, Action onError = null); - } - - // From https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html#signals - internal enum Response - { - Success = 0, - UserCancelled = 1, - Other = 2 - } -} diff --git a/src/Uno.UI.Runtime.Skia.X11/LinuxFilePickerExtension.cs b/src/Uno.UI.Runtime.Skia.X11/LinuxFilePickerExtension.cs index fb2a4ba3b443..54b3be9593fe 100644 --- a/src/Uno.UI.Runtime.Skia.X11/LinuxFilePickerExtension.cs +++ b/src/Uno.UI.Runtime.Skia.X11/LinuxFilePickerExtension.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Globalization; using System.Linq; using System.Text; @@ -8,12 +9,12 @@ using Windows.Storage; using Windows.Storage.Pickers; using Windows.UI.ViewManagement; -using Tmds.DBus; +using Tmds.DBus.Protocol; using Uno.Extensions.Storage.Pickers; using Uno.Foundation.Logging; using Uno.UI.Helpers; using Uno.UI.Helpers.WinUI; -using Uno.WinUI.Runtime.Skia.X11.Dbus; +using Uno.WinUI.Runtime.Skia.X11.DBus; namespace Uno.WinUI.Runtime.Skia.X11; @@ -43,133 +44,161 @@ public async Task> PickMultipleFilesAsync(Cancellatio public async Task> PickFilesAsync(CancellationToken token, bool multiple, bool directory) { - Connection? connection; - ConnectionInfo? info; - try - { - connection = Connection.Session; - info = await connection.ConnectAsync(); - } - catch (Exception e) + var sessionsAddressBus = Address.Session; + if (sessionsAddressBus is null) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Unable to connect to DBus, see https://aka.platform.uno/x11-dbus-troubleshoot for troubleshooting information.", e); + this.Log().Error($"Can not determine DBus session bus address"); } - - return await Task.FromResult((IReadOnlyList)Array.Empty()); + return ImmutableList.Empty; } - var fileChooser = connection.CreateProxy(Service, ObjectPath); - - if (fileChooser is null) + if (token.IsCancellationRequested) { - if (this.Log().IsEnabled(LogLevel.Error)) - { - this.Log().Error($"Unable to find object {ObjectPath} at DBus service {Service}, make sure you have an xdg-desktop-portal implementation installed. For more information, visit https://wiki.archlinux.org/title/XDG_Desktop_Portal#List_of_backends_and_interfaces"); - } - - return await Task.FromResult((IReadOnlyList)Array.Empty()); + return ImmutableList.Empty; } - if (!X11Helper.XamlRootHostFromApplicationView(ApplicationView.GetForCurrentViewSafe(), out var host)) + using var connection = new Connection(sessionsAddressBus); + var connectionTcs = new TaskCompletionSource(); + // ConnectAsync calls ConfigureAwait(false), so we need this TCS dance to make the continuation continue on the UI thread + _ = connection.ConnectAsync().AsTask().ContinueWith(_ => connectionTcs.TrySetResult(), token); + var timeoutTask = Task.Delay(1000, token); + var finishedTask = await Task.WhenAny(connectionTcs.Task, timeoutTask); + if (finishedTask == timeoutTask) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Unable to get the {nameof(X11XamlRootHost)} instance from the application view."); + this.Log().Error($"Timed out while trying to connect to DBus"); } - - return await Task.FromResult((IReadOnlyList)Array.Empty()); + return ImmutableList.Empty; } - var handleToken = "UnoFileChooser" + Random.Shared.Next(); try { - var requestPath = $"{ResultObjectPathPrefix}/{info.LocalName[1..].Replace(".", "_")}/{handleToken}"; + var desktopService = new DesktopService(connection, Service); + var chooser = desktopService.CreateFileChooser(ObjectPath); - var result = connection.CreateProxy(Service, requestPath); + if (token.IsCancellationRequested) + { + return ImmutableList.Empty; + } - var tcs = new TaskCompletionSource>(); + var version = await chooser.GetVersionAsync(); + if (version != 3) + { + if (this.Log().IsEnabled(LogLevel.Error)) + { + this.Log().Error($"File pickers are only implemented for version 3 of the File chooser portal, but version {version} was found"); + } + return ImmutableList.Empty; + } - token.Register(() => + if (!X11Helper.XamlRootHostFromApplicationView(ApplicationView.GetForCurrentViewSafe(), out var host)) { - if (this.Log().IsEnabled(LogLevel.Debug)) + if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Debug($"File picker cancelled."); + this.Log().Error($"Unable to get the {nameof(X11XamlRootHost)} instance from the application view."); } - tcs.TrySetResult(Array.Empty()); - }); + return ImmutableList.Empty; + } + + var handleToken = "UnoFileChooser" + Random.Shared.NextInt64(); + var requestPath = $"{ResultObjectPathPrefix}/{connection.UniqueName![1..].Replace(".", "_")}/{handleToken}"; + + if (token.IsCancellationRequested) + { + return ImmutableList.Empty; + } // We listen for the signal BEFORE we send the request. The spec API reference // points out the race condition that could occur otherwise. - using var _ = await result.WatchResponseAsync(r => + var request = desktopService.CreateRequest(requestPath); + var responseTcs = new TaskCompletionSource<(uint Response, Dictionary Results)>(); + _ = request.WatchResponseAsync((exception, tuple) => { - if (r.Response is Response.Success) + if (exception is not null) { - tcs.TrySetResult(((IReadOnlyList)r.results["uris"]).Select(s => new Uri(s).AbsolutePath).ToList()); + responseTcs.SetException(exception); } else { - if (this.Log().IsEnabled(LogLevel.Debug)) - { - this.Log().Debug($"File picker received an unsuccessful response {r.Response}."); - } - - tcs.TrySetResult(Array.Empty()); + responseTcs.SetResult(tuple); } - }, e => + }); + + if (token.IsCancellationRequested) + { + return ImmutableList.Empty; + } + + var actualRequestPath = await chooser.OpenFileAsync( + parentWindow: "x11:" + host.RootX11Window.Window.ToString("X", CultureInfo.InvariantCulture), + title: (multiple, directory) switch + { + (true, true) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_DIRECTORY_MULTIPLE"), + (true, false) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_FILE_MULTIPLE"), + (false, true) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_DIRECTORY_SINGLE"), + (false, false) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_FILE_SINGLE") + }, + options: new Dictionary + { + { "handle_token", handleToken }, + { "accept_label", string.IsNullOrEmpty(picker.CommitButtonTextInternal) ? ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_ACCEPT_LABEL") : picker.CommitButtonTextInternal }, + { "multiple", multiple }, + { "directory", directory }, + { "filters", GetPortalFilters() }, + { "current_folder", new Array(Encoding.UTF8.GetBytes(PickerHelpers.GetInitialDirectory(picker.SuggestedStartLocationInternal)).Append((byte)'\0')) } + }); + + if (actualRequestPath != requestPath) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"File picker failed to receive a response.", e); + this.Log().Error($"{nameof(chooser.OpenFileAsync)} returned a path '{actualRequestPath}' that is different from supplied handle_token -based path '{requestPath}'"); } - tcs.TrySetResult(Array.Empty()); - }); + return ImmutableList.Empty; + } - var title = (multiple, directory) switch - { - (true, true) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_DIRECTORY_MULTIPLE"), - (true, false) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_FILE_MULTIPLE"), - (false, true) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_DIRECTORY_SINGLE"), - (false, false) => ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE_FILE_SINGLE") - }; - var window = "x11:" + host.RootX11Window.Window.ToString("X", CultureInfo.InvariantCulture); - var requestPath2 = await fileChooser.OpenFileAsync(window, title, new Dictionary - { - { "handle_token", handleToken }, - { "accept_label", string.IsNullOrEmpty(picker.CommitButtonTextInternal) ? ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_ACCEPT_LABEL") : picker.CommitButtonTextInternal }, - { "multiple", multiple }, - { "directory", directory }, - { "filters", GetPortalFilters(picker.FileTypeFilterInternal) }, - { "current_folder", Encoding.UTF8.GetBytes(PickerHelpers.GetInitialDirectory(picker.SuggestedStartLocationInternal)).Append((byte)'\0') } - }); + var (response, results) = await responseTcs.Task; - if (requestPath != requestPath2) + if (!Enum.IsDefined(typeof(Response), response)) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"We are waiting at a wrong path {requestPath} instead of {requestPath2}"); + this.Log().Error($"FileChooser returned an invalid response number {response}."); } - tcs.TrySetResult(Array.Empty()); + return ImmutableList.Empty; } - return await tcs.Task; + + if ((Response)response is not Response.Success) + { + if ((Response)response is not Response.UserCancelled && this.Log().IsEnabled(LogLevel.Error)) + { + this.Log().Error($"FileChooser's response indicates an unsuccessful operation {(Response)response}"); + } + + return ImmutableList.Empty; + } + + return results["uris"].GetArray().Select(s => new Uri(s).AbsolutePath).ToImmutableList(); } catch (Exception e) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Failed to pick file", e); + this.Log().Error($"DBus FileChooser error, see https://aka.platform.uno/x11-dbus-troubleshoot for troubleshooting information.", e); } - return await Task.FromResult((IReadOnlyList)Array.Empty()); + return ImmutableList.Empty; } } - private (string, (uint, string)[])[] GetPortalFilters(IList filters) + private Array>>> GetPortalFilters() { // Except from the API reference // filters (a(sa(us))) @@ -185,35 +214,33 @@ public async Task> PickFilesAsync(CancellationToken token, // Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])] // // Note that filters are purely there to aid the user in making a useful selection. The portal may still allow the user to select files that don’t match any filter criteria, and applications must be prepared to handle that. - // - var list = new List<(uint kind, string pattern)>(); - foreach (var filter in filters) + + // We don't have a way to map a filter to a category (e.g. image/png -> Images), so we make every filter its own category + var list = new Array>>>(); + foreach (var pattern in picker.FileTypeFilterInternal.Distinct()) { - try + if (pattern is null) { - // will throw if not a valid MIME type - list.Add((1, new System.Net.Mime.ContentType(filter).ToString())); + continue; } - catch (Exception) + + if (pattern == "*") { - if (this.Log().IsEnabled(LogLevel.Trace)) - { - this.Log().Trace($"Failed to parse portal filer {filter} as a MIME type, falling back to glob."); - } - // The portal accepts any glob pattern, but to be similar to other platforms, we - // assume the filter is of the form `.extension`. - if (filter == "*") - { - list.Add((0, filter)); - } - else + list.Add(Struct.Create("All Files", new Array>(new[] { Struct.Create((uint)0, "*.*") }))); + } + else if (pattern.StartsWith('.') && pattern[1..] is var ext && ext.All(char.IsLetterOrDigit)) + { + list.Add(Struct.Create($"{ext.ToUpperInvariant()} Files", new Array>(new[] { Struct.Create((uint)0, $"*.{ext}") }))); + } + else + { + if (this.Log().IsEnabled(LogLevel.Error)) { - list.Add((0, $"*{filter}")); + this.Log().Error($"Skipping invalid file extension filter: '{pattern}'"); } } } - // We don't have a way to map a filter to a category (e.g. image/png -> Images), so we make every filter its own category - return list.Select(f => (f.pattern, new[] { f })).ToArray(); + return list; } } diff --git a/src/Uno.UI.Runtime.Skia.X11/LinuxFileSaverExtension.cs b/src/Uno.UI.Runtime.Skia.X11/LinuxFileSaverExtension.cs index 480c24dab1b5..ef351fa9cf4d 100644 --- a/src/Uno.UI.Runtime.Skia.X11/LinuxFileSaverExtension.cs +++ b/src/Uno.UI.Runtime.Skia.X11/LinuxFileSaverExtension.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -9,12 +8,12 @@ using Windows.Storage; using Windows.Storage.Pickers; using Windows.UI.ViewManagement; -using Tmds.DBus; +using Tmds.DBus.Protocol; using Uno.Extensions.Storage.Pickers; using Uno.Foundation.Logging; using Uno.UI.Helpers; using Uno.UI.Helpers.WinUI; -using Uno.WinUI.Runtime.Skia.X11.Dbus; +using Uno.WinUI.Runtime.Skia.X11.DBus; namespace Uno.WinUI.Runtime.Skia.X11; @@ -32,148 +31,153 @@ internal class LinuxFileSaverExtension(FileSavePicker picker) : IFileSavePickerE public async Task PickSaveFileAsync(CancellationToken token) { - Connection? connection; - ConnectionInfo? info; - try - { - connection = Connection.Session; - info = await connection.ConnectAsync(); - } - catch (Exception e) + var sessionsAddressBus = Address.Session; + if (sessionsAddressBus is null) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Unable to connect to DBus, see https://aka.platform.uno/x11-dbus-troubleshoot for troubleshooting information.", e); + this.Log().Error($"Can not determine DBus session bus address"); } - - return await Task.FromResult(null); + return null; } - var fileChooser = connection.CreateProxy(Service, ObjectPath); - - if (fileChooser is null) + if (token.IsCancellationRequested) { - if (this.Log().IsEnabled(LogLevel.Error)) - { - this.Log().Error($"Unable to find object {ObjectPath} at DBus service {Service}, make sure you have an xdg-desktop-portal implementation installed. For more information, visit https://wiki.archlinux.org/title/XDG_Desktop_Portal#List_of_backends_and_interfaces"); - } - - return await Task.FromResult(null); + return null; } - if (!X11Helper.XamlRootHostFromApplicationView(ApplicationView.GetForCurrentViewSafe(), out var host)) + using var connection = new Connection(sessionsAddressBus); + var connectionTcs = new TaskCompletionSource(); + // ConnectAsync calls ConfigureAwait(false), so we need this TCS dance to make the continuation continue on the UI thread + _ = connection.ConnectAsync().AsTask().ContinueWith(_ => connectionTcs.TrySetResult(), token); + var timeoutTask = Task.Delay(1000, token); + var finishedTask = await Task.WhenAny(connectionTcs.Task, timeoutTask); + if (finishedTask == timeoutTask) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Unable to get the {nameof(X11XamlRootHost)} instance from the application view."); + this.Log().Error($"Timed out while trying to connect to DBus"); } - - return await Task.FromResult(null); + return null; } - var handleToken = "UnoFileChooser" + Random.Shared.Next(); try { - var requestPath = $"{ResultObjectPathPrefix}/{info.LocalName[1..].Replace(".", "_")}/{handleToken}"; + var desktopService = new DesktopService(connection, Service); + var chooser = desktopService.CreateFileChooser(ObjectPath); - var result = connection.CreateProxy(Service, requestPath); + if (token.IsCancellationRequested) + { + return null; + } - var tcs = new TaskCompletionSource(); + var version = await chooser.GetVersionAsync(); + if (version != 3) + { + if (this.Log().IsEnabled(LogLevel.Error)) + { + this.Log().Error($"File pickers are only implemented for version 3 of the File chooser portal, but version {version} was found"); + } + return null; + } - token.Register(() => + if (!X11Helper.XamlRootHostFromApplicationView(ApplicationView.GetForCurrentViewSafe(), out var host)) { - if (this.Log().IsEnabled(LogLevel.Debug)) + if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Debug($"File picker cancelled."); + this.Log().Error($"Unable to get the {nameof(X11XamlRootHost)} instance from the application view."); } - tcs.TrySetResult(null); - }); + return null; + } + + var handleToken = "UnoFileChooser" + Random.Shared.NextInt64(); + var requestPath = $"{ResultObjectPathPrefix}/{connection.UniqueName![1..].Replace(".", "_")}/{handleToken}"; + + if (token.IsCancellationRequested) + { + return null; + } // We listen for the signal BEFORE we send the request. The spec API reference // points out the race condition that could occur otherwise. - using var _ = await result.WatchResponseAsync(r => + var request = desktopService.CreateRequest(requestPath); + var responseTcs = new TaskCompletionSource<(uint Response, Dictionary Results)>(); + _ = request.WatchResponseAsync((exception, tuple) => { - if (r.Response is Response.Success) + if (exception is not null) { - var uris = (IReadOnlyList)r.results["uris"]; - tcs.TrySetResult(uris.Select(uri => new Uri(uri).AbsolutePath).FirstOrDefault((string?)null)); + responseTcs.SetException(exception); } else { - if (this.Log().IsEnabled(LogLevel.Debug)) - { - this.Log().Debug($"File picker received an unsuccessful response {r.Response}."); - } - - tcs.TrySetResult(null); + responseTcs.SetResult(tuple); } - }, e => + }); + + if (token.IsCancellationRequested) + { + return null; + } + + var actualRequestPath = await chooser.SaveFileAsync( + parentWindow: "x11:" + host.RootX11Window.Window.ToString("X", CultureInfo.InvariantCulture), + title: ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE"), + options: new Dictionary + { + { "handle_token", handleToken }, + { "accept_label", string.IsNullOrEmpty(picker.CommitButtonText) ? ResourceAccessor.GetLocalizedStringResource("FILE_SAVER_ACCEPT_LABEL") : picker.CommitButtonText }, + { "filters", GetPortalFilters(picker.FileTypeChoices) }, + { "current_name", picker.SuggestedFileName }, + { "current_folder", new Array(Encoding.UTF8.GetBytes(PickerHelpers.GetInitialDirectory(picker.SuggestedStartLocation)).Append((byte)'\0')) } + }); + + if (actualRequestPath != requestPath) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"File picker failed to receive a response.", e); + this.Log().Error($"{nameof(chooser.OpenFileAsync)} returned a path '{actualRequestPath}' that is different from supplied handle_token -based path '{requestPath}'"); } - tcs.TrySetResult(null); - }); + return null; + } - var window = "x11:" + host.RootX11Window.Window.ToString("X", CultureInfo.InvariantCulture); - var requestPath2 = await fileChooser.SaveFileAsync(window, ResourceAccessor.GetLocalizedStringResource("FILE_PICKER_TITLE"), new Dictionary - { - { "handle_token", handleToken }, - { "accept_label", string.IsNullOrEmpty(picker.CommitButtonText) ? ResourceAccessor.GetLocalizedStringResource("FILE_SAVER_ACCEPT_LABEL") : picker.CommitButtonText }, - { "filters", GetPortalFilters(picker.FileTypeChoices) }, - { "current_name", picker.SuggestedFileName }, - { "current_folder", Encoding.UTF8.GetBytes(PickerHelpers.GetInitialDirectory(picker.SuggestedStartLocation)).Append((byte)'\0') } - }); + var (response, results) = await responseTcs.Task; - if (requestPath != requestPath2) + if (!Enum.IsDefined(typeof(Response), response)) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"We are waiting at a wrong path {requestPath} instead of {requestPath2}"); + this.Log().Error($"FileChooser returned an invalid response number {response}."); } - tcs.TrySetResult(null); + return null; } - return await tcs.Task.ContinueWith(task => + if ((Response)response is not Response.Success) { - if (task.Result is { } path) + if ((Response)response is not Response.UserCancelled && this.Log().IsEnabled(LogLevel.Error)) { - try - { - File.Create(path).Dispose(); - } - catch - { - if (this.Log().IsEnabled(LogLevel.Error)) - { - this.Log().Error($"Failed to create file at {path}"); - } - - return null; - } - - return StorageFile.GetFileFromPath(path); + this.Log().Error($"FileChooser's response indicates an unsuccessful operation {(Response)response}"); } return null; - }, token); + } + + return StorageFile.GetFileFromPath(new Uri(results["uris"].GetArray()[0]).AbsolutePath); } catch (Exception e) { if (this.Log().IsEnabled(LogLevel.Error)) { - this.Log().Error($"Failed to save file", e); + this.Log().Error($"DBus FileChooser error, see https://aka.platform.uno/x11-dbus-troubleshoot for troubleshooting information.", e); } - return await Task.FromResult(null); + return null; } } - private (string, (uint, string)[])[] GetPortalFilters(IDictionary> filterDictionary) + private Array>>> GetPortalFilters(IDictionary> filterDictionary) { // Except from the API reference // filters (a(sa(us))) @@ -189,16 +193,16 @@ internal class LinuxFileSaverExtension(FileSavePicker picker) : IFileSavePickerE // Example: [('Images', [(0, '*.ico'), (1, 'image/png')]), ('Text', [(0, '*.txt')])] // // Note that filters are purely there to aid the user in making a useful selection. The portal may still allow the user to select files that don’t match any filter criteria, and applications must be prepared to handle that. - // - var result = new List<(string, (uint, string)[])>(); + + var list = new Array>>>(); foreach (var (category, filters) in filterDictionary) { - result.Add((category, - filters - .Select(filter => ((uint)0, $"*{filter}")) // filter should be `.extension`. The portal want a `*.extension` format. - .ToArray())); + var adjustedFilters = filters + .Where(pattern => pattern.StartsWith('.') && pattern[1..] is var ext && ext.All(char.IsLetterOrDigit)) + .Select(pattern => Struct.Create((uint)0, $"*{pattern}")); // pattern should be `.extension`. The portal wants a `*.extension` format. + list.Add(Struct.Create(category, new Array>(adjustedFilters))); } - return result.ToArray(); + return list; } } diff --git a/src/Uno.UI.Runtime.Skia.X11/Uno.UI.Runtime.Skia.X11.csproj b/src/Uno.UI.Runtime.Skia.X11/Uno.UI.Runtime.Skia.X11.csproj index 0b411c30b000..a2ff80f3ffb3 100644 --- a/src/Uno.UI.Runtime.Skia.X11/Uno.UI.Runtime.Skia.X11.csproj +++ b/src/Uno.UI.Runtime.Skia.X11/Uno.UI.Runtime.Skia.X11.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/Uno.UWP/Storage/Pickers/FileOpenPicker.cs b/src/Uno.UWP/Storage/Pickers/FileOpenPicker.cs index 54bb0e459acf..74bede1d507c 100644 --- a/src/Uno.UWP/Storage/Pickers/FileOpenPicker.cs +++ b/src/Uno.UWP/Storage/Pickers/FileOpenPicker.cs @@ -48,8 +48,8 @@ public string CommitButtonText } string IFilePicker.CommitButtonTextInternal => CommitButtonText; - PickerLocationId IFilePicker.SuggestedStartLocationInternal => PickerLocationId.DocumentsLibrary; - IList IFilePicker.FileTypeFilterInternal => new FileExtensionVector(); + PickerLocationId IFilePicker.SuggestedStartLocationInternal => SuggestedStartLocation; + IList IFilePicker.FileTypeFilterInternal => FileTypeFilter; #if __SKIA__ || __WASM__ || __IOS__ || __ANDROID__ || __MACOS__ public FileOpenPicker() diff --git a/src/Uno.UWP/Storage/Pickers/FolderPicker.cs b/src/Uno.UWP/Storage/Pickers/FolderPicker.cs index 2c87c24e855e..8fdce4210c97 100644 --- a/src/Uno.UWP/Storage/Pickers/FolderPicker.cs +++ b/src/Uno.UWP/Storage/Pickers/FolderPicker.cs @@ -58,8 +58,8 @@ public string CommitButtonText } string IFilePicker.CommitButtonTextInternal => CommitButtonText; - PickerLocationId IFilePicker.SuggestedStartLocationInternal => PickerLocationId.DocumentsLibrary; - IList IFilePicker.FileTypeFilterInternal => new FileExtensionVector(); + PickerLocationId IFilePicker.SuggestedStartLocationInternal => SuggestedStartLocation; + IList IFilePicker.FileTypeFilterInternal => FileTypeFilter; #if __SKIA__ || __MACOS__ || __WASM__ || __IOS__ || __ANDROID__ public FolderPicker()