[gnome-shell/wip/jimmac/dash-icon-spacing: 62/72] overviewControls: Incorporate AppDisplay and WorkspacesDisplay




commit bb8cb9a207b2b5eb020a894da4bd75c4c8d9f03f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Jan 14 20:23:15 2021 -0300

    overviewControls: Incorporate AppDisplay and WorkspacesDisplay
    
    Move AppDisplay and WorkspacesDisplay from ViewSelector to ControlsManager.
    This allows to always allocate the correct size for AppDisplay, and will
    enable for a plethora of further improvements. The end goal is to completely
    remove ViewSelector, and let ControlsManager handle the layout of everything
    that's visible in the overview.
    
    For now, replace the apps page with a dummy actor in ViewSelector.
    
    Adjust various callers around the codebase to not access the ViewSelector
    directly from the overview anymore.

 js/ui/overview.js         |   9 +--
 js/ui/overviewControls.js | 165 +++++++++++++++++++++++++++++++++++++++++-----
 js/ui/shellDBus.js        |   2 +-
 js/ui/viewSelector.js     | 105 ++---------------------------
 js/ui/workspacesView.js   |   2 +-
 5 files changed, 158 insertions(+), 125 deletions(-)
---
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 5f98ed59a7..7408a17cc0 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -143,10 +143,6 @@ var Overview = class {
         return this.dash.iconSize;
     }
 
-    get viewSelector() {
-        return this._overview.viewSelector;
-    }
-
     get animationInProgress() {
         return this._animationInProgress;
     }
@@ -271,11 +267,11 @@ var Overview = class {
     }
 
     addSearchProvider(provider) {
-        this.viewSelector.addSearchProvider(provider);
+        this._overview.viewSelector.addSearchProvider(provider);
     }
 
     removeSearchProvider(provider) {
-        this.viewSelector.removeSearchProvider(provider);
+        this._overview.viewSelector.removeSearchProvider(provider);
     }
 
     //
@@ -646,7 +642,6 @@ var Overview = class {
         // Re-enable unredirection
         Meta.enable_unredirect_for_display(global.display);
 
-        this.viewSelector.hide();
         this._desktopFade.hide();
         this._coverPane.hide();
 
diff --git a/js/ui/overviewControls.js b/js/ui/overviewControls.js
index ebe889e234..bf379bab49 100644
--- a/js/ui/overviewControls.js
+++ b/js/ui/overviewControls.js
@@ -3,11 +3,13 @@
 
 const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi;
 
+const AppDisplay = imports.ui.appDisplay;
 const Dash = imports.ui.dash;
 const Main = imports.ui.main;
 const ViewSelector = imports.ui.viewSelector;
 const Overview = imports.ui.overview;
 const WindowManager = imports.ui.windowManager;
+const WorkspacesView = imports.ui.workspacesView;
 
 var SIDE_CONTROLS_ANIMATION_TIME = Overview.ANIMATION_TIME;
 
@@ -58,9 +60,11 @@ class DashFader extends St.Bin {
 
 var ControlsManagerLayout = GObject.registerClass(
 class ControlsManagerLayout extends Clutter.BinLayout {
-    _init(searchEntry, viewSelector, dash, adjustment) {
+    _init(searchEntry, appDisplay, workspacesDisplay, viewSelector, dash, adjustment) {
         super._init();
 
+        this._appDisplay = appDisplay;
+        this._workspacesDisplay = workspacesDisplay;
         this._adjustment = adjustment;
         this._searchEntry = searchEntry;
         this._viewSelector = viewSelector;
@@ -69,6 +73,29 @@ class ControlsManagerLayout extends Clutter.BinLayout {
         adjustment.connect('notify::value', () => this.layout_changed());
     }
 
+    _getWorkspacesBoxForState(state, params) {
+        const workspaceBox = params.box.copy();
+        const [width, height] = workspaceBox.get_size();
+
+        switch (state) {
+        case ControlsState.HIDDEN:
+            break;
+        case ControlsState.WINDOW_PICKER:
+            workspaceBox.set_origin(0, params.searchHeight + params.spacing);
+            workspaceBox.set_size(width,
+                height -
+                params.dashHeight - params.spacing -
+                params.searchHeight - params.spacing);
+            break;
+        case ControlsState.APP_GRID:
+            workspaceBox.set_origin(0, params.searchHeight + params.spacing);
+            workspaceBox.set_size(width, Math.round(Math.max(height * 0.15)));
+            break;
+        }
+
+        return workspaceBox;
+    }
+
     vfunc_set_container(container) {
         this._container = container;
     }
@@ -101,19 +128,41 @@ class ControlsManagerLayout extends Clutter.BinLayout {
 
         availableHeight -= dashHeight + spacing;
 
-        // ViewSelector
-        const initialBox = new Clutter.ActorBox();
-        initialBox.set_origin(0, 0);
-        initialBox.set_size(width, height);
+        // Workspaces
+        const params = { box, searchHeight, dashHeight, spacing };
+        const workspaceBoxes = [
+            this._getWorkspacesBoxForState(ControlsState.HIDDEN, params),
+            this._getWorkspacesBoxForState(ControlsState.WINDOW_PICKER, params),
+            this._getWorkspacesBoxForState(ControlsState.APP_GRID, params),
+        ];
+        const [state, initialState, finalState, progress] =
+            this._adjustment.getState();
+        if (initialState === finalState) {
+            const workspacesBox = workspaceBoxes[state];
+            this._workspacesDisplay.allocate(workspacesBox);
+        } else {
+            const initialBox = workspaceBoxes[initialState];
+            const finalBox = workspaceBoxes[finalState];
+
+            this._workspacesDisplay.allocate(initialBox.interpolate(finalBox, progress));
+        }
+
+        // AppDisplay
+        const appGridBox = workspaceBoxes[ControlsState.APP_GRID];
+
+        childBox.set_origin(0, searchHeight + spacing + appGridBox.get_height());
+        childBox.set_size(width,
+            height -
+            searchHeight - spacing -
+            appGridBox.get_height() - spacing -
+            dashHeight);
 
+        this._appDisplay.allocate(childBox);
+
+        // ViewSelector
         childBox.set_origin(0, searchHeight + spacing);
         childBox.set_size(width, availableHeight);
-
-        const page = this._viewSelector.getActivePage();
-        const progress = page === ViewSelector.ViewPage.SEARCH
-            ? 1 : Math.min(this._adjustment.value, 1);
-        const viewSelectorBox = initialBox.interpolate(childBox, progress);
-        this._viewSelector.allocate(viewSelectorBox);
+        this._viewSelector.allocate(childBox);
     }
 });
 
@@ -201,22 +250,33 @@ class ControlsManager extends St.Widget {
         });
 
         this._adjustment = new OverviewAdjustment(this);
+        this._adjustment.connect('notify::value', this._update.bind(this));
 
         this._nWorkspacesNotifyId =
             workspaceManager.connect('notify::n-workspaces',
                 this._updateAdjustment.bind(this));
 
         this.viewSelector = new ViewSelector.ViewSelector(this._searchEntry,
+            this.dash.showAppsButton);
+        this.viewSelector.connect('page-empty', this._onPageEmpty.bind(this));
+
+        this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay(
             this._workspaceAdjustment,
-            this.dash.showAppsButton,
             this._adjustment);
+        this._appDisplay = new AppDisplay.AppDisplay();
 
         this.add_child(searchEntryBin);
+        this.add_child(this._appDisplay);
         this.add_child(this._dashFader);
         this.add_child(this.viewSelector);
+        this.add_child(this._workspacesDisplay);
 
         this.layout_manager = new ControlsManagerLayout(searchEntryBin,
-            this.viewSelector, this._dashFader, this._adjustment);
+            this._appDisplay,
+            this._workspacesDisplay,
+            this.viewSelector,
+            this._dashFader,
+            this._adjustment);
 
         this.dash.showAppsButton.connect('notify::checked',
             this._onShowAppsButtonToggled.bind(this));
@@ -229,6 +289,59 @@ class ControlsManager extends St.Widget {
             this._toggleAppsPage.bind(this));
 
         this.connect('destroy', this._onDestroy.bind(this));
+
+        this._update();
+    }
+
+    _getSnapForState(state) {
+        switch (state) {
+        case ControlsState.HIDDEN:
+        case ControlsState.WINDOW_PICKER:
+            return Clutter.Orientation.VERTICAL;
+        case ControlsState.APP_GRID:
+            return Clutter.Orientation.HORIZONTAL;
+        default:
+            return Clutter.Orientation.VERTICAL;
+        }
+    }
+
+    _update() {
+        const [, initialState, finalState, progress] = this._adjustment.getState();
+
+        const snapAxis = Math.interpolate(
+            this._getSnapForState(initialState),
+            this._getSnapForState(finalState),
+            progress);
+
+        const { snapAdjustment } = this._workspacesDisplay;
+        snapAdjustment.value = snapAxis;
+    }
+
+    _onPageEmpty() {
+        const page = this.viewSelector.getActivePage();
+        const isApps = page === ViewSelector.ViewPage.APPS;
+
+        if (isApps) {
+            this._appDisplay.show();
+            this._workspacesDisplay.reactive = true;
+            this._workspacesDisplay.setPrimaryWorkspaceVisible(true);
+        }
+
+        this._appDisplay.ease({
+            opacity: isApps ? 255 : 0,
+            duration: SIDE_CONTROLS_ANIMATION_TIME,
+            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+            onComplete: () => (this._appDisplay.visible = isApps),
+        });
+        this._workspacesDisplay.ease({
+            opacity: isApps ? 255 : 0,
+            duration: SIDE_CONTROLS_ANIMATION_TIME,
+            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+            onComplete: () => {
+                this._workspacesDisplay.reactive = isApps;
+                this._workspacesDisplay.setPrimaryWorkspaceVisible(isApps);
+            },
+        });
     }
 
     _onShowAppsButtonToggled() {
@@ -272,10 +385,18 @@ class ControlsManager extends St.Widget {
         this._workspaceAdjustment.value = activeIndex;
     }
 
+    vfunc_unmap() {
+        this._workspacesDisplay.hide();
+        super.vfunc_unmap();
+    }
+
     animateToOverview(state, onComplete) {
         this._animating = true;
 
         this.viewSelector.prepareToEnterOverview();
+        this._workspacesDisplay.prepareToEnterOverview();
+        if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
+            Main.overview.fadeOutDesktop();
 
         this._adjustment.value = ControlsState.HIDDEN;
         this._adjustment.ease(state, {
@@ -293,7 +414,9 @@ class ControlsManager extends St.Widget {
     animateFromOverview(onComplete) {
         this._animating = true;
 
-        this.viewSelector.prepareToLeaveOverview();
+        this._workspacesDisplay.prepareToLeaveOverview();
+        if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
+            Main.overview.fadeInDesktop();
 
         this._adjustment.ease(ControlsState.HIDDEN, {
             duration: SIDE_CONTROLS_ANIMATION_TIME,
@@ -326,6 +449,9 @@ class ControlsManager extends St.Widget {
 
         tracker.confirmSwipe(baseDistance, points, progress, cancelProgress);
         this.viewSelector.prepareToEnterOverview();
+        this._workspacesDisplay.prepareToEnterOverview();
+        if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
+            Main.overview.fadeInDesktop();
     }
 
     gestureProgress(progress) {
@@ -335,8 +461,11 @@ class ControlsManager extends St.Widget {
     gestureEnd(target, duration, onComplete) {
         this._animating = true;
 
-        if (target === ControlsState.HIDDEN)
-            this.viewSelector.prepareToLeaveOverview();
+        if (target === ControlsState.HIDDEN) {
+            this._workspacesDisplay.prepareToLeaveOverview();
+            if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
+                Main.overview.fadeInDesktop();
+        }
 
         this._adjustment.ease(target, {
             duration,
@@ -348,4 +477,8 @@ class ControlsManager extends St.Widget {
             target === ControlsState.APP_GRID;
         this._animating = false;
     }
+
+    get appDisplay() {
+        return this._appDisplay;
+    }
 });
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 7af71af55a..d68ceabdad 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -100,7 +100,7 @@ var GnomeShell = class {
 
     FocusApp(id) {
         this.ShowApplications();
-        Main.overview.viewSelector.appDisplay.selectApp(id);
+        Main.overview.appDisplay.selectApp(id);
     }
 
     ShowApplications() {
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index 8c1a5339e4..0910dd7f95 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -3,13 +3,11 @@
 
 const { Clutter, GObject, Shell, St } = imports.gi;
 
-const AppDisplay = imports.ui.appDisplay;
 const Main = imports.ui.main;
 const OverviewControls = imports.ui.overviewControls;
 const Params = imports.misc.params;
 const Search = imports.ui.search;
 const ShellEntry = imports.ui.shellEntry;
-const WorkspacesView = imports.ui.workspacesView;
 
 var ViewPage = {
     APPS: 1,
@@ -35,88 +33,13 @@ function getTermsForSearchString(searchString) {
     return terms;
 }
 
-var AppsPageContainer = GObject.registerClass(
-class AppsPageContainer extends St.Widget {
-    _init(workspacesDisplay, appDisplay, overviewAdjustment) {
-        super._init();
-
-        // 0 for window picker, 1 for app grid
-        this._adjustment = new St.Adjustment({
-            actor: this,
-            value: 0,
-            lower: 0,
-            upper: 1,
-        });
-        this._adjustment.connect('notify::value', () => {
-            this._update();
-            this.queue_relayout();
-        });
-
-        overviewAdjustment.connect('notify::value', () => {
-            const overviewState = overviewAdjustment.value;
-
-            this._appDisplay.visible =
-                overviewState >= OverviewControls.ControlsState.WINDOW_PICKER;
-            this._adjustment.value = Math.max(overviewAdjustment.value -
-                OverviewControls.ControlsState.WINDOW_PICKER, 0);
-        });
-
-        this._appDisplay = appDisplay;
-        this.add_child(appDisplay);
-
-        this._workspacesDisplay = workspacesDisplay;
-        this.add_child(workspacesDisplay);
-
-        this.connect('notify::mapped', () => {
-            workspacesDisplay.setPrimaryWorkspaceVisible(this.mapped);
-        });
-
-        this._update();
-    }
-
-    _update() {
-        const progress = this._adjustment.value;
-
-        this._appDisplay.opacity = progress * 255;
-
-        const { snapAdjustment } = this._workspacesDisplay;
-        snapAdjustment.value = 1 - progress;
-    }
-
-    _getWorkspacesBoxes(box) {
-        const initialBox = box.copy();
-
-        const finalBox = box.copy();
-        finalBox.set_size(
-            box.get_width(),
-            Math.round(box.get_height() * 0.15));
-
-        return [initialBox, finalBox];
-    }
-
-    vfunc_allocate(box) {
-        this.set_allocation(box);
-
-        const progress = this._adjustment.value;
-        const [initialBox, finalBox] = this._getWorkspacesBoxes(box);
-        const workspacesBox = initialBox.interpolate(finalBox, progress);
-        this._workspacesDisplay.allocate(workspacesBox);
-
-        if (this._appDisplay.visible) {
-            const appDisplayBox = box.copy();
-            appDisplayBox.y1 += Math.ceil(finalBox.get_height());
-            this._appDisplay.allocate(appDisplayBox);
-        }
-    }
-});
-
 var ViewSelector = GObject.registerClass({
     Signals: {
         'page-changed': {},
         'page-empty': {},
     },
 }, class ViewSelector extends Shell.Stack {
-    _init(searchEntry, workspaceAdjustment, showAppsButton, overviewAdjustment) {
+    _init(searchEntry, showAppsButton) {
         super._init({
             name: 'viewSelector',
             x_expand: true,
@@ -159,14 +82,9 @@ var ViewSelector = GObject.registerClass({
         this._iconClickedId = 0;
         this._capturedEventId = 0;
 
-        this._workspacesDisplay =
-            new WorkspacesView.WorkspacesDisplay(workspaceAdjustment, overviewAdjustment);
-        this.appDisplay = new AppDisplay.AppDisplay();
-
-        const appsContainer = new AppsPageContainer(
-            this._workspacesDisplay, this.appDisplay, overviewAdjustment);
+        const dummy = new Clutter.Actor();
         this._appsPage =
-            this._addPage(appsContainer, _('Applications'), 'view-app-grid-symbolic');
+            this._addPage(dummy, _('Applications'), 'view-app-grid-symbolic');
 
         this._searchResults = new Search.SearchResultsView();
         this._searchPage = this._addPage(this._searchResults,
@@ -198,28 +116,15 @@ var ViewSelector = GObject.registerClass({
     }
 
     prepareToEnterOverview() {
-        this.show();
         this.reset();
-        this._workspacesDisplay.prepareToEnterOverview();
         this._activePage = null;
         this._showPage(this._appsPage);
-
-        if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
-            Main.overview.fadeOutDesktop();
-    }
-
-    prepareToLeaveOverview() {
-        this._workspacesDisplay.prepareToLeaveOverview();
-
-        if (!this._workspacesDisplay.activeWorkspaceHasMaximizedWindows())
-            Main.overview.fadeInDesktop();
     }
 
-    vfunc_hide() {
+    vfunc_unmap() {
         this.reset();
-        this._workspacesDisplay.hide();
 
-        super.vfunc_hide();
+        super.vfunc_unmap();
     }
 
     _addPage(actor, name, a11yIcon, params) {
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index cc3a1e47bc..9d390a20ec 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -666,7 +666,6 @@ class WorkspacesDisplay extends St.Widget {
     _init(scrollAdjustment, overviewAdjustment) {
         super._init({
             reactive: true,
-            visible: false,
             y_expand: true,
             layout_manager: new Clutter.BinLayout(),
         });
@@ -983,6 +982,7 @@ class WorkspacesDisplay extends St.Widget {
 
             if (i === this._primaryIndex) {
                 view.visible = this._primaryVisible;
+                this.bind_property('opacity', view, 'opacity', GObject.BindingFlags.SYNC_CREATE);
                 this.add_child(view);
             } else {
                 const { x, y, width, height } =


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