[gnome-shell] extensionPrefs: Split user and system extensions



commit f1bd94a3678df96abc4ca9b56d68ab2fec759e5e
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Nov 30 08:08:05 2019 +0100

    extensionPrefs: Split user and system extensions
    
    Until now, it didn't matter whether an extension was installed in the
    user's home or system-wide. However with support for uninstallation,
    there is now a significant different, as that action is only available
    for user extensions.
    
    Account for that by separating extensions by type, so that users don't
    have to second-guess which extensions can be fully-managed and which
    appear as part of the system.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/issues/1968

 js/extensionPrefs/main.js                 | 41 ++++++++++++++++++++++---------
 js/extensionPrefs/ui/extensions-window.ui | 41 ++++++++++++++++++++++++++++++-
 2 files changed, 70 insertions(+), 12 deletions(-)
---
diff --git a/js/extensionPrefs/main.js b/js/extensionPrefs/main.js
index bb1e46eaf3..f8ce4fb7ae 100644
--- a/js/extensionPrefs/main.js
+++ b/js/extensionPrefs/main.js
@@ -80,7 +80,8 @@ var ExtensionsWindow = GObject.registerClass({
     GTypeName: 'ExtensionsWindow',
     Template: 'resource:///org/gnome/shell/ui/extensions-window.ui',
     InternalChildren: [
-        'extensionsList',
+        'userList',
+        'systemList',
         'killSwitch',
         'mainBox',
         'mainStack',
@@ -106,8 +107,11 @@ var ExtensionsWindow = GObject.registerClass({
             this._killSwitch, 'active',
             Gio.SettingsBindFlags.DEFAULT | Gio.SettingsBindFlags.INVERT_BOOLEAN);
 
-        this._extensionsList.set_sort_func(this._sortList.bind(this));
-        this._extensionsList.set_header_func(this._updateHeader.bind(this));
+        this._userList.set_sort_func(this._sortList.bind(this));
+        this._userList.set_header_func(this._updateHeader.bind(this));
+
+        this._systemList.set_sort_func(this._sortList.bind(this));
+        this._systemList.set_header_func(this._updateHeader.bind(this));
 
         this._shellProxy.connectSignal('ExtensionStateChanged',
             this._onExtensionStateChanged.bind(this));
@@ -152,11 +156,8 @@ var ExtensionsWindow = GObject.registerClass({
         if (this._prefsDialog)
             return false;
 
-        let row = this._extensionsList.get_children().find(c => {
-            return c.uuid === uuid && c.hasPrefs;
-        });
-
-        if (!row)
+        let row = this._findExtensionRow(uuid);
+        if (!row || !row.hasPrefs)
             return false;
 
         let widget;
@@ -346,13 +347,24 @@ var ExtensionsWindow = GObject.registerClass({
     }
 
     _findExtensionRow(uuid) {
-        return this._extensionsList.get_children().find(c => c.uuid === uuid);
+        return [
+            ...this._userList.get_children(),
+            ...this._systemList.get_children(),
+        ].find(c => c.uuid === uuid);
     }
 
     _onExtensionStateChanged(proxy, senderName, [uuid, newState]) {
         let extension = ExtensionUtils.deserializeExtension(newState);
         let row = this._findExtensionRow(uuid);
 
+        // the extension's type changed; remove the corresponding row
+        // and reset the variable to null so that we create a new row
+        // below and add it to the appropriate list
+        if (row && row.type !== extension.type) {
+            row.destroy();
+            row = null;
+        }
+
         if (row) {
             if (extension.state === ExtensionState.UNINSTALLED)
                 row.destroy();
@@ -384,11 +396,18 @@ var ExtensionsWindow = GObject.registerClass({
     _addExtensionRow(extension) {
         let row = new ExtensionRow(extension);
         row.show_all();
-        this._extensionsList.add(row);
+
+        if (row.type === ExtensionType.PER_USER)
+            this._userList.add(row);
+        else
+            this._systemList.add(row);
     }
 
     _extensionsLoaded() {
-        if (this._extensionsList.get_children().length > 0)
+        this._userList.visible = this._userList.get_children().length > 0;
+        this._systemList.visible = this._systemList.get_children().length > 0;
+
+        if (this._userList.visible || this._systemList.visible)
             this._mainStack.visible_child_name = 'main';
         else
             this._mainStack.visible_child_name = 'placeholder';
diff --git a/js/extensionPrefs/ui/extensions-window.ui b/js/extensionPrefs/ui/extensions-window.ui
index 1a5cc14d43..3d211395f0 100644
--- a/js/extensionPrefs/ui/extensions-window.ui
+++ b/js/extensionPrefs/ui/extensions-window.ui
@@ -116,8 +116,47 @@
                     <property name="orientation">vertical</property>
                     <property name="halign">center</property>
                     <property name="margin">36</property>
+                    <property name="spacing">12</property>
                     <child>
-                      <object class="GtkListBox" id="extensionsList">
+                      <object class="GtkLabel">
+                        <property name="visible"
+                                  bind-source="userList"
+                                  bind-property="visible"
+                                  bind-flags="sync-create"/>
+                        <property name="halign">start</property>
+                        <property name="hexpand">True</property>
+                        <property name="label" translatable="yes">Manually Installed</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBox" id="userList">
+                        <property name="visible">True</property>
+                        <property name="selection_mode">none</property>
+                        <property name="margin_bottom">24</property>
+                        <style>
+                          <class name="frame"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible"
+                                  bind-source="systemList"
+                                  bind-property="visible"
+                                  bind-flags="sync-create"/>
+                        <property name="halign">start</property>
+                        <property name="hexpand">True</property>
+                        <property name="label" translatable="yes">Built-In</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBox" id="systemList">
                         <property name="visible">True</property>
                         <property name="selection_mode">none</property>
                         <style>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]