[gnome-shell/eos3.8: 41/255] appStore: Add a new D-Bus service to manage apps and folders on the desktop



commit f592bfdb2f95f64aee45e1c960a2a3e7483b1181
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Fri Sep 15 18:58:37 2017 +0100

    appStore: Add a new D-Bus service to manage apps and folders on the desktop
    
    This is basically a wrapper around some of the functions if IconGridLayout
    and will be used from GNOME Software to add/remove/list apps from the
    desktop and from the old AppStore (where it draws its name from) to add
    new folders to the desktop.
    
     - 2020-03-14:
          + Squash with 380739252
          + Squash with c3f930da8
    
    https://phabricator.endlessm.com/T18781

 data/dbus-interfaces/meson.build                  |   1 +
 data/dbus-interfaces/org.gnome.Shell.AppStore.xml |  30 ++++++
 data/gnome-shell-dbus-interfaces.gresource.xml    |   1 +
 js/ui/shellDBus.js                                | 110 +++++++++++++++++++++-
 4 files changed, 141 insertions(+), 1 deletion(-)
---
diff --git a/data/dbus-interfaces/meson.build b/data/dbus-interfaces/meson.build
index c96bbbb4da..107888bec8 100644
--- a/data/dbus-interfaces/meson.build
+++ b/data/dbus-interfaces/meson.build
@@ -1,4 +1,5 @@
 dbus_interfaces = [
+  'org.gnome.Shell.AppStore.xml',
   'org.gnome.Shell.Extensions.xml',
   'org.gnome.Shell.Introspect.xml',
   'org.gnome.Shell.PadOsd.xml',
diff --git a/data/dbus-interfaces/org.gnome.Shell.AppStore.xml 
b/data/dbus-interfaces/org.gnome.Shell.AppStore.xml
new file mode 100644
index 0000000000..477d7525cf
--- /dev/null
+++ b/data/dbus-interfaces/org.gnome.Shell.AppStore.xml
@@ -0,0 +1,30 @@
+<node>
+  <interface name="org.gnome.Shell.AppStore">
+    <method name="AddApplication">
+      <arg type="s" direction="in" name="id" />
+    </method>
+    <method name="AddAppIfNotVisible">
+      <arg type="s" direction="in" name="id" />
+    </method>
+    <method name="ReplaceApplication">
+      <arg type="s" direction="in" name="originalId" />
+      <arg type="s" direction="in" name="replacementId" />
+    </method>
+    <method name="RemoveApplication">
+      <arg type="s" direction="in" name="id" />
+    </method>
+    <method name="ListApplications">
+      <arg type="as" direction="out" name="applications" />
+    </method>
+    <method name="AddFolder">
+      <arg type="s" direction="in" name="id" />
+    </method>
+    <method name="RemoveFolder">
+      <arg type="s" direction="in" name="id" />
+    </method>
+    <method name="ResetDesktop" />
+    <signal name="ApplicationsChanged">
+      <arg type="as" name="applications" />
+    </signal>
+  </interface>
+</node>
diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml
index 22140c3da3..118a19e74d 100644
--- a/data/gnome-shell-dbus-interfaces.gresource.xml
+++ b/data/gnome-shell-dbus-interfaces.gresource.xml
@@ -39,6 +39,7 @@
     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Power.Screen.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Rfkill.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.SettingsDaemon.Wacom.xml</file>
+    <file preprocess="xml-stripblanks">org.gnome.Shell.AppStore.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.AudioDeviceSelection.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.CalendarServer.xml</file>
     <file preprocess="xml-stripblanks">org.gnome.Shell.ClocksIntegration.xml</file>
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 2b6b2ae964..832cf220bd 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -1,11 +1,12 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported GnomeShell, ScreenSaverDBus */
 
-const { Gio, GLib, Meta } = imports.gi;
+const { EosMetrics, Gio, GLib, Meta } = imports.gi;
 
 const Config = imports.misc.config;
 const ExtensionDownloader = imports.ui.extensionDownloader;
 const ExtensionUtils = imports.misc.extensionUtils;
+const IconGridLayout = imports.ui.iconGridLayout;
 const Main = imports.ui.main;
 const Screenshot = imports.ui.screenshot;
 
@@ -14,6 +15,9 @@ const { loadInterfaceXML } = imports.misc.fileUtils;
 const GnomeShellIface = loadInterfaceXML('org.gnome.Shell');
 const ScreenSaverIface = loadInterfaceXML('org.gnome.ScreenSaver');
 
+// Occurs when an application is added to the app grid.
+const SHELL_APP_ADDED_EVENT = '51640a4e-79aa-47ac-b7e2-d3106a06e129';
+
 var GnomeShell = class {
     constructor() {
         this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
@@ -22,6 +26,11 @@ var GnomeShell = class {
         this._extensionsService = new GnomeShellExtensions();
         this._screenshotService = new Screenshot.ScreenshotService();
 
+        this._appstoreService = null;
+
+        Main.sessionMode.connect('updated', this._sessionModeChanged.bind(this));
+        this._sessionModeChanged();
+
         this._grabbedAccelerators = new Map();
         this._grabbers = new Map();
 
@@ -37,6 +46,17 @@ var GnomeShell = class {
                               this._checkOverviewVisibleChanged.bind(this));
     }
 
+    _sessionModeChanged() {
+        // These two D-Bus interfaces are only useful if a user is logged in
+        // and can run apps or has a desktop.
+        if (Main.sessionMode.isGreeter !== true) {
+            if (!this._appstoreService)
+                this._appstoreService = new AppStoreService();
+        } else {
+            this._appstoreService = null;
+        }
+    }
+
     /**
      * Eval:
      * @param {string} code: A string containing JavaScript code
@@ -408,3 +428,91 @@ var ScreenSaverDBus = class {
             return 0;
     }
 };
+
+function _iconIsVisibleOnDesktop(id) {
+    const iconGridLayout = IconGridLayout.getDefault();
+    let visibleIcons = iconGridLayout.getIcons(IconGridLayout.DESKTOP_GRID_ID);
+    return visibleIcons.indexOf(id) !== -1;
+}
+
+function _reportAppAddedMetric(id) {
+    let eventRecorder = EosMetrics.EventRecorder.get_default();
+    let appId = new GLib.Variant('s', id);
+    eventRecorder.record_event(SHELL_APP_ADDED_EVENT, appId);
+}
+
+const AppStoreIface = loadInterfaceXML('org.gnome.Shell.AppStore');
+
+var AppStoreService = class {
+    constructor() {
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(AppStoreIface, this);
+        this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
+        this._iconGridLayout = IconGridLayout.getDefault();
+
+        this._iconGridLayout.connect(
+            'layout-changed',
+            this._emitApplicationsChanged.bind(this));
+    }
+
+    AddApplication(id) {
+        let eventRecorder = EosMetrics.EventRecorder.get_default();
+        let appId = new GLib.Variant('s', id);
+        eventRecorder.record_event(SHELL_APP_ADDED_EVENT, appId);
+
+        if (!this._iconGridLayout.iconIsFolder(id))
+            this._iconGridLayout.appendIcon(id, IconGridLayout.DESKTOP_GRID_ID);
+    }
+
+    AddAppIfNotVisible(id) {
+        if (this._iconGridLayout.iconIsFolder(id))
+            return;
+
+        if (!_iconIsVisibleOnDesktop(id)) {
+            this._iconGridLayout.appendIcon(id, IconGridLayout.DESKTOP_GRID_ID);
+            _reportAppAddedMetric(id);
+        }
+    }
+
+    ReplaceApplication(originalId, replacementId) {
+        // Can't replace a folder
+        if (this._iconGridLayout.iconIsFolder(originalId))
+            return;
+
+        // We can just replace the app icon directly now,
+        // since the replace operation degenerates to
+        // append if the source icon was not available
+        this._iconGridLayout.replaceIcon(originalId, replacementId, IconGridLayout.DESKTOP_GRID_ID);
+
+        // We only care about reporting a metric if the replacement id was visible
+        if (!_iconIsVisibleOnDesktop(replacementId))
+            _reportAppAddedMetric(replacementId);
+    }
+
+    RemoveApplication(id) {
+        if (!this._iconGridLayout.iconIsFolder(id))
+            this._iconGridLayout.removeIcon(id, false);
+    }
+
+    AddFolder(id) {
+        if (this._iconGridLayout.iconIsFolder(id))
+            this._iconGridLayout.appendIcon(id, IconGridLayout.DESKTOP_GRID_ID);
+    }
+
+    RemoveFolder(id) {
+        if (this._iconGridLayout.iconIsFolder(id))
+            this._iconGridLayout.removeIcon(id, false);
+    }
+
+    ResetDesktop() {
+        this._iconGridLayout.resetDesktop();
+    }
+
+    ListApplications() {
+        return this._iconGridLayout.listApplications();
+    }
+
+    _emitApplicationsChanged() {
+        let allApps = this._iconGridLayout.listApplications();
+        this._dbusImpl.emit_signal('ApplicationsChanged', GLib.Variant.new('(as)', [allApps]));
+    }
+};


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