diff -Nru gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/debian/changelog gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/debian/changelog --- gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/debian/changelog 2022-07-08 04:08:23.000000000 +0000 +++ gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/debian/changelog 2023-06-02 02:12:06.000000000 +0000 @@ -1,3 +1,42 @@ +gnome-shell-extension-ubuntu-dock (72~ubuntu5.22.04.2.1) jammy; urgency=medium + + * Keep shell overview always visible and usable (LP: #1979096): + - docking: Do ControlsManagerLayout allocation with box-adjusted workArea + - docking: Be more consistent in reducing the overlay layout space + - docking: Add both bottom and top spacing when there are no workspaces + + -- Marco Trevisan (Treviño) Fri, 02 Jun 2023 04:12:06 +0200 + +gnome-shell-extension-ubuntu-dock (72~ubuntu5.22.04.2) jammy; urgency=medium + + [ Marco Trevisan (Treviño) ] + * debian/control: Update maintainer to myself + * Ensure startup animations are performed on monitor changes (LP: #2019751): + - utils: Ensure we destroy the Signals handler as last thing on destroy + - docking: Do not wait for dash animation two times with no overview + - docking: Ensure we perform the startup animation completely on docks + updates (LP: #1965208) + - docking: Use a try/catch statement on our promise to show errors in case + - docking: Cleanup startup animation injections once done + - docking: Handle monitors changed events while preparing startup animation + - docking: Keep clip and coverPane size matching current setup + - docking: Handle when dash is destroyed during the login animation + * Do not hide the dock when menus are closed (LP: #1983130): + - docking: Ignore hover changes if overview is visible (LP: #1983130) + - docking: Check if autohide or intellihide is enabled on menu closed + * Keep shell overview always visible and usable (LP: #1979096): + - docking: Also reduce the app grid area when in auto-hide mode + (LP: #1992847) + - docking: Use an even width for the overview content area + - docking: Keep overview controls layout proportions when resizing it + (LP: #1992847) + + [ Daniel van Vugt ] + * docking: Handle when dash is destroyed during the login animation + (LP: #2019751) + + -- Marco Trevisan (Treviño) Mon, 15 May 2023 21:15:29 +0200 + gnome-shell-extension-ubuntu-dock (72~ubuntu5.22.04.1) jammy; urgency=medium [ Daniel van Vugt ] diff -Nru gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/debian/control gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/debian/control --- gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/debian/control 2022-07-08 04:08:23.000000000 +0000 +++ gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/debian/control 2023-06-02 02:12:06.000000000 +0000 @@ -1,7 +1,7 @@ Source: gnome-shell-extension-ubuntu-dock Section: gnome Priority: optional -Maintainer: Didier Roche +Maintainer: Marco Trevisan Build-Depends: debhelper (>= 10), dh-translations, eslint , diff -Nru gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/docking.js gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/docking.js --- gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/docking.js 2022-07-08 04:08:23.000000000 +0000 +++ gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/docking.js 2023-06-02 02:12:06.000000000 +0000 @@ -694,7 +694,7 @@ _onMenuClosed() { this._ignoreHover = false; this._box.sync_hover(); - this._hoverChanged(); + this._updateDashVisibility(); } _hoverChanged() { @@ -702,7 +702,7 @@ // Skip if dock is not in autohide mode for instance because it is shown // by intellihide. if (this._autohideIsEnabled) { - if (this._box.hover) + if (this._box.hover || Main.overview.visible) this._show(); else this._hide(); @@ -1939,7 +1939,7 @@ this.emit('docks-ready'); } - _prepareStartupAnimation() { + _prepareStartupAnimation(callback) { DockManager.allDocks.forEach(dock => { const { dash } = dock; @@ -1950,6 +1950,31 @@ translation_y: 0, }); }); + + // We need to ensure that if docks are destroyed before animation is + // completed, then we still ensure the animation runs anyways. + const label = 'startup-animation'; + this._signalsHandler.removeWithLabel(label); + + // This shouldn't really ever happen, but in theory the manager + // could be destroyed at any time, in such case complete the animation + this._signalsHandler.addWithLabel(label, this, 'destroy', () => + Main.overview.runStartupAnimation(callback)); + + const waitForDocksReady = () => { + global.window_group.remove_clip(); + this._signalsHandler.addWithLabel(label, this, 'docks-ready', () => { + this._signalsHandler.removeWithLabel(label); + Main.overview.runStartupAnimation(callback); + }); + }; + + if (this._allDocks.length) { + this._signalsHandler.addWithLabel(label, this, 'docks-destroyed', + () => waitForDocksReady()); + } else { + waitForDocksReady(); + } } _runStartupAnimation(callback) { @@ -1974,8 +1999,13 @@ } const mainDockProperties = {}; - if (dock === this.mainDock) - mainDockProperties.onComplete = callback; + if (dock === this.mainDock) { + mainDockProperties.onComplete = () => { + this._signalsHandler.removeWithLabel('startup-animation'); + if (callback) + callback(); + }; + } dash.ease({ opacity: 255, @@ -2046,56 +2076,135 @@ const { ControlsManager, ControlsManagerLayout } = OverviewControls; - this._methodInjections.addWithLabel('main-dash', ControlsManager.prototype, - 'runStartupAnimation', async function (originalMethod, callback) { - const injections = new Utils.InjectionsHandler(); - const dockManager = DockManager.getDefault(); - DockManager.allDocks.forEach(dock => (dock.opacity = 0)); - injections.add(dockManager.mainDock.dash, 'ease', () => {}); - let callbackArgs = []; - const ret = await originalMethod.call(this, - (...args) => (callbackArgs = [...args])); - injections.destroy(); - - if (!DockManager.allDocks.length) { - // Docks may have been destroyed, let's wait till we've one again - const readyPromise = new Promise(resolve => { - const id = dockManager.connect('docks-ready', () => { - dockManager.disconnect(id); - resolve(); + this._methodInjections.removeWithLabel('startup-animation'); + this._methodInjections.addWithLabel('startup-animation', + Main.layoutManager.constructor.prototype, '_startupAnimationComplete', + originalMethod => { + originalMethod.call(Main.layoutManager); + this._methodInjections.removeWithLabel('startup-animation'); + this._signalsHandler.removeWithLabel('startup-animation'); + }); + + if (Main.layoutManager._startingUp && Main.layoutManager._waitLoaded) { + // Disable this on versions that will include: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2763 + this._methodInjections.addWithLabel('startup-animation', + Main.layoutManager.constructor.prototype, + '_prepareStartupAnimation', function (originalMethod, ...args) { + /* eslint-disable no-invalid-this */ + const dockManager = DockManager.getDefault(); + const temporaryInjections = new Utils.InjectionsHandler( + dockManager); + + const waitLoadedHandlingMonitors = (_, bgManager) => { + return new Promise((resolve, reject) => { + const connections = new Utils.GlobalSignalsHandler( + dockManager); + connections.add(bgManager, 'loaded', () => { + connections.destroy(); + resolve(); + }); + + connections.add(Meta.MonitorManager.get(), 'monitors-changed', () => { + connections.destroy(); + + reject(new GLib.Error(Gio.IOErrorEnum, + Gio.IOErrorEnum.CANCELLED, 'Loading was cancelled')); + }); }); - }) - await readyPromise; - } + }; + + async function updateBg(originalUpdateBg, ...bgArgs) { + // eslint-disable-next-line no-constant-condition + while (true) { + try { + // eslint-disable-next-line no-await-in-loop + await originalUpdateBg.call(this, ...bgArgs); + break; + } catch (e) { + if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { + logError(e); + return; + } + } + } + } - dockManager._prepareStartupAnimation(); - dockManager._runStartupAnimation(() => callback(...callbackArgs)); - return ret; + temporaryInjections.add(this.constructor.prototype, + '_waitLoaded', waitLoadedHandlingMonitors); + temporaryInjections.add(this.constructor.prototype, + '_updateBackgrounds', updateBg); + + dockManager._signalsHandler.addWithLabel('startup-animation', + Meta.MonitorManager.get(), 'monitors-changed', () => { + const { x, y, width, height } = this.primaryMonitor; + global.window_group.set_clip(x, y, width, height); + this._coverPane?.set({ + width: global.screen_width, + height: global.screen_height, + }); + }); + + try { + originalMethod.call(this, ...args); + } finally { + temporaryInjections.destroy(); + } + /* eslint-enable no-invalid-this */ + }); + } + + this._methodInjections.addWithLabel('startup-animation', ControlsManager.prototype, + 'runStartupAnimation', async function (originalMethod, callback) { + try { + const injections = new Utils.InjectionsHandler(); + const dockManager = DockManager.getDefault(); + dockManager._prepareStartupAnimation(callback); + injections.add(dockManager.mainDock.dash, 'ease', () => {}); + let callbackArgs = []; + const ret = await originalMethod.call(this, + (...args) => (callbackArgs = [...args])); + injections.destroy(); + + const onComplete = () => callback(...callbackArgs); + dockManager._prepareStartupAnimation(onComplete); + dockManager._runStartupAnimation(onComplete); + return ret; + } catch (e) { + logError(e); + } }); - const maybeAdjustBoxToDock = (state, box, spacing) => { + const maybeAdjustBoxSize = (state, box, spacing) => { if (state === OverviewControls.ControlsState.WINDOW_PICKER) { const searchBox = this.overviewControls._searchEntry.get_allocation_box(); const { shouldShow: wsThumbnails } = this.overviewControls._thumbnailsBox; - if (!wsThumbnails) + if (!wsThumbnails) { box.y1 += spacing; + box.y2 -= spacing; + } box.y2 -= searchBox.get_height() + spacing; - - if (!wsThumbnails && this.mainDock.position === St.Side.BOTTOM) - box.y2 -= spacing; - } else if (state === OverviewControls.ControlsState.APP_GRID) { - return box; + box.y2 -= spacing; } + return box; + }; + + const maybeAdjustBoxToDock = (state, box, spacing) => { + maybeAdjustBoxSize(state, box, spacing); + if (this.mainDock.isHorizontal || this.settings.dockFixed) return box; - const [, preferredWidth] = this.mainDock.get_preferred_width(box.get_height()); - box.x2 -= preferredWidth; + const [, preferredWidth] = this.mainDock.get_preferred_width( + box.get_height()); + if (this.mainDock.position === St.Side.LEFT) - box.set_origin(box.x1 + preferredWidth, box.y1); + box.x1 += preferredWidth; + else if (this.mainDock.position === St.Side.RIGHT) + box.x2 -= preferredWidth; return box; } @@ -2113,17 +2222,19 @@ workAreaBox.set_origin(startX, startY); workAreaBox.set_size(workArea.width, workArea.height); + maybeAdjustBoxToDock(undefined, workAreaBox, this.spacing); + const oldStartY = workAreaBox.y1; + const propertyInjections = new Utils.PropertyInjectionsHandler(); - propertyInjections.add(Main.layoutManager.panelBox, 'height', { value: workAreaBox.y1 }); + propertyInjections.add(Main.layoutManager.panelBox, 'height', { value: startY }); if (Main.layoutManager.panelBox.y === Main.layoutManager.primaryMonitor.y) - workAreaBox.y1 -= startY; + workAreaBox.y1 -= oldStartY; this.vfunc_allocate(container, workAreaBox); propertyInjections.destroy(); - workAreaBox.y1 = startY; - maybeAdjustBoxToDock(undefined, workAreaBox, this.spacing); + workAreaBox.y1 = oldStartY; const adjustActorHorizontalAllocation = actor => { if (!actor.visible || !workAreaBox.x1) @@ -2153,19 +2264,22 @@ ControlsManagerLayout.prototype, '_computeWorkspacesBoxForState', function (originalFunction, state, ...args) { + /* eslint-disable no-invalid-this */ + if (state === OverviewControls.ControlsState.HIDDEN) + return originalFunction.call(this, state, ...args); + const box = workspaceBoxOriginFixer.call(this, originalFunction, state, ...args); - if (state !== OverviewControls.ControlsState.HIDDEN) - maybeAdjustBoxToDock(state, box, this.spacing); - return box; - } + return maybeAdjustBoxSize(state, box, this.spacing); + /* eslint-enable no-invalid-this */ + }, ], [ ControlsManagerLayout.prototype, '_getAppDisplayBoxForState', - function (state, ...args) { - const { spacing } = this; - const box = workspaceBoxOriginFixer.call(this, state, ...args); - return maybeAdjustBoxToDock(state, box, spacing); - } + function (originalFunction, ...args) { + /* eslint-disable no-invalid-this */ + return workspaceBoxOriginFixer.call(this, originalFunction, ...args); + /* eslint-enable no-invalid-this */ + }, ]); this._vfuncInjections.addWithLabel('main-dash', Workspace.WorkspaceBackground.prototype, @@ -2234,7 +2348,7 @@ if (Main.layoutManager._startingUp && Main.sessionMode.hasOverview && this._settings.disableOverviewOnStartup) { - this._methodInjections.addWithLabel('main-dash', + this._methodInjections.addWithLabel('startup-animation', Overview.Overview.prototype, 'runStartupAnimation', (_originalFunction, callback) => { const monitor = Main.layoutManager.primaryMonitor; @@ -2242,7 +2356,7 @@ const y = monitor.y + monitor.height / 2.0; const { STARTUP_ANIMATION_TIME } = Layout; - this._prepareStartupAnimation(); + this._prepareStartupAnimation(callback); Main.uiGroup.set_pivot_point( x / global.screen_width, y / global.screen_height); @@ -2258,11 +2372,10 @@ opacity: 255, duration: STARTUP_ANIMATION_TIME, mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - callback(); - this._runStartupAnimation(); - }, + onComplete: callback, }); + + this._runStartupAnimation(); }); } } @@ -2279,6 +2392,8 @@ // Delete all docks this._allDocks.forEach(d => d.destroy()); this._allDocks = []; + + this.emit('docks-destroyed'); } _restoreDash() { diff -Nru gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/utils.js gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/utils.js --- gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.1/utils.js 2022-07-08 04:08:23.000000000 +0000 +++ gnome-shell-extension-ubuntu-dock-72~ubuntu5.22.04.2.1/utils.js 2023-06-02 02:12:06.000000000 +0000 @@ -146,6 +146,12 @@ let id = connector.call(object, event, callback); + if (event === 'destroy' && object === this._parentObject) { + this._parentObject.disconnect(this._destroyId); + this._destroyId = + this._parentObject.connect('destroy', () => this.destroy()); + } + return [object, id]; }