summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/glib-appinfo-watch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/glib-appinfo-watch.patch')
-rw-r--r--gnu/packages/patches/glib-appinfo-watch.patch92
1 files changed, 92 insertions, 0 deletions
diff --git a/gnu/packages/patches/glib-appinfo-watch.patch b/gnu/packages/patches/glib-appinfo-watch.patch
new file mode 100644
index 0000000000..638a5e0949
--- /dev/null
+++ b/gnu/packages/patches/glib-appinfo-watch.patch
@@ -0,0 +1,92 @@
+This patch lets GLib's GDesktopAppInfo API watch and notice changes
+to the Guix user and system profiles. That way, the list of available
+applications shown by the desktop environment is immediately updated
+when the user runs "guix install", "guix remove", or "guix system
+reconfigure" (see <https://issues.guix.gnu.org/35594>).
+
+It does so by monitoring /var/guix/profiles (for changes to the system
+profile) and /var/guix/profiles/per-user/USER (for changes to the user
+profile) and crawling their share/applications sub-directory when
+changes happen.
+
+diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
+index f1e2fdd..095c110 100644
+--- a/gio/gdesktopappinfo.c
++++ b/gio/gdesktopappinfo.c
+@@ -148,6 +148,7 @@ typedef struct
+ gchar *alternatively_watching;
+ gboolean is_config;
+ gboolean is_setup;
++ gchar *guix_profile_watch_dir;
+ GFileMonitor *monitor;
+ GHashTable *app_names;
+ GHashTable *mime_tweaks;
+@@ -180,6 +181,7 @@ desktop_file_dir_unref (DesktopFileDir *dir)
+ {
+ desktop_file_dir_reset (dir);
+ g_free (dir->path);
++ g_free (dir->guix_profile_watch_dir);
+ g_free (dir);
+ }
+ }
+@@ -204,6 +206,13 @@ desktop_file_dir_get_alternative_dir (DesktopFileDir *dir)
+ {
+ gchar *parent;
+
++ /* If DIR is a profile, watch the specified directory--e.g.,
++ * /var/guix/profiles/per-user/$USER/ for the user profile. Do not watch
++ * ~/.guix-profile or /run/current-system/profile because GFileMonitor does
++ * not pass IN_DONT_FOLLOW and thus cannot notice any change. */
++ if (dir->guix_profile_watch_dir != NULL)
++ return g_strdup (dir->guix_profile_watch_dir);
++
+ /* If the directory itself exists then we need no alternative. */
+ if (g_access (dir->path, R_OK | X_OK) == 0)
+ return NULL;
+@@ -249,11 +258,11 @@ desktop_file_dir_changed (GFileMonitor *monitor,
+ *
+ * If this is a notification for a parent directory (because the
+ * desktop directory didn't exist) then we shouldn't fire the signal
+- * unless something actually changed.
++ * unless something actually changed or it's in /var/guix/profiles.
+ */
+ g_mutex_lock (&desktop_file_dir_lock);
+
+- if (dir->alternatively_watching)
++ if (dir->alternatively_watching && dir->guix_profile_watch_dir == NULL)
+ {
+ gchar *alternative_dir;
+
+@@ -1555,6 +1564,32 @@ desktop_file_dirs_lock (void)
+ for (i = 0; dirs[i]; i++)
+ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new (dirs[i]));
+
++ {
++ /* Monitor the system and user profile under /var/guix/profiles and
++ * treat modifications to them as if they were modifications to their
++ * /share sub-directory. */
++ const gchar *user;
++ DesktopFileDir *system_profile_dir, *user_profile_dir;
++
++ system_profile_dir =
++ desktop_file_dir_new ("/var/guix/profiles/system/profile/share");
++ system_profile_dir->guix_profile_watch_dir = g_strdup ("/var/guix/profiles");
++ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (system_profile_dir));
++
++ user = g_get_user_name ();
++ if (user != NULL)
++ {
++ gchar *profile_dir, *user_data_dir;
++
++ profile_dir = g_build_filename ("/var/guix/profiles/per-user", user, NULL);
++ user_data_dir = g_build_filename (profile_dir, "guix-profile", "share", NULL);
++ user_profile_dir = desktop_file_dir_new (user_data_dir);
++ user_profile_dir->guix_profile_watch_dir = profile_dir;
++ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (user_profile_dir));
++ g_free (user_data_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;