diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/DesktopIntegration.vala | 71 | ||||
-rw-r--r-- | src/International.vala | 2 | ||||
-rw-r--r-- | src/Portal.vala | 71 | ||||
-rw-r--r-- | src/Resources.vala | 12 | ||||
-rw-r--r-- | src/main.vala | 4 | ||||
-rw-r--r-- | src/meson.build | 4 |
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') |