Ludovic Courtès <l...@gnu.org> skribis: > This is not news to us, but as > <https://distrowatch.com/weekly.php?issue=20190624#guixsd> notes, the > application menu of desktop environments is not automatically updated > when a package is installed or removed. It’d be great if we could > somehow notify the desktop environment.
We’ve investigated today on IRC with Maxim and Leo P. and here’s the summary of our findings: • GNOME Shell, in ‘appDisplay.js’, “listens” to the ‘installed-changed’ GLib signals and uses that to rebuild its application menu. • In ‘shell-app-system.c’, ‘installed-changed’ is emitted when the GAppInfoMonitor emits ‘changed’: monitor = g_app_info_monitor_get (); g_signal_connect (monitor, "changed", G_CALLBACK (installed_changed), self); installed_changed (monitor, self); • GLib emits the ‘changed’ signal when ‘g_app_info_monitor_fire’ is called from ‘desktop_file_dir_changed’, itself called when one of the directories in $XDG_DATA_DIRS (among others) changes. It uses ‘GFileMonitor’ under the hood, which is essentially inotify. The GLib patch below is an attempt to monitor ~/.guix-profile and to treat changes to that symlink as if they were changes to ~/.guix-profile/share/applications (which contains ‘.desktop’ files.) It actually builds but I haven’t tested it yet. :-) WDYT? If we take that route, we could add a ‘replacement’ for GLib. Thanks, Ludo’.
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index f1e2fdd..96dcc32 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -161,6 +161,7 @@ static DesktopFileDir *desktop_file_dir_user_config = NULL; /* (owned) */ static DesktopFileDir *desktop_file_dir_user_data = NULL; /* (owned) */ static GMutex desktop_file_dir_lock; static const gchar *gio_launch_desktop_path = NULL; +static GFileMonitor *guix_profile_monitor = NULL; /* Monitor 'changed' signal handler {{{2 */ static void desktop_file_dir_reset (DesktopFileDir *dir); @@ -230,6 +231,22 @@ desktop_file_dir_get_alternative_dir (DesktopFileDir *dir) return parent; } +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;