ublue-os / main

OCI base images of Fedora with batteries included
https://universal-blue.org/images/main/
Apache License 2.0
508 stars 51 forks source link

Add xdg-terminal-exec #211

Closed orowith2os closed 9 months ago

orowith2os commented 1 year ago

Describe the package

GNOME/GLib currently uses xdg-terminal-exec as the first terminal binary, and then falls back to other terminals, like Console and Terminal.

Having xdg-terminal-exec would not only allow an easy way to set the default terminal, it would help get the script to be tested in the real world and maybe find more bugs that can be fixed with it.

The dconf preference on GNOME for the default terminal is deprecated and will not be used on recent versions of GNOME.

Information on the package

https://github.com/Vladimir-csp/xdg-terminal-exec

There is no Fedora package available as of now, but this is a simple script, so it could be put into the user's bin directories (like /usr/local/bin) fairly easily.

This may break existing setups that rely on the hardcoded terminal binaries. In response to that, I say: we should try and make the current hardcoded GLib terminals Just Work with xdg-terminal-exec. For the time being, we can go down the list of terminals in GLib's list and provide a desktop file with each of them that works with xdg-terminal-exec.

Image

Silverblue

castrojo commented 1 year ago

Just adding some links:

and we'd need to find Fedora's plans/spec for this

bigpod98 commented 1 year ago

from my limited testing in silverblue unless you have gnome terminal or xterm(not shipped with fedora silverblue or ublue silverblue ootb) or another terminal preprepared to work with xdg-terminal-exec, opening an app from desktop that is run in terminal doesnt open anything, including no error message.

orowith2os commented 1 year ago

opening an app from desktop that is run in terminal doesnt open anything, including no error message.

That's one thing I meant by finding bugs that can be fixed. And this shouldn't be too much of a worry if you relied on GLib's autodetection, as ideally several premade desktop files will be shipped, and ideally upstreamed.

bigpod98 commented 1 year ago

based on this limited testing i would propose holding on any changes as it is fairly disruptive until fedora shows any sign of adoption. as of writing i couldnt find anything regarding fedora adopting this proposed spec.

Arcitec commented 1 year ago

as ideally several premade desktop files will be shipped, and ideally upstreamed.

Unfortunately, this won't work. This is an immutable distro. Most people would do something like this:

rpm-ostree remove gnome-terminal gnome-terminal-nautilus
flatpak install --system com.raggesilver.BlackBox

If we want to ship pre-made .desktop files that contain the necessary X-ExecArg=-x (or whatever argument each specific terminal needs for launching a custom command), then we have to guess:

orowith2os commented 1 year ago

@Arcitec that's why upstreaming the patches is a good idea. For terminals already shipped in Flatpak, the fix would get to end users fairly quickly. For normal packages, they'd have to be shipped as a patch for the time being.

Arcitec commented 1 year ago

What is xdg-terminal-exec?

Installation

I already use it on my own custom image, since its purpose doesn't surprise me and I've done the necessary setup in my own image. Here's how to install it system-wide:

wget "https://raw.githubusercontent.com/Vladimir-csp/xdg-terminal-exec/master/xdg-terminal-exec" -O "/usr/bin/xdg-terminal-exec"
chmod +x "/usr/bin/xdg-terminal-exec"

However, it can (and I think this is the best way) be installed manually for any users who want it, by simply doing the following;

mkdir -p ~/.local/bin
wget "https://raw.githubusercontent.com/Vladimir-csp/xdg-terminal-exec/master/xdg-terminal-exec" -O ~/.local/bin/xdg-terminal-exec
chmod +x ~/.local/bin/xdg-terminal-exec

Configuration of Terminals

Every terminal that you want to support needs to have a magical X-ExecArg=-x value added to its .desktop file (where -x should be set to whatever argument the terminal binary needs to be given to accept a "custom command to execute"). Most terminals don't have that in their .desktop files. GNOME Terminal has it, but that's most likely because they saw that GLib added temporary support for it and wanted to be sure GNOME Terminal would still work (otherwise it would immediately break GNOME Terminal as soon as a user installs xdg-terminal-exec and the user would have to go through the messy configuration process manually).

Furthermore, every terminal's .desktop file must be a file or symlink inside a special "xdg-terminal-exec data directory". It doesn't just use the normal system's desktop files (that's probably a big part of why it was rejected due to being so overly complicated).

Here's an example of setting up a terminal on the per-user level, to illustrate the messy process:

  1. Create the xdg-terminal-exec data folder.
mkdir -p ~/.local/share/xdg-terminals/
  1. Copy the desired terminal desktop file to your local app folder. If you use the Flatpak app, then you must have the Flatpak version of the .desktop file. If you use a native app, then you must have the native version of the .desktop file. That is why we cannot ship pre-configured desktop files.
cp /usr/share/applications/com.gexperts.Tilix.desktop ~/.local/share/applications/
  1. Edit your local desktop file in a text editor, such as the ~/.local/share/applications/com.gexperts.Tilix.desktop file in this example.

  2. Insert the magical, required string next to its normal Exec= line. Use the flags that your terminal requires for launching arbitrary commands. Example:

X-ExecArg=-e
  1. Symlink the modified desktop file into xdg-terminal-exec's data folder.
ln -s ~/.local/share/applications/com.gexperts.Tilix.desktop ~/.local/share/xdg-terminals/com.gexperts.Tilix.desktop

Now that specific terminal is ready to be launched by xdg-terminal-exec. But you aren't done yet.

Next, we need...

User Configuration

It's not enough to configure the terminal itself above. You must also manually tell xdg-terminal-exec which terminal you want to run. That's done as follows...

  1. Open ~/.config/xdg-terminals.list in a text editor.

  2. Write the name of the ".desktop" file (without any full path) of the intended terminal into that config file. Example:

com.gexperts.Tilix.desktop

If that "terminal list" config file doesn't exist or nothing is written into it, then xdg-terminal-exec falls back to trying to launch xterm, which doesn't exist on Silverblue, so all attempts to launch terminal apps breaks.

If any of these steps are skipped...

Then the system breaks.

That's bad. Installing xdg-terminal-exec breaks GLib's automatic detection of what terminal you've got installed. It will instead only run xdg-terminal-exec. Nothing else. And if it isn't configured, then it's Game Over for our users. They won't see any terminal apps when launching terminal-based app shortcuts. Their systems simply stop working.

Upstreaming X-ExecArg into upstream desktop files?

It helps a little bit with one small part of the process (adding the ExecArg), but...

  1. The spec is rejected, so X-ExecArg is a "dead argument" that we'll be asking people to insert. I am sure many will refuse.
  2. We would have to wait a long time for packaging and upstreams to roll forwards, into new releases, new distro packages, new Flatpaks, to get the new .desktop files.
  3. Many projects are dead and will not be getting updates (terminal emulators are notorious for being dead projects).
  4. Adding the argument is just one small part. We also need to create symlinks from xdg-terminal-exec's data directory to the actual .desktop file. Which doesn't happen automatically when you install Flatpak versions of terminals. In fact, only GNOME Terminal (native package) ships the necessary symlink by default. Every other terminal would be broken.
  5. We would have to create symlinks to every location of .desktop files, pre-emptively.
  6. We can't do that, since we don't know the location of the user's .desktop files. So even if we get X-ExecArg= into every upstream Terminal's .desktop file, and all of them magically release new versions to appease us, and the packages finally reach our distro/flathub, then we are still completely screwed and unable to ship this to users "seamlessly", because we simply cannot know where those .desktop file will exist on disk.
  7. We can only create 1 link per app. We'd have to guess: Is it native? System flatpak? Or user flatpak? We can only link to one of those potential .desktop locations from xdg-terminal-exec's data dir. Now it becomes even clearer why the spec was rejected.

Better alternatives...

You know all that complicated setup above? There's a simpler solution. And I don't mean simpler for us. I don't mean simpler for distro packagers. I don't mean simpler for terminal app maintainers... I literally mean simpler for the users. It's literally easier than configuring the overly complicated xdg-terminal-exec's configuration files, desktop file edits, creating data directories and creating symlinks. And it illustrates well why the spec was deemed badly designed and rejected:

  1. We know that GLib looks for xdg-terminal-exec as a binary, and simply submits the "command to run" as the arguments to it.

  2. So, instead of going through alllllll that arcane ritual stuff above, you can just create your own "xdg-terminal exec" "binary" file instead, and stick the exact terminal into it. So create ~/.local/bin/xdg-terminal-exec in a text editor, save it with the following example contents, mark it as executable (chmod +x it), and you're done. Way easier than trying to follow the rejected spec.

Launching native Tilix:

#!/usr/bin/env bash

tilix -e "$@"

If you instead want to launch Flatpak Blackbox (not tested, but the principle is like this):

#!/usr/bin/env bash

flatpak run com.raggesilver.BlackBox -- -c "$@"

Suddenly it becomes clear why it isn't even worth attempting to follow the arcane rituals. It's literally easier to create your own script to launch the exact terminal you want. With just 1 config file and just 1 line of actual code/config.

Lastly, I don't think we should prop up such a bad, rejected spec. A spec that fails so spectacularly that it's literally easier to replace its binary name than to try to configure it.

orowith2os commented 1 year ago

I'll look into reimplementing xdg-terminal-exec but without some of its design flaws in a bit to hopefully address most everything.

Arcitec commented 1 year ago

I'll look into reimplementing xdg-terminal-exec but without some of its design flaws in a bit to hopefully address most everything.

That would be a great idea.

The worst issue is the X-ExecArg=... in the .desktop files, since it's a nightmare to add that to desktop files. But the need to manually symlink specific desktop files is horrific too.

Something where you can just say the desktop file's basic name and the argument would be ideal. Imagine if we could just do this in a ~/.config/xdg-terminal-exec.list (slightly changed config filename to avoid confusion?):

com.raggesilver.BlackBox.desktop -c

And then have it automatically scan for the matching .desktop file (using XDG priority) and then launch it with the given -c <command line> arg. That would be a good solution.

Just remember that it would need to have a fallback that also scans for all of GLib's normal defaults seamlessly, if no config is found:

https://gitlab.gnome.org/GNOME/glib/-/blob/2.76.2/gio/gdesktopappinfo.c?ref_type=tags#L2701-2713

And if literally nothing is found, a final fallback to xterm makes sense.

orowith2os commented 1 year ago

I plan on just naming the binary xdg-terminal-exec and needing the desired terminal to be added there directly. It wouldn't need desktop file modifications, and it would easily work with almost any terminal emulator. I'll discuss a bit more when I start work on it.

Arcitec commented 1 year ago

Sounds good, and that would also solve the the issue of config search-paths, etc. I'm excited to see what you come up with! Especially if you make it detect Flatpak versions of the Terminals automatically. ;)

Just be sure that it automatically detects every terminal that GLib currently handles automatically, so we don't break systems.

As long as it's a seamless transition that automatically falls back to the same terminal list as GLib, so that users won't know the difference, then I'll be in favor of adding the improved reimplementation.

Arcitec commented 1 year ago

@orowith2os Oh wait... keep one thing in mind: If this is a proposal for shipping the binary inside uBlue, then it'd be installed at /usr/bin/xdg-terminal-exec (or /usr/local/bin) which means it's immutable, so editing the config via editing the script itself won't work.

But if it's a different proposal, to just have something anyone can drop into their local ~/.local/bin/xdg-terminal-exec then the solution sounds nice.

Just asking, since this discussion is about adding something to the uBlue images' system-wide install by default. So if that is still the goal, then per-user configurability should be part of the new design's spec. There would need to be a ~/.config/something file to set the terminal choice per-user. And I recommend picking a name that's different from the original's ~/.config/xdg-terminals.list since the config file format would need changes to support adding arbitrary terminals (native, Flatpak) and a way to specify the "argument the terminal needs for executing a command". Being able to write down a list of terminals in preferred order in the config and having it pick the "first one it finds" is also a good feature.

Lastly, one of the only good parts of the original version was that it tries to fall back to the "first discovered terminal" (from a build-in list of supported ones) if it cannot find the user-specified terminal. That behavior would probably be desirable here too. So that users are guaranteed to see a terminal window, rather than "desktop shortcuts" completely breaking and failing to do anything if the "primary" configured terminal cannot be found.

orowith2os commented 1 year ago

which means it's immutable, so editing the config via editing the script itself won't work.

This would be written in Rust, so you'd be editing binary even if it was mutable ;)

I'll write everything to a unified config file with all the terminals and everything so it's not hardcoded but can still fall back to some defaults.

bigpod98 commented 1 year ago

currently i still think we should wait a bit to see this play out more, specifically how our upstream fedora handles this entire thing, there is no need to my knowledge that we need to act now.

orowith2os commented 1 year ago

Yes, there's no need, but it would vastly improve the user experience to have some sort of xdg-terminal-exec for the GNOME images.

bigpod98 commented 1 year ago

What is the case with other desktop environments oustide of gnome do they use this same proposed spec

Arcitec commented 1 year ago

What is the case with other desktop environments oustide of gnome do they use this same proposed spec

Nobody else uses it and FreeDesktop has no interest in accepting it.

The only reason this is even a discussion or proposal is because GNOME decided to remove the old dconf variables that used to be able to set a "terminal binary and launch argument". Typical GNOME fashion (I use GNOME too...), where they remove something without a replacement solution. Users were understandably upset that they could no longer choose which terminal GNOME uses when launching desktop shortcuts.

GNOME just begrudgingly added xdg-terminal-exec because they were tired of being told to manually add new terminals to the list of supported terminals in GLib. And they said okay since it was a simple matter of adding 1 line to place xdg-terminal-exec as the first "Terminal binary" in the list, so they decided to temporarily add it, and announced that that they won't be updating the terminal list manually anymore.

They decided that it will be removed from GNOME again when xdg-default-apps has a mechanism for handling "default terminal". But that proposal seems to be stalled due to lack of consensus, if you check the comments.

Arcitec commented 1 year ago

This would be written in Rust, so you'd be editing binary even if it was mutable ;)

I'll write everything to a unified config file with all the terminals and everything so it's not hardcoded but can still fall back to some defaults.

@orowith2os That sounds brilliant. I wish you lots of luck and fun with the implementation and look forward to seeing it. You have a good understanding of the situation now and the pitfalls, so I am sure you'll come up with something nice! :)

castrojo commented 1 year ago

Yes, there's no need, but it would vastly improve the user experience to have some sort of xdg-terminal-exec for the GNOME images.

I'm down to play, I've added this to bluefin and will follow up on how to set up blackbox and stuff:

https://github.com/ublue-os/bluefin/pull/223

orowith2os commented 1 year ago

I've published my source code to my GitLab, it's almost ready. Just need to sort out a few more things until it's ready. Contributions greatly appreciated!

https://gitlab.com/OroWith2Os/xdg-terminal-exec

mcepl commented 1 year ago

Overcomplicated? 359 lines of shell script doesn’t sound so bad.

mcepl commented 1 year ago

The worst issue is the X-ExecArg=... in the .desktop files, since it's a nightmare to add that to desktop files.

Why? Changing of like 20 .desktop files (how many terminals is out there relevant for Fedora?) doesn’t seem like to much a big deal.

castrojo commented 9 months ago

Downstreams are using Ptyxis now.