|
|
18fbde |
From b593bf334a7aada890d8ec4ce358c9f431b605ff Mon Sep 17 00:00:00 2001
|
|
|
18fbde |
From: Carlos Garnacho <carlosg@gnome.org>
|
|
|
18fbde |
Date: Mon, 3 Dec 2018 13:09:47 +0100
|
|
|
18fbde |
Subject: [PATCH 1/4] shell-global: Make saving of persistent state
|
|
|
18fbde |
asynchronous
|
|
|
18fbde |
|
|
|
18fbde |
This is an expensive operation that is best avoided in the main loop. Given
|
|
|
18fbde |
the call doesn't care much about returning error or status, it can just
|
|
|
18fbde |
be made async within.
|
|
|
18fbde |
|
|
|
18fbde |
Every operation on a given file will be destructive wrt previous
|
|
|
18fbde |
operations on the same file, so we just cancel any pending operation on
|
|
|
18fbde |
it before batching the current one.
|
|
|
18fbde |
|
|
|
18fbde |
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/815
|
|
|
18fbde |
---
|
|
|
18fbde |
src/shell-global.c | 85 ++++++++++++++++++++++++++++++++++++++++------
|
|
|
18fbde |
1 file changed, 75 insertions(+), 10 deletions(-)
|
|
|
18fbde |
|
|
|
18fbde |
diff --git a/src/shell-global.c b/src/shell-global.c
|
|
|
18fbde |
index 961fd3a70..8f5418677 100644
|
|
|
18fbde |
--- a/src/shell-global.c
|
|
|
18fbde |
+++ b/src/shell-global.c
|
|
|
18fbde |
@@ -88,6 +88,8 @@ struct _ShellGlobal {
|
|
|
18fbde |
/* For sound notifications */
|
|
|
18fbde |
ca_context *sound_context;
|
|
|
18fbde |
|
|
|
18fbde |
+ GHashTable *save_ops;
|
|
|
18fbde |
+
|
|
|
18fbde |
gboolean has_modal;
|
|
|
18fbde |
gboolean frame_timestamps;
|
|
|
18fbde |
gboolean frame_finish_timestamp;
|
|
|
18fbde |
@@ -331,6 +333,10 @@ shell_global_init (ShellGlobal *global)
|
|
|
18fbde |
NULL);
|
|
|
18fbde |
|
|
|
18fbde |
g_strfreev (search_path);
|
|
|
18fbde |
+
|
|
|
18fbde |
+ global->save_ops = g_hash_table_new_full (g_file_hash,
|
|
|
18fbde |
+ (GEqualFunc) g_file_equal,
|
|
|
18fbde |
+ g_object_unref, g_object_unref);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
static void
|
|
|
18fbde |
@@ -350,6 +356,8 @@ shell_global_finalize (GObject *object)
|
|
|
18fbde |
g_free (global->imagedir);
|
|
|
18fbde |
g_free (global->userdatadir);
|
|
|
18fbde |
|
|
|
18fbde |
+ g_hash_table_unref (global->save_ops);
|
|
|
18fbde |
+
|
|
|
18fbde |
G_OBJECT_CLASS(shell_global_parent_class)->finalize (object);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
@@ -1775,20 +1783,77 @@ shell_global_get_session_mode (ShellGlobal *global)
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
static void
|
|
|
18fbde |
-save_variant (GFile *dir,
|
|
|
18fbde |
- const char *property_name,
|
|
|
18fbde |
- GVariant *variant)
|
|
|
18fbde |
+delete_variant_cb (GObject *object,
|
|
|
18fbde |
+ GAsyncResult *result,
|
|
|
18fbde |
+ gpointer user_data)
|
|
|
18fbde |
+{
|
|
|
18fbde |
+ ShellGlobal *global = user_data;
|
|
|
18fbde |
+ GError *error = NULL;
|
|
|
18fbde |
+
|
|
|
18fbde |
+ if (!g_file_delete_finish (G_FILE (object), result, &error))
|
|
|
18fbde |
+ {
|
|
|
18fbde |
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
18fbde |
+ {
|
|
|
18fbde |
+ g_warning ("Could not delete runtime/persistent state file: %s\n",
|
|
|
18fbde |
+ error->message);
|
|
|
18fbde |
+ }
|
|
|
18fbde |
+
|
|
|
18fbde |
+ g_error_free (error);
|
|
|
18fbde |
+ }
|
|
|
18fbde |
+
|
|
|
18fbde |
+ g_hash_table_remove (global->save_ops, object);
|
|
|
18fbde |
+}
|
|
|
18fbde |
+
|
|
|
18fbde |
+static void
|
|
|
18fbde |
+replace_variant_cb (GObject *object,
|
|
|
18fbde |
+ GAsyncResult *result,
|
|
|
18fbde |
+ gpointer user_data)
|
|
|
18fbde |
+{
|
|
|
18fbde |
+ ShellGlobal *global = user_data;
|
|
|
18fbde |
+ GError *error = NULL;
|
|
|
18fbde |
+
|
|
|
18fbde |
+ if (!g_file_replace_contents_finish (G_FILE (object), result, NULL, &error))
|
|
|
18fbde |
+ {
|
|
|
18fbde |
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
18fbde |
+ {
|
|
|
18fbde |
+ g_warning ("Could not replace runtime/persistent state file: %s\n",
|
|
|
18fbde |
+ error->message);
|
|
|
18fbde |
+ }
|
|
|
18fbde |
+
|
|
|
18fbde |
+ g_error_free (error);
|
|
|
18fbde |
+ }
|
|
|
18fbde |
+
|
|
|
18fbde |
+ g_hash_table_remove (global->save_ops, object);
|
|
|
18fbde |
+}
|
|
|
18fbde |
+
|
|
|
18fbde |
+static void
|
|
|
18fbde |
+save_variant (ShellGlobal *global,
|
|
|
18fbde |
+ GFile *dir,
|
|
|
18fbde |
+ const char *property_name,
|
|
|
18fbde |
+ GVariant *variant)
|
|
|
18fbde |
{
|
|
|
18fbde |
GFile *path = g_file_get_child (dir, property_name);
|
|
|
18fbde |
+ GCancellable *cancellable;
|
|
|
18fbde |
+
|
|
|
18fbde |
+ cancellable = g_hash_table_lookup (global->save_ops, path);
|
|
|
18fbde |
+ g_cancellable_cancel (cancellable);
|
|
|
18fbde |
+
|
|
|
18fbde |
+ cancellable = g_cancellable_new ();
|
|
|
18fbde |
+ g_hash_table_insert (global->save_ops, g_object_ref (path), cancellable);
|
|
|
18fbde |
|
|
|
18fbde |
if (variant == NULL || g_variant_get_data (variant) == NULL)
|
|
|
18fbde |
- (void) g_file_delete (path, NULL, NULL);
|
|
|
18fbde |
+ {
|
|
|
18fbde |
+ g_file_delete_async (path, G_PRIORITY_DEFAULT, cancellable,
|
|
|
18fbde |
+ delete_variant_cb, global);
|
|
|
18fbde |
+ }
|
|
|
18fbde |
else
|
|
|
18fbde |
{
|
|
|
18fbde |
- gsize size = g_variant_get_size (variant);
|
|
|
18fbde |
- g_file_replace_contents (path, g_variant_get_data (variant), size,
|
|
|
18fbde |
- NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
|
|
|
18fbde |
- NULL, NULL, NULL);
|
|
|
18fbde |
+ g_file_replace_contents_async (path,
|
|
|
18fbde |
+ g_variant_get_data (variant),
|
|
|
18fbde |
+ g_variant_get_size (variant),
|
|
|
18fbde |
+ NULL, FALSE,
|
|
|
18fbde |
+ G_FILE_CREATE_REPLACE_DESTINATION,
|
|
|
18fbde |
+ cancellable, replace_variant_cb, global);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
g_object_unref (path);
|
|
|
18fbde |
@@ -1842,7 +1907,7 @@ shell_global_set_runtime_state (ShellGlobal *global,
|
|
|
18fbde |
const char *property_name,
|
|
|
18fbde |
GVariant *variant)
|
|
|
18fbde |
{
|
|
|
18fbde |
- save_variant (global->runtime_state_path, property_name, variant);
|
|
|
18fbde |
+ save_variant (global, global->runtime_state_path, property_name, variant);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
/**
|
|
|
18fbde |
@@ -1877,7 +1942,7 @@ shell_global_set_persistent_state (ShellGlobal *global,
|
|
|
18fbde |
const char *property_name,
|
|
|
18fbde |
GVariant *variant)
|
|
|
18fbde |
{
|
|
|
18fbde |
- save_variant (global->userdatadir_path, property_name, variant);
|
|
|
18fbde |
+ save_variant (global, global->userdatadir_path, property_name, variant);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
/**
|
|
|
18fbde |
--
|
|
|
18fbde |
2.23.0
|
|
|
18fbde |
|
|
|
18fbde |
|
|
|
18fbde |
From 6e898656365c18ad48349b7e3586e2d10b9ead9a Mon Sep 17 00:00:00 2001
|
|
|
18fbde |
From: Carlos Garnacho <carlosg@gnome.org>
|
|
|
18fbde |
Date: Mon, 3 Dec 2018 13:18:19 +0100
|
|
|
18fbde |
Subject: [PATCH 2/4] appDisplay: Reduce g_app_info_get_all() calls
|
|
|
18fbde |
|
|
|
18fbde |
Whenever the AllView needs (re)populating, we used to do one general
|
|
|
18fbde |
g_app_info_get_all() to get all GAppInfo, plus one per app folder in order
|
|
|
18fbde |
to check the ones that fall within that category. This calls results in a
|
|
|
18fbde |
fair amount of I/O blocking the main loop.
|
|
|
18fbde |
|
|
|
18fbde |
In order to ease this, keep the GAppInfo list around in AllView, and make
|
|
|
18fbde |
the AppFolders use it when figuring out the contained apps. Since reloading
|
|
|
18fbde |
the AllView results in AppFolders regenerated from scratch, the app info
|
|
|
18fbde |
list is ensured to be up-to-date for any later change within the AppFolder
|
|
|
18fbde |
(eg. through the GSettings key changing).
|
|
|
18fbde |
|
|
|
18fbde |
As the list was already filtered in the first place, we can also remove
|
|
|
18fbde |
the try{}catch() in AppFolder in order to discard desktop files with
|
|
|
18fbde |
invalid encoding.
|
|
|
18fbde |
|
|
|
18fbde |
Related: https://gitlab.gnome.org/GNOME/gnome-shell/issues/832
|
|
|
18fbde |
---
|
|
|
18fbde |
js/ui/appDisplay.js | 18 +++++++++++-------
|
|
|
18fbde |
1 file changed, 11 insertions(+), 7 deletions(-)
|
|
|
18fbde |
|
|
|
18fbde |
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
|
|
18fbde |
index 070057c69..115eb8f92 100644
|
|
|
18fbde |
--- a/js/ui/appDisplay.js
|
|
|
18fbde |
+++ b/js/ui/appDisplay.js
|
|
|
18fbde |
@@ -498,15 +498,21 @@ var AllView = new Lang.Class({
|
|
|
18fbde |
});
|
|
|
18fbde |
},
|
|
|
18fbde |
|
|
|
18fbde |
+ getAppInfos() {
|
|
|
18fbde |
+ return this._appInfoList;
|
|
|
18fbde |
+ },
|
|
|
18fbde |
+
|
|
|
18fbde |
_loadApps() {
|
|
|
18fbde |
- let apps = Gio.AppInfo.get_all().filter(appInfo => {
|
|
|
18fbde |
+ this._appInfoList = Gio.AppInfo.get_all().filter(appInfo => {
|
|
|
18fbde |
try {
|
|
|
18fbde |
let id = appInfo.get_id(); // catch invalid file encodings
|
|
|
18fbde |
} catch(e) {
|
|
|
18fbde |
return false;
|
|
|
18fbde |
}
|
|
|
18fbde |
return appInfo.should_show();
|
|
|
18fbde |
- }).map(app => app.get_id());
|
|
|
18fbde |
+ });
|
|
|
18fbde |
+
|
|
|
18fbde |
+ let apps = this._appInfoList.map(app => app.get_id());
|
|
|
18fbde |
|
|
|
18fbde |
let appSys = Shell.AppSystem.get_default();
|
|
|
18fbde |
|
|
|
18fbde |
@@ -1329,15 +1335,13 @@ var FolderIcon = new Lang.Class({
|
|
|
18fbde |
folderApps.forEach(addAppId);
|
|
|
18fbde |
|
|
|
18fbde |
let folderCategories = this._folder.get_strv('categories');
|
|
|
18fbde |
- Gio.AppInfo.get_all().forEach(appInfo => {
|
|
|
18fbde |
+ let appInfos = this._parentView.getAppInfos();
|
|
|
18fbde |
+ appInfos.forEach(appInfo => {
|
|
|
18fbde |
let appCategories = _getCategories(appInfo);
|
|
|
18fbde |
if (!_listsIntersect(folderCategories, appCategories))
|
|
|
18fbde |
return;
|
|
|
18fbde |
|
|
|
18fbde |
- try {
|
|
|
18fbde |
- addAppId(appInfo.get_id()); // catch invalid file encodings
|
|
|
18fbde |
- } catch(e) {
|
|
|
18fbde |
- }
|
|
|
18fbde |
+ addAppId(appInfo.get_id());
|
|
|
18fbde |
});
|
|
|
18fbde |
|
|
|
18fbde |
this.actor.visible = this.view.getAllItems().length > 0;
|
|
|
18fbde |
--
|
|
|
18fbde |
2.23.0
|
|
|
18fbde |
|
|
|
18fbde |
|
|
|
18fbde |
From cf823de60bff23872d20dfbb05ee4c51e3ebe9a3 Mon Sep 17 00:00:00 2001
|
|
|
18fbde |
From: Carlos Garnacho <carlosg@gnome.org>
|
|
|
18fbde |
Date: Wed, 19 Dec 2018 13:13:42 +0100
|
|
|
18fbde |
Subject: [PATCH 3/4] shell-app-system: Cache GAppInfos around
|
|
|
18fbde |
|
|
|
18fbde |
This was called here just to end up emitting ::installed-changed,
|
|
|
18fbde |
which would trigger other g_app_info_get_all() calls. Cache it here
|
|
|
18fbde |
so it may be reused later on.
|
|
|
18fbde |
---
|
|
|
18fbde |
src/shell-app-system.c | 30 +++++++++++++++++++++++++-----
|
|
|
18fbde |
src/shell-app-system.h | 2 ++
|
|
|
18fbde |
2 files changed, 27 insertions(+), 5 deletions(-)
|
|
|
18fbde |
|
|
|
18fbde |
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
|
|
|
18fbde |
index 8edf757a9..58e0185d1 100644
|
|
|
18fbde |
--- a/src/shell-app-system.c
|
|
|
18fbde |
+++ b/src/shell-app-system.c
|
|
|
18fbde |
@@ -50,6 +50,7 @@ struct _ShellAppSystemPrivate {
|
|
|
18fbde |
GHashTable *running_apps;
|
|
|
18fbde |
GHashTable *id_to_app;
|
|
|
18fbde |
GHashTable *startup_wm_class_to_id;
|
|
|
18fbde |
+ GList *installed_apps;
|
|
|
18fbde |
};
|
|
|
18fbde |
|
|
|
18fbde |
static void shell_app_system_finalize (GObject *object);
|
|
|
18fbde |
@@ -82,12 +83,14 @@ static void
|
|
|
18fbde |
scan_startup_wm_class_to_id (ShellAppSystem *self)
|
|
|
18fbde |
{
|
|
|
18fbde |
ShellAppSystemPrivate *priv = self->priv;
|
|
|
18fbde |
- GList *apps, *l;
|
|
|
18fbde |
+ GList *l;
|
|
|
18fbde |
|
|
|
18fbde |
g_hash_table_remove_all (priv->startup_wm_class_to_id);
|
|
|
18fbde |
|
|
|
18fbde |
- apps = g_app_info_get_all ();
|
|
|
18fbde |
- for (l = apps; l != NULL; l = l->next)
|
|
|
18fbde |
+ g_list_free_full (priv->installed_apps, g_object_unref);
|
|
|
18fbde |
+ priv->installed_apps = g_app_info_get_all ();
|
|
|
18fbde |
+
|
|
|
18fbde |
+ for (l = priv->installed_apps; l != NULL; l = l->next)
|
|
|
18fbde |
{
|
|
|
18fbde |
GAppInfo *info = l->data;
|
|
|
18fbde |
const char *startup_wm_class, *id, *old_id;
|
|
|
18fbde |
@@ -105,8 +108,6 @@ scan_startup_wm_class_to_id (ShellAppSystem *self)
|
|
|
18fbde |
g_hash_table_insert (priv->startup_wm_class_to_id,
|
|
|
18fbde |
g_strdup (startup_wm_class), g_strdup (id));
|
|
|
18fbde |
}
|
|
|
18fbde |
-
|
|
|
18fbde |
- g_list_free_full (apps, g_object_unref);
|
|
|
18fbde |
}
|
|
|
18fbde |
|
|
|
18fbde |
static gboolean
|
|
|
18fbde |
@@ -198,6 +199,7 @@ shell_app_system_finalize (GObject *object)
|
|
|
18fbde |
g_hash_table_destroy (priv->running_apps);
|
|
|
18fbde |
g_hash_table_destroy (priv->id_to_app);
|
|
|
18fbde |
g_hash_table_destroy (priv->startup_wm_class_to_id);
|
|
|
18fbde |
+ g_list_free_full (priv->installed_apps, g_object_unref);
|
|
|
18fbde |
|
|
|
18fbde |
G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
|
|
|
18fbde |
}
|
|
|
18fbde |
@@ -437,3 +439,21 @@ shell_app_system_search (const char *search_string)
|
|
|
18fbde |
|
|
|
18fbde |
return results;
|
|
|
18fbde |
}
|
|
|
18fbde |
+
|
|
|
18fbde |
+/**
|
|
|
18fbde |
+ * shell_app_system_get_installed:
|
|
|
18fbde |
+ * @self: the #ShellAppSystem
|
|
|
18fbde |
+ *
|
|
|
18fbde |
+ * Returns all installed apps, as a list of #GAppInfo
|
|
|
18fbde |
+ *
|
|
|
18fbde |
+ * Returns: (transfer none) (element-type GAppInfo): a list of #GAppInfo
|
|
|
18fbde |
+ * describing all known applications. This memory is owned by the
|
|
|
18fbde |
+ * #ShellAppSystem and should not be freed.
|
|
|
18fbde |
+ **/
|
|
|
18fbde |
+GList *
|
|
|
18fbde |
+shell_app_system_get_installed (ShellAppSystem *self)
|
|
|
18fbde |
+{
|
|
|
18fbde |
+ ShellAppSystemPrivate *priv = self->priv;
|
|
|
18fbde |
+
|
|
|
18fbde |
+ return priv->installed_apps;
|
|
|
18fbde |
+}
|
|
|
18fbde |
diff --git a/src/shell-app-system.h b/src/shell-app-system.h
|
|
|
18fbde |
index 445671f5b..8719dbcf2 100644
|
|
|
18fbde |
--- a/src/shell-app-system.h
|
|
|
18fbde |
+++ b/src/shell-app-system.h
|
|
|
18fbde |
@@ -27,4 +27,6 @@ ShellApp *shell_app_system_lookup_desktop_wmclass (ShellAppSystem *s
|
|
|
18fbde |
GSList *shell_app_system_get_running (ShellAppSystem *self);
|
|
|
18fbde |
char ***shell_app_system_search (const char *search_string);
|
|
|
18fbde |
|
|
|
18fbde |
+GList *shell_app_system_get_installed (ShellAppSystem *self);
|
|
|
18fbde |
+
|
|
|
18fbde |
#endif /* __SHELL_APP_SYSTEM_H__ */
|
|
|
18fbde |
--
|
|
|
18fbde |
2.23.0
|
|
|
18fbde |
|
|
|
18fbde |
|
|
|
18fbde |
From e294793e3d5525897e1c293cd9fd77ccf8983ca7 Mon Sep 17 00:00:00 2001
|
|
|
18fbde |
From: Carlos Garnacho <carlosg@gnome.org>
|
|
|
18fbde |
Date: Wed, 19 Dec 2018 13:26:54 +0100
|
|
|
18fbde |
Subject: [PATCH 4/4] appDisplay: Use GAppInfo list from ShellAppSystem
|
|
|
18fbde |
|
|
|
18fbde |
It is now cached there, so the number of g_app_info_get_all() calls
|
|
|
18fbde |
is reduced to one per change.
|
|
|
18fbde |
---
|
|
|
18fbde |
js/ui/appDisplay.js | 2 +-
|
|
|
18fbde |
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
18fbde |
|
|
|
18fbde |
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
|
|
18fbde |
index 115eb8f92..233deeb92 100644
|
|
|
18fbde |
--- a/js/ui/appDisplay.js
|
|
|
18fbde |
+++ b/js/ui/appDisplay.js
|
|
|
18fbde |
@@ -503,7 +503,7 @@ var AllView = new Lang.Class({
|
|
|
18fbde |
},
|
|
|
18fbde |
|
|
|
18fbde |
_loadApps() {
|
|
|
18fbde |
- this._appInfoList = Gio.AppInfo.get_all().filter(appInfo => {
|
|
|
18fbde |
+ this._appInfoList = Shell.AppSystem.get_default().get_installed().filter(appInfo => {
|
|
|
18fbde |
try {
|
|
|
18fbde |
let id = appInfo.get_id(); // catch invalid file encodings
|
|
|
18fbde |
} catch(e) {
|
|
|
18fbde |
--
|
|
|
18fbde |
2.23.0
|
|
|
18fbde |
|