summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DesktopIntegration.vala71
-rw-r--r--src/International.vala2
-rw-r--r--src/Portal.vala71
-rw-r--r--src/Resources.vala12
-rw-r--r--src/main.vala4
-rw-r--r--src/meson.build4
6 files changed, 120 insertions, 44 deletions
diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala
index 80e8b2e..024bc8b 100644
--- a/src/DesktopIntegration.vala
+++ b/src/DesktopIntegration.vala
@@ -6,7 +6,6 @@
namespace DesktopIntegration {
-private const string SENDTO_EXEC = "nautilus-sendto";
private const string DESKTOP_SLIDESHOW_XML_FILENAME = "wallpaper.xml";
private int init_count = 0;
@@ -22,8 +21,12 @@ private bool set_screensaver = false;
public void init() {
if (init_count++ != 0)
return;
-
- send_to_installed = Environment.find_program_in_path(SENDTO_EXEC) != null;
+ try{
+ Portal.get_instance();
+ send_to_installed = true;
+ } catch (Error error) {
+ send_to_installed = false;
+ }
}
public void terminate() {
@@ -90,36 +93,50 @@ public string? get_app_open_command(AppInfo app_info) {
}
public bool is_send_to_installed() {
+ // FIXME: Check if portal is available
return send_to_installed;
}
-public void files_send_to(File[] files) {
+public async void files_send_to(File[] files) {
if (files.length == 0)
return;
- string[] argv = new string[files.length + 1];
- argv[0] = SENDTO_EXEC;
-
- for (int ctr = 0; ctr < files.length; ctr++)
- argv[ctr + 1] = files[ctr].get_path();
-
- try {
- AppWindow.get_instance().set_busy_cursor();
-
- Pid child_pid;
- Process.spawn_async(
- "/",
- argv,
- null, // environment
- SpawnFlags.SEARCH_PATH,
- null, // child setup
- out child_pid);
-
- AppWindow.get_instance().set_normal_cursor();
- } catch (Error err) {
- AppWindow.get_instance().set_normal_cursor();
- AppWindow.error_message(_("Unable to launch Nautilus Send-To: %s").printf(err.message));
+ var file_names = new StringBuilder();
+ var files_builder = new VariantBuilder (new VariantType ("ah"));
+ var file_descriptors = new UnixFDList ();
+ for (int i=0; i<files.length; i++){
+ var fd = Posix.open (files[i].get_path (), Posix.O_RDONLY | Posix.O_CLOEXEC);
+ if (fd == -1) {
+ warning ("Send to: cannot open file: '%s'", files[i].get_path ());
+ continue;
+ }
+ try {
+ files_builder.add ("h", file_descriptors.append (fd));
+ } catch (Error e) {
+ warning ("Send to: cannot append file %s to file descriptor list: %s",
+ files[i].get_path(), e.message);
+ }
+ file_names.append(files[i].get_basename());
+ if(i<files.length-1){
+ file_names.append(", ");
+ }
+ }
+
+ var options = new HashTable<string, Variant> (str_hash, str_equal);
+ options.insert ("subject", _("Send files per Mail: ") + file_names.str);
+ options.insert ("attachment_fds", files_builder.end());
+ options.insert ("addresses", new Variant ("as", null));
+ AppWindow.get_instance().set_busy_cursor();
+ try{
+ var response = yield Portal.get_instance().compose_email (options, file_descriptors);
+ if (response == null){
+ throw new DBusError.FAILED("Did not get response");
+ }
+ } catch (Error e){
+ AppWindow.error_message(_("Unable to send file %s, %s").printf(
+ file_names.str, e.message));
}
+ AppWindow.get_instance().set_normal_cursor();
}
public void send_to(Gee.Collection<MediaSource> media) {
@@ -150,7 +167,7 @@ public void send_to(Gee.Collection<MediaSource> media) {
private void on_send_to_export_completed(Exporter exporter, bool is_cancelled) {
if (!is_cancelled)
- files_send_to(exporter.get_exported_files());
+ files_send_to.begin(exporter.get_exported_files());
send_to_exporter = null;
}
diff --git a/src/International.vala b/src/International.vala
index 555a91f..73f0763 100644
--- a/src/International.vala
+++ b/src/International.vala
@@ -4,8 +4,6 @@
* See the COPYING file in this distribution.
*/
-extern const string _LANG_SUPPORT_DIR;
-
public const string TRANSLATABLE = "translatable";
namespace InternationalSupport {
diff --git a/src/Portal.vala b/src/Portal.vala
new file mode 100644
index 0000000..c2e8e1e
--- /dev/null
+++ b/src/Portal.vala
@@ -0,0 +1,71 @@
+[DBus (name="org.freedesktop.portal.Email")]
+private interface PortalEmail : DBusProxy {
+ [DBus (name = "version")]
+ public abstract uint version { get; }
+}
+
+public class Portal : GLib.Object {
+ private static Portal portal;
+ public static Portal get_instance () {
+ if (portal == null){
+ portal = new Portal ();
+ }
+ return portal;
+ }
+
+ private const string BUS_NAME = "org.freedesktop.portal.Desktop";
+ private const string OBJECT_PATH = "/org/freedesktop/portal/desktop";
+
+ private GLib.DBusConnection bus;
+
+ public async Variant compose_email (HashTable<string, Variant> options,
+ UnixFDList attachments) throws Error{
+ if (bus == null){
+ bus = yield Bus.get(BusType.SESSION);
+ }
+
+ options.insert ("handle_token", Portal.generate_handle());
+
+ var options_builder = new VariantBuilder (VariantType.VARDICT);
+ options.foreach ((key, val) => {
+ options_builder.add ("{sv}", key, val);
+ });
+
+ PortalEmail? email = yield bus.get_proxy(BUS_NAME, OBJECT_PATH);
+
+ var response = email.call_with_unix_fd_list_sync (
+ "ComposeEmail",
+ new Variant ("(sa{sv})", yield Portal.get_parent_window(), options_builder),
+ DBusCallFlags.NONE,
+ -1,
+ attachments
+ );
+ return response;
+ }
+
+ private static string generate_handle () {
+ return "%s_%i".printf (
+ GLib.Application.get_default ().application_id.replace (".", "_").replace("-", "_"),
+ Random.int_range (0, int32.MAX)
+ );
+ }
+
+ private static async string get_parent_window () {
+ var window = AppWindow.get_instance().get_window ();
+
+ if (window is Gdk.Wayland.Window) {
+ var handle = "wayland:";
+ ((Gdk.Wayland.Window) window).export_handle ((w, h) => {
+ handle += h;
+ get_parent_window.callback ();
+ });
+ yield;
+ return handle;
+ } else if (window is Gdk.X11.Window) {
+ return "x11:%x".printf ((uint) ((Gdk.X11.Window) window).get_xid ());
+ } else {
+ warning ("Could not get parent window");
+ return "";
+ }
+ }
+}
diff --git a/src/Resources.vala b/src/Resources.vala
index 801305c..f9fa875 100644
--- a/src/Resources.vala
+++ b/src/Resources.vala
@@ -4,25 +4,13 @@
* See the COPYING file in this distribution.
*/
-// defined by ./configure or Makefile and included by gcc -D
-extern const string _PREFIX;
-extern const string _VERSION;
-extern const string GETTEXT_PACKAGE;
-extern const string _LIB;
-extern const string _LIBEXECDIR;
-extern const string? _GIT_VERSION;
-
namespace Resources {
public const string APP_TITLE = "Shotwell";
public const string APP_LIBRARY_ROLE = _("Photo Manager");
public const string APP_DIRECT_ROLE = _("Photo Viewer");
public const string APP_VERSION = _VERSION;
-#if _GITVERSION
public const string? GIT_VERSION = _GIT_VERSION;
-#else
- public const string? GIT_VERSION = null;
-#endif
public const string COPYRIGHT = _("Copyright 2016 Software Freedom Conservancy Inc.");
public const string APP_GETTEXT_PACKAGE = GETTEXT_PACKAGE;
diff --git a/src/main.vala b/src/main.vala
index 8313ba1..a971f15 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -383,7 +383,7 @@ void main(string[] args) {
}
if (CommandlineOptions.show_version) {
- if (Resources.GIT_VERSION != null)
+ if (Resources.GIT_VERSION != "")
print("%s %s (%s)\n", Resources.APP_TITLE, Resources.APP_VERSION, Resources.GIT_VERSION);
else
print("%s %s\n", Resources.APP_TITLE, Resources.APP_VERSION);
@@ -415,7 +415,7 @@ void main(string[] args) {
Debug.init(is_string_empty(filename) ? Debug.LIBRARY_PREFIX : Debug.VIEWER_PREFIX);
- if (Resources.GIT_VERSION != null)
+ if (Resources.GIT_VERSION != "")
message("Shotwell %s %s (%s)",
is_string_empty(filename) ? Resources.APP_LIBRARY_ROLE : Resources.APP_DIRECT_ROLE,
Resources.APP_VERSION, Resources.GIT_VERSION);
diff --git a/src/meson.build b/src/meson.build
index e252a82..530d6af 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -32,7 +32,7 @@ endif
shotwell_deps = [gio, gee, sqlite, gtk, sqlite, posix, gphoto2,
gstreamer_pbu, gio_unix, gudev, gexiv2, gmodule,
- libraw, libexif, sw_plugin]
+ libraw, libexif, sw_plugin, gdk, version]
if unity_available
shotwell_deps += [unity]
endif
@@ -197,6 +197,7 @@ executable('shotwell',
'MediaPage.vala',
'MediaDataRepresentation.vala',
'DesktopIntegration.vala',
+ 'Portal.vala',
'MediaInterfaces.vala',
'MediaMetadata.vala',
'VideoMetadata.vala',
@@ -244,6 +245,7 @@ executable('shotwell',
vala_args : ['--pkg', 'libgphoto2',
'--pkg', 'libraw',
'--pkg', 'libexif',
+ '--pkg', 'version',
'--gresources',
join_paths(meson.source_root(),
'org.gnome.Shotwell.gresource.xml')