Files misplaced in sandbox?


New here, please be patient.

My app was just published on flathub (Install Password Safe on Linux | Flathub), and of course people have started finding issues, mainly related to files not being where they’re expected. Specifically:

  1. The app expects to find a file under /usr/share/passwordsafe/xml/. Looking in the sandbox via ‘flatpak enter’, I see the file under /app/share/passwordsafe/xml. How is this mapped to /usr/share? What’s odd is that the app “sees” the help file under /app/share/passwordsafe/help. Why this but not the xml file?

  2. Even stranger, the localized files are in a clearly incorrect location, e,g,
    /app/share/runtime/locale/fr/share/fr/LC_MESSAGES/ instead of

The project is built using a pretty standard cmake file, and .deb and rpm packages place these files correctly.
Any suggestions on how to approach this would be greatly appreciated.


In the sandbox, the app is mounted at /app, the runtime is mounted at /usr, and various extensions are mounted below those.

flatpak-builder just sets the CMake install prefix to /app. Instead of hardcoding the location of that directory, you should use a config header to get it from the buildsystem: configure_file — CMake 3.28.3 Documentation

Flatpak does set XDG_DATA_DIRS to include /app/share, which may be how the other directory is working.

I’m not an expert on the .Locale extension system, but this seems to match other apps. flatpak-builder defines the Locale extension point automatically with directory=share/runtime/locale and locale-subset=true. This requires that the locale extension contain top-level directories corresponding to each language code. The seemingly redundant path allows locale subsets to also include locale definitions for lib/locale. This is necessary for the platform locale extension at least.

The app gets access to these via symlinks in /app/share/locale. I notice those are mostly missing for your app; only ko is present. I’m not sure what layer creates them, but I’d guess that they’re created for each directory the app creates in /app/share/locale.

After writing most of this, I found a great explanation from Alex here: 1621074 - fix l10n in Flatpaks

Thanks for the prompt reply. I’m still trying to understand what you & Alex wrote about locales. Regarding the help and xml directories:
For help, there’s an environment variable (PWS_HELPDIR) that’s used in the org.pwsafe.pwsafe.yml file to override the default (hardcoded) value of /usr/share/passwordsafe/help/ to /app/share/passwordsafe/help/
I can add the same logic for the xml directory (/usr/share/passwordsafe/xml/ → /app/share/passwordsafe/xml/), but surely there’s a more elegant way to do this?
For example, is there a way to instruct flatpak to install these directly under /usr?

This is already wrong by design. It should honour “prefix”. Decades of software written for UNIX do that.

No, this is a fundamental part of flatpak’s design. /usr is the runtime, and /app is the app.

As I mentioned before, the standard approach is to have the buildsystem generate a file containing constants for the install locations. For example you could have DATADIR, which would be set to /app/share for a flatpak build. Then in your code, simply reference DATADIR "/passwordsafe/xml", and you have it as a compile-time constant.

You could alternatively choose to follow the XDG basedir spec and search XDG_DATA_DIRS (with fallback as described in the spec). That depends on whether you want this to be extensible, or to only use the files shipped with the app.

I’ve looked into this a bit more. It is basically as I thought: whatever you install into /app/share/locale is relocated into the extension directory and replaced with a symlink. I’ve determined that the cleanup: /share directive in your wxwidgets module is removing those symlinks. This shouldn’t be possible according to the documentation (it should only apply to that module). I think what’s happening is that wxwidgets also creates directories in /app/share/locale, so it also ‘owns’ those symlinks.

I’m not sure that cleanup: /share is correct anyway though. I’d expect that wxwidgets should have message catalogs for its own strings as well.

Removing /share from cleanup didn’t help.
I notice that when trying to test the PR with the cleanup, I get:

$ flatpak install --user

org.pwsafe.pwsafe permissions:
    ipc      fallback-x11      wayland      x11      devices     file access [1]

    [1] xdg-documents

        ID                                 Branch           Op           Remote                 Download
 1.     org.pwsafe.pwsafe.Locale           test             i            pwsafe-origin          < 290.8 kB (partial)
 2.     org.pwsafe.pwsafe                  test             i            pwsafe-origin           < 21.8 MB

What does the “partial” in the org.pwsafe.pwsafe.locale indicate? Upon downloading, it doesn’t even download the entire locale:

       ID                                 Branch           Op           Remote                 Download
 1. [✓] org.pwsafe.pwsafe.Locale           test             i            pwsafe-origin           3.1 kB / 290.8 kB
 2. [✓] org.pwsafe.pwsafe                  test             i            pwsafe-origin          21.8 MB / 21.8 MB

Could it be that the flatpak installer is optimizing based on my current locale? If so, how can I test this for other languages?

What do you mean by “didn’t help”? I did test this locally, and I see the same with your PR (I only checked the first build). The symlinks in /app/share/locale are now present as expected.

Yes, this is how a locale-subset=true extension works. You can control which locales are installed using flatpak config:

flatpak config --set extra-languages fr
flatpak update org.pwsafe.pwsafe # or update everything
LANG=fr_FR.utf8 org.pwsafe.pwsafe
flatpak config --unset extra-languages

Alternatively, you can use flatpak update --subpath=fr org.pwsafe.pwsafe.Locale. I can’t find an option to install all subpaths (without specifying each one), but it may exist.

flatpak update --subpath xx did the trick, thanks!

How can I set this up by default? What’s this locale-subset=true of which you speak? What happens if it’s false (and where can I set it)?

See flatpak info -m org.pwsafe.pwsafe:

[Extension org.pwsafe.pwsafe.Locale]

flatpak-builder generates this extension automatically by default. You can disable that in your manifest (separate-locales), but you shouldn’t. Flatpak will automatically install the correct subset for the user’s locale.

If you want flatpak to install all languages for you, you can set languages to all or * using flatpak-config.