affederaffe / tmds.dbus.sourcegenerator Goto Github PK
View Code? Open in Web Editor NEWA roslyn source generator for creating proxies targeting the Tmds.DBus.Protocol API
License: MIT License
A roslyn source generator for creating proxies targeting the Tmds.DBus.Protocol API
License: MIT License
I have a method like this defined in my interface.xaml
<method name="set_number">
<arg type="d" name="number" direction="in"/>
</method>
and the outputed dbus call is this:
writer.WriteMethodCallHeader(_destination, _path, Interface, "SetNumber", "d");
Which is incorrect
The Tmds.Dbus.Protocol.Connection class can only handle one MethodHandler at a time. Given that there are times that you need to provide multiple interfaces in the same path, is there any proper way of doing that with this sourcegen?
Hi, I've been using this source generator to write a wrapper over the D-Bus Secret Service API. I've run into an issue where reading individual properties (i.e. GetSomePropertyAsync
) appears to be broken, but reading all properties at once (i.e. GetAllPropertiesAsync
) works fine.
I've created a minimal repro here: https://github.com/Ace4896/SecretsTest
bool
and ulong
values, the returned values seem to be incorrectIndexOutOfRangeException
is thrown:Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Tmds.DBus.Protocol.ThrowHelper.ThrowIndexOutOfRange()
at Tmds.DBus.Protocol.Reader.ReadSpan(Int32 length)
at Tmds.DBus.Protocol.Reader.ReadSpan()
at Tmds.DBus.Protocol.Reader.ReadString()
at Tmds.DBus.SourceGenerator.ReaderExtensions.ReadMessage_s(Message message, Object _) in /home/jpacheco/Documents/Repositories/Local/C#/SecretsTest/SecretsTest.Generated/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.ReaderExtensions.cs:line 111
at Tmds.DBus.Protocol.DBusConnection.<>c__41`1.<CallMethodAsync>b__41_0(Exception exception, Message message, Object state1, Object state2, Object state3)
--- End of stack trace from previous location ---
at Tmds.DBus.Protocol.DBusConnection.MyValueTaskSource`1.System.Threading.Tasks.Sources.IValueTaskSource<T>.GetResult(Int16 token)
at Tmds.DBus.Protocol.DBusConnection.CallMethodAsync[T](MessageBuffer message, MessageValueReader`1 valueReader, Object state)
at Tmds.DBus.Protocol.Connection.CallMethodAsync[T](MessageBuffer message, MessageValueReader`1 reader, Object readerState)
at SecretsTest.Generated.Program.Main(String[] args) in /home/jpacheco/Documents/Repositories/Local/C#/SecretsTest/SecretsTest.Generated/Program.cs:line 35
at SecretsTest.Generated.Program.<Main>(String[] args)
ObjectPath
values, an ArgumentOutOfRangeException
is thrown:Unhandled exception. System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'count')
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument)
at System.Buffers.SequenceReader`1.AdvanceToNextSpan(Int64 count)
at Tmds.DBus.Protocol.Reader.ReadSpan(Int32 length)
at Tmds.DBus.Protocol.Reader.ReadSpan()
at Tmds.DBus.Protocol.Reader.ReadString()
at Tmds.DBus.Protocol.Reader.ReadObjectPath()
at Tmds.DBus.SourceGenerator.ReaderExtensions.ReadArray_ao(Reader& reader) in /home/jpacheco/Documents/Repositories/Local/C#/SecretsTest/SecretsTest.Generated/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.ReaderExtensions.cs:line 37
at Tmds.DBus.SourceGenerator.ReaderExtensions.ReadMessage_ao(Message message, Object _) in /home/jpacheco/Documents/Repositories/Local/C#/SecretsTest/SecretsTest.Generated/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.ReaderExtensions.cs:line 96
at Tmds.DBus.Protocol.DBusConnection.<>c__41`1.<CallMethodAsync>b__41_0(Exception exception, Message message, Object state1, Object state2, Object state3)
--- End of stack trace from previous location ---
at Tmds.DBus.Protocol.DBusConnection.MyValueTaskSource`1.System.Threading.Tasks.Sources.IValueTaskSource<T>.GetResult(Int16 token)
at Tmds.DBus.Protocol.DBusConnection.CallMethodAsync[T](MessageBuffer message, MessageValueReader`1 valueReader, Object state)
at Tmds.DBus.Protocol.Connection.CallMethodAsync[T](MessageBuffer message, MessageValueReader`1 reader, Object readerState)
at SecretsTest.Generated.Program.Main(String[] args) in /home/jpacheco/Documents/Repositories/Local/C#/SecretsTest/SecretsTest.Generated/Program.cs:line 38
at SecretsTest.Generated.Program.<Main>(String[] args)
Based on the stack traces, I'm not sure if it's the protocol library or generated code that's causing the issue...
If it helps, I'm running Fedora 38, kernel 6.4.14-200, KDE 5.27.7.
So we have the ff:
<interface name="org.a11y.atspi.Event.Focus">
<!-- Focus is deprecated in favor of StateChanged with focus passed as its first argument -->
<signal name="Focus">
<arg type="s"/>
<arg type="i"/>
<arg type="i"/>
<arg type="v"/>
<arg name="properties" type="a{sv}"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QSpiEvent"/>
</signal>
</interface>
IDE complains about 'OrgA11yAtspiEventFocus' does not implement interface member 'IDBusInterfaceHandler.ReplyInterfaceRequest(MethodContext)' and using the handler without pathhandler would make signals emit fail.
When update Avalonia.FreeDesktop.csproj with
Lib | Version |
---|---|
Tmds.DBus.Protocol | 0.17.0 |
Tmds.DBus.SourceGenerator | 0.16.0 |
I'm trying to generate the handler code for the org.bluez.LEAdvertisement1
interface containing some dictionary properties.
This is a snipped of the generated code trying to access Key
and Value
from the ManufacturerData
dictionary instance:
case "ManufacturerData":
{
MessageWriter writer = context.CreateReplyWriter("v");
writer.WriteDBusVariant(new DBusVariantItem("a{qv}", new DBusDictEntryItem(new DBusUInt16Item(BackingProperties.ManufacturerData.Key), new DBusVariantItem(BackingProperties.ManufacturerData.Value))));
context.Reply(writer.CreateMessage());
writer.Dispose();
break;
}
LEAdvertisement1
<?xml version="1.0" encoding="utf-8" ?>
<node>
<interface name="org.bluez.LEAdvertisement1">
<method name="Release"/>
<property name="Type" type="s" access="read"/>
<property name="ServiceUUIDs" type="as" access="read"/>
<property name="ManufacturerData" type="a{qv}" access="read"/>
<property name="SolicitUUIDs" type="as" access="read"/>
<property name="ServiceData" type="a{sv}" access="read"/>
<property name="Includes" type="as" access="read"/>
<property name="LocalName" type="s" access="read"/>
<property name="Appearance" type="q" access="read"/>
<property name="Duration" type="q" access="read"/>
<property name="Timeout" type="q" access="read"/>
</interface>
</node>
Btw: Very nice library! ❤️
The lib's version currently on Avalonia master branch has duplicate introspection entries when it tries to generate org.a11y.atspi.Accessible
Hi, after upgrading from 0.0.11 to 0.0.12, I found that the generated code for structs seem to be incorrect. I've created a minimal repro here - master
branch is on 0.0.11 and generator-0.0.12
branch on 0.0.12.
It seems to be missing out the last field in structs, like these methods from ReaderExtensions
:
// Should be (ObjectPath, byte[], byte[], string)
public static (ObjectPath, byte[], byte[]) ReadStruct_roayaysz(this ref Reader reader)
{
reader.AlignStruct();
return ValueTuple.Create(reader.ReadObjectPath(), reader.ReadArray_ay(), reader.ReadArray_ay());
}
// Should be (ObjectPath, byte[], byte[])
public static (ObjectPath, byte[]) ReadStruct_roayayz(this ref Reader reader)
{
reader.AlignStruct();
return ValueTuple.Create(reader.ReadObjectPath(), reader.ReadArray_ay());
}
God knows why these spec writers at FreeDesktop/AT-SPI did this but they have a crazy struct and this sourcegen fails to compensate with it.
<interface name="org.a11y.atspi.Collection">
<method name="GetMatches">
<arg direction="in" name="rule" type="(aiia{ss}iaiiasib)"/>
public static (int[], int, Dictionary<string, string>, int, int[], int, string[], int, bool) ReadStruct_raiiaessiaiiasibz(this ref Reader reader)
{
reader.AlignStruct();
return ValueTuple.Create(reader.ReadArray_ai(), reader.ReadInt32(), reader.ReadDictionary_aess(), reader.ReadInt32(), reader.ReadArray_ai(), reader.ReadInt32(), reader.ReadArray_as(), reader.ReadInt32(), reader.ReadBool());
}
I wonder if it's possible to use a struct instead, though the naming convention for it is something to think about i guess.
Just noticed on the latest commit that Connection prop is always null. Maybe we missed setting it somewhere?
I'm trying to generate a handler for these two interfaces:
org.mpris.MediaPlayer2
org.mpris.MediaPlayer2.Player
But for both of them, the generated code doesn't compile since it has several switch cases for Introspect
:
Tmds.DBus.SourceGenerator.OrgMprisMediaPlayer2Player.g.cs
lines 309-341:
case "org.mpris.MediaPlayer2.Player":
switch (context.Request.MemberAsString, context.Request.SignatureAsString)
{
case ("Introspect", "" or null):
{
break;
}
case ("Introspect", "" or null):
{
break;
}
case ("Introspect", "" or null):
{
break;
}
case ("Introspect", "" or null):
{
break;
}
case ("Introspect", "" or null):
{
break;
}
case ("Introspect", "" or null):
{
break;
}
Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.OrgMprisMediaPlayer2Player.g.cs(317,30): error CS8120: The switch case is unreachable. It has already been handled by a previous case or it is impossible to match.
Hey affe,
i tried to use your source generator in order to publish a little project with native aot compilation. but upon adding the nuget package, the interface xml template and the project configuration i receive a ton of build errors:
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.ReaderExtensions.cs(16,44): error CS0122: 'Message' is inaccessible due to its protection level [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(111,54): error CS0122: 'MessageWriter' is inaccessible due to its protection level [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(111,28): error CS8337: The first parameter of a 'ref' extension method 'WriteDBusVariant' must be a value type or a generic type constrained to struct. [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(117,51): error CS0122: 'MessageWriter' is inaccessible due to its protection level [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(117,28): error CS8337: The first parameter of a 'ref' extension method 'WriteDBusItem' must be a value type or a generic type constrained to struct. [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(16,64): error CS0246: The type or namespace name 'Reader' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(16,39): error CS8337: The first parameter of a 'ref' extension method 'ReadDBusVariant' must be a value type or a generic type constrained to struct. [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.SignalHelper.cs(16,86): error CS0246: The type or namespace name 'MatchRule' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(25,73): error CS0246: The type or namespace name 'Reader' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(25,88): error CS0246: The type or namespace name 'DBusType' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(25,42): error CS8337: The first parameter of a 'ref' extension method 'ReadDBusBasicTypeItem' must be a value type or a generic type constrained to struct. [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(327,16): error CS0246: The type or namespace name 'DBusType' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(43,55): error CS0246: The type or namespace name 'Reader' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(43,70): error CS0246: The type or namespace name 'DBusType' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(43,33): error CS8337: The first parameter of a 'ref' extension method 'ReadDBusItem' must be a value type or a generic type constrained to struct. [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.SignalHelper.cs(21,89): error CS0246: The type or namespace name 'MatchRule' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.SignalHelper.cs(21,105): error CS0246: The type or namespace name 'MessageValueReader<>' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.VariantExtensions.cs(321,30): error CS0246: The type or namespace name 'DBusType' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
/home/fedora/Projects/priv/Tiler/Tmds.DBus.SourceGenerator/Tmds.DBus.SourceGenerator.DBusSourceGenerator/Tmds.DBus.SourceGenerator.SignalHelper.cs(26,152): error CS0246: The type or namespace name 'MessageValueReader<>' could not be found (are you missing a using directive or an assembly reference?) [/home/fedora/Projects/priv/Tiler/Tiler.csproj]
Same thing happens when cloning your project and adding it via project reference. I have the code pushed to a branch here: https://github.com/langebo/Tiler/tree/features/native-aot
The dbus windows interface I use comes from a gnome shell extension: https://extensions.gnome.org/extension/4724/window-calls/
Can you tell me what I am doing wrong? Thanks in advance
Running the source generator against the NetworkManager introspection xml (https://github.com/NetworkManager/NetworkManager/blob/main/introspection/org.freedesktop.NetworkManager.xml) results in generated code that duplicates the GetDevicesAsync()
and GetAllDevicesAsync()
methods.
To recreate, add the specified org.freedesktop.NetworkManager.xml
as an AdditionalItem to the project, then note the compile errors in the generated code.
Found against package version 0.0.6.
I'm trying on https://github.com/AvaloniaUI/Avalonia/tree/feature/linux-automation to see if the interfaces were working fine but upon using Accerciser or D-feet, getting the value of any properties from ("org.a11y.atspi.Accessible" "/org/a11y/atspi/accessible/root")
had it close the connection entirely and show this on managed side:
System.IO.IOException: Connection closed by peer
at Tmds.DBus.Protocol.MessageStream.ReadFromSocketIntoPipe() in /var/home/strix/RiderProjects/Avalonia/src/Linux/Tmds.DBus.Protocol/MessageStream.cs:line 62
and here on D-feet's side:
It would be nice to set properties on an object directly instead of using the BackingProperties
property as a proxy.
To prevent conflicts, you could implement IMethodHandler
explicitly.
This would have the added "benefit" of hiding the implementation detail of IMethodHandler
.
Major breaking changes.
Hi! I'm new to this repo.
I've managed to find this example by searching through old issues, but some official examples of how the XML should look like would be highly appreciated!
Hi @affederaffe! Sorry we didnt know how to reach you except for your github project here.
We're just wondering since for some reason D-Feet can't check the status of the trayicon's dbus object like so:
Was wondering if it's good to have INPC available for Handler objects so we could properly interface with propchanges notifications
Unused collection properties are initialized as null
.
Therfore the handler code might throw a NullReferenceException
.
Initialize generated collection properties to Array<T>.Empty()
, new Dictionary<A, B>()
or new List<T>()
.
This xml cannot get parsed: https://raw.githubusercontent.com/flatpak/xdg-desktop-portal/main/data/org.freedesktop.portal.ScreenCast.xml
I believe it fails at parsing this:
<arg type="h" name="fd" direction="out"/>
Maybe this library doesn't support the "h" type?
Methods using handles don't compile, as ReadHandle
is generic and SafeHandle
is abstract.
error CS0411: The type arguments for method 'Reader.ReadHandle<T>()' cannot be inferred from the usage. Try specifying the type arguments explicitly.
org.bluez.Profile1
<?xml version="1.0" encoding="utf-8" ?>
<node>
<interface name="org.bluez.Profile1">
<method name="NewConnection">
<arg type="o" direction="in"/>
<arg type="h" direction="in"/>
<arg type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QVariantMap"/>
</method>
<method name="RequestDisconnection">
<arg type="o" direction="in"/>
</method>
<method name="Release">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
</interface>
</node>
Use SafeFileHandle
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.