From a12e7eed43531538fdd893bfe4fbd4df41c62da5 Mon Sep 17 00:00:00 2001 From: Christopher Davis Date: Wed, 29 Dec 2021 17:43:58 -0800 Subject: [PATCH] window: Use portal to open files in other apps Calling `xdg-open` is the wrong thing to do, and has flaky reliability. What we want is to use the portal directly with the exact behavior we want. When using the portal we can't just pass the uri - we need to own a file descriptor. --- Cargo.lock | 84 +++++++++++++++++++++++++++++++++------------------ src/window.rs | 25 +++++++++++---- 2 files changed, 74 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01edebf..a1064e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" [[package]] name = "ashpd" version = "0.2.0-alpha-5" -source = "git+https://github.com/bilelmoussaoui/ashpd#e6c4628a50b5e16c37b14bd4588fca853fa5604e" +source = "git+https://github.com/bilelmoussaoui/ashpd#157c0dc5709082ace2e57cb469455251abcac495" dependencies = [ "enumflags2", "futures", @@ -33,8 +33,8 @@ dependencies = [ "zbus", "zbus_macros", "zbus_names", - "zvariant", - "zvariant_derive", + "zvariant 3.0.0", + "zvariant_derive 3.0.0", ] [[package]] @@ -280,9 +280,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "a25c90b056b3f84111cf183cbeddef0d3a0bbe9a674f057e1a1533c315f24def" dependencies = [ "enumflags2_derive", "serde", @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "144ec79496cbab6f84fa125dc67be9264aef22eb8a28da8454d9c33f15108da4" dependencies = [ "proc-macro2", "quote", @@ -952,7 +952,7 @@ dependencies = [ "once_cell", "pretty_env_logger", "zbus", - "zvariant", + "zvariant 2.10.0", ] [[package]] @@ -981,9 +981,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.21.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", @@ -1027,6 +1027,16 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +[[package]] +name = "ordered-stream" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44630c059eacfd6e08bdaa51b1db2ce33119caa4ddc1235e923109aa5f25ccb1" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "pango" version = "0.15.0" @@ -1297,15 +1307,6 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" -[[package]] -name = "slotmap" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" -dependencies = [ - "version_check", -] - [[package]] name = "smallvec" version = "1.7.0" @@ -1522,9 +1523,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zbus" -version = "2.0.0-beta.7" +version = "2.0.0-beta.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2e14e7c15f04af391e91950081f5ac19c6a595a8906bc156f5d914ab57b681" +checksum = "2422a0f87e8307730a734dc6c59af0dcd680db1b9944ab1a2fb5061194e47233" dependencies = [ "async-broadcast", "async-channel", @@ -1544,22 +1545,22 @@ dependencies = [ "hex", "nix", "once_cell", + "ordered-stream", "rand", "serde", "serde_repr", "sha1", - "slotmap", "static_assertions", "zbus_macros", "zbus_names", - "zvariant", + "zvariant 3.0.0", ] [[package]] name = "zbus_macros" -version = "2.0.0-beta.7" +version = "2.0.0-beta.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d54aa0d29b3e36e112361c54bc3b750e12a45d704f86ca543e3101b338834ad" +checksum = "b229592c7b16f37d82a9a83fc7c20dd4979efca70c714edec5847ac5c168e744" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1570,13 +1571,13 @@ dependencies = [ [[package]] name = "zbus_names" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45b644a32f28e5fc17974d63d3d8ee9f9f7985f9f4fb6f4e12d8be2fa3eaa31" +checksum = "ae1f142d242d6854815a8c5c2aea83d9508f72f5757d0a137c21ef4b07bfee66" dependencies = [ "serde", "static_assertions", - "zvariant", + "zvariant 3.0.0", ] [[package]] @@ -1584,13 +1585,26 @@ name = "zvariant" version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a68c7b55f2074489b7e8e07d2d0a6ee6b4f233867a653c664d8020ba53692525" +dependencies = [ + "byteorder", + "libc", + "serde", + "static_assertions", + "zvariant_derive 2.10.0", +] + +[[package]] +name = "zvariant" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a946c049b2eac1a253f98e9267a8ce7a3d93be274ea146e6dd7a0965232a911" dependencies = [ "byteorder", "enumflags2", "libc", "serde", "static_assertions", - "zvariant_derive", + "zvariant_derive 3.0.0", ] [[package]] @@ -1604,3 +1618,15 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zvariant_derive" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28fce5afb8d639bff79b1e8cdb258a3ca22d458f4603b23d794b4cb4e878c990" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] diff --git a/src/window.rs b/src/window.rs index 7492a0e..4c428a7 100644 --- a/src/window.rs +++ b/src/window.rs @@ -25,6 +25,9 @@ use gtk::prelude::*; use gtk::subclass::prelude::*; use gtk::CompositeTemplate; +use ashpd::desktop::open_uri; +use ashpd::WindowIdentifier; + use crate::config; use crate::util; use crate::widgets::LpImageView; @@ -198,7 +201,7 @@ mod imp { glib::wrapper! { pub struct LpWindow(ObjectSubclass) @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, - @implements gio::ActionMap, gio::ActionGroup; + @implements gio::ActionMap, gio::ActionGroup, gtk::Native; } impl LpWindow { @@ -263,12 +266,22 @@ impl LpWindow { fn open_with(&self) { let imp = self.imp(); + let ctx = glib::MainContext::default(); - if let Some(uri) = imp.image_view.uri() { - std::process::Command::new("xdg-open") - .arg(uri) - .output() - .unwrap(); + if let Some(file) = imp + .image_view + .uri() + .map(|u| u.trim_start_matches("file://").to_string()) + .map(|u| std::fs::File::open(u).ok()) + .flatten() + { + ctx.spawn_local(clone!(@weak self as win => async move { + if let Err(e) = + open_uri::open_file(&WindowIdentifier::from_native(&win).await, &file, true, true).await + { + log::error!("Could not open image in external program: {}", e); + } + })); } else { log::error!("No URI for current image.") }