Repository: wezterm/wezterm (language: rust)

Issue:
[KDE] wezterm cannot be configured as default terminal because it doesn't support "-e CMD"
### What Operating System(s) are you seeing this problem on?

Linux X11

### Which Wayland compositor or X11 Window manager(s) are you using?

KDE 5.25

### WezTerm version

wezterm 20220905-102802-7d4b8249

### Describe the bug

I have configured wezterm as the default terminal emulator in KDE and am using mutt as my default mail client.

When I run `xdg-open 'mailto:test@test.com'`, wezterm fails to start mutt with the following error message:
```
ERROR  wezterm_gui > Unable to spawn -e because it doesn't exist on the filesystem and was not found in PATH; terminating
```

This is because KDE assumes that terminal applications use a `-e CMD` parameter to start a given command, which is the case for most terminal emulators, e.g. for konsole, gnome-terminal and alacritty.
On a low level KDE calls wezterm with the following cmdline for the above `xdg-open`:
```bash
wezterm start --cwd . -- -e mutt 'mailto:test@test.com'
```

It would be good if wezterm supported the `-e CMD` parameter as well, **right now wezterm tries to start an executable with name `-e`**.

I know that the `-e CMD` behaviour is not the official XDG spec, but it is how this is unofficially working for almost all other terminal emulators so it would be great if wezterm supported this as well.

Here is the current Exec line of `wezterm.desktop`:
```
Exec=wezterm start --cwd . --
```

And here is `mutt.desktop`:
```
Exec=mutt %u
Terminal=true
```

The relevant part how KDE parses the desktop file when we call `xdg-open` can be found here: https://github.com/KDE/kio/blob/ad27f0e299e7a7a1f4059431f882f9a4ebba71fd/src/core/desktopexecparser.cpp#L532

As you can see, KDE always prepends an `-e` as that has worked for most terminal emulators.

**In summary** we might get better compatibility, if we implement `-e CMD` and do the following diff on our desktop file:
```diff
-Exec=wezterm start --cwd . --
+Exec=wezterm start --cwd .
```

What is your opinion on this? Do you think this change makes sense, or would you rather want KDE to change its behaviour as it is "non-standard"?


Discussion / hints:
I also just manually tested that using `Exec=wezterm start --cwd .` in the desktop file does not break the functionality in Dolphin as described in #2271, and pretty much all emulators don't add `-e` (which in this case would be equivalent to wezterm's `--`) to their desktop file.

So I think implementing `-e` and adapting the desktop file as above would increase compatibility without breaking anything.
I think the KDE behavior is problematic and there should probably at least be an issue raised against KDE to discuss it.

I'm not opposed to making small changes to wezterm make things easier in the mean time, but it's still problematic; I'm not sure how to instruct the clap crate to handle `-e` for this case off the top of my head, for example.

https://github.com/wez/wezterm/blob/main/assets/open-wezterm-here was added for dolphin.  Maybe that concept can be extended to make that script accept and ignore `-e` and then pass the remaining parameters down?

Then wezterm's .desktop file can point to that script instead?




> I'm not sure how to instruct the clap crate to handle `-e` for this case

There exists [trailing_var_arg](https://docs.rs/clap/latest/clap/builder/struct.Arg.html#method.trailing_var_arg) in clap exactly for this purpose

> https://github.com/wez/wezterm/blob/main/assets/open-wezterm-here was added for dolphin. Maybe that concept can be extended to make that script accept and ignore `-e` and then pass the remaining parameters down?
> 
> Then wezterm's .desktop file can point to that script instead?

That would be a possibility but I don't think we would need to go that complicated. Also I don't really understand why the `open-wezterm-here` script is needed, the change in #2271 should have been sufficient, but then again I didn't test on XFCE.

I can open an issue against KDE, but I think it is unlikely they will want to drop the `-e` as that is the only way to pass the cmdline to other terminals such as konsole or alacritty.
The upstream KDE bug is tracked at: https://bugs.kde.org/show_bug.cgi?id=460387

Let's first wait what KDE says about this, I expect they don't want to drop the `-e` thing.

If it is indeed not fixable on the KDE side, I can look at this myself in wezterm and make a PR for you (implementing `-e` support and adapting the desktop file), hopefully not breaking anything else ;)
I think the opinion of KDE devs is stated in https://bugs.kde.org/show_bug.cgi?id=459616#c4. If I understand it correctly, they want to propose a change in the FreeDesktop spec, which sounds like it may take quite some time.

Fix patch:
diff --git a/assets/wezterm.desktop b/assets/wezterm.desktop
index 751588740e0..6ad25398de0 100644
--- a/assets/wezterm.desktop
+++ b/assets/wezterm.desktop
@@ -5,7 +5,7 @@ Keywords=shell;prompt;command;commandline;cmd;
 Icon=org.wezfurlong.wezterm
 StartupWMClass=org.wezfurlong.wezterm
 TryExec=wezterm
-Exec=wezterm start --cwd . --
+Exec=wezterm start --cwd .
 Type=Application
 Categories=System;TerminalEmulator;Utility;
 Terminal=false
diff --git a/wezterm-gui-subcommands/src/lib.rs b/wezterm-gui-subcommands/src/lib.rs
index 06318aca9d3..46f04ff5094 100644
--- a/wezterm-gui-subcommands/src/lib.rs
+++ b/wezterm-gui-subcommands/src/lib.rs
@@ -163,6 +163,18 @@ pub struct StartCommand {
     #[arg(long = "cwd", value_parser, value_hint=ValueHint::DirPath)]
     pub cwd: Option<OsString>,
 
+    /// Dummy argument that consumes "-e" and does nothing.
+    /// This is meant as a compatibility layer for supporting the
+    /// widely adopted standard of passing the command to execute
+    /// to the terminal via a "-e" option.
+    /// This works because we then treat the remaining cmdline as
+    /// trailing options, that will automatically be parsed via the
+    /// existing "prog" option.
+    /// This option exists only as a fallback. It is recommended to pass
+    /// the command as a normal trailing command instead if possible.
+    #[arg(short = 'e', hide = true)]
+    pub _cmd: bool,
+
     /// Override the default windowing system class.
     /// The default is "org.wezfurlong.wezterm".
     /// Under X11 and Windows this changes the window class.
diff --git a/wezterm-gui/src/main.rs b/wezterm-gui/src/main.rs
index 1cc56910951..3140dfc513d 100644
--- a/wezterm-gui/src/main.rs
+++ b/wezterm-gui/src/main.rs
@@ -143,6 +143,7 @@ async fn async_run_ssh(opts: SshCommand) -> anyhow::Result<()> {
         position: opts.position,
         workspace: None,
         prog: opts.prog.clone(),
+        ..Default::default()
     };
 
     let cmd = if !opts.prog.is_empty() {


Test patch: