Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting mimeapps.list breaks GNOME/GLib's handling of MIME aliases #42

Open
nyanpasu64 opened this issue Jun 10, 2021 · 0 comments
Open

Comments

@nyanpasu64
Copy link

This application currently sorts each section of mimeapps.list alphabetically when rewriting it. This occurs because it's stored internally as a randomly-ordered HashMap and exposing this randomness externally is undesirable. Unfortunately this interacts in complex ways with MIME aliases.

What are MIME aliases? Each MIME type .xml can declare other MIME types as aliases for the XML file's "canonical name". For example, in the shared-mime-info database, audio/flac is the canonical name for FLAC files, with alias audio/x-flac. (You can see this by looking in /usr/share/mime/audio/flac.xml and spotting the line <alias type="audio/x-flac"/>.) And audio/x-wav is the canonical name for WAV files, with alias audio/wav.

MIME aliases cause problems

The problem is that GNOME/GTK/GLib apps depend on the order of mimeapps.list when resolving the apps bound to a MIME type with aliases. I've done some research on a (GNOME GitLab bug report](https://gitlab.gnome.org/GNOME/glib/-/issues/1298#note_1125791). If multiple aliases of the same MIME type appear in mimeapps.list, GLib will use whichever list of applications appears first, rather than the canonical MIME type. This confused me at first, when I was editing [Default Applications] audio/flac and it didn't take effect because audio/x-flac appeared earlier. Luckily, GNOME usually (but not always) only writes the canonical MIME type to mimeapps.list, or writes the canonical MIME type before aliases.

Unfortunately handlr (like KDE) sorts each section of mimeapps.list alphabetically. If this sorts an alias before a canonical type, then GLib will use an alias for resolving default apps, but the canonical type for setting default apps, preventing the user from setting the default app for that file type!

For example, both KDE (kmimetypefinder5 -f foo.wav) and GNOME (gio info must-exist.wav) think .wav files are audio/x-wav (the canonical name). But when handlr rewrites mimeapps.list, it sorts each section of ~/.config/mimeapps.list alphabetically:

handlr/src/apps/user.rs

Lines 191 to 196 in b5468c1

for (k, v) in self.added_associations.iter().sorted() {
writer.write_all(k.essence_str().as_ref())?;
writer.write_all(b"=")?;
writer.write_all(v.iter().join(";").as_ref())?;
writer.write_all(b";\n")?;
}

So now audio/wav (a nonstandard alias) comes before audio/x-wav, and GTK/GNOME/GLib will use the "ghost" audio/wav association when opening WAV files, preventing .wav files from being reconfigured in either KDE or GNOME! (Reconfiguring in either KDE or GNOME edits the canonical MIME type, which only takes effect in KDE and not GNOME.)


The alternative is to prioritize the canonical MIME mapping over aliases. This is what KDE does.

After researching this issue extensively, I've concluded that both approaches are flawed. Searching the shared-mime-info repo's commit history, I found that the shared-mime-info db is actively swapping main/alias declarations. I think that this can cause KDE to leave behind stale associations for aliases when it writes new associations to the new canonical names.

Preserving mimeapps.list order?

If you want to minimize the amount that this program changes mimeapps.list, one approach is to preserve the order of mimeapps.list and only append items to the end. This requires modifying the code to preserve the order of items in the hashmap, which will not be easy.

Fixing mimeapps.list?

After researching the MIME alias issue I described earlier, I had the idea to write a MIME fixer app in Rust (since GNOME didn't seem to be fixing the issue) coupled with a MIME editing GUI. Then I found handlr (a MIME editing CLI) and thought it would make sense to integrate this functionality into handlr instead.

Are you interested in extending handlr to fix mimeapps.list files to behave properly on GLib/GNOME and erase stale entries? (Perhaps fixing mimeapps.list should only occur when a settings flag is enabled, and if not, handlr will leave mimeapps.list in their original order, and unedited except for entries you explicitly modify.)

My idea for a MIME fixer is to store all associations in the program by their canonical name. If fixing is enabled, when loading mimeapps.list from disk, the program merges the associations of canonical names and aliases (preferring the canonical name to aliases, but falling back to the first alias in the file if no canonical name is present). And when the user tries to set the file association of a MIME alias, if fixing is enabled, handlr will set the association of the canonical name instead.

Initially, I wanted to always write MIME associations to all MIME type aliases as well as the canonical name. However this is a flawed idea because in the shared-mime-info database, some MIME type aliases have switched between different canonical MIME types, and if the canonical MIME types are mapped to different apps, this can lead to inconsistencies between the canonical and aliased MIME types.

I think it's a better idea to erase all MIME aliases present and never write MIME aliases at all, only write to the canonical name. This way, as long as MIME types never change canonical names, they will never go stale. And if MIME types do change canonical names, running the MIME-fixing program again will rename the mimeapps.list entry to the new name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant