Browse Source

fail

feature/linux-automation-backup
Jumar Macato 2 years ago
parent
commit
1de1639a76
  1. 43
      Avalonia.sln.DotSettings
  2. 260
      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. 32
      src/Linux/Tmds.DBus.Protocol/DBusConnection.cs
  6. 20
      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>

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

@ -12,136 +12,154 @@ using Tmds.DBus.SourceGenerator;
namespace Avalonia.FreeDesktop.Automation;
// internal class HandlerAtspiApplication : OrgA11yAtspiApplication
// {
// public const string RootPath = "/org/a11y/atspi/accessible/root";
//
// public HandlerAtspiApplication(Connection connection)
// {
// Connection = connection;
// AtspiVersion = atspiVersion;
// ToolkitName = "Avalonia";
// Id = 0;
// Version = typeof(HandlerAtspiApplication).Assembly.GetName().Version.ToString();
// }
//
// private const string atspiVersion = "2.1";
// protected override Connection Connection { get; }
// public override string Path => RootPath;
// protected override async ValueTask<string> OnGetLocaleAsync(uint lctype)
// {
// return string.Empty;
// }
// }
//
// internal class AtspiAccessibleHandler : OrgA11yAtspiAccessible
// {
// public AtspiAccessibleHandler(Connection a11YConnection, Func<AutomationPeer?> peer, string path)
// {
// Name = Application.Current?.Name ?? "Avalonia Application";
// Description = string.Empty;
// Locale = Environment.GetEnvironmentVariable("LANG") ?? CultureInfo.CurrentCulture.Name;
// ChildCount = peer()?.GetChildren()?.Count ?? 0;
// Connection = a11YConnection;
// Path = path;
// }
//
// protected override Connection Connection { get; }
// public override string Path { get; }
// protected override ValueTask<(string, ObjectPath)> OnGetChildAtIndexAsync(int index)
// {
// return default;
// }
//
// protected override ValueTask<(string, ObjectPath)[]> OnGetChildrenAsync()
// {
// return default;
// }
//
// protected override ValueTask<int> OnGetIndexInParentAsync()
// {
// return default;
// }
//
// protected override ValueTask<(uint, (string, ObjectPath)[])[]> OnGetRelationSetAsync()
// {
// return default;
// }
//
// protected override ValueTask<uint> OnGetRoleAsync()
// {
// return default;
// }
//
// protected override ValueTask<string> OnGetRoleNameAsync()
// {
// return default;
// }
//
// protected override ValueTask<string> OnGetLocalizedRoleNameAsync()
// {
// return default;
// }
//
// protected override ValueTask<uint[]> OnGetStateAsync()
// {
// 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 HandlerAtspiApplication : OrgA11yAtspiApplication
{
// private static bool s_instanceInitialized;
// private static AtspiMainContext? _instance;
// private readonly HandlerAtspiApplication _app;
// private readonly Connection _connection;
public const string RootPath = "/org/a11y/atspi/accessible/root";
public HandlerAtspiApplication(Connection connection)
{
Connection = connection;
AtspiVersion = atspiVersion;
ToolkitName = "Avalonia";
Id = 0;
Version = typeof(HandlerAtspiApplication).Assembly.GetName().Version.ToString();
}
private const string atspiVersion = "2.1";
public override string Path => RootPath;
protected override Connection Connection { get; }
protected override async ValueTask<string> OnGetLocaleAsync(uint lctype)
{
return String.Empty;
}
protected override async ValueTask OnRegisterEventListenerAsync(string @event)
{
}
protected override async ValueTask OnDeregisterEventListenerAsync(string @event)
{
}
}
internal class AtspiAccessibleHandler : OrgA11yAtspiAccessible
{
public AtspiAccessibleHandler(Connection a11YConnection, Func<AutomationPeer?> peer, string path)
{
Name = Application.Current?.Name ?? "Avalonia Application";
Description = string.Empty;
Locale = Environment.GetEnvironmentVariable("LANG") ?? CultureInfo.CurrentCulture.Name;
ChildCount = 0; //peer()?.GetChildren()?.Count ?? 0;
Connection = a11YConnection;
Path = path;
}
protected override Connection Connection { get; }
public override string Path { get; }
protected override ValueTask<(string, ObjectPath)> OnGetChildAtIndexAsync(int index)
{
return default;
}
protected override ValueTask<(string, ObjectPath)[]> OnGetChildrenAsync()
{
return default;
}
protected override ValueTask<int> OnGetIndexInParentAsync()
{
return default;
}
protected override ValueTask<(uint, (string, ObjectPath)[])[]> OnGetRelationSetAsync()
{
return default;
}
protected override ValueTask<uint> OnGetRoleAsync()
{
return default;
}
protected override ValueTask<string> OnGetRoleNameAsync()
{
return default;
}
protected override ValueTask<string> OnGetLocalizedRoleNameAsync()
{
return default;
}
protected override ValueTask<uint[]> OnGetStateAsync()
{
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
{
private static bool s_instanceInitialized;
private static AtspiMainContext? _instance;
private readonly HandlerAtspiApplication _app;
private readonly Connection _connection;
private readonly MethodHandlerMultiplexer _multiplex;
// private readonly List<AtspiAccessibleHandler> handlers = new List<AtspiAccessibleHandler>();
private AtspiMainContext(Connection a11yConnection)
{
// _connection = a11yConnection;
// _app = new HandlerAtspiApplication(_connection);
}
_connection = a11yConnection;
_multiplex = new MethodHandlerMultiplexer(HandlerAtspiApplication.RootPath);
_connection.AddMethodHandler(_multiplex);
_app = new HandlerAtspiApplication(_connection);
_multiplex.AddHandler("org.a11y.atspi.Application", _app);
var rootAccessible = new AtspiAccessibleHandler(_connection, null, HandlerAtspiApplication.RootPath);
_multiplex.AddHandler("org.a11y.atspi.Accessible", rootAccessible);
}
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 async void StartService()
{
// if (s_instanceInitialized || DBusHelper.Connection is not { } sessionConnection) return;
// var bus1 = new OrgA11yBus(sessionConnection, "org.a11y.Bus", "/org/a11y/bus");
//
// var address = await bus1.GetAddressAsync();
//
// if (DBusHelper.TryCreateNewConnection(address) is not { } a11YConnection) return;
//
// await a11YConnection.ConnectAsync();
//
// _instance = new AtspiMainContext(a11YConnection);
// s_instanceInitialized = true;
}
if (s_instanceInitialized || DBusHelper.Connection is not { } sessionConnection) return;
var bus1 = new OrgA11yBus(sessionConnection, "org.a11y.Bus", "/org/a11y/bus");
var address = await bus1.GetAddressAsync();
if (DBusHelper.TryCreateNewConnection(address) is not { } a11YConnection) return;
await a11YConnection.ConnectAsync();
_instance = new AtspiMainContext(a11YConnection);
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"?>
<node name="/org/a11y/atspi/accessible/root">
<!-- GDBus 2.80.2 -->
<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">
<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">
<arg direction="in" name="index" type="i"/>
<arg direction="out" type="(so)"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0"
value="QSpiObjectReference"/>
<arg type="i" name="index" direction="in"/>
<arg type="(so)" name="unnamed_arg1" direction="out"/>
</method>
<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 name="GetIndexInParent">
<arg direction="out" type="i"/>
<arg type="i" name="unnamed_arg0" direction="out"/>
</method>
<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 name="GetRole">
<arg direction="out" type="u"/>
<arg type="u" name="unnamed_arg0" direction="out"/>
</method>
<method name="GetRoleName">
<arg direction="out" type="s"/>
<arg type="s" name="unnamed_arg0" direction="out"/>
</method>
<method name="GetLocalizedRoleName">
<arg direction="out" type="s"/>
<arg type="s" name="unnamed_arg0" direction="out"/>
</method>
<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 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 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 name="GetInterfaces">
<arg direction="out" type="as"/>
</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"/>
<arg type="as" name="unnamed_arg0" direction="out"/>
</method>
</interface>
<interface name="org.a11y.atspi.Collection">
<method name="GetMatches">
<arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
<arg direction="in" name="sortby" 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="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>
<property type="s" name="Name" access="read"/>
<property type="s" name="Description" access="read"/>
<property type="(so)" name="Parent" access="read">
<annotation name="org.qtproject.QtDBus.QtTypeName"
value="QSpiObjectReference"/>
</property>
<property type="i" name="ChildCount" access="read"/>
<property type="s" name="Locale" access="read"/>
<property type="s" name="AccessibleId" access="read"/>
</interface>
</node>

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

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

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

@ -6,7 +6,7 @@ sealed class PathNode
// a string if there is a single child name
// a List<string> List<string>.Count child names
private object? _childNames;
public IMethodHandler? MethodHandler;
public List<IMethodHandler>? MethodHandlers = new();
public PathNode? Parent { get; set; }
public int ChildNameCount =>
@ -178,7 +178,7 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
if (_dictionary.Remove(path, out PathNode? node))
{
nodes[j++] = (path, node);
node.MethodHandler = null;
node.MethodHandlers.Clear();
}
}
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");
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.ClearChildNames();
@ -261,11 +261,11 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
PathNode node = GetOrCreateNode(path);
if (node.MethodHandler is not null)
{
throw new InvalidOperationException($"A method handler is already registered for the path '{path}'.");
}
node.MethodHandler = methodHandler;
// if (node.MethodHandler is not null)
// {
// throw new InvalidOperationException($"A method handler is already registered for the path '{path}'.");
// }
node.MethodHandlers.Add(methodHandler);
}
public void RemoveMethodHandler(string path)
@ -279,7 +279,7 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
if (node.ChildNameCount > 0)
{
// Node is still needed for its children.
node.MethodHandler = null;
node.MethodHandlers.Clear();
_dictionary.Add(path, node);
}
else
@ -308,4 +308,4 @@ sealed class PathNodeDictionary : IMethodHandlerDictionary
public int Compare((string Path, PathNode Node) x, (string Path, PathNode Node) y)
=> x.Path.Length - y.Path.Length;
}
}
}

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