Hi Ludovic! > +static void > +guix_profile_changed (GFileMonitor *monitor, > + GFile *file, > + GFile *other_file, > + GFileMonitorEvent event_type, > + gpointer user_data) > +{ > + DesktopFileDir *dir = user_data; > + > + desktop_file_dir_reset (dir); > + > + /* When ~/.guix-profile changes, emit the 'changed' signal so everyone > + knows. */ > + g_app_info_monitor_fire (); > +} > + > static void > desktop_file_dir_changed (GFileMonitor *monitor, > GFile *file, > @@ -1531,6 +1548,7 @@ desktop_file_dirs_lock (void) > > if (desktop_file_dirs == NULL || desktop_file_dirs->len == 0) > { > + const gchar *home; > const char * const *dirs; > gint i; > > @@ -1555,6 +1573,27 @@ desktop_file_dirs_lock (void) > for (i = 0; dirs[i]; i++) > g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new (dirs[i])); > > + home = g_get_home_dir (); > + if (guix_profile_monitor == NULL && home != NULL) > + { > + DesktopFileDir *dir; > + const gchar *profile, *data_dir; > + profile = g_build_filename (home, ".guix-profile", NULL); > + data_dir = g_build_filename (profile, "share", NULL); > + dir = desktop_file_dir_new (data_dir); > + > + /* Monitor ~/.guix-profile and treat modifications to > + ~/.guix-profile as if they were modifications to > + ~/.guix-profile/share. */ > + guix_profile_monitor = > + g_local_file_monitor_new_in_worker (profile, FALSE, > G_FILE_MONITOR_NONE, > + guix_profile_changed, > + desktop_file_dir_ref (dir), > + closure_notify_cb, NULL); > + > + g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (dir)); > + } > + > /* The list of directories will never change after this, unless > * g_get_user_config_dir() changes due to %G_TEST_OPTION_ISOLATE_DIRS. > */ > desktop_file_dirs_config_dir = user_config_dir;
I think the attached patch is an improvement over the above, by also supporting /run/current-system/share, being a bit simpler, and not adding extra monitors. I've reused the cool trick of passing FALSE to g_local_file_monitor_new_in_worker to force it to use its polling mode fallback.
>From a79645c565e56ac201e66936d9f9883ad9387b06 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer <maxim.courno...@gmail.com> Date: Thu, 5 Nov 2020 00:24:29 -0500 Subject: [PATCH] gdesktopappinfo: Fix monitoring of a Guix profile XDG_DATA_DIR. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes <https://issues.guix.gnu.org/35594>. Treat the $HOME/.guix-profile/share and /run/current-system/share XDG_DATA_DIRS file names specially so that the inotify-based monitors placed by GLib monitor their parent link rather than an immutable directory. Co-authored by Ludovic Courtès <ļu...@gnu.org>. --- gio/gdesktopappinfo.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index f1e2fdd65..e659034d5 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -1380,7 +1380,8 @@ closure_notify_cb (gpointer data, static void desktop_file_dir_init (DesktopFileDir *dir) { - const gchar *watch_dir; + const gchar *watch_dir, *guix_profile_data, *system_profile_data; + gboolean is_directory = TRUE; g_assert (!dir->is_setup); @@ -1390,13 +1391,25 @@ desktop_file_dir_init (DesktopFileDir *dir) dir->alternatively_watching = desktop_file_dir_get_alternative_dir (dir); watch_dir = dir->alternatively_watching ? dir->alternatively_watching : dir->path; + /* Workaround for Guix: watch the link of a profile, not its + * immutable 'share' sub-directory. */ + guix_profile_data = g_build_filename (g_get_home_dir (), ".guix-profile", "share", NULL); + system_profile_data = "/run/current-system/share"; + + if (g_str_equal (watch_dir, guix_profile_data) + || g_str_equal (watch_dir, system_profile_data)) + { + is_directory = FALSE; + watch_dir = g_path_get_dirname (watch_dir); + } + /* There is a very thin race here if the watch_dir has been _removed_ * between when we checked for it and when we establish the watch. * Removes probably don't happen in usual operation, and even if it * does (and we catch the unlikely race), the only degradation is that * we will fall back to polling. */ - dir->monitor = g_local_file_monitor_new_in_worker (watch_dir, TRUE, G_FILE_MONITOR_NONE, + dir->monitor = g_local_file_monitor_new_in_worker (watch_dir, is_directory, G_FILE_MONITOR_NONE, desktop_file_dir_changed, desktop_file_dir_ref (dir), closure_notify_cb, NULL); -- 2.28.0
It's untested because 'guix vm' is taking more time to complete than I'm willing to wait for in the middle of the night :-). I'll try it tomorrow. Thanks, Maxim