@@ -16,28 +16,69 @@ pub mod error;
16
16
mod graphics;
17
17
18
18
impl DesktopEntry < ' _ > {
19
+ /// Launch the given desktop entry action either via dbus or via its `Exec` key with the default gpu or
20
+ /// the alternative one if available.
21
+ pub fn launch_action ( & self , action : & str , uris : & [ & str ] ) -> Result < ( ) , ExecError > {
22
+ let has_action = self
23
+ . actions ( )
24
+ . map ( |actions| actions. split ( ';' ) . any ( |act| act == action) )
25
+ . unwrap_or ( false ) ;
26
+
27
+ if !has_action {
28
+ return Err ( ExecError :: ActionNotFound {
29
+ action : action. to_string ( ) ,
30
+ desktop_entry : self . path ,
31
+ } ) ;
32
+ }
33
+
34
+ match Connection :: session ( ) {
35
+ Ok ( conn) => {
36
+ if self . is_bus_actionable ( & conn) {
37
+ self . dbus_launch ( & conn, uris, Some ( action. to_string ( ) ) )
38
+ } else {
39
+ self . shell_launch ( uris, Some ( action. to_string ( ) ) )
40
+ }
41
+ }
42
+ Err ( _) => self . shell_launch ( uris, Some ( action. to_string ( ) ) ) ,
43
+ }
44
+ }
45
+
19
46
/// Launch the given desktop entry either via dbus or via its `Exec` key with the default gpu or
20
47
/// the alternative one if available.
21
48
pub fn launch ( & self , uris : & [ & str ] ) -> Result < ( ) , ExecError > {
22
49
match Connection :: session ( ) {
23
50
Ok ( conn) => {
24
51
if self . is_bus_actionable ( & conn) {
25
- self . dbus_launch ( & conn, uris)
52
+ self . dbus_launch ( & conn, uris, None )
26
53
} else {
27
- self . shell_launch ( uris)
54
+ self . shell_launch ( uris, None )
28
55
}
29
56
}
30
- Err ( _) => self . shell_launch ( uris) ,
57
+ Err ( _) => self . shell_launch ( uris, None ) ,
31
58
}
32
59
}
33
60
34
- fn shell_launch ( & self , uris : & [ & str ] ) -> Result < ( ) , ExecError > {
35
- let exec = self . exec ( ) ;
36
- if exec. is_none ( ) {
37
- return Err ( ExecError :: MissingExecKey ( self . path ) ) ;
38
- }
61
+ fn shell_launch ( & self , uris : & [ & str ] , action : Option < String > ) -> Result < ( ) , ExecError > {
62
+ let exec = match action {
63
+ None => {
64
+ let exec = self . exec ( ) ;
65
+ if exec. is_none ( ) {
66
+ return Err ( ExecError :: MissingExecKey ( self . path ) ) ;
67
+ }
68
+ exec. unwrap ( )
69
+ }
70
+ Some ( action) => {
71
+ let exec = self . action_exec ( & action) ;
72
+ if exec. is_none ( ) {
73
+ return Err ( ExecError :: ActionExecKeyNotFound {
74
+ action,
75
+ desktop_entry : self . path ,
76
+ } ) ;
77
+ }
39
78
40
- let exec = exec. unwrap ( ) ;
79
+ exec. unwrap ( )
80
+ }
81
+ } ;
41
82
42
83
let mut exec_args = vec ! [ ] ;
43
84
@@ -281,12 +322,34 @@ mod test {
281
322
let de = DesktopEntry :: decode ( path. as_path ( ) , & input) . unwrap ( ) ;
282
323
let path = std:: env:: current_dir ( ) . unwrap ( ) ;
283
324
let path = path. to_string_lossy ( ) ;
284
- let path = format ! ( "file:/// {path}" ) ;
325
+ let path = format ! ( "file://{path}" ) ;
285
326
let result = de. launch ( & [ path. as_str ( ) ] ) ;
286
327
287
328
assert_that ! ( result) . is_ok ( ) ;
288
329
}
289
330
331
+ #[ test]
332
+ #[ ignore = "Needs a desktop environment with alacritty installed, run locally only" ]
333
+ fn should_launch_action ( ) {
334
+ let path = PathBuf :: from ( "/usr/share/applications/Alacritty.desktop" ) ;
335
+ let input = fs:: read_to_string ( & path) . unwrap ( ) ;
336
+ let de = DesktopEntry :: decode ( path. as_path ( ) , & input) . unwrap ( ) ;
337
+ let result = de. launch_action ( "New" , & [ ] ) ;
338
+
339
+ assert_that ! ( result) . is_ok ( ) ;
340
+ }
341
+
342
+ #[ test]
343
+ #[ ignore = "Needs a desktop environment with Nautilus installed, run locally only" ]
344
+ fn should_launch_action_via_dbus ( ) {
345
+ let path = PathBuf :: from ( "/usr/share/applications/org.gnome.Nautilus.desktop" ) ;
346
+ let input = fs:: read_to_string ( & path) . unwrap ( ) ;
347
+ let de = DesktopEntry :: decode ( path. as_path ( ) , & input) . unwrap ( ) ;
348
+ let result = de. launch_action ( "new-window" , & [ ] ) ;
349
+
350
+ assert_that ! ( result) . is_ok ( ) ;
351
+ }
352
+
290
353
#[ test]
291
354
fn should_build_command_with_gpu ( ) {
292
355
let cmd = with_non_default_gpu ( Command :: new ( "glxgears" ) ) ;
0 commit comments