This specification is inspired by Android's share system. A brief overview can be found here. (Tldr: app pass info using intents, which contain stuff like mime type and stuff shared)
Unlike Android where intents are tightly knit into the system (in fact it's the way the apps are launched!), we have to make to do with desktop files and dbus.
Now the second inspiration for this specification are application actions. In fact the .desktop part shares a lot of similarities with that spec.
- Share target - basic action provided by app that include Name, Icon. They are also referred to as static in this document.
- Dynamic target - this is a target provided by app during runtime for targets that aren't static. This includes people, notes, etc. (Think of it as a version of Android's direct share)
- Extras - concept directly inspired by Android intent system. This includes all the extra data include with share data and allows for extensibility
- Target id - id of a dynamic target. This is generated by the app and provided as a part of dynamic target. If a dynamic target is chosen during share process, the id will be passed to the app for identification purposes.
[Desktop Entry]
Share=Generic;ChangeProfileImage;Debug;
The [Desktop Entry] has two new keys:
- Share - this is a list of all share targets delimited by semicolon
[Desktop Share Generic]
Name=Share with peeps
Icon=group
MimeType=image/png;text/plain;
AcceptsMultipleFiles=true
This specification introduces a new share entry group type. The share group is a group named Desktop Share %s, where %s is the share target identifier.
Each group can have the following keys:
- Name - the name of the share target, this only needs to be unambiguous within one application and should not include the application name. (localestring)
- Icon to be shown together with the share target. If the name is an absolute path, the given file will be used. If the name is not an absolute path, the algorithm described in the Icon Theme Specification will be used to locate the icon. Implementations may choose to ignore it. (iconstring)
- MimeType - mime types accepted by share target delimited by semicolon. The list may be different from [Desktop Entry], be it a subset or something completely different. If target can't handle a MimeType it won't be shown during share process.
- AcceptsMultipleFiles - whether the share target can handle multiple files. If false target won't be shown when sharing multiple files. Defaults to false (boolean)
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.Share">
<method name="Send">
<arg name="mime" type="s" direction="in"/>
<arg name="extras" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
</method>
<method name="CanShare">
<arg name="mime" type="s" direction="in"/>
<arg name="extras" type="a{sv}" direction="in"/>
<arg name="shareable" type="b" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
</method>
<method name="DynamicRegister">
<arg name="app" type="s" direction="in"/>
<arg name="targets" type="aa{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QList<QVariantMap>"/>
</method>
<method name="DynamicClear">
<arg name="app" type="s" direction="in"/>
</method>
</interface>
</node>
Can be vendored ("x-vendor-name."). The value type for the extras dictionary in D-BUS is of the DBUS_TYPE_VARIANT container type. This allows different data types (string, integer, boolean, etc.) to be used for hints. When adding a dictionary of hints, this type must be used, rather than putting the actual extra value in as the dictionary value.
The only necessary value is "text" or "files" when sharing text and "files" when sharing files.
Name | Value Type | Description |
---|---|---|
title | STRING | Title of shared data. |
description | STRING | Description of shared data. Useful when sharing stuff with description (App store entries, video description etc.) |
text | STRING | Shared text. Only used when mime is text |
files | as | uris of shared files. Unused when mime is text |
The data that describes dynamics target. All field are required.
Name | Value Type | Description |
---|---|---|
id | STRING | Target id |
title | STRING | Title of target e.g. name of a person or name of a journal. |
image | STRING | URI of image used (e.g. image of a contact) |
mime | as | Mime types that the target accepts. If target can't handle a MimeType it won't be shown during share process. |
acceptsMultipleFiles | BOOLEAN | Whether the share target can handle multiple files. If false target won't be shown when sharing multiple files. Defaults to false (boolean) |
priority | INT32 | Priority of the target. Can be used when determining order of dynamic target (For example people that you chat with most often) |
void org.freedesktop.Share.Send (mime, extras); STRING mime; a{sv} extras;
Sends share data to the share server.
Name | Value Type | Description |
---|---|---|
mime | STRING | Mime type of shared data. Can be text ("text/*") |
extras | a{sv} | Extra data that can be passed to the server from the client program. Can be used to pass along information, that the server may be able to make use of. See Extras. |
bool org.freedesktop.Share.CanShare (mime, extras); STRING mime; a{sv} extras; BOOLEAN shareable;
Whether the data can be shared. This checks if the data is valid using the validation algorithm described below.
Name | Value Type | Description |
---|---|---|
mime | STRING | Mime type of shared data. Can be text ("text/*") |
extras | a{sv} | Extra data that can be passed to the server from the client program. Can be used to pass along information, that the server may be able to make use of. See Extras. |
shareable | BOOLEAN | Whether the data can be shared. |
- Check the mime value. If it's empty return false. No further checks shall be performed in this step.
- Check the extras value. If it's empty return false.
- Check the values in the extras:
- If the mime starts with "text/" check if files or text are empty. If both of them are empty return false.
- If the mime type doesn't start with "text/" check if files is empty. If it is return false.
- If files isn't empty check the uris for validity. If any uris are invalid return false. If any file mime types don't match up with the mime value also return false.
- Return true
void org.freedesktop.Share.DynamicRegister (app, targets); STRING app; aa{sv} targets;
Sends dynamic targets data to the share server. Will overwrite existing dynamic targets data.
Name | Value Type | Description |
---|---|---|
app | STRING | uri of desktop file that used the method |
targets | aa{sv} | Array of dynamic targets (target[]) that can be seen during sharing process. See Target. |
void org.freedesktop.Share.DynamicClear (app); STRING app;
Clears dynamic targets data from the share server.
Name | Value Type | Description |
---|---|---|
app | STRING | uri of desktop file that used the method |
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.ShareTarget">
<method name="Receive">
<!-- Target id or name -->
<arg name="target" type="s" direction="in"/>
<arg name="mime" type="s" direction="in"/>
<arg name="extras" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QVariantMap"/>
</method>
</interface>
</node>
The application must have a D-Bus service activatable at the well-known name that is equal to the desktop file name with the .desktop portion removed (for our example, org.bar.FooSocial). The above interface must be implemented at an object path "/org/freedesktop/ShareTarget"
void org.freedesktop.ShareTarget.Receive (target, mime, extras); STRING target; STRING mime; a{sv} extras;
Sends share data to the share server.
Name | Value Type | Description |
---|---|---|
target | s | Share target identifier as defined in the desktop file or a id in the case of dynamic targets. |
mime | s | Mime types of shared content. |
extras | a{sv} | Extra data that was passed to the server by send method. See Extras. |
The sharing flow consists of three parts: sending the data, choosing target using the share dialog and receiving the data
The sending flow is pretty simple: the app calls org.freedesktop.Share.Send with data it wants to send.
After the sharing server receives the data we move on to the next stage. No further action from the sending app is required.
Next the server show user the share dialog with all the targets (static and dynamic) that have matching mime types (and also accept multiple files if multiple files were sent).
User chooses the target and server launches the appropriate program if it's not already running. NOTE: It might make sense to require dbus activation here and to potentially expand org.freedesktop.Application interface with the share target support instead of dedicated org.freedesktop.ShareTarget. (opinion from more folks sorely needed)
The server calls org.freedesktop.ShareTarget from the app's service. The app gets the data and displays it to the user.