[gnome-shell/T27795: 94/138] viewsSelector: New ViewsClone class for desaturated versions of the desktop



commit 92d85bb632ef8cb1b88f5b111279bce424c28bc1
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Wed Jun 14 18:09:45 2017 +0100

    viewsSelector: New ViewsClone class for desaturated versions of the desktop
    
    This will be used from the main layout manager and the overview to create
    desaturated versions of the desktop (desktop search widget + icons grid)
    that we can show both underneath running windows and when in the "window
    picker" mode.
    
    https://phabricator.endlessm.com/T17662
    https://phabricator.endlessm.com/T17789
    https://phabricator.endlessm.com/T17979
    https://phabricator.endlessm.com/T19824

 js/ui/appDisplay.js   |  21 ++++++++++
 js/ui/viewSelector.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 135 insertions(+)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 5715e256e1..bab2f44ea5 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -56,6 +56,15 @@ const EOS_LINK_PREFIX = 'eos-link-';
 
 const EOS_APP_CENTER_ID = 'org.gnome.Software.desktop';
 
+var EOS_INACTIVE_GRID_OPACITY = 96;
+var EOS_ACTIVE_GRID_OPACITY = 255;
+
+var EOS_INACTIVE_GRID_TRANSITION = Clutter.AnimationMode.EASE_OUT_QUAD;
+var EOS_ACTIVE_GRID_TRANSITION = Clutter.AnimationMode.EASE_IN_QUAD;
+
+var EOS_INACTIVE_GRID_SATURATION = 1;
+var EOS_ACTIVE_GRID_SATURATION = 0;
+
 function _getCategories(info) {
     let categoriesStr = info.get_categories();
     if (!categoriesStr)
@@ -283,6 +292,10 @@ class BaseAppView {
 
         this._grid.ease(params);
     }
+
+    get gridActor() {
+        return this._grid;
+    }
 }
 Signals.addSignalMethods(BaseAppView.prototype);
 
@@ -908,6 +921,14 @@ var AppDisplay = class AppDisplay {
     adaptToSize(width, height) {
         return this._allView.adaptToSize(width, height);
     }
+
+    get gridContainer() {
+        return this._allView.actor;
+    }
+
+    get gridActor() {
+        return this._allView.gridActor;
+    }
 };
 
 var AppSearchProvider = class AppSearchProvider {
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index a8f77158c7..adb86c0426 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -474,6 +474,120 @@ var ViewsDisplay = class {
     }
 };
 
+var ViewsClone = GObject.registerClass(
+class ViewsClone extends St.Widget {
+    _init(viewSelector, viewsDisplay, forOverview) {
+        this._viewSelector = viewSelector;
+        this._viewsDisplay = viewsDisplay;
+        this._forOverview = forOverview;
+
+        let appDisplay = this._viewsDisplay.appDisplay;
+        let entry = new ShellEntry.OverviewEntry();
+        entry.reactive = false;
+        entry.clutter_text.reactive = false;
+
+        let iconGridClone = new Clutter.Clone({
+            source: appDisplay.gridActor,
+            x_expand: true,
+            y_expand: true,
+            reactive: false,
+        });
+
+        let appGridContainer =
+            new AppDisplay.AllViewContainer(iconGridClone, {
+                allowScrolling: false
+        });
+        appGridContainer.reactive = false;
+
+        let layoutManager = new ViewsDisplayLayout(entry, appGridContainer, null);
+        super._init({
+            layout_manager: layoutManager,
+            x_expand: true,
+            y_expand: true,
+            reactive: false,
+        });
+
+        // Ensure the cloned grid is scrolled to the same page as the original one
+        let originalGridContainer = appDisplay.gridContainer;
+        let originalAdjustment = originalGridContainer.scrollView.vscroll.adjustment;
+        let cloneAdjustment = appGridContainer.scrollView.vscroll.adjustment;
+        originalAdjustment.bind_property('value', cloneAdjustment, 'value', 
GObject.BindingFlags.SYNC_CREATE);
+
+        this.add_child(entry);
+        this.add_child(appGridContainer);
+
+        this._saturation = new Clutter.DesaturateEffect({
+            name: 'saturation',
+            factor: AppDisplay.EOS_INACTIVE_GRID_SATURATION,
+            enabled: false,
+        });
+        this.add_effect(this._saturation);
+
+        let workareaConstraint = new Monitor.MonitorConstraint({ primary: true,
+                                                                 work_area: true });
+        this.add_constraint(workareaConstraint);
+
+        Main.overview.connect('showing', () => {
+            this.opacity = AppDisplay.EOS_INACTIVE_GRID_OPACITY;
+            this._saturation.factor = AppDisplay.EOS_INACTIVE_GRID_SATURATION;
+            this._saturation.enabled = this._forOverview;
+        });
+        Main.overview.connect('hidden', () => {
+            this.opacity = AppDisplay.EOS_INACTIVE_GRID_OPACITY;
+            this._saturation.factor = AppDisplay.EOS_INACTIVE_GRID_SATURATION;
+            this._saturation.enabled = !this._forOverview;
+
+            // When we're hidden and coming from the apps page, tween out the
+            // clone saturation and opacity in the background as an override
+            if (!this._forOverview &&
+                this._viewSelector.getActivePage() == ViewPage.APPS) {
+                this.opacity = AppDisplay.EOS_ACTIVE_GRID_OPACITY;
+                this.saturation = AppDisplay.EOS_ACTIVE_GRID_SATURATION;
+                this.ease({
+                    opacity: AppDisplay.EOS_INACTIVE_GRID_OPACITY,
+                    duration: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
+                    mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+                });
+
+                this.ease_property(
+                    '@effects.saturation.factor',
+                    AppDisplay.EOS_INACTIVE_GRID_SATURATION, {
+                        duration: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
+                        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+                    }
+                );
+            }
+        });
+
+        let settings = Clutter.Settings.get_default();
+        settings.connect('notify::font-dpi', () => {
+            let overviewVisible = Main.layoutManager.overviewGroup.visible;
+            let saturationEnabled = this._saturation.enabled;
+
+            // Maybe because of the already known issue with FBO and ClutterClones,
+            // simply redrawing the overview group without assuring it is visible
+            // won't work. Clutter was supposed to do that, but it doesn't. The
+            // FBO, in this case, is introduced through the saturation effect.
+            this._saturation.enabled = false;
+            Main.layoutManager.overviewGroup.visible = true;
+
+            Main.layoutManager.overviewGroup.queue_redraw();
+
+            // Restore the previous states
+            Main.layoutManager.overviewGroup.visible = overviewVisible;
+            this._saturation.enabled = saturationEnabled;
+        });
+    }
+
+    set saturation(factor) {
+        this._saturation.factor = factor;
+    }
+
+    get saturation() {
+        return this._saturation.factor;
+    }
+});
+
 var ViewsDisplayConstraint = GObject.registerClass(
 class ViewsDisplayConstraint extends Monitor.MonitorConstraint {
     vfunc_update_allocation(actor, actorBox) {


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