Browse Source

fail

feature/linux-automation-backup
Jumar Macato 2 years ago
parent
commit
1de1639a76
  1. 43
      Avalonia.sln.DotSettings
  2. 242
      src/Avalonia.FreeDesktop/Automation/AtspiMainContext.cs
  3. 75
      src/Avalonia.FreeDesktop/Automation/MethodHandlerMultiplexer.cs
  4. 181
      src/Avalonia.FreeDesktop/DBusXml/org.a11y.atspi.accessible.root.xml
  5. 30
      src/Linux/Tmds.DBus.Protocol/DBusConnection.cs
  6. 18
      src/Linux/Tmds.DBus.Protocol/PathNodeDictionary.cs
  7. 8
      src/Linux/Tmds.DBus.SourceGenerator/Properties/launchSettings.json

43
Avalonia.sln.DotSettings

@ -1,43 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=3E53A01A_002DB331_002D47F3_002DB828_002D4A5717E77A24_002Fd_003Aglass/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=6417B24E_002D49C2_002D4985_002D8DB2_002D3AB9D898EC91/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=E3A1060B_002D50D0_002D44E8_002D88B6_002DF44EF2E5BD72_002Ff_003Ahtml_002Ehtm/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBePrivate_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantUsingDirective/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=DECLSPEC_005FPROPERTY/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=ENUM/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=ENUMERATOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GETTER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GLOBAL_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GLOBAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=LOCAL_005FTYPEDEF/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=LOCAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=NAMESPACE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=PARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=SETTER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="set_" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="_" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT_005FMETHODS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TEMPLATE_005FPARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TYPEDEF/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Interfaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="I" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Locals/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=MethodPropertyEvent/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Other/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Parameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Activatable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fcitx/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=swapchain/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

242
src/Avalonia.FreeDesktop/Automation/AtspiMainContext.cs

@ -12,136 +12,154 @@ using Tmds.DBus.SourceGenerator;
namespace Avalonia.FreeDesktop.Automation; namespace Avalonia.FreeDesktop.Automation;
// internal class HandlerAtspiApplication : OrgA11yAtspiApplication internal class HandlerAtspiApplication : OrgA11yAtspiApplication
// { {
// public const string RootPath = "/org/a11y/atspi/accessible/root"; public const string RootPath = "/org/a11y/atspi/accessible/root";
//
// public HandlerAtspiApplication(Connection connection) public HandlerAtspiApplication(Connection connection)
// { {
// Connection = connection; Connection = connection;
// AtspiVersion = atspiVersion; AtspiVersion = atspiVersion;
// ToolkitName = "Avalonia"; ToolkitName = "Avalonia";
// Id = 0; Id = 0;
// Version = typeof(HandlerAtspiApplication).Assembly.GetName().Version.ToString(); Version = typeof(HandlerAtspiApplication).Assembly.GetName().Version.ToString();
// } }
//
// private const string atspiVersion = "2.1"; private const string atspiVersion = "2.1";
// protected override Connection Connection { get; } public override string Path => RootPath;
// public override string Path => RootPath;
// protected override async ValueTask<string> OnGetLocaleAsync(uint lctype) protected override Connection Connection { get; }
// {
// return string.Empty; protected override async ValueTask<string> OnGetLocaleAsync(uint lctype)
// } {
// } return String.Empty;
// }
// internal class AtspiAccessibleHandler : OrgA11yAtspiAccessible
// { protected override async ValueTask OnRegisterEventListenerAsync(string @event)
// public AtspiAccessibleHandler(Connection a11YConnection, Func<AutomationPeer?> peer, string path) {
// { }
// Name = Application.Current?.Name ?? "Avalonia Application";
// Description = string.Empty; protected override async ValueTask OnDeregisterEventListenerAsync(string @event)
// Locale = Environment.GetEnvironmentVariable("LANG") ?? CultureInfo.CurrentCulture.Name; {
// ChildCount = peer()?.GetChildren()?.Count ?? 0; }
// Connection = a11YConnection; }
// Path = path;
// } internal class AtspiAccessibleHandler : OrgA11yAtspiAccessible
// {
// protected override Connection Connection { get; } public AtspiAccessibleHandler(Connection a11YConnection, Func<AutomationPeer?> peer, string path)
// public override string Path { get; } {
// protected override ValueTask<(string, ObjectPath)> OnGetChildAtIndexAsync(int index) Name = Application.Current?.Name ?? "Avalonia Application";
// { Description = string.Empty;
// return default; Locale = Environment.GetEnvironmentVariable("LANG") ?? CultureInfo.CurrentCulture.Name;
// } ChildCount = 0; //peer()?.GetChildren()?.Count ?? 0;
// Connection = a11YConnection;
// protected override ValueTask<(string, ObjectPath)[]> OnGetChildrenAsync() Path = path;
// { }
// return default;
// } protected override Connection Connection { get; }
// public override string Path { get; }
// protected override ValueTask<int> OnGetIndexInParentAsync()
// { protected override ValueTask<(string, ObjectPath)> OnGetChildAtIndexAsync(int index)
// return default; {
// } return default;
// }
// protected override ValueTask<(uint, (string, ObjectPath)[])[]> OnGetRelationSetAsync()
// { protected override ValueTask<(string, ObjectPath)[]> OnGetChildrenAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<uint> OnGetRoleAsync()
// { protected override ValueTask<int> OnGetIndexInParentAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<string> OnGetRoleNameAsync()
// { protected override ValueTask<(uint, (string, ObjectPath)[])[]> OnGetRelationSetAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<string> OnGetLocalizedRoleNameAsync()
// { protected override ValueTask<uint> OnGetRoleAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<uint[]> OnGetStateAsync()
// { protected override ValueTask<string> OnGetRoleNameAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<Dictionary<string, string>> OnGetAttributesAsync()
// { protected override ValueTask<string> OnGetLocalizedRoleNameAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<(string, ObjectPath)> OnGetApplicationAsync()
// { protected override ValueTask<uint[]> OnGetStateAsync()
// return default; {
// } return default;
// }
// protected override ValueTask<string[]> OnGetInterfacesAsync()
// {
// return default;
// }
// }
protected override ValueTask<Dictionary<string, string>> OnGetAttributesAsync()
{
return default;
}
protected override ValueTask<(string, ObjectPath)> OnGetApplicationAsync()
{
return default;
}
protected override ValueTask<string[]> OnGetInterfacesAsync()
{
return default;
}
}
internal class AtspiMainContext internal class AtspiMainContext
{ {
// private static bool s_instanceInitialized; private static bool s_instanceInitialized;
// private static AtspiMainContext? _instance; private static AtspiMainContext? _instance;
// private readonly HandlerAtspiApplication _app; private readonly HandlerAtspiApplication _app;
// private readonly Connection _connection; private readonly Connection _connection;
private readonly MethodHandlerMultiplexer _multiplex;
// private readonly List<AtspiAccessibleHandler> handlers = new List<AtspiAccessibleHandler>(); // private readonly List<AtspiAccessibleHandler> handlers = new List<AtspiAccessibleHandler>();
private AtspiMainContext(Connection a11yConnection) private AtspiMainContext(Connection a11yConnection)
{ {
_connection = a11yConnection;
_multiplex = new MethodHandlerMultiplexer(HandlerAtspiApplication.RootPath);
_connection.AddMethodHandler(_multiplex);
_app = new HandlerAtspiApplication(_connection);
// _connection = a11yConnection; _multiplex.AddHandler("org.a11y.atspi.Application", _app);
// _app = new HandlerAtspiApplication(_connection);
} var rootAccessible = new AtspiAccessibleHandler(_connection, null, HandlerAtspiApplication.RootPath);
_multiplex.AddHandler("org.a11y.atspi.Accessible", rootAccessible);
}
public void RegisterRootPeer(Func<AutomationPeer?> peer) public void RegisterRootPeer(Func<AutomationPeer?> peer)
{ {
// var rootAccessible = new AtspiAccessibleHandler(_connection, peer, HandlerAtspiApplication.RootPath); }
// handlers.Add(rootAccessible);
}
public static AtspiMainContext? Instance { get /*=> _instance*/; } public static AtspiMainContext? Instance { get /*=> _instance*/; }
public static async void StartService() public static async void StartService()
{ {
// if (s_instanceInitialized || DBusHelper.Connection is not { } sessionConnection) return; if (s_instanceInitialized || DBusHelper.Connection is not { } sessionConnection) return;
// var bus1 = new OrgA11yBus(sessionConnection, "org.a11y.Bus", "/org/a11y/bus"); var bus1 = new OrgA11yBus(sessionConnection, "org.a11y.Bus", "/org/a11y/bus");
//
// var address = await bus1.GetAddressAsync(); var address = await bus1.GetAddressAsync();
//
// if (DBusHelper.TryCreateNewConnection(address) is not { } a11YConnection) return; if (DBusHelper.TryCreateNewConnection(address) is not { } a11YConnection) return;
//
// await a11YConnection.ConnectAsync(); await a11YConnection.ConnectAsync();
//
// _instance = new AtspiMainContext(a11YConnection); _instance = new AtspiMainContext(a11YConnection);
// s_instanceInitialized = true; s_instanceInitialized = true;
} }
} }

75
src/Avalonia.FreeDesktop/Automation/MethodHandlerMultiplexer.cs

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Avalonia.Controls.Shapes;
using Tmds.DBus.Protocol;
namespace Avalonia.FreeDesktop.Automation;
internal class MethodHandlerMultiplexer(string rootPath) : IMethodHandler
{
private Dictionary<string, IMethodHandler> _handlers = new();
public void AddHandler(string @interface, IMethodHandler handler)
{
_handlers.Add(@interface, handler);
}
public string Path { get; } = rootPath;
private ReadOnlyMemory<byte> _introspectXml =
"<node name=\"/org/a11y/atspi/accessible/root\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" >\n <interface name=\"org.freedesktop.DBus.Properties\">\n <method name=\"Get\">\n <arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n <arg type=\"s\" name=\"property_name\" direction=\"in\"/>\n <arg type=\"v\" name=\"value\" direction=\"out\"/>\n </method>\n <method name=\"GetAll\">\n <arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n <arg type=\"a{sv}\" name=\"properties\" direction=\"out\"/>\n </method>\n <method name=\"Set\">\n <arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n <arg type=\"s\" name=\"property_name\" direction=\"in\"/>\n <arg type=\"v\" name=\"value\" direction=\"in\"/>\n </method>\n <signal name=\"PropertiesChanged\">\n <arg type=\"s\" name=\"interface_name\"/>\n <arg type=\"a{sv}\" name=\"changed_properties\"/>\n <arg type=\"as\" name=\"invalidated_properties\"/>\n </signal>\n </interface>\n <interface name=\"org.freedesktop.DBus.Introspectable\">\n <method name=\"Introspect\">\n <arg type=\"s\" name=\"xml_data\" direction=\"out\"/>\n </method>\n </interface>\n <interface name=\"org.freedesktop.DBus.Peer\">\n <method name=\"Ping\"/>\n <method name=\"GetMachineId\">\n <arg type=\"s\" name=\"machine_uuid\" direction=\"out\"/>\n </method>\n </interface>\n <interface name=\"org.a11y.atspi.Application\">\n <method name=\"GetLocale\">\n <arg type=\"u\" name=\"lctype\" direction=\"in\"/>\n <arg type=\"s\" name=\"unnamed_arg1\" direction=\"out\"/>\n </method>\n <method name=\"RegisterEventListener\">\n <arg type=\"s\" name=\"event\" direction=\"in\"/>\n </method>\n <method name=\"DeregisterEventListener\">\n <arg type=\"s\" name=\"event\" direction=\"in\"/>\n </method>\n <property type=\"s\" name=\"ToolkitName\" access=\"read\"/>\n <property type=\"s\" name=\"Version\" access=\"read\"/>\n <property type=\"s\" name=\"AtspiVersion\" access=\"read\"/>\n <property type=\"i\" name=\"Id\" access=\"readwrite\"/>\n </interface>\n <interface name=\"org.a11y.atspi.Accessible\">\n <method name=\"GetChildAtIndex\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiObjectReference\"/>\n <arg type=\"i\" name=\"index\" direction=\"in\"/>\n <arg type=\"(so)\" name=\"unnamed_arg1\" direction=\"out\"/>\n </method>\n <method name=\"GetChildren\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiObjectReferenceArray\"/>\n <arg type=\"a(so)\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetIndexInParent\">\n <arg type=\"i\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetRelationSet\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiRelationArray\"/>\n <arg type=\"a(ua(so))\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetRole\">\n <arg type=\"u\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetRoleName\">\n <arg type=\"s\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetLocalizedRoleName\">\n <arg type=\"s\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetState\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiIntList\"/>\n <arg type=\"au\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetAttributes\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiAttributeSet\"/>\n <arg type=\"a{ss}\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetApplication\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\"\n value=\"QSpiObjectReference\"/>\n <arg type=\"(so)\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <method name=\"GetInterfaces\">\n <arg type=\"as\" name=\"unnamed_arg0\" direction=\"out\"/>\n </method>\n <property type=\"s\" name=\"Name\" access=\"read\"/>\n <property type=\"s\" name=\"Description\" access=\"read\"/>\n <property type=\"(so)\" name=\"Parent\" access=\"read\">\n <annotation name=\"org.qtproject.QtDBus.QtTypeName\"\n value=\"QSpiObjectReference\"/>\n </property>\n <property type=\"i\" name=\"ChildCount\" access=\"read\"/>\n <property type=\"s\" name=\"Locale\" access=\"read\"/>\n <property type=\"s\" name=\"AccessibleId\" access=\"read\"/>\n </interface>\n</node>"u8
.ToArray();
public async ValueTask HandleMethodAsync(MethodContext context)
{
var reqInt = context.Request.InterfaceAsString;
switch (reqInt)
{
case "org.freedesktop.DBus.Properties":
switch (context.Request.MemberAsString)
{
case ("PropertiesChanged"):
case ("GetAll"):
case ("Get"):
case ("Set"):
Reply();
void Reply()
{
Reader reader = context.Request.GetBodyReader();
string intfc = reader.ReadString();
if (_handlers.TryGetValue(intfc, out var m2))
m2.HandleMethodAsync(context);
}
break;
}
break;
case "org.freedesktop.DBus.Introspectable":
switch (context.Request.MemberAsString, context.Request.SignatureAsString)
{
case ("Introspect", "" or null):
{
context.ReplyIntrospectXml(new[] { _introspectXml });
break;
}
}
break;
default:
if (_handlers.TryGetValue(reqInt, out var matchHandler))
matchHandler.HandleMethodAsync(context);
break;
}
}
public bool RunMethodHandlerSynchronously(Message message) => true;
}

181
src/Avalonia.FreeDesktop/DBusXml/org.a11y.atspi.accessible.root.xml

@ -1,123 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?> <!-- GDBus 2.80.2 -->
<node name="/org/a11y/atspi/accessible/root"> <node>
<!-- <interface name="org.freedesktop.DBus.Properties">-->
<!-- <method name="Get">-->
<!-- <arg type="s" name="interface_name" direction="in"/>-->
<!-- <arg type="s" name="property_name" direction="in"/>-->
<!-- <arg type="v" name="value" direction="out"/>-->
<!-- </method>-->
<!-- <method name="GetAll">-->
<!-- <arg type="s" name="interface_name" direction="in"/>-->
<!-- <arg type="a{sv}" name="properties" direction="out"/>-->
<!-- </method>-->
<!-- <method name="Set">-->
<!-- <arg type="s" name="interface_name" direction="in"/>-->
<!-- <arg type="s" name="property_name" direction="in"/>-->
<!-- <arg type="v" name="value" direction="in"/>-->
<!-- </method>-->
<!-- <signal name="PropertiesChanged">-->
<!-- <arg type="s" name="interface_name"/>-->
<!-- <arg type="a{sv}" name="changed_properties"/>-->
<!-- <arg type="as" name="invalidated_properties"/>-->
<!-- </signal>-->
<!-- </interface>-->
<!-- <interface name="org.freedesktop.DBus.Introspectable">-->
<!-- <method name="Introspect">-->
<!-- <arg type="s" name="xml_data" direction="out"/>-->
<!-- </method>-->
<!-- </interface>-->
<!-- <interface name="org.freedesktop.DBus.Peer">-->
<!-- <method name="Ping"/>-->
<!-- <method name="GetMachineId">-->
<!-- <arg type="s" name="machine_uuid" direction="out"/>-->
<!-- </method>-->
<!-- </interface>-->
<interface name="org.a11y.atspi.Application">
<method name="GetLocale">
<arg type="u" name="lctype" direction="in"/>
<arg type="s" name="unnamed_arg1" direction="out"/>
</method>
<method name="RegisterEventListener">
<arg type="s" name="event" direction="in"/>
</method>
<method name="DeregisterEventListener">
<arg type="s" name="event" direction="in"/>
</method>
<property type="s" name="ToolkitName" access="read"/>
<property type="s" name="Version" access="read"/>
<property type="s" name="AtspiVersion" access="read"/>
<property type="i" name="Id" access="readwrite"/>
</interface>
<interface name="org.a11y.atspi.Accessible"> <interface name="org.a11y.atspi.Accessible">
<property name="Name" type="s" access="read"/>
<property name="Description" type="s" access="read"/>
<property name="Parent" type="(so)" access="read">
</property>
<property name="ChildCount" type="i" access="read"/>
<property name="Locale" type="s" access="read"/>
<property name="AccessibleId" type="s" access="read"/>
<property name="HelpText" type="s" access="read"/>
<method name="GetChildAtIndex"> <method name="GetChildAtIndex">
<arg direction="in" name="index" type="i"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
<arg direction="out" type="(so)"/> value="QSpiObjectReference"/>
<arg type="i" name="index" direction="in"/>
<arg type="(so)" name="unnamed_arg1" direction="out"/>
</method> </method>
<method name="GetChildren"> <method name="GetChildren">
<arg direction="out" type="a(so)"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiObjectReferenceArray"/>
<arg type="a(so)" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetIndexInParent"> <method name="GetIndexInParent">
<arg direction="out" type="i"/> <arg type="i" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetRelationSet"> <method name="GetRelationSet">
<arg direction="out" type="a(ua(so))"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiRelationArray"/>
<arg type="a(ua(so))" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetRole"> <method name="GetRole">
<arg direction="out" type="u"/> <arg type="u" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetRoleName"> <method name="GetRoleName">
<arg direction="out" type="s"/> <arg type="s" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetLocalizedRoleName"> <method name="GetLocalizedRoleName">
<arg direction="out" type="s"/> <arg type="s" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetState"> <method name="GetState">
<arg direction="out" type="au"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiIntList"/>
<arg type="au" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetAttributes"> <method name="GetAttributes">
<arg direction="out" type="a{ss}"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiAttributeSet"/>
<arg type="a{ss}" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetApplication"> <method name="GetApplication">
<arg direction="out" type="(so)"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiObjectReference"/>
<arg type="(so)" name="unnamed_arg0" direction="out"/>
</method> </method>
<method name="GetInterfaces"> <method name="GetInterfaces">
<arg direction="out" type="as"/> <arg type="as" name="unnamed_arg0" direction="out"/>
</method>
</interface>
<interface name="org.a11y.atspi.Application">
<property name="ToolkitName" type="s" access="read"/>
<property name="Version" type="s" access="read"/>
<property name="AtspiVersion" type="s" access="read"/>
<property name="Id" type="i" access="readwrite"/>
<method name="GetLocale">
<arg direction="in" name="lctype" type="u"/>
<arg direction="out" type="s"/>
</method> </method>
</interface> <property type="s" name="Name" access="read"/>
<interface name="org.a11y.atspi.Collection"> <property type="s" name="Description" access="read"/>
<method name="GetMatches"> <property type="(so)" name="Parent" access="read">
<arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/> <annotation name="org.qtproject.QtDBus.QtTypeName"
value="QSpiObjectReference"/>
<arg direction="in" name="sortby" type="u"/> </property>
<arg direction="in" name="count" type="i"/> <property type="i" name="ChildCount" access="read"/>
<arg direction="in" name="traverse" type="b"/> <property type="s" name="Locale" access="read"/>
<arg direction="out" type="a(so)"/> <property type="s" name="AccessibleId" access="read"/>
</method>
<method name="GetMatchesTo">
<arg direction="in" name="current_object" type="o"/>
<arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
<arg direction="in" name="sortby" type="u"/>
<arg direction="in" name="tree" type="u"/>
<arg direction="in" name="limit_scope" type="b"/>
<arg direction="in" name="count" type="i"/>
<arg direction="in" name="traverse" type="b"/>
<arg direction="out" type="a(so)"/>
</method>
<method name="GetMatchesFrom">
<arg direction="in" name="current_object" type="o"/>
<arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
<arg direction="in" name="sortby" type="u"/>
<arg direction="in" name="tree" type="u"/>
<arg direction="in" name="count" type="i"/>
<arg direction="in" name="traverse" type="b"/>
<arg direction="out" type="a(so)"/>
</method>
<method name="GetActiveDescendant">
<arg direction="out" type="(so)"/>
</method>
</interface>
<interface name="org.a11y.atspi.Socket">
<method name="Embed">
<arg direction="in" name="plug" type="(so)"/>
<arg direction="out" name="socket" type="(so)"/>
</method>
<method name="Embedded">
<arg direction="in" name="path" type="s"/>
</method>
<method name="Unembed">
<arg direction="in" name="plug" type="(so)"/>
</method>
<signal name="Available">
<arg name="socket" type="(so)"/>
</signal>
</interface> </interface>
</node> </node>

30
src/Linux/Tmds.DBus.Protocol/DBusConnection.cs

@ -290,7 +290,7 @@ class DBusConnection : IDisposable
{ {
bool returnMessageToPool = true; bool returnMessageToPool = true;
MessageHandler pendingCall = default; MessageHandler pendingCall = default;
IMethodHandler? methodHandler = null; IEnumerable<IMethodHandler>? methodHandlers = null;
Action<Exception?, DisposableMessage>? monitor = null; Action<Exception?, DisposableMessage>? monitor = null;
bool isMethodCall = message.MessageType == MessageType.MethodCall; bool isMethodCall = message.MessageType == MessageType.MethodCall;
MethodContext? methodContext = null; MethodContext? methodContext = null;
@ -327,7 +327,7 @@ class DBusConnection : IDisposable
{ {
if (_pathNodes.TryGetValue(message.PathAsString!, out PathNode? node)) if (_pathNodes.TryGetValue(message.PathAsString!, out PathNode? node))
{ {
methodHandler = node.MethodHandler; methodHandlers = node.MethodHandlers;
bool isDBusIntrospect = message.Member.SequenceEqual("Introspect"u8) && bool isDBusIntrospect = message.Member.SequenceEqual("Introspect"u8) &&
message.Interface.SequenceEqual("org.freedesktop.DBus.Introspectable"u8); message.Interface.SequenceEqual("org.freedesktop.DBus.Introspectable"u8);
@ -372,23 +372,29 @@ class DBusConnection : IDisposable
if (isMethodCall) if (isMethodCall)
{ {
Debug.Assert(methodContext is not null); Debug.Assert(methodContext is not null);
if (methodHandler is not null) if (methodHandlers is not null)
{ {
// Suppress methodContext nullability warnings. // Suppress methodContext nullability warnings.
#if NETSTANDARD2_0 #if NETSTANDARD2_0
#pragma warning disable CS8604 #pragma warning disable CS8604
#endif #endif
bool runHandlerSynchronously = methodHandler.RunMethodHandlerSynchronously(message);
if (runHandlerSynchronously) foreach (var methodHandler in methodHandlers)
{
await methodHandler.HandleMethodAsync(methodContext).ConfigureAwait(false);
HandleNoReplySent(methodContext);
}
else
{ {
returnMessageToPool = false;
RunMethodHandler(methodHandler, methodContext); bool runHandlerSynchronously = methodHandler.RunMethodHandlerSynchronously(message);
if (runHandlerSynchronously)
{
await methodHandler.HandleMethodAsync(methodContext).ConfigureAwait(false);
HandleNoReplySent(methodContext);
}
else
{
returnMessageToPool = false;
RunMethodHandler(methodHandler, methodContext);
}
} }
} }
else else
{ {

18
src/Linux/Tmds.DBus.Protocol/PathNodeDictionary.cs

@ -6,7 +6,7 @@ sealed class PathNode
// a string if there is a single child name // a string if there is a single child name
// a List<string> List<string>.Count child names // a List<string> List<string>.Count child names
private object? _childNames; private object? _childNames;
public IMethodHandler? MethodHandler; public List<IMethodHandler>? MethodHandlers = new();
public PathNode? Parent { get; set; } public PathNode? Parent { get; set; }
public int ChildNameCount => public int ChildNameCount =>
@ -178,7 +178,7 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
if (_dictionary.Remove(path, out PathNode? node)) if (_dictionary.Remove(path, out PathNode? node))
{ {
nodes[j++] = (path, node); nodes[j++] = (path, node);
node.MethodHandler = null; node.MethodHandlers.Clear();
} }
} }
count = j; j = 0; count = j; j = 0;
@ -217,7 +217,7 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
Debug.Assert(parent.ChildNameCount >= 1, "node is expected to be a known child"); Debug.Assert(parent.ChildNameCount >= 1, "node is expected to be a known child");
if (parent.ChildNameCount == 1) // We're the only child. if (parent.ChildNameCount == 1) // We're the only child.
{ {
if (parent.MethodHandler is not null) if (parent.MethodHandlers.Count > 0)
{ {
// Parent is still needed for the MethodHandler. // Parent is still needed for the MethodHandler.
parent.ClearChildNames(); parent.ClearChildNames();
@ -261,11 +261,11 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
PathNode node = GetOrCreateNode(path); PathNode node = GetOrCreateNode(path);
if (node.MethodHandler is not null) // if (node.MethodHandler is not null)
{ // {
throw new InvalidOperationException($"A method handler is already registered for the path '{path}'."); // throw new InvalidOperationException($"A method handler is already registered for the path '{path}'.");
} // }
node.MethodHandler = methodHandler; node.MethodHandlers.Add(methodHandler);
} }
public void RemoveMethodHandler(string path) public void RemoveMethodHandler(string path)
@ -279,7 +279,7 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
if (node.ChildNameCount > 0) if (node.ChildNameCount > 0)
{ {
// Node is still needed for its children. // Node is still needed for its children.
node.MethodHandler = null; node.MethodHandlers.Clear();
_dictionary.Add(path, node); _dictionary.Add(path, node);
} }
else else

8
src/Linux/Tmds.DBus.SourceGenerator/Properties/launchSettings.json

@ -0,0 +1,8 @@
{
"profiles": {
"Generator": {
"commandName": "DebugRoslynComponent",
"targetProject": "/var/home/strix/RiderProjects/Avalonia/src/Avalonia.FreeDesktop/Avalonia.FreeDesktop.csproj"
}
}
}
Loading…
Cancel
Save