diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 16:02:53 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 16:02:53 +0000 |
commit | 4d8b071804d73b7a733f2b7696fde40caf8800bb (patch) | |
tree | 86aefc1c0ea9c596bab0ecbc0c054a2378d6cd13 /extensions/44/vertical-workspaces/lib/overviewControls.js | |
parent | Updating 44/no-overview to version 44 [68db01d]. (diff) | |
download | gnome-shell-extensions-extra-4d8b071804d73b7a733f2b7696fde40caf8800bb.tar.xz gnome-shell-extensions-extra-4d8b071804d73b7a733f2b7696fde40caf8800bb.zip |
Updating 44/vertical-workspaces to version 37+20231208 [0d82192].
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'extensions/44/vertical-workspaces/lib/overviewControls.js')
-rw-r--r-- | extensions/44/vertical-workspaces/lib/overviewControls.js | 827 |
1 files changed, 582 insertions, 245 deletions
diff --git a/extensions/44/vertical-workspaces/lib/overviewControls.js b/extensions/44/vertical-workspaces/lib/overviewControls.js index 4959b83..7528682 100644 --- a/extensions/44/vertical-workspaces/lib/overviewControls.js +++ b/extensions/44/vertical-workspaces/lib/overviewControls.js @@ -10,90 +10,148 @@ 'use strict'; -const { Clutter, GLib, GObject, St } = imports.gi; +const Clutter = imports.gi.Clutter; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Meta = imports.gi.Meta; +const Shell = imports.gi.Shell; +const St = imports.gi.St; + +const Background = imports.ui.background; +const Layout = imports.ui.layout; const Main = imports.ui.main; -const Util = imports.misc.util; +const Overview = imports.ui.overview; const OverviewControls = imports.ui.overviewControls; +const Workspace = imports.ui.workspace; const WorkspaceThumbnail = imports.ui.workspaceThumbnail; +const WorkspacesView = imports.ui.workspacesView; +const Util = imports.misc.util; -const ControlsState = imports.ui.overviewControls.ControlsState; -const FitMode = imports.ui.workspacesView.FitMode; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); - -const _Util = Me.imports.lib.util; - -let _overrides; +let Me; let opt; +// gettext +let _; + +const ControlsState = OverviewControls.ControlsState; +const FitMode = WorkspacesView.FitMode; -const ANIMATION_TIME = imports.ui.overview.ANIMATION_TIME; +const ANIMATION_TIME = Overview.ANIMATION_TIME; const DASH_MAX_SIZE_RATIO = 0.25; let _originalSearchControllerSigId; let _searchControllerSigId; let _timeouts; -let _startupInitComplete = false; -function update(reset = false) { - if (_overrides) - _overrides.removeAll(); +var OverviewControlsModule = class { + constructor(me) { + Me = me; + opt = Me.opt; + _ = Me.gettext; - if (_timeouts) { - Object.values(_timeouts).forEach(id => { - if (id) - GLib.source_remove(id); - }); + this._firstActivation = true; + this.moduleEnabled = false; + this._overrides = null; } - _replaceOnSearchChanged(reset); - - if (reset) { - _overrides = null; + cleanGlobals() { + Me = null; opt = null; - _timeouts = null; - return; + _ = null; } - _timeouts = {}; + update(reset) { + this._removeTimeouts(); + this.moduleEnabled = true; + const conflict = false; - opt = Me.imports.lib.settings.opt; - _overrides = new _Util.Overrides(); + reset = reset || !this.moduleEnabled || conflict; - _overrides.addOverride('ControlsManager', OverviewControls.ControlsManager.prototype, ControlsManager); + // don't touch the original code if module disabled + if (reset && !this._firstActivation) { + this._disableModule(); + } else if (!reset) { + this._firstActivation = false; + this._activateModule(); + } + if (reset && this._firstActivation) + console.debug(' OverviewControlsModule - Keeping untouched'); + } - if (opt.ORIENTATION === Clutter.Orientation.VERTICAL) - _overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutVertical); - else - _overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutHorizontal); -} + _activateModule() { + if (!this._overrides) + this._overrides = new Me.Util.Overrides(); + + _timeouts = {}; + + this._replaceOnSearchChanged(); + + this._overrides.addOverride('ControlsManager', OverviewControls.ControlsManager.prototype, ControlsManagerCommon); + + if (opt.ORIENTATION === Clutter.Orientation.VERTICAL) + this._overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutVertical); + else + this._overrides.addOverride('ControlsManagerLayout', OverviewControls.ControlsManagerLayout.prototype, ControlsManagerLayoutHorizontal); + + // if DtD is enabled, we need to replace _prepareStartupAnimation() to minimize the mess in the overview + // const dashToDockEnabled = Me.Util.getEnabledExtensions('dash-to-dock').length || + // Me.Util.getEnabledExtensions('ubuntu-dock').length; + // if (dashToDockEnabled) + this._overrides.addOverride('LayoutManagerDtD', Layout.LayoutManager.prototype, LayoutManager); + + console.debug(' OverviewControlsModule - Activated'); + } + + _disableModule() { + if (this._overrides) + this._overrides.removeAll(); + this._overrides = null; + + const reset = true; + this._replaceOnSearchChanged(reset); + Main.overview._overview._controls._appDisplay.opacity = 255; -function _replaceOnSearchChanged(reset = false) { - const searchController = Main.overview._overview.controls._searchController; - if (reset) { - if (_searchControllerSigId) { - searchController.disconnect(_searchControllerSigId); - _searchControllerSigId = 0; + console.debug(' OverviewControlsModule - Disabled'); + } + + _removeTimeouts() { + if (_timeouts) { + Object.values(_timeouts).forEach(t => { + if (t) + GLib.source_remove(t); + }); + _timeouts = null; } - if (_originalSearchControllerSigId) { - searchController.unblock_signal_handler(_originalSearchControllerSigId); - _originalSearchControllerSigId = 0; + } + + _replaceOnSearchChanged(reset) { + const searchController = Main.overview._overview.controls._searchController; + if (reset) { + if (_searchControllerSigId) { + searchController.disconnect(_searchControllerSigId); + _searchControllerSigId = 0; + } + if (_originalSearchControllerSigId) { + searchController.unblock_signal_handler(_originalSearchControllerSigId); + _originalSearchControllerSigId = 0; + } + Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_x = 0; + Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_y = 0; + Main.overview.searchEntry.visible = true; + Main.overview.searchEntry.opacity = 255; + } else { + // reconnect signal to use custom function (callbacks cannot be overridden in class prototype, they are already in memory as a copy for the given callback) + if (!_originalSearchControllerSigId) + _originalSearchControllerSigId = GObject.signal_handler_find(searchController, { signalId: 'notify', detail: 'search-active' }); + if (_originalSearchControllerSigId) + searchController.block_signal_handler(_originalSearchControllerSigId); + + if (!_searchControllerSigId) + _searchControllerSigId = searchController.connect('notify::search-active', ControlsManagerCommon._onSearchChanged.bind(Main.overview._overview.controls)); } - Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_x = 0; - Main.overview._overview._controls.layoutManager._searchController._searchResults.translation_y = 0; - Main.overview.searchEntry.visible = true; - Main.overview.searchEntry.opacity = 255; - } else { - // reconnect signal to use custom function (callbacks cannot be overridden in class prototype, they are already in memory as a copy for the given callback) - _originalSearchControllerSigId = GObject.signal_handler_find(searchController, { signalId: 'notify', detail: 'search-active' }); - if (_originalSearchControllerSigId) - searchController.block_signal_handler(_originalSearchControllerSigId); - - _searchControllerSigId = searchController.connect('notify::search-active', ControlsManager._onSearchChanged.bind(Main.overview._overview.controls)); } -} +}; -const ControlsManager = { +const ControlsManagerCommon = { // this function is used as a callback by a signal handler, needs to be reconnected after modification as the original callback uses a copy of the original function /* _update: function() { ... @@ -105,16 +163,21 @@ const ControlsManager = { }, _updateThumbnailsBox() { + const { currentState } = this._stateAdjustment.getStateTransitionParams(); const { shouldShow } = this._thumbnailsBox; - const thumbnailsBoxVisible = shouldShow; + const thumbnailsBoxVisible = shouldShow && + ((currentState < ControlsState.APP_GRID && opt.SHOW_WS_TMB) || + (currentState > ControlsState.WINDOW_PICKER && opt.SHOW_WS_TMB_APPGRID) || + (currentState > ControlsState.WINDOW_PICKER && this._searchController.searchActive && opt.SHOW_WS_TMB) + ); this._thumbnailsBox.visible = thumbnailsBoxVisible; // this call should be directly in _update(), but it's used as a callback function and it would require to reconnect the signal - this._updateWorkspacesDisplay(); + this._updateOverview(); }, // this function is pure addition to the original code and handles wsDisp transition to APP_GRID view - _updateWorkspacesDisplay() { + _updateOverview() { this._workspacesDisplay.translation_x = 0; this._workspacesDisplay.translation_y = 0; this._workspacesDisplay.scale_x = 1; @@ -167,18 +230,21 @@ const ControlsManager = { ws._background.opacity = opacity; } + if (opt.WORKSPACE_MODE) + Workspace.WINDOW_PREVIEW_MAXIMUM_SCALE = 0.95; + // if ws preview background is disabled, animate tmb box and dash const tmbBox = this._thumbnailsBox; const dash = this.dash; const searchEntryBin = this._searchEntryBin; // this dash transition collides with startup animation and freezes GS for good, needs to be delayed (first Main.overview 'hiding' event enables it) - const skipDash = _Util.dashNotDefault(); + const skipDash = Me.Util.dashNotDefault(); // OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread) const animateOverviewMode2 = opt.OVERVIEW_MODE2 && !(finalState === 1 && opt.WORKSPACE_MODE); if (!Main.layoutManager._startingUp && ((!opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2) || animateOverviewMode2)) { if (!tmbBox._translationOriginal || Math.abs(tmbBox._translationOriginal[0]) > 500) { // swipe gesture can call this calculation before tmbBox is finalized, giving nonsense width - const [tmbTranslationX, tmbTranslationY, dashTranslationX, dashTranslationY, searchTranslationY] = _Util.getOverviewTranslations(opt, dash, tmbBox, searchEntryBin); + const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] = this._getOverviewTranslations(dash, tmbBox, searchEntryBin); tmbBox._translationOriginal = [tmbTranslationX, tmbTranslationY]; dash._translationOriginal = [dashTranslationX, dashTranslationY]; searchEntryBin._translationOriginal = searchTranslationY; @@ -229,7 +295,7 @@ const ControlsManager = { // set searchEntry above appDisplay this.set_child_above_sibling(this._searchEntryBin, null); // move dash above wsTmb for case that dash and wsTmb animate from the same side - if (!_Util.dashNotDefault()) + if (!Me.Util.dashNotDefault()) this.set_child_above_sibling(dash, null); this.set_child_below_sibling(this._thumbnailsBox, null); this.set_child_below_sibling(this._workspacesDisplay, null); @@ -238,7 +304,7 @@ const ControlsManager = { // set dash above workspace in the overview this.set_child_above_sibling(this._thumbnailsBox, null); this.set_child_above_sibling(this._searchEntryBin, null); - if (!_Util.dashNotDefault()) + if (!Me.Util.dashNotDefault()) this.set_child_above_sibling(this.dash, null); this.dash._isAbove = true; @@ -247,6 +313,7 @@ const ControlsManager = { this.set_child_above_sibling(this._workspacesDisplay, null); this.dash._isAbove = false; } + }, // fix for upstream bug - appGrid.visible after transition from APP_GRID to HIDDEN @@ -258,12 +325,6 @@ const ControlsManager = { if (this.dash.showAppsButton.checked) this._searchTransition = false; - // update App Grid after settings changed - // only if the App Grid is currently visible on the screen, the paging updates correctly - if (currentState === ControlsState.APP_GRID && this._appDisplay.visible && opt._appGridNeedsRedisplay) { - Me.imports.lib.appDisplay._updateAppGridProperties(); - opt._appGridNeedsRedisplay = false; - } // if !APP_GRID_ANIMATION, appGrid needs to be hidden in WINDOW_PICKER mode (1) // but needs to be visible for transition from HIDDEN (0) to APP_GRID (2) this._appDisplay.visible = @@ -305,11 +366,19 @@ const ControlsManager = { this._workspacesDisplay.reactive = true; this._workspacesDisplay.setPrimaryWorkspaceVisible(true); } else { + if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) + this._searchController._searchResults._statusText.add_style_class_name('search-statustext-om2'); + else + this._searchController._searchResults._statusText.remove_style_class_name('search-statustext-om2'); this._searchController.show(); entry.visible = true; entry.opacity = 255; + // avoid awkward ws scale animation during search activation + WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 0; } + if (opt.SHOW_BG_IN_OVERVIEW && this._bgManagers) + this._updateBackground(this._bgManagers[0]); this._searchTransition = true; this._searchController._searchResults.translation_x = 0; @@ -317,34 +386,33 @@ const ControlsManager = { this._searchController.opacity = 255; this._searchController.visible = true; - if (opt.SEARCH_VIEW_ANIMATION && !this.dash.showAppsButton.checked && ![4, 8].includes(opt.WS_TMB_POSITION) /* && !opt.OVERVIEW_MODE2*/) { + if (opt.SEARCH_VIEW_ANIMATION && ![4, 8].includes(opt.WS_TMB_POSITION) /* && !opt.OVERVIEW_MODE2*/) { this._updateAppDisplayVisibility(); + this.layoutManager._searchController._searchResults._statusBin.opacity = 1; this._searchController.opacity = searchActive ? 255 : 0; let translationX = 0; let translationY = 0; const geometry = global.display.get_monitor_geometry(global.display.get_primary_monitor()); - if (currentState < ControlsState.APP_GRID) { - switch (opt.SEARCH_VIEW_ANIMATION) { - case 1: - // make it longer to cover the delay before results appears - translationX = geometry.width; - translationY = 0; - break; - case 2: - translationX = -geometry.width; - translationY = 0; - break; - case 3: - translationX = 0; - translationY = geometry.height; - break; - case 5: - translationX = 0; - translationY = -geometry.height; - break; - } + switch (opt.SEARCH_VIEW_ANIMATION) { + case 1: + // make it longer to cover the delay before results appears + translationX = geometry.width; + translationY = 0; + break; + case 2: + translationX = -geometry.width; + translationY = 0; + break; + case 3: + translationX = 0; + translationY = geometry.height; + break; + case 5: + translationX = 0; + translationY = -geometry.height; + break; } if (searchActive) { @@ -363,6 +431,8 @@ const ControlsManager = { onComplete: () => { this._searchController.visible = searchActive; this._searchTransition = false; + this.layoutManager._searchController._searchResults._statusBin.opacity = 255; + WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 200; }, }); @@ -372,7 +442,10 @@ const ControlsManager = { opacity: searchActive || currentState < 2 ? 0 : 255, duration: SIDE_CONTROLS_ANIMATION_TIME / 2, mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => this._updateAppDisplayVisibility(), + onComplete: () => { + this._updateAppDisplayVisibility(); + WorkspaceThumbnail.RESCALE_ANIMATION_TIME = 200; + }, }); // this._updateAppDisplayVisibility(); @@ -390,7 +463,7 @@ const ControlsManager = { this._searchController.opacity = searchActive ? 0 : 255; this._searchController.ease({ opacity: searchActive ? 255 : 0, - duration: searchActive ? SIDE_CONTROLS_ANIMATION_TIME * 2 : 0, + duration: searchActive ? SIDE_CONTROLS_ANIMATION_TIME : 0, mode: Clutter.AnimationMode.EASE_OUT_QUAD, onComplete: () => (this._searchController.visible = searchActive), }); @@ -398,14 +471,16 @@ const ControlsManager = { // reuse already tuned overview transition, just replace APP_GRID with the search view if (!(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) && !Main.overview._animationInProgress && finalState !== ControlsState.HIDDEN && !this.dash.showAppsButton.checked) { - Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-om2'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg-om2'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg'); Main.overview.searchEntry.remove_style_class_name('search-entry-om2'); + const duration = opt.SEARCH_VIEW_ANIMATION ? 150 : 0; this._stateAdjustment.ease(searchActive ? ControlsState.APP_GRID : ControlsState.WINDOW_PICKER, { // shorter animation time when entering search view can avoid stuttering in transition // collecting search results take some time and the problematic part is the realization of the object on the screen // if the ws animation ends before this event, the whole transition is smoother // removing the ws transition (duration: 0) seems like the best solution here - duration: searchActive || (opt.OVERVIEW_MODE && !opt.WORKSPACE_MODE) ? 80 : SIDE_CONTROLS_ANIMATION_TIME, + duration: searchActive ? duration : SIDE_CONTROLS_ANIMATION_TIME, mode: Clutter.AnimationMode.EASE_OUT_QUAD, onComplete: () => { this._workspacesDisplay.setPrimaryWorkspaceVisible(!searchActive); @@ -413,18 +488,20 @@ const ControlsManager = { }); } else if (opt.OVERVIEW_MODE2 && !(opt.WORKSPACE_MODE || this.dash.showAppsButton.checked)) { // add background to search results and make searchEntry border thicker for better visibility - Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-om2'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg-om2'); Main.overview.searchEntry.add_style_class_name('search-entry-om2'); } else { - Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-om2'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.add_style_class_name('search-section-content-bg'); + Main.overview._overview._controls.layoutManager._searchController._searchResults._content.remove_style_class_name('search-section-content-bg-om2'); Main.overview.searchEntry.remove_style_class_name('search-entry-om2'); } }, async runStartupAnimation(callback) { this._ignoreShowAppsButtonToggle = true; - this._searchController.prepareToEnterOverview(); - this._workspacesDisplay.prepareToEnterOverview(); + + this.prepareToEnterOverview(); this._stateAdjustment.value = ControlsState.HIDDEN; this._stateAdjustment.ease(ControlsState.WINDOW_PICKER, { @@ -436,16 +513,20 @@ const ControlsManager = { this._ignoreShowAppsButtonToggle = false; // Set the opacity here to avoid a 1-frame flicker - this.opacity = 0; + this.opacity = 1; + this._appDisplay.opacity = 1; // We can't run the animation before the first allocation happens await this.layout_manager.ensureAllocation(); - const { STARTUP_ANIMATION_TIME } = imports.ui.layout; + this._setBackground(); + Main.panel.opacity = 255; + + const { STARTUP_ANIMATION_TIME } = Layout; // Opacity this.ease({ - opacity: 255, + opacity: opt.STARTUP_STATE === 1 ? 0 : 255, duration: STARTUP_ANIMATION_TIME, mode: Clutter.AnimationMode.LINEAR, onComplete: () => { @@ -465,53 +546,24 @@ const ControlsManager = { } const searchEntryBin = this._searchEntryBin; - const [tmbTranslationX, tmbTranslationY, dashTranslationX, dashTranslationY, searchTranslationY] = - _Util.getOverviewTranslations(opt, dash, tmbBox, searchEntryBin); + const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] = + this._getOverviewTranslations(dash, tmbBox, searchEntryBin); const onComplete = function () { // running init callback again causes issues (multiple connections) - if (!_startupInitComplete) + if (!Main.overview._startupInitComplete) callback(); - _startupInitComplete = true; - - // force app grid to build before the first visible animation to remove possible stuttering - this._appDisplay.opacity = 1; - - const [x, y] = this._appDisplay.get_position(); - const translationX = -x; - const translationY = -y; - this._appDisplay.translation_x = translationX; - this._appDisplay.translation_y = translationY; - GLib.idle_add(0, () => { - this._appDisplay._removeItem(this._appDisplay._orderedItems[0]); - this._appDisplay._redisplay(); - }); - // let the main loop realize previous changes before continuing - _timeouts.startupAnim1 = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - 10, - () => { - GLib.idle_add(0, () => { - this._appDisplay._removeItem(this._appDisplay._orderedItems[0]); - this._appDisplay._redisplay(); - }); - this._appDisplay.translation_x = 0; - this._appDisplay.translation_y = 0; - this._appDisplay.visible = false; - if (opt.STARTUP_STATE === 1) { - Main.overview.hide(); - } else if (opt.STARTUP_STATE === 2) { - this._appDisplay.opacity = 255; - this.dash.showAppsButton.checked = true; - } - _timeouts.startupAnim1 = 0; - return GLib.SOURCE_REMOVE; - } - ); + const appDisplayModule = Me.Modules.appDisplayModule; + if (!appDisplayModule.moduleEnabled) + this._finishStartupSequence(); + else + this._realizeAppDisplayAndFinishSequence(); + + Main.overview._startupInitComplete = true; }.bind(this); - if (dash.visible && !_Util.dashNotDefault()) { + if (dash.visible && !Me.Util.dashNotDefault()) { dash.translation_x = dashTranslationX; dash.translation_y = dashTranslationY; dash.opacity = 255; @@ -521,9 +573,7 @@ const ControlsManager = { delay: STARTUP_ANIMATION_TIME / 2, duration: STARTUP_ANIMATION_TIME, mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - onComplete(); - }, + onComplete, }); } else { // set dash opacity to make it visible if user enable it later @@ -535,6 +585,7 @@ const ControlsManager = { STARTUP_ANIMATION_TIME * 2 * St.Settings.get().slow_down_factor, () => { onComplete(); + Main.overview._startupInitComplete = true; _timeouts.startupAnim2 = 0; return GLib.SOURCE_REMOVE; } @@ -571,7 +622,6 @@ const ControlsManager = { if (view._monitorIndex !== global.display.get_primary_monitor() && view._thumbnails.visible) { const secTmbBox = view._thumbnails; - _Util.getOverviewTranslations(opt, dash, secTmbBox, searchEntryBin); if (opt.SEC_WS_TMB_LEFT) secTmbBox.translation_x = -(secTmbBox.width + 12); // compensate for padding else if (opt.SEC_WS_TMB_RIGHT) @@ -594,13 +644,129 @@ const ControlsManager = { } }, + _realizeAppDisplayAndFinishSequence() { + const appDisplayModule = Me.Modules.appDisplayModule; + // realize app grid for smoother first animation + appDisplayModule._updateAppGrid(false, this._finishStartupSequence.bind(this)); + }, + + _finishStartupSequence(priority = GLib.PRIORITY_LOW) { + if (!this._bgManagers) + this._setBackground(); + + _timeouts.finishStartup = GLib.idle_add( + priority, () => { + this._appDisplay.opacity = 255; + if (opt.STARTUP_STATE === 1) { + Main.overview.hide(); + } else if (opt.STARTUP_STATE === 2) { + Main.overview.show(2); // just because of DtD, because we skipped startup animation + this.dash.showAppsButton.checked = true; + } else if (!opt.STARTUP_STATE && Me.Util.dashNotDefault()) { + Main.overview.show(); + } + + _timeouts.finishStartup = 0; + return GLib.SOURCE_REMOVE; + } + ); + }, + + setInitialTranslations() { + const dash = this.dash; + const tmbBox = this._thumbnailsBox; + const searchEntryBin = this._searchEntryBin; + const [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY] = + this._getOverviewTranslations(dash, tmbBox, searchEntryBin); + if (!Me.Util.dashNotDefault()) { + dash.translation_x = dashTranslationX; + dash.translation_y = dashTranslationY; + } + tmbBox.translation_x = tmbTranslationX; + tmbBox.translation_y = tmbTranslationY; + searchEntryBin.translation_y = searchTranslationY; + }, + + _getOverviewTranslations(dash, tmbBox, searchEntryBin) { + // const tmbBox = Main.overview._overview._controls._thumbnailsBox; + const animationsDisabled = !St.Settings.get().enable_animations || (opt.SHOW_WS_PREVIEW_BG && !opt.OVERVIEW_MODE2); + if (animationsDisabled) + return [0, 0, 0, 0, 0]; + + let searchTranslationY = 0; + if (searchEntryBin.visible) { + const offset = (dash.visible && (!opt.DASH_VERTICAL ? dash.height + 12 : 0)) + + (opt.WS_TMB_TOP ? tmbBox.height + 12 : 0); + searchTranslationY = -searchEntryBin.height - offset - 30; + } + + let tmbTranslationX = 0; + let tmbTranslationY = 0; + let offset; + if (tmbBox.visible) { + const tmbWidth = tmbBox.width === Infinity ? 0 : tmbBox.width; + const tmbHeight = tmbBox.height === Infinity ? 0 : tmbBox.height; + switch (opt.WS_TMB_POSITION) { + case 3: // left + offset = 10 + (dash?.visible && opt.DASH_LEFT ? dash.width : 0); + tmbTranslationX = -tmbWidth - offset; + tmbTranslationY = 0; + break; + case 1: // right + offset = 10 + (dash?.visible && opt.DASH_RIGHT ? dash.width : 0); + tmbTranslationX = tmbWidth + offset; + tmbTranslationY = 0; + break; + case 0: // top + offset = 10 + (dash?.visible && opt.DASH_TOP ? dash.height : 0) + Main.panel.height; + tmbTranslationX = 0; + tmbTranslationY = -tmbHeight - offset; + break; + case 2: // bottom + offset = 10 + (dash?.visible && opt.DASH_BOTTOM ? dash.height : 0) + Main.panel.height; // just for case the panel is at bottom + tmbTranslationX = 0; + tmbTranslationY = tmbHeight + offset; + break; + } + } + + let dashTranslationX = 0; + let dashTranslationY = 0; + let position = opt.DASH_POSITION; + // if DtD replaced the original Dash, read its position + if (Me.Util.dashIsDashToDock()) + position = dash._position; + + if (dash?.visible) { + const dashWidth = dash.width === Infinity ? 0 : dash.width; + const dashHeight = dash.height === Infinity ? 0 : dash.height; + switch (position) { + case 0: // top + dashTranslationX = 0; + dashTranslationY = -dashHeight - dash.margin_bottom - Main.panel.height; + break; + case 1: // right + dashTranslationX = dashWidth; + dashTranslationY = 0; + break; + case 2: // bottom + dashTranslationX = 0; + dashTranslationY = dashHeight + dash.margin_bottom + Main.panel.height; + break; + case 3: // left + dashTranslationX = -dashWidth; + dashTranslationY = 0; + break; + } + } + + return [dashTranslationX, dashTranslationY, tmbTranslationX, tmbTranslationY, searchTranslationY]; + }, + animateToOverview(state, callback) { this._ignoreShowAppsButtonToggle = true; this._searchTransition = false; - this._searchController.prepareToEnterOverview(); - this._workspacesDisplay.prepareToEnterOverview(); - this._stateAdjustment.value = ControlsState.HIDDEN; // building window thumbnails takes some time and with many windows on the workspace @@ -627,10 +793,151 @@ const ControlsManager = { this._ignoreShowAppsButtonToggle = false; }, + + _setBackground(reset = false) { + if (this._bgManagers) { + this._bgManagers.forEach(bg => { + Main.overview._overview._controls._stateAdjustment.disconnect(bg._fadeSignal); + bg.destroy(); + }); + } + + // if (!SHOW_BG_IN_OVERVIEW && !SHOW_WS_PREVIEW_BG) the background is used for static transition from wallpaper to empty bg in the overview + if (reset || (!opt.SHOW_BG_IN_OVERVIEW && opt.SHOW_WS_PREVIEW_BG)) { + delete this._bgManagers; + return; + } + + this._bgManagers = []; + for (const monitor of Main.layoutManager.monitors) { + const bgManager = new Background.BackgroundManager({ + monitorIndex: monitor.index, + container: Main.layoutManager.overviewGroup, + vignette: true, + }); + + bgManager.backgroundActor.content.vignette_sharpness = 0; + bgManager.backgroundActor.content.brightness = 1; + + + bgManager._fadeSignal = Main.overview._overview._controls._stateAdjustment.connect('notify::value', v => { + this._updateBackground(bgManager, v.value, v); + }); + + if (monitor.index === global.display.get_primary_monitor()) { + bgManager._primary = true; + this._bgManagers.unshift(bgManager); // primary monitor first + } else { + bgManager._primary = false; + this._bgManagers.push(bgManager); + } + } + }, + + _updateBackground(bgManager, stateValue = 2, stateAdjustment = null) { + // Blur My Shell extension destroys all background actors in the overview and doesn't care about consequences + if (this._bgManagers[0] && !Main.layoutManager.overviewGroup.get_children().includes(this._bgManagers[0].backgroundActor)) { + Main.notifyError(`[${Me.metadata.name}]`, _('Overview background crashed!\nIf you are using Blur My Shell, disable overview blur in its settings and re-enable V-Shell Overview Background to avoid visual glitches.')); + // remove and disconnect our destroyed backgrounds to avoid more errors + this._setBackground(true); + return; + } + + const finalState = stateAdjustment?.getStateTransitionParams().finalState; + if (!opt.SHOW_BG_IN_OVERVIEW && !opt.SHOW_WS_PREVIEW_BG) { + // if no bg shown in the overview, fade out the wallpaper + if (!(opt.OVERVIEW_MODE2 && opt.WORKSPACE_MODE && finalState === 1)) + bgManager.backgroundActor.opacity = Util.lerp(255, 0, Math.min(stateValue, 1)); + } else { + let VIGNETTE, BRIGHTNESS, bgValue; + if (opt.OVERVIEW_MODE2 && stateValue <= 1 && !opt.WORKSPACE_MODE) { + VIGNETTE = 0; + BRIGHTNESS = 1; + bgValue = stateValue; + } else { + VIGNETTE = 0.2; + BRIGHTNESS = opt.OVERVIEW_BG_BRIGHTNESS; + if (opt.OVERVIEW_MODE2 && stateValue > 1 && !opt.WORKSPACE_MODE) + bgValue = stateValue - 1; + else + bgValue = stateValue; + } + + let blurEffect = bgManager.backgroundActor.get_effect('blur'); + if (!blurEffect) { + blurEffect = new Shell.BlurEffect({ + brightness: 1, + sigma: 0, + mode: Shell.BlurMode.ACTOR, + }); + bgManager.backgroundActor.add_effect_with_name('blur', blurEffect); + } + + const searchActive = Main.overview._overview.controls._searchController.searchActive; + if (searchActive) + BRIGHTNESS = opt.SEARCH_BG_BRIGHTNESS; + + bgManager.backgroundActor.content.vignette_sharpness = VIGNETTE; + bgManager.backgroundActor.content.brightness = BRIGHTNESS; + + let vignetteInit, brightnessInit;// , sigmaInit; + if (opt.SHOW_BG_IN_OVERVIEW && opt.SHOW_WS_PREVIEW_BG) { + vignetteInit = VIGNETTE; + brightnessInit = BRIGHTNESS; + // sigmaInit = opt.OVERVIEW_BG_BLUR_SIGMA; + } else { + vignetteInit = 0; + brightnessInit = 1; + // sigmaInit = 0; + } + + if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) { + bgManager.backgroundActor.content.vignette_sharpness = Util.lerp(vignetteInit, VIGNETTE, bgValue); + bgManager.backgroundActor.content.brightness = Util.lerp(brightnessInit, BRIGHTNESS, bgValue); + } else { + bgManager.backgroundActor.content.vignette_sharpness = Util.lerp(vignetteInit, VIGNETTE, Math.min(stateValue, 1)); + bgManager.backgroundActor.content.brightness = Util.lerp(brightnessInit, BRIGHTNESS, Math.min(stateValue, 1)); + } + + if (opt.OVERVIEW_BG_BLUR_SIGMA || opt.APP_GRID_BG_BLUR_SIGMA) { + // reduce number of steps of blur transition to improve performance + const step = opt.SMOOTH_BLUR_TRANSITIONS ? 0.05 : 0.2; + const progress = stateValue - (stateValue % step); + if (opt.SHOW_WS_PREVIEW_BG && stateValue < 1 && !searchActive) { // no need to animate transition, unless appGrid state is involved, static bg is covered by the ws preview bg + if (blurEffect.sigma !== opt.OVERVIEW_BG_BLUR_SIGMA) + blurEffect.sigma = opt.OVERVIEW_BG_BLUR_SIGMA; + } else if (stateValue < 1 && !searchActive && !(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)) { + const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress)); + if (sigma !== blurEffect.sigma) + blurEffect.sigma = sigma; + } else if (stateValue < 1 && !searchActive && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && blurEffect.sigma)) { + const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress)); + if (sigma !== blurEffect.sigma) + blurEffect.sigma = sigma; + } else if (stateValue > 1 && !searchActive && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE && finalState === 1)) { + const sigma = Math.round(Util.lerp(0, opt.OVERVIEW_BG_BLUR_SIGMA, progress % 1)); + if (sigma !== blurEffect.sigma) + blurEffect.sigma = sigma; + } else if ((stateValue > 1 && bgManager._primary) || searchActive) { + const sigma = Math.round(Util.lerp(opt.OVERVIEW_BG_BLUR_SIGMA, opt.APP_GRID_BG_BLUR_SIGMA, progress % 1)); + if (sigma !== blurEffect.sigma) + blurEffect.sigma = sigma; + } else if (stateValue === 1 && !(opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE)) { + blurEffect.sigma = opt.OVERVIEW_BG_BLUR_SIGMA; + } else if (stateValue === 0 || (stateValue === 1 && (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE))) { + blurEffect.sigma = 0; + } + } + } + }, }; const ControlsManagerLayoutVertical = { - _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, searchHeight, startY) { + _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, thumbnailsHeight, searchHeight, startY) { + // in case the function is called from the DtD + if (startY === undefined) { + workAreaBox = box; + } const workspaceBox = box.copy(); let [width, height] = workspaceBox.get_size(); // const { x1: startX/* y1: startY*/ } = workAreaBox; @@ -640,7 +947,7 @@ const ControlsManagerLayoutVertical = { const dash = Main.overview.dash; // including Dash to Dock and clones properties for compatibility - if (_Util.dashIsDashToDock()) { + if (Me.Util.dashIsDashToDock()) { // Dash to Dock also always affects workAreaBox Main.layoutManager._trackedActors.forEach(actor => { if (actor.affectsStruts && actor.actor.width === dash.width) { @@ -678,7 +985,7 @@ const ControlsManagerLayoutVertical = { case ControlsState.APP_GRID: if (opt.WS_ANIMATION && opt.SHOW_WS_TMB && state === ControlsState.APP_GRID) { workspaceBox.set_origin(...this._workspacesThumbnails.get_position()); - workspaceBox.set_size(...this._workspacesThumbnails.get_size()); + workspaceBox.set_size(thumbnailsWidth, thumbnailsHeight); } else if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) { if (opt.START_Y_OFFSET) { let [x, y] = workAreaBox.get_origin(); @@ -693,7 +1000,7 @@ const ControlsManagerLayoutVertical = { height = opt.PANEL_POSITION_TOP ? height : height - Main.panel.height; searchHeight = opt.SHOW_SEARCH_ENTRY ? searchHeight : 0; wWidth = width - - (opt.DASH_VERTICAL ? dash.width : 0) - + (opt.DASH_VERTICAL ? dashWidth : 0) - thumbnailsWidth - 4 * spacing; wHeight = height - @@ -739,7 +1046,7 @@ const ControlsManagerLayoutVertical = { } const wsBoxX = /* startX + */xOffset; - wsBoxY = Math.round(startY + yOffset); + wsBoxY = startY + yOffset; workspaceBox.set_origin(Math.round(wsBoxX), Math.round(wsBoxY)); workspaceBox.set_size(Math.round(wWidth), Math.round(wHeight)); } @@ -749,6 +1056,10 @@ const ControlsManagerLayoutVertical = { }, _getAppDisplayBoxForState(state, box, workAreaBox, searchHeight, dashWidth, dashHeight, thumbnailsWidth, startY) { + // in case the function is called from the DtD + if (startY === undefined) { + workAreaBox = box; + } const [width] = box.get_size(); const { x1: startX } = workAreaBox; // const { y1: startY } = workAreaBox; @@ -762,11 +1073,11 @@ const ControlsManagerLayoutVertical = { const xOffsetR = (opt.WS_TMB_RIGHT ? thumbnailsWidth : 0) + (opt.DASH_RIGHT ? dashWidth : 0); const yOffsetT = (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0); const yOffsetB = opt.DASH_BOTTOM ? dashHeight : 0; - const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 4 * spacing : width - xOffsetL - xOffsetR - 4 * spacing; - const adHeight = height - yOffsetT - yOffsetB - 4 * spacing; + const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 2 * spacing : width - xOffsetL - xOffsetR - 2 * spacing; + const adHeight = height - yOffsetT - yOffsetB; const appDisplayX = opt.CENTER_APP_GRID ? (width - adWidth) / 2 : xOffsetL + 2 * spacing; - const appDisplayY = startY + yOffsetT + 2 * spacing; + const appDisplayY = startY + yOffsetT; switch (state) { case ControlsState.HIDDEN: @@ -774,43 +1085,43 @@ const ControlsManagerLayoutVertical = { // 1 - left, 2 - right, 3 - bottom, 5 - top switch (opt.APP_GRID_ANIMATION) { case 0: - appDisplayBox.set_origin(appDisplayX, appDisplayY); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY)); break; case 1: - appDisplayBox.set_origin(startX + width, appDisplayY); + appDisplayBox.set_origin(Math.round(startX + width), Math.round(appDisplayY)); break; case 2: - appDisplayBox.set_origin(startX - adWidth, appDisplayY); + appDisplayBox.set_origin(Math.round(startX - adWidth), Math.round(appDisplayY)); break; case 3: - appDisplayBox.set_origin(appDisplayX, workAreaBox.y2); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y2)); break; case 5: - appDisplayBox.set_origin(appDisplayX, workAreaBox.y1 - adHeight); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y1 - adHeight)); break; } break; case ControlsState.APP_GRID: - appDisplayBox.set_origin(appDisplayX, appDisplayY); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY)); break; } - appDisplayBox.set_size(adWidth, adHeight); + appDisplayBox.set_size(Math.round(adWidth), Math.round(adHeight)); return appDisplayBox; }, vfunc_allocate(container, box) { - const childBox = new Clutter.ActorBox(); + const transitionParams = this._stateAdjustment.getStateTransitionParams(); + const childBox = new Clutter.ActorBox(); const { spacing } = this; - + const halfSpacing = spacing / 2; const monitor = Main.layoutManager.findMonitorForActor(this._container); const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index); const startX = workArea.x - monitor.x; // if PANEL_OVERVIEW_ONLY, the affectStruts property is set to false to avoid stuttering // therefore we need to add panel height to startY let startY = workArea.y - monitor.y + opt.START_Y_OFFSET; - const workAreaBox = new Clutter.ActorBox(); workAreaBox.set_origin(startX, startY); workAreaBox.set_size(workArea.width, workArea.height); @@ -818,7 +1129,7 @@ const ControlsManagerLayoutVertical = { box.x1 += startX; let [width, height] = box.get_size(); // if panel is at bottom position, - // compensate the height of the available box (the box size is calculated for top panel) + // compensate for the height of the available box (the box size is calculated for top panel) height = opt.PANEL_POSITION_TOP ? height : height - Main.panel.height; let availableHeight = height; @@ -830,8 +1141,8 @@ const ControlsManagerLayoutVertical = { // dash cloud be overridden by the Dash to Dock clone const dash = Main.overview.dash; - if (_Util.dashIsDashToDock()) { - // if Dash to Dock replaced the default dash and its inteli-hide id disabled we need to compensate for affected startY + if (Me.Util.dashIsDashToDock()) { + // if Dash to Dock replaced the default dash and its inteli-hide is disabled we need to compensate for affected startY if (!Main.overview.dash.get_parent()?.get_parent()?.get_parent()?._intellihideIsEnabled) { if (Main.panel.y === monitor.y) startY = Main.panel.height + spacing; @@ -857,48 +1168,48 @@ const ControlsManagerLayoutVertical = { } } - const transitionParams = this._stateAdjustment.getStateTransitionParams(); - // Workspace Thumbnails let wsTmbWidth = 0; let wsTmbHeight = 0; - if (this._workspacesThumbnails.visible) { - // const { expandFraction } = this._workspacesThumbnails; + let maxWsTmbScale = opt.MAX_THUMBNAIL_SCALE; + if (opt.SHOW_WS_TMB) { const dashHeightReservation = !opt.WS_TMB_FULL && !opt.DASH_VERTICAL ? dashHeight : 0; - let maxScale = opt.MAX_THUMBNAIL_SCALE; - if (!opt.MAX_THUMBNAIL_SCALE_STABLE) { + const searchActive = this._searchController.searchActive; + if (!opt.MAX_THUMBNAIL_SCALE_STABLE && !searchActive) { const initState = transitionParams.initialState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE; const finalState = transitionParams.finalState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE; - maxScale = Util.lerp(initState, finalState, transitionParams.progress); + maxWsTmbScale = Util.lerp(initState, finalState, transitionParams.progress); } - wsTmbWidth = width * maxScale; + wsTmbWidth = width * maxWsTmbScale; let totalTmbSpacing; - [totalTmbSpacing, wsTmbHeight] = this._workspacesThumbnails.get_preferred_custom_height(wsTmbWidth); + [totalTmbSpacing, wsTmbHeight] = this._workspacesThumbnails.get_preferred_height(wsTmbWidth); wsTmbHeight += totalTmbSpacing; - const wsTmbHeightMax = height - dashHeightReservation; + const wsTmbHeightMax = opt.WS_TMB_FULL + ? height - spacing + : height - dashHeightReservation - 2 * spacing; if (wsTmbHeight > wsTmbHeightMax) { wsTmbHeight = wsTmbHeightMax; - wsTmbWidth = this._workspacesThumbnails.get_preferred_custom_width(wsTmbHeight)[1]; + wsTmbWidth = Math.round(this._workspacesThumbnails.get_preferred_width(wsTmbHeight)[1]); } let wsTmbX; if (opt.WS_TMB_RIGHT) - wsTmbX = Math.round(startX + width - (opt.DASH_RIGHT ? dashWidth : 0) - wsTmbWidth - spacing / 2); + wsTmbX = Math.round(startX + width - (opt.DASH_RIGHT ? dashWidth : 0) - wsTmbWidth /* - halfSpacing*/); // this halfSpacing is a part od dash style else - wsTmbX = Math.round((opt.DASH_LEFT ? dashWidth : 0) + spacing / 2); + wsTmbX = Math.round(opt.DASH_LEFT ? dashWidth : 0/* + halfSpacing*/); // this halfSpacing is a part od dash style let wstOffset = (height - wsTmbHeight - (opt.DASH_VERTICAL ? 0 : dashHeightReservation)) / 2; - wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - spacing / 2); + wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - halfSpacing); let wsTmbY = Math.round(startY + (dashHeightReservation && opt.DASH_TOP ? dashHeight : 0) + wstOffset); childBox.set_origin(wsTmbX, wsTmbY); - childBox.set_size(Math.round(wsTmbWidth), Math.round(wsTmbHeight)); + childBox.set_size(Math.max(wsTmbWidth, 1), Math.max(wsTmbHeight, 1)); this._workspacesThumbnails.allocate(childBox); } @@ -927,7 +1238,7 @@ const ControlsManagerLayoutVertical = { if (!opt.DASH_VERTICAL) { offset = (width - ((opt.WS_TMB_FULL || opt.CENTER_DASH_WS) && !this._xAlignCenter ? wsTmbWidth : 0) - dashWidth) / 2; - offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2); + offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing); dashX = offset; if ((opt.WS_TMB_FULL || opt.CENTER_DASH_WS) && !this._xAlignCenter) { @@ -944,7 +1255,7 @@ const ControlsManagerLayoutVertical = { } } else { offset = (height - dashHeight) / 2; - dashY = startY + (offset - opt.DASH_POSITION_ADJUSTMENT * offset); + dashY = startY + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing)); } childBox.set_origin(Math.round(startX + dashX), Math.round(dashY)); @@ -957,7 +1268,7 @@ const ControlsManagerLayoutVertical = { let [searchHeight] = this._searchEntry.get_preferred_height(width - wsTmbWidth); // Workspaces - let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, searchHeight, startY]; + let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, wsTmbHeight, searchHeight, startY]; // Update cached boxes for (const state of Object.values(ControlsState)) { @@ -983,7 +1294,7 @@ const ControlsManagerLayoutVertical = { // Y position under top Dash let searchEntryX, searchEntryY; if (opt.DASH_TOP) - searchEntryY = startY + dashHeight - spacing; + searchEntryY = startY + dashHeight; else searchEntryY = startY; @@ -1005,7 +1316,11 @@ const ControlsManagerLayoutVertical = { availableHeight -= searchHeight + spacing; // if (this._appDisplay.visible)... ? Can cause problems - params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbWidth, startY]; // send startY, can be corrected + // Calculate appDisplay always for AppGrid state WsTmb scale + let wsTmbWidthAppGrid = opt.MAX_THUMBNAIL_SCALE_APPGRID > 0 + ? Math.round(wsTmbWidth / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE_APPGRID) + : Math.round(wsTmbWidth / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE); + params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbWidthAppGrid, startY]; // send startY, can be corrected let appDisplayBox; if (!transitionParams.transitioning) { appDisplayBox = @@ -1024,9 +1339,9 @@ const ControlsManagerLayoutVertical = { if (opt.CENTER_SEARCH_VIEW) { const dashW = (opt.DASH_VERTICAL ? dashWidth : 0) + spacing; searchWidth = width - 2 * wsTmbWidth - 2 * dashW; - childBox.set_origin(wsTmbWidth + dashW, startY + (opt.DASH_TOP ? dashHeight : spacing) + searchHeight); + childBox.set_origin(wsTmbWidth + dashW, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + searchHeight); } else { - childBox.set_origin(this._xAlignCenter ? wsTmbWidth + spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight : spacing) + searchHeight); + childBox.set_origin(this._xAlignCenter ? wsTmbWidth + spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + searchHeight); } childBox.set_size(searchWidth, availableHeight); @@ -1037,7 +1352,11 @@ const ControlsManagerLayoutVertical = { }; const ControlsManagerLayoutHorizontal = { - _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsHeight, searchHeight, startY) { + _computeWorkspacesBoxForState(state, box, workAreaBox, dashWidth, dashHeight, thumbnailsWidth, thumbnailsHeight, searchHeight, startY) { + // in case the function is called from the DtD + if (startY === undefined) { + workAreaBox = box; + } const workspaceBox = box.copy(); let [width, height] = workspaceBox.get_size(); // let { x1: startX/* , y1: startY*/ } = workAreaBox; @@ -1046,7 +1365,7 @@ const ControlsManagerLayoutHorizontal = { const dash = Main.overview.dash; // including Dash to Dock and clones properties for compatibility - if (_Util.dashIsDashToDock()) { + if (Me.Util.dashIsDashToDock()) { // Dash to Dock always affects workAreaBox Main.layoutManager._trackedActors.forEach(actor => { if (actor.affectsStruts && actor.actor.width === dash.width) { @@ -1084,7 +1403,7 @@ const ControlsManagerLayoutHorizontal = { case ControlsState.APP_GRID: if (opt.WS_ANIMATION && opt.SHOW_WS_TMB && state === ControlsState.APP_GRID) { workspaceBox.set_origin(...this._workspacesThumbnails.get_position()); - workspaceBox.set_size(...this._workspacesThumbnails.get_size()); + workspaceBox.set_size(thumbnailsWidth, thumbnailsHeight); } else if (opt.OVERVIEW_MODE2 && !opt.WORKSPACE_MODE) { if (opt.START_Y_OFFSET) { let [x, y] = workAreaBox.get_origin(); @@ -1146,7 +1465,7 @@ const ControlsManagerLayoutHorizontal = { } wsBoxX = /* startX + */xOffset; - wsBoxY = Math.round(startY + yOffset); + wsBoxY = startY + yOffset; workspaceBox.set_origin(Math.round(wsBoxX), Math.round(wsBoxY)); workspaceBox.set_size(Math.round(wWidth), Math.round(wHeight)); } @@ -1156,6 +1475,10 @@ const ControlsManagerLayoutHorizontal = { }, _getAppDisplayBoxForState(state, box, workAreaBox, searchHeight, dashWidth, dashHeight, thumbnailsHeight, startY) { + // in case the function is called from the DtD + if (startY === undefined) { + workAreaBox = box; + } const [width] = box.get_size(); const { x1: startX } = workAreaBox; // const { y1: startY } = workAreaBox; @@ -1163,16 +1486,16 @@ const ControlsManagerLayoutHorizontal = { const appDisplayBox = new Clutter.ActorBox(); const { spacing } = this; - const yOffsetT = (opt.WS_TMB_TOP ? thumbnailsHeight : 0) + (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0) + 2 * spacing; - const yOffsetB = (opt.WS_TMB_BOTTOM ? thumbnailsHeight : 0) + (opt.DASH_BOTTOM ? dashHeight : 0); + const yOffsetT = (opt.WS_TMB_TOP ? thumbnailsHeight + spacing : 0) + (opt.DASH_TOP ? dashHeight : 0) + (opt.SHOW_SEARCH_ENTRY ? searchHeight : 0); + const yOffsetB = (opt.WS_TMB_BOTTOM ? thumbnailsHeight + spacing : 0) + (opt.DASH_BOTTOM ? dashHeight : 0); const xOffsetL = opt.DASH_LEFT ? dashWidth : 0; const xOffsetR = opt.DASH_RIGHT ? dashWidth : 0; - const hSpacing = xOffsetL + xOffsetR ? 2 * spacing : 0; + const hSpacing = xOffsetL + xOffsetR ? spacing : 0; const adWidth = opt.CENTER_APP_GRID ? width - 2 * Math.max(xOffsetL, xOffsetR) - 2 * hSpacing : width - xOffsetL - xOffsetR - 2 * hSpacing; - const adHeight = height - yOffsetT - yOffsetB - 4 * spacing; + const adHeight = height - yOffsetT - yOffsetB; const appDisplayX = opt.CENTER_APP_GRID ? (width - adWidth) / 2 : xOffsetL + hSpacing; - const appDisplayY = startY + yOffsetT + hSpacing; + const appDisplayY = startY + yOffsetT; switch (state) { case ControlsState.HIDDEN: @@ -1180,36 +1503,36 @@ const ControlsManagerLayoutHorizontal = { // 1 - left, 2 - right, 3 - bottom, 5 - top switch (opt.APP_GRID_ANIMATION) { case 0: - appDisplayBox.set_origin(appDisplayX, appDisplayY); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY)); break; case 1: - appDisplayBox.set_origin(startX + width, appDisplayY); + appDisplayBox.set_origin(Math.round(startX + width), Math.round(appDisplayY)); break; case 2: - appDisplayBox.set_origin(startX - adWidth, appDisplayY); + appDisplayBox.set_origin(Math.round(startX - adWidth), Math.round(appDisplayY)); break; case 3: - appDisplayBox.set_origin(appDisplayX, workAreaBox.y2); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y2)); break; case 5: - appDisplayBox.set_origin(appDisplayX, workAreaBox.y1 - adHeight); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(workAreaBox.y1 - adHeight)); break; } break; case ControlsState.APP_GRID: - appDisplayBox.set_origin(appDisplayX, appDisplayY); + appDisplayBox.set_origin(Math.round(appDisplayX), Math.round(appDisplayY)); break; } - appDisplayBox.set_size(adWidth, adHeight); + appDisplayBox.set_size(Math.round(adWidth), Math.round(adHeight)); return appDisplayBox; }, vfunc_allocate(container, box) { + const transitionParams = this._stateAdjustment.getStateTransitionParams(); const childBox = new Clutter.ActorBox(); - const { spacing } = this; - + const halfSpacing = spacing / 2; const monitor = Main.layoutManager.findMonitorForActor(this._container); const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index); const startX = workArea.x - monitor.x; @@ -1235,7 +1558,7 @@ const ControlsManagerLayoutHorizontal = { // dash cloud be overridden by the Dash to Dock clone const dash = Main.overview.dash; - if (_Util.dashIsDashToDock()) { + if (Me.Util.dashIsDashToDock()) { // if Dash to Dock replaced the default dash and its inteli-hide is disabled we need to compensate for affected startY if (!Main.overview.dash.get_parent()?.get_parent()?.get_parent()?._intellihideIsEnabled) { // if (Main.panel.y === monitor.y) @@ -1265,60 +1588,53 @@ const ControlsManagerLayoutHorizontal = { let [searchHeight] = this._searchEntry.get_preferred_height(width); - const transitionParams = this._stateAdjustment.getStateTransitionParams(); - // Workspace Thumbnails let wsTmbWidth = 0; let wsTmbHeight = 0; - if (this._workspacesThumbnails.visible) { - // const { expandFraction } = this._workspacesThumbnails; + let maxWsTmbScale = opt.MAX_THUMBNAIL_SCALE; + if (opt.SHOW_WS_TMB) { const dashWidthReservation = !opt.WS_TMB_FULL && opt.DASH_VERTICAL ? dashWidth : 0; - let maxScale = opt.MAX_THUMBNAIL_SCALE; - if (!opt.MAX_THUMBNAIL_SCALE_STABLE) { + const searchActive = this._searchController.searchActive; + if (!opt.MAX_THUMBNAIL_SCALE_STABLE && !searchActive) { const initState = transitionParams.initialState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE; const finalState = transitionParams.finalState === ControlsState.APP_GRID ? opt.MAX_THUMBNAIL_SCALE_APPGRID : opt.MAX_THUMBNAIL_SCALE; - maxScale = Util.lerp(initState, finalState, transitionParams.progress); + maxWsTmbScale = Util.lerp(initState, finalState, transitionParams.progress); } - wsTmbHeight = height * maxScale; + wsTmbHeight = Math.round(height * maxWsTmbScale); let totalTmbSpacing; - [totalTmbSpacing, wsTmbWidth] = this._workspacesThumbnails.get_preferred_custom_width(wsTmbHeight); + [totalTmbSpacing, wsTmbWidth] = this._workspacesThumbnails.get_preferred_width(wsTmbHeight); wsTmbWidth += totalTmbSpacing; const wsTmbWidthMax = opt.WS_TMB_FULL - ? width - : width - (opt.DASH_VERTICAL ? 0 : dashWidthReservation); + ? width - spacing + : width - dashWidthReservation - 2 * spacing; if (wsTmbWidth > wsTmbWidthMax) { wsTmbWidth = wsTmbWidthMax; - wsTmbHeight = this._workspacesThumbnails.get_preferred_custom_height(wsTmbWidth)[1]; + wsTmbHeight = Math.round(this._workspacesThumbnails.get_preferred_height(wsTmbWidth)[1]); } let wsTmbY; if (opt.WS_TMB_TOP) - wsTmbY = Math.round(startY + /* searchHeight + */(opt.DASH_TOP ? dashHeight : spacing / 2)); + wsTmbY = Math.round(startY + (opt.DASH_TOP ? dashHeight : halfSpacing)); else - wsTmbY = Math.round(startY + height - (opt.DASH_BOTTOM ? dashHeight : 0) - wsTmbHeight); + wsTmbY = Math.round(startY + height - (opt.DASH_BOTTOM ? dashHeight : halfSpacing) - wsTmbHeight); - let wstOffset = (width - wsTmbWidth) / 2; - wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * (wstOffset - spacing / 2); - let wsTmbX = Math.round(Math.clamp( - startX + wstOffset, - startX + (opt.DASH_LEFT ? dashWidthReservation : 0), - width - wsTmbWidth - startX - (opt.DASH_RIGHT ? dashWidthReservation : 0) - )); + let wstOffset = (width - wsTmbWidth - dashWidthReservation) / 2; + wstOffset -= opt.WS_TMB_POSITION_ADJUSTMENT * wstOffset; + let wsTmbX = Math.round(startX + (opt.DASH_LEFT ? dashWidthReservation : 0) + wstOffset); childBox.set_origin(wsTmbX, wsTmbY); - childBox.set_size(Math.round(wsTmbWidth), Math.round(wsTmbHeight)); + childBox.set_size(Math.max(wsTmbWidth, 1), Math.max(wsTmbHeight, 1)); this._workspacesThumbnails.allocate(childBox); availableHeight -= wsTmbHeight + spacing; } - if (this._dash.visible) { if (opt.WS_TMB_FULL && opt.DASH_VERTICAL) { const wMaxHeight = height - spacing - wsTmbHeight; @@ -1339,25 +1655,24 @@ const ControlsManagerLayoutHorizontal = { else dashY = startY + height - dashHeight; - if (opt.DASH_VERTICAL) { if (opt.WS_TMB_FULL) { offset = (height - dashHeight - wsTmbHeight) / 2; if (opt.WS_TMB_TOP) { - offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2); + offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing); dashY = startY + offset + wsTmbHeight; } else { - offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2); + offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing); dashY = startY + offset; } } else { offset = (height - dashHeight) / 2; - offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - spacing / 2); + offset -= opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing); dashY = startY + offset; } } else { offset = (width - dashWidth) / 2; - dashX = startX + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - spacing)); + dashX = startX + (offset - opt.DASH_POSITION_ADJUSTMENT * (offset - halfSpacing)); } childBox.set_origin(Math.round(startX + dashX), Math.round(dashY)); @@ -1368,7 +1683,7 @@ const ControlsManagerLayoutHorizontal = { availableHeight -= opt.DASH_VERTICAL ? 0 : dashHeight; // Workspaces - let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbHeight, searchHeight, startY]; + let params = [box, workAreaBox, dashWidth, dashHeight, wsTmbWidth, wsTmbHeight, searchHeight, startY]; // Update cached boxes for (const state of Object.values(ControlsState)) { @@ -1394,7 +1709,7 @@ const ControlsManagerLayoutHorizontal = { // Y position under top Dash let searchEntryX, searchEntryY; if (opt.DASH_TOP) - searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight : 0) + dashHeight - spacing; + searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight : 0) + dashHeight; else searchEntryY = startY + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0); @@ -1416,7 +1731,11 @@ const ControlsManagerLayoutHorizontal = { availableHeight -= searchHeight + spacing; // if (this._appDisplay.visible)... ? Can cause problems - params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbHeight, startY]; + // Calculate appDisplay always for AppGrid state WsTmb scale + let wsTmbHeightAppGrid = opt.MAX_THUMBNAIL_SCALE_APPGRID > 0 + ? Math.round(wsTmbHeight / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE_APPGRID) + : Math.round(wsTmbHeight / maxWsTmbScale * opt.MAX_THUMBNAIL_SCALE); + params = [box, workAreaBox, searchHeight, dashWidth, dashHeight, wsTmbHeightAppGrid, startY]; let appDisplayBox; if (!transitionParams.transitioning) { appDisplayBox = @@ -1435,9 +1754,9 @@ const ControlsManagerLayoutHorizontal = { if (opt.CENTER_SEARCH_VIEW) { const dashW = (opt.DASH_VERTICAL ? dashWidth : 0) + spacing; searchWidth = width - 2 * dashW; - childBox.set_origin(dashW, startY + (opt.DASH_TOP ? dashHeight : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight); + childBox.set_origin(dashW, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight); } else { - childBox.set_origin(this._xAlignCenter ? spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight); + childBox.set_origin(this._xAlignCenter ? spacing : searchXoffset, startY + (opt.DASH_TOP ? dashHeight + spacing : spacing) + (opt.WS_TMB_TOP ? wsTmbHeight + spacing : 0) + searchHeight); } childBox.set_size(searchWidth, availableHeight); @@ -1462,3 +1781,21 @@ function _getFitModeForState(state) { return FitMode.SINGLE; } } + +const LayoutManager = { + _startupAnimation() { + if (Me.Util.dashIsDashToDock() && !Meta.is_restart()) { + // DtD breaks overview on startup + // Skip animation to hide the mess + this._startupAnimationComplete(); + const controlsManager = Main.overview._overview.controls; + controlsManager._finishStartupSequence.bind(controlsManager)(); + } else if (Meta.is_restart()) { + this._startupAnimationComplete(); + } else if (Main.sessionMode.isGreeter) { + this._startupAnimationGreeter(); + } else { + this._startupAnimationSession(); + } + }, +}; |