7
7
//! * Path to non-existent file generates an error for both implementations.
8
8
9
9
use crate :: OpenError ;
10
- use dbus:: arg:: messageitem:: MessageItem ;
11
- use dbus:: arg:: { Append , Variant } ;
12
- use dbus:: blocking:: Connection ;
10
+ use std:: collections:: HashMap ;
13
11
use std:: fs:: File ;
12
+ use std:: os:: fd:: AsFd ;
14
13
use std:: path:: Path ;
15
- use std:: time:: Duration ;
16
14
use std:: { error, fmt, io} ;
17
15
use url:: Url ;
18
-
19
- const DBUS_TIMEOUT : Duration = Duration :: from_secs ( 5 ) ;
16
+ use zbus:: blocking:: Connection ;
20
17
21
18
// We should prefer the OpenURI interface, because it correctly handles runtimes such as Flatpak.
22
19
// However, OpenURI was broken in the original version of the interface (it did not highlight the items).
23
20
// This version is still in use by some distributions, which would result in degraded functionality for some users.
24
21
// That's why we're first trying to use the FileManager1 interface, falling back to the OpenURI interface.
25
22
// Source: https://chromium-review.googlesource.com/c/chromium/src/+/3009959
26
23
pub ( crate ) fn reveal_with_dbus ( path : & Path ) -> Result < ( ) , OpenError > {
27
- let connection = Connection :: new_session ( ) . map_err ( dbus_to_open_error) ?;
24
+ let connection = Connection :: session ( ) . map_err ( dbus_to_open_error) ?;
28
25
reveal_with_filemanager1 ( path, & connection)
29
26
. or_else ( |_| reveal_with_open_uri_portal ( path, & connection) )
30
27
}
31
28
32
29
fn reveal_with_filemanager1 ( path : & Path , connection : & Connection ) -> Result < ( ) , OpenError > {
33
30
let uri = path_to_uri ( path) ?;
34
- let proxy = connection. with_proxy (
35
- "org.freedesktop.FileManager1" ,
36
- "/org/freedesktop/FileManager1" ,
37
- DBUS_TIMEOUT ,
38
- ) ;
39
- proxy
40
- . method_call (
41
- "org.freedesktop.FileManager1" ,
42
- "ShowItems" ,
43
- ( vec ! [ uri. as_str( ) ] , "" ) ,
44
- )
45
- . map_err ( dbus_to_open_error)
31
+ let proxy = FileManager1Proxy :: new ( connection) . map_err ( dbus_to_open_error) ?;
32
+ proxy. show_items ( & [ uri] , "" ) . map_err ( dbus_to_open_error)
46
33
}
47
34
48
35
fn reveal_with_open_uri_portal ( path : & Path , connection : & Connection ) -> Result < ( ) , OpenError > {
49
36
let file = File :: open ( path) . map_err ( OpenError :: Io ) ?;
50
- let proxy = connection. with_proxy (
51
- "org.freedesktop.portal.Desktop" ,
52
- "/org/freedesktop/portal/desktop" ,
53
- DBUS_TIMEOUT ,
54
- ) ;
37
+ let proxy = OpenURIProxy :: new ( connection) . map_err ( dbus_to_open_error) ?;
55
38
proxy
56
- . method_call (
57
- "org.freedesktop.portal.OpenURI" ,
58
- "OpenDirectory" ,
59
- ( "" , file, empty_vardict ( ) ) ,
60
- )
39
+ . open_directory ( "" , file. as_fd ( ) . into ( ) , HashMap :: new ( ) )
61
40
. map_err ( dbus_to_open_error)
62
- }
63
-
64
- fn empty_vardict ( ) -> impl Append {
65
- dbus:: arg:: Dict :: < & ' static str , Variant < MessageItem > , _ > :: new ( std:: iter:: empty ( ) )
41
+ . map ( |_| ( ) )
66
42
}
67
43
68
44
fn path_to_uri ( path : & Path ) -> Result < Url , OpenError > {
@@ -77,7 +53,7 @@ fn uri_to_open_error() -> OpenError {
77
53
) )
78
54
}
79
55
80
- fn dbus_to_open_error ( error : dbus :: Error ) -> OpenError {
56
+ fn dbus_to_open_error ( error : zbus :: Error ) -> OpenError {
81
57
OpenError :: Io ( io:: Error :: other ( error) )
82
58
}
83
59
@@ -91,3 +67,32 @@ impl fmt::Display for FilePathToUriError {
91
67
}
92
68
93
69
impl error:: Error for FilePathToUriError { }
70
+
71
+ /// # D-Bus interface proxy for `org.freedesktop.FileManager1` interface.
72
+ #[ zbus:: proxy(
73
+ gen_async = false ,
74
+ interface = "org.freedesktop.FileManager1" ,
75
+ default_service = "org.freedesktop.FileManager1" ,
76
+ default_path = "/org/freedesktop/FileManager1"
77
+ ) ]
78
+ trait FileManager1 {
79
+ /// ShowItems method
80
+ fn show_items ( & self , uris : & [ Url ] , startup_id : & str ) -> zbus:: Result < ( ) > ;
81
+ }
82
+
83
+ /// # D-Bus interface proxy for: `org.freedesktop.portal.OpenURI`
84
+ #[ zbus:: proxy(
85
+ gen_async = false ,
86
+ interface = "org.freedesktop.portal.OpenURI" ,
87
+ default_service = "org.freedesktop.portal.Desktop" ,
88
+ default_path = "/org/freedesktop/portal/desktop"
89
+ ) ]
90
+ pub trait OpenURI {
91
+ /// OpenDirectory method
92
+ fn open_directory (
93
+ & self ,
94
+ parent_window : & str ,
95
+ fd : zbus:: zvariant:: Fd < ' _ > ,
96
+ options : HashMap < & str , & zbus:: zvariant:: Value < ' _ > > ,
97
+ ) -> zbus:: Result < zbus:: zvariant:: OwnedObjectPath > ;
98
+ }
0 commit comments