Skip to content

Commit c62781f

Browse files
committed
Add TrashPortal
1 parent f724ab0 commit c62781f

5 files changed

Lines changed: 80 additions & 8 deletions

File tree

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ The package `LinuxDesktopUtils.XDGBaseDirectories` implements version 0.8 of the
1111
The package `LinuxDesktopUtils.XDGDesktopPortals` makes the following [XDG Desktop Portals](https://flatpak.github.io/xdg-desktop-portal/docs/api-reference.html) available in an easy-to-use API:
1212

1313
- [ ] [File Chooser](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.FileChooser.html) version 4
14-
- [x] `OpenFile`
15-
- [x] `SaveFile`
16-
- [ ] `SaveFiles`
14+
- [x] `OpenFile`
15+
- [x] `SaveFile`
16+
- [ ] `SaveFiles`
1717
- [x] [OpenURI](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.OpenURI.html) version 5
18-
- [x] `OpenURI`
19-
- [x] `OpenFile`
20-
- [x] `OpenDirectory`
21-
- [x] `SchemeSupported`
18+
- [x] `OpenURI`
19+
- [x] `OpenFile`
20+
- [x] `OpenDirectory`
21+
- [x] `SchemeSupported`
2222
- [x] [Secret](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Secret.html) version 1
23-
- [x] `RetrieveSecret`: Note that this method requires a static application ID, which can only be obtained correctly for sandboxed applications. As such, applications running directly on the host will likely get a new master secret with each restart. Applications running on the host should use `libsecret` directly.
23+
- [x] `RetrieveSecret`: Note that this method requires a static application ID, which can only be obtained correctly for sandboxed applications. As such, applications running directly on the host will likely get a new master secret with each restart. Applications running on the host should use `libsecret` directly.
24+
- [x] [Trash](https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Trash.html) version 1
25+
- [x] `TrashFile`
2426

2527
## License
2628

src/LinuxDesktopUtils.XDGDesktopPortal/DesktopPortalConnectionManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ internal string GetWindowIdentifier(Optional<WindowIdentifier> preferredIdentifi
6060
/// </summary>
6161
public ValueTask<SecretPortal> GetSecretPortalAsync() => GetPortalAsync(SecretPortal.CreateAsync);
6262

63+
/// <summary>
64+
/// Gets the <see cref="TrashPortal"/>.
65+
/// </summary>
66+
public ValueTask<TrashPortal> GetTrashPortalAsync() => GetPortalAsync(TrashPortal.CreateAsync);
67+
6368
private ValueTask<T> GetPortalAsync<T>(Func<DesktopPortalConnectionManager, ValueTask<T>> factory) where T : class, IPortal
6469
{
6570
if (!_portalInstances.TryGetValue(typeof(T), out var portal)) return GetPortalImplAsync(factory);

src/LinuxDesktopUtils.XDGDesktopPortal/LinuxDesktopUtils.XDGDesktopPortal.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
<DBusGeneratorMode>Proxy</DBusGeneratorMode>
3636
<Link>DBusXml\org.freedesktop.portal.Secret.xml</Link>
3737
</AdditionalFiles>
38+
39+
<AdditionalFiles Include="..\..\extern\flatpak\xdg-desktop-portal\data\org.freedesktop.portal.Trash.xml">
40+
<DBusGeneratorMode>Proxy</DBusGeneratorMode>
41+
<Link>DBusXml\org.freedesktop.portal.Trash.xml</Link>
42+
</AdditionalFiles>
3843
</ItemGroup>
3944

4045
<ItemGroup>

src/LinuxDesktopUtils.XDGDesktopPortal/LinuxDesktopUtils.XDGDesktopPortal.csproj.DotSettings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=portals_005Cfilechooser/@EntryIndexedValue">True</s:Boolean>
55
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=portals_005Copenuri/@EntryIndexedValue">True</s:Boolean>
66
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=portals_005Csecret/@EntryIndexedValue">True</s:Boolean>
7+
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=portals_005Ctrash/@EntryIndexedValue">True</s:Boolean>
78
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=utils/@EntryIndexedValue">True</s:Boolean>
89
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=valueobjects/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
using JetBrains.Annotations;
4+
using Tmds.DBus.SourceGenerator;
5+
6+
namespace LinuxDesktopUtils.XDGDesktopPortal;
7+
8+
/// <summary>
9+
/// Portal for trashing files.
10+
///
11+
/// This simple interface lets sandboxed applications send files to the trashcan.
12+
/// </summary>
13+
/// <remarks>
14+
/// https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Trash.html
15+
/// </remarks>
16+
[PublicAPI]
17+
public class TrashPortal : IPortal
18+
{
19+
private readonly DesktopPortalConnectionManager _connectionManager;
20+
private readonly OrgFreedesktopPortalTrashProxy _instance;
21+
private readonly uint _version;
22+
23+
/// <inheritdoc/>
24+
uint IPortal.Version => _version;
25+
26+
private TrashPortal(
27+
DesktopPortalConnectionManager connectionManager,
28+
OrgFreedesktopPortalTrashProxy instance,
29+
uint version)
30+
{
31+
_connectionManager = connectionManager;
32+
_instance = instance;
33+
_version = version;
34+
}
35+
36+
internal static async ValueTask<TrashPortal> CreateAsync(DesktopPortalConnectionManager connectionManager)
37+
{
38+
var instance = new OrgFreedesktopPortalTrashProxy(connectionManager.GetConnection(), destination: DBusHelper.BusName, path: DBusHelper.ObjectPath);
39+
var version = await instance.GetVersionPropertyAsync().ConfigureAwait(false);
40+
41+
return new TrashPortal(connectionManager, instance, version);
42+
}
43+
44+
/// <summary>
45+
/// Sends a file to the trashcan. Applications are allowed to trash a file if they can open it in r/w mode.
46+
/// </summary>
47+
/// <param name="file">Absolute path to the file.</param>
48+
/// <returns>Whether the file was trashed successfully</returns>
49+
public async Task<bool> TrashFileAsync(FilePath file)
50+
{
51+
using var safeFileHandle = File.OpenHandle(file.Value, FileMode.Open, FileAccess.ReadWrite);
52+
53+
var result = await _instance.TrashFileAsync(
54+
fd: safeFileHandle
55+
).ConfigureAwait(false);
56+
57+
return result == 1;
58+
}
59+
}

0 commit comments

Comments
 (0)