From 609fd11cd7b663d4813e456df356be7039995bd5 Mon Sep 17 00:00:00 2001 From: Leandro Rodrigues Date: Sun, 30 Aug 2026 15:59:18 -0300 Subject: [PATCH] feat(dock): show dock in overview --- data/po/pt_BR.po | 66 +++--- ....shell.extensions.aurora-shell.gschema.xml | 5 + src/dock/dock.manifest.ts | 6 + src/dock/dock.ts | 114 +++++++++- src/shared/ui/dash.ts | 25 ++- src/shared/ui/dashVisibility.ts | 1 + tests/shell/dock/dock.test.js | 194 +++++++++++++----- tests/unit/project/schema.test.ts | 4 + 8 files changed, 317 insertions(+), 98 deletions(-) diff --git a/data/po/pt_BR.po b/data/po/pt_BR.po index 1cbf242..109eb05 100644 --- a/data/po/pt_BR.po +++ b/data/po/pt_BR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: aurora-shell\n" "Report-Msgid-Bugs-To: https://github.com/luminusOS/aurora-shell/issues\n" -"POT-Creation-Date: 2026-08-19 22:54-0300\n" +"POT-Creation-Date: 2026-08-30 09:40-0300\n" "PO-Revision-Date: 2026-07-16 09:20-0300\n" "Last-Translator: Aurora Shell Contributors\n" "Language-Team: Portuguese (Brazil)\n" @@ -361,10 +361,18 @@ msgid "Keep the dock visible until a window overlaps it" msgstr "Mantém o dock visível até que uma janela sobreponha seu espaço" #: dist/dock/dock.manifest.js:25 +msgid "Show Dock in Overview" +msgstr "Mostrar dock na visão geral" + +#: dist/dock/dock.manifest.js:26 +msgid "Keep the dock visible in the window picker and app grid" +msgstr "Manter o dock visível no seletor de janelas e na grade de aplicativos" + +#: dist/dock/dock.manifest.js:31 msgid "Show Dock on All Monitors" msgstr "Mostrar dock em todos os monitores" -#: dist/dock/dock.manifest.js:27 +#: dist/dock/dock.manifest.js:33 msgid "" "Create a separate dock on each monitor with a free edge in the dock " "direction; otherwise, the primary dock shows all workspace apps" @@ -373,91 +381,91 @@ msgstr "" "caso contrário, o dock principal mostra todos os aplicativos do espaço de " "trabalho" -#: dist/dock/dock.manifest.js:33 +#: dist/dock/dock.manifest.js:39 msgid "Dock Position" msgstr "Posição do dock" -#: dist/dock/dock.manifest.js:34 +#: dist/dock/dock.manifest.js:40 msgid "Screen edge where the dock appears" msgstr "Borda da tela onde o dock aparece" -#: dist/dock/dock.manifest.js:37 +#: dist/dock/dock.manifest.js:43 msgid "Bottom" msgstr "Inferior" -#: dist/dock/dock.manifest.js:38 +#: dist/dock/dock.manifest.js:44 msgid "Left" msgstr "Esquerda" -#: dist/dock/dock.manifest.js:39 +#: dist/dock/dock.manifest.js:45 msgid "Right" msgstr "Direita" -#: dist/dock/dock.manifest.js:44 +#: dist/dock/dock.manifest.js:50 msgid "Maximum Icon Size" msgstr "Tamanho máximo dos ícones" -#: dist/dock/dock.manifest.js:46 +#: dist/dock/dock.manifest.js:52 msgid "" "Maximum dock icon size in pixels (16–64); shrinks automatically when needed" msgstr "" "Tamanho máximo dos ícones da dock em pixels (16–64); reduz automaticamente " "quando necessário" -#: dist/dock/dock.manifest.js:55 +#: dist/dock/dock.manifest.js:61 msgid "Show Trash Icon" msgstr "Mostrar ícone da lixeira" -#: dist/dock/dock.manifest.js:56 +#: dist/dock/dock.manifest.js:62 msgid "Show a trash can in the dock; click to open it, right-click to empty it" msgstr "" "Mostra uma lixeira no dock; clique para abri-la e clique com o botão direito " "para esvaziá-la" -#: dist/dock/dock.manifest.js:61 +#: dist/dock/dock.manifest.js:67 msgid "Show External Storage" msgstr "Mostrar armazenamento externo" -#: dist/dock/dock.manifest.js:62 +#: dist/dock/dock.manifest.js:68 msgid "Show removable drives in the dock when they are connected" msgstr "Mostra unidades removíveis no dock quando estão conectadas" -#: dist/dock/dock.manifest.js:67 +#: dist/dock/dock.manifest.js:73 msgid "Window Previews" msgstr "Pré-visualizações de janelas" -#: dist/dock/dock.manifest.js:68 +#: dist/dock/dock.manifest.js:74 msgid "" "Show live previews and window actions when hovering over running applications" msgstr "" "Mostra pré-visualizações ao vivo e ações de janela ao passar o mouse sobre " "aplicativos em execução" -#: dist/dock/dock.manifest.js:73 +#: dist/dock/dock.manifest.js:79 msgid "Icon Hover & Press Effects" msgstr "Efeitos ao passar o mouse e pressionar o ícone" -#: dist/dock/dock.manifest.js:74 +#: dist/dock/dock.manifest.js:80 msgid "Animate dock icons on hover and click" msgstr "Anima os ícones do dock ao passar o mouse e clicar" -#: dist/dock/dock.manifest.js:79 +#: dist/dock/dock.manifest.js:85 msgid "Effect Intensity" msgstr "Intensidade do efeito" -#: dist/dock/dock.manifest.js:80 +#: dist/dock/dock.manifest.js:86 msgid "How strong the hover and press effects are" msgstr "Define a intensidade dos efeitos ao passar o mouse e pressionar" -#: dist/dock/dock.manifest.js:83 +#: dist/dock/dock.manifest.js:89 msgid "Subtle" msgstr "Sutil" -#: dist/dock/dock.manifest.js:84 +#: dist/dock/dock.manifest.js:90 msgid "Balanced" msgstr "Equilibrado" -#: dist/dock/dock.manifest.js:85 +#: dist/dock/dock.manifest.js:91 msgid "Expressive" msgstr "Expressivo" @@ -667,27 +675,27 @@ msgstr "" "Mostra o nível da bateria e ícones animados no painel de Configurações " "Rápidas do Bluetooth" -#: dist/panel/clock/meetingClock/meetingAlertController.js:115 +#: dist/panel/clock/meetingClock/meetingAlertController.js:118 msgid "Meeting starting soon" msgstr "Reunião começará em breve" -#: dist/panel/clock/meetingClock/meetingAlertController.js:124 +#: dist/panel/clock/meetingClock/meetingAlertController.js:127 msgid "Join" msgstr "Participar" -#: dist/panel/clock/meetingClock/meetingAlertController.js:126 +#: dist/panel/clock/meetingClock/meetingAlertController.js:129 msgid "Snooze" msgstr "Adiar" -#: dist/panel/clock/meetingClock/meetingAlertController.js:127 +#: dist/panel/clock/meetingClock/meetingAlertController.js:130 msgid "Dismiss" msgstr "Dispensar" -#: dist/panel/clock/meetingClock/meetingAlertController.js:129 +#: dist/panel/clock/meetingClock/meetingAlertController.js:132 msgid "Ignore" msgstr "Ignorar" -#: dist/panel/clock/meetingClock/meetingAlertController.js:186 +#: dist/panel/clock/meetingClock/meetingAlertController.js:189 #: dist/panel/clock/meetingClock/meetingClock.manifest.js:8 msgid "Meeting Clock" msgstr "Relógio de reuniões" @@ -1067,7 +1075,7 @@ msgstr "" "Oculta o conteúdo do painel durante o compartilhamento de tela; mostra " "apenas o indicador de compartilhamento" -#: dist/shared/ui/dashWindowPreviews.js:311 +#: dist/shared/ui/dashWindowPreviews.js:307 msgid "Close" msgstr "Fechar" diff --git a/data/schemas/org.gnome.shell.extensions.aurora-shell.gschema.xml b/data/schemas/org.gnome.shell.extensions.aurora-shell.gschema.xml index bfae688..f2d16e5 100644 --- a/data/schemas/org.gnome.shell.extensions.aurora-shell.gschema.xml +++ b/data/schemas/org.gnome.shell.extensions.aurora-shell.gschema.xml @@ -127,6 +127,11 @@ Use intelligent dock auto-hide Keep the dock visible until a window overlaps its screen space + + true + Show dock in overview + Keep the Aurora dock visible in the window picker and app grid + false Show dock on all monitors diff --git a/src/dock/dock.manifest.ts b/src/dock/dock.manifest.ts index 21426bd..27a30fa 100644 --- a/src/dock/dock.manifest.ts +++ b/src/dock/dock.manifest.ts @@ -20,6 +20,12 @@ export const manifest: ModuleManifest = { subtitle: _('Keep the dock visible until a window overlaps it'), type: 'switch', }, + { + key: 'dock-show-in-overview', + title: _('Show Dock in Overview'), + subtitle: _('Keep the dock visible in the window picker and app grid'), + type: 'switch', + }, { key: 'dock-show-on-all-monitors', title: _('Show Dock on All Monitors'), diff --git a/src/dock/dock.ts b/src/dock/dock.ts index 4590f6d..d5392df 100644 --- a/src/dock/dock.ts +++ b/src/dock/dock.ts @@ -6,6 +6,7 @@ import GLib from '@girs/glib-2.0'; import Meta from '@girs/meta-18'; import * as Main from '@girs/gnome-shell/ui/main'; +import * as OverviewControls from '@girs/gnome-shell/ui/overviewControls'; import type { ExtensionContext } from '~/core/context.ts'; import { LifecycleScope } from '~/core/lifecycleScope.ts'; @@ -55,6 +56,13 @@ export class Dock extends Module { private _dragReveal: ContextualDragRevealCoordinator | null = null; private _sessionWasLocked = false; private _fullscreenMonitors = new Set(); + private _overviewLayoutPatch: { + layout: any; + computeOriginal: (...args: any[]) => any; + computeWrapper: (...args: any[]) => any; + appOriginal: (...args: any[]) => any; + appWrapper: (...args: any[]) => any; + } | null = null; constructor(context: ExtensionContext) { super(context); @@ -91,6 +99,7 @@ export class Dock extends Module { ); Main.overview.dash.hide(); + this._installOverviewLayoutPatch(); this._sessionWasLocked = Boolean(Main.sessionMode.isLocked); this._fullscreenMonitors = this._getFullscreenMonitors(); @@ -154,6 +163,10 @@ export class Dock extends Module { () => this._handleConfigurationChange('alwaysShow'), 'changed::dock-intellihide', () => this._handleConfigurationChange('intellihide'), + 'changed::dock-show-in-overview', + () => { + if (Main.overview.visible) this._setOverviewVisible(true); + }, 'changed::dock-show-on-all-monitors', () => this._handleConfigurationChange('showOnAllMonitors'), 'changed::dock-position', @@ -179,6 +192,7 @@ export class Dock extends Module { } override disable(): void { + this._removeOverviewLayoutPatch(); Main.overview.dash.show(); this._dragReveal?.destroy(); this._dragReveal = null; @@ -406,6 +420,7 @@ export class Dock extends Module { trackFullscreen: true, affectsStruts: false, }); + container.connectObject('notify::allocation', () => this._queueOverviewRelayout(), this); const dash = new AuroraDash({ monitorIndex, @@ -489,12 +504,22 @@ export class Dock extends Module { return binding; } - private _syncStacking(): void { + private _syncStacking(forceUiGroup = Main.overview.visible): void { const windowGroup = global.window_group; - const popup = windowGroup.get_children().find((actor) => { - const window = (actor as typeof actor & { meta_window?: Meta.Window }).meta_window; - return window && APPLICATION_POPUP_WINDOW_TYPES.includes(window.get_window_type()); - }); + let popup: Meta.WindowActor | null = null; + if (!forceUiGroup) { + for (const actor of global.get_window_actors()) { + const window = actor.meta_window; + if ( + actor.get_parent() === windowGroup && + window !== null && + APPLICATION_POPUP_WINDOW_TYPES.includes(window.get_window_type()) + ) { + popup = actor; + break; + } + } + } const targetGroup = popup ? windowGroup : Main.uiGroup; for (const binding of this._bindings.values()) { @@ -795,15 +820,23 @@ export class Dock extends Module { return; } + this._syncStacking(overviewShowing); + const showInOverview = + overviewShowing && this.context.settings.getBoolean('dock-show-in-overview'); this._bindings.forEach((binding) => { if (overviewShowing) { this._clearHotAreaReveal(binding); this._clearHotAreaEnable(binding); binding.hotAreaActive = false; binding.hotArea?.setEnabled(false); - binding.dash.blockAutoHide(false); - binding.dash.hide(false); - binding.container.hide(); + this._updateWorkArea(binding); + binding.dash.blockAutoHide(showInOverview); + if (showInOverview) { + binding.dash.show(false); + } else { + binding.dash.hide(false); + binding.container.hide(); + } } else { binding.hotArea?.setEnabled(true); this._updateWorkArea(binding); @@ -817,5 +850,70 @@ export class Dock extends Module { } } }); + this._queueOverviewRelayout(); + } + + private _installOverviewLayoutPatch(): void { + if (this._overviewLayoutPatch) return; + + const layout = Main.overview._overview.controls.layout_manager as any; + const computeOriginal = layout._computeWorkspacesBoxForState; + const appOriginal = layout._getAppDisplayBoxForState; + const computeWrapper = (...args: any[]) => { + const box = computeOriginal.apply(layout, args); + return args[0] === OverviewControls.ControlsState.HIDDEN + ? box + : this._reserveOverviewDockSpace(box); + }; + const appWrapper = (...args: any[]) => { + const box = appOriginal.apply(layout, args); + return args[0] === OverviewControls.ControlsState.APP_GRID + ? this._reserveOverviewDockSpace(box) + : box; + }; + + layout._computeWorkspacesBoxForState = computeWrapper; + layout._getAppDisplayBoxForState = appWrapper; + this._overviewLayoutPatch = { + layout, + computeOriginal, + computeWrapper, + appOriginal, + appWrapper, + }; + layout.layout_changed(); + } + + private _removeOverviewLayoutPatch(): void { + const patch = this._overviewLayoutPatch; + if (!patch) return; + if (patch.layout._computeWorkspacesBoxForState === patch.computeWrapper) + patch.layout._computeWorkspacesBoxForState = patch.computeOriginal; + if (patch.layout._getAppDisplayBoxForState === patch.appWrapper) + patch.layout._getAppDisplayBoxForState = patch.appOriginal; + patch.layout.layout_changed(); + this._overviewLayoutPatch = null; + } + + private _reserveOverviewDockSpace(box: any): any { + if (!this.context.settings.getBoolean('dock-show-in-overview')) return box; + + const monitorIndex = Main.layoutManager.primaryIndex; + const monitor = Main.layoutManager.monitors?.[monitorIndex]; + const container = this._bindings.get(monitorIndex)?.container; + if (!monitor || !container) return box; + + if (this._position === 'left') { + box.x1 = Math.min(box.x2, Math.max(box.x1, container.x + container.width - monitor.x)); + } else if (this._position === 'right') { + box.x2 = Math.max(box.x1, Math.min(box.x2, container.x - monitor.x)); + } else { + box.y2 = Math.max(box.y1, Math.min(box.y2, container.y - monitor.y)); + } + return box; + } + + private _queueOverviewRelayout(): void { + this._overviewLayoutPatch?.layout.layout_changed(); } } diff --git a/src/shared/ui/dash.ts b/src/shared/ui/dash.ts index 2877419..6298440 100644 --- a/src/shared/ui/dash.ts +++ b/src/shared/ui/dash.ts @@ -112,8 +112,25 @@ export const AuroraDash = GObject.registerClass( this.connect('notify::mapped', () => this._unredirectInhibitor.setInhibited(this.mapped)); const button = this.showAppsButton; - button.set_toggle_mode(false); - button.connectObject('clicked', () => Main.overview.showApps(), this); + const overviewShowAppsButton = Main.overview.dash.showAppsButton; + button.set_toggle_mode(true); + button.checked = overviewShowAppsButton.checked; + overviewShowAppsButton.connectObject( + 'notify::checked', + () => (button.checked = overviewShowAppsButton.checked), + this, + ); + button.connectObject( + 'clicked', + () => { + if (Main.overview.visible) { + overviewShowAppsButton.checked = !overviewShowAppsButton.checked; + } else { + Main.overview.showApps(); + } + }, + this, + ); const dashContainer = this._dashContainer; dashContainer.set_track_hover(true); @@ -280,6 +297,7 @@ export const AuroraDash = GObject.registerClass( } this.showAppsButton.disconnectObject(this); + Main.overview.dash.showAppsButton.disconnectObject(this); if (this._dashBox) { this._dashBox.disconnectObject(this); @@ -756,6 +774,7 @@ export const AuroraDash = GObject.registerClass( const size = this._getAllocationSize(); if (!size) return; + this._visibility.flushPendingShow(); if (!this.visible || this.translation_x !== 0 || this.translation_y !== 0) return; const [stageX, stageY] = this.get_transformed_position(); @@ -771,8 +790,6 @@ export const AuroraDash = GObject.registerClass( this._targetBox = bounds; if (this._targetBoxListener) this._targetBoxListener(this._targetBox); } - - this._visibility.flushPendingShow(); } private _getEdgeMargin(): number { diff --git a/src/shared/ui/dashVisibility.ts b/src/shared/ui/dashVisibility.ts index 47e934b..31f3264 100644 --- a/src/shared/ui/dashVisibility.ts +++ b/src/shared/ui/dashVisibility.ts @@ -92,6 +92,7 @@ export class DashVisibilityController { show(animate = true, onComplete?: () => void): void { this._options.getContainer()?.show(); + this._options.showActor(); this._setContainerInputEnabled(true); if (onComplete) { diff --git a/tests/shell/dock/dock.test.js b/tests/shell/dock/dock.test.js index eff092d..8442cc8 100644 --- a/tests/shell/dock/dock.test.js +++ b/tests/shell/dock/dock.test.js @@ -44,6 +44,125 @@ function findDockActor() { return null; } +async function waitForDockVisibility(dock, visible, description) { + if (!dock || dock.bindings.length === 0) + throw new Error(`Could not find the primary Dock while waiting for ${description}`); + const binding = dock.bindings[0]; + + try { + await waitForCondition({ + evaluate: () => + binding.dash.visible === visible && + binding.container.reactive === visible && + (!visible || (binding.container.visible && binding.container.mapped)), + signals: [ + [binding.dash, 'notify::visible'], + [binding.container, 'notify::visible'], + [binding.container, 'notify::mapped'], + [binding.container, 'notify::reactive'], + ], + description, + }); + } catch (error) { + const allocation = binding.dash.get_allocation_box(); + throw new Error( + `${error}; dash.visible=${binding.dash.visible} ` + + `container.visible=${binding.container.visible} mapped=${binding.container.mapped} ` + + `reactive=${binding.container.reactive} parent=${binding.container.get_parent()?.name} ` + + `target=${binding.dash._visibility._target} ` + + `pending=${Boolean(binding.dash._visibility._pendingShow)} ` + + `allocation=${allocation.x1},${allocation.y1},${allocation.x2},${allocation.y2}`, + ); + } +} + +async function exerciseOverviewVisibility(settings, dock) { + const originalIntellihide = settings.get_boolean('dock-intellihide'); + const controls = Main.overview._overview.controls; + const originalControlsMargins = [ + controls.margin_left, + controls.margin_right, + controls.margin_bottom, + ]; + const assertNoDockOverlap = (actor, description) => { + const actorBox = actor.get_transformed_extents(); + const dockBox = dock.bindings[0].container.get_transformed_extents(); + if ( + actorBox.x1 < dockBox.x2 && + actorBox.x2 > dockBox.x1 && + actorBox.y1 < dockBox.y2 && + actorBox.y2 > dockBox.y1 + ) + throw new Error(`${description} overlaps the visible Aurora Dock`); + }; + settings.set_boolean('dock-intellihide', false); + settings.set_boolean('dock-show-in-overview', true); + await Scripting.waitLeisure(); + + Main.overview.show(); + await waitForDockVisibility(dock, true, 'Dock to appear in the window picker'); + if (Main.overview.dash.visible) throw new Error('Native GNOME Dash is visible with Aurora Dock'); + if (dock.bindings[0].container.get_parent() !== Main.uiGroup) + throw new Error('Dock was not moved to visible Shell chrome for the overview'); + if ( + controls.margin_left !== originalControlsMargins[0] || + controls.margin_right !== originalControlsMargins[1] || + controls.margin_bottom !== originalControlsMargins[2] + ) + throw new Error('Aurora Dock changed the root overview margins'); + assertNoDockOverlap(controls._workspacesDisplay, 'Overview workspace'); + + dock.bindings[0].dash.showAppsButton.emit('clicked', Clutter.BUTTON_PRIMARY); + await waitForCondition({ + evaluate: () => + controls.appDisplay.visible && + controls._stateAdjustment.value === controls._stateAdjustment.upper, + signals: [ + [controls.appDisplay, 'notify::visible'], + [controls._stateAdjustment, 'notify::value'], + ], + description: 'overview to finish entering the app grid', + }); + if (!dock.bindings[0].dash.showAppsButton.checked || !Main.overview.dash.showAppsButton.checked) + throw new Error('Aurora Show Apps button does not expose the active app-grid state'); + await waitForDockVisibility(dock, true, 'Dock to remain visible in the app grid'); + assertNoDockOverlap(controls.appDisplay, 'Overview app grid'); + + dock.bindings[0].dash.showAppsButton.emit('clicked', Clutter.BUTTON_PRIMARY); + await waitForCondition({ + evaluate: () => + !dock.bindings[0].dash.showAppsButton.checked && + !Main.overview.dash.showAppsButton.checked && + controls._stateAdjustment.value === controls._stateAdjustment.upper - 1, + signals: [ + [dock.bindings[0].dash.showAppsButton, 'notify::checked'], + [Main.overview.dash.showAppsButton, 'notify::checked'], + [controls._stateAdjustment, 'notify::value'], + ], + description: 'Show Apps buttons to return to the window picker and clear their checked state', + }); + await waitForDockVisibility(dock, true, 'Dock to remain visible after leaving the app grid'); + + settings.set_boolean('dock-show-in-overview', false); + await waitForDockVisibility(dock, false, 'Dock to hide after disabling overview visibility'); + if (dock.bindings[0].container.visible) + throw new Error('Dock container remains visible after disabling overview visibility'); + + settings.set_boolean('dock-show-in-overview', true); + await waitForDockVisibility(dock, true, 'Dock to reappear after enabling overview visibility'); + + await ensureOverviewHidden(); + await waitForDockVisibility(dock, false, 'always-auto-hide Dock to restore after overview'); + Main.overview.show(); + await waitForDockVisibility(dock, true, 'Dock to appear on the second overview opening'); + assertNoDockOverlap(controls._workspacesDisplay, 'Second overview workspace'); + await ensureOverviewHidden(); + await waitForDockVisibility(dock, false, 'Dock to restore after the second overview opening'); + global.display.emit('restacked'); + settings.set_boolean('dock-intellihide', originalIntellihide); + await Scripting.waitLeisure(); +} + async function exerciseDockStacking(settings, dock) { const originalShowOnAllMonitors = settings.get_boolean('dock-show-on-all-monitors'); const originalAlwaysShow = settings.get_boolean('dock-always-show'); @@ -65,64 +184,9 @@ async function exerciseDockStacking(settings, dock) { ) throw new Error('Dock containers and struts are not tracked as Shell chrome'); - const normalActor = new St.Widget({ name: 'aurora-test-normal-window' }); - global.window_group.add_child(normalActor); - try { - for (const windowType of [ - Meta.WindowType.DROPDOWN_MENU, - Meta.WindowType.POPUP_MENU, - Meta.WindowType.COMBO, - ]) { - const popupActor = new St.Widget({ name: 'aurora-test-application-popup' }); - popupActor.meta_window = { get_window_type: () => windowType }; - global.window_group.add_child(popupActor); - - try { - global.display.emit('restacked'); - const children = global.window_group.get_children(); - const normalIndex = children.indexOf(normalActor); - const popupIndex = children.indexOf(popupActor); - for (const binding of bindings) { - const strutIndex = children.indexOf(binding.strutActor); - const dockIndex = children.indexOf(binding.container); - if ( - binding.strutActor.get_parent() !== global.window_group || - binding.container.get_parent() !== global.window_group || - !(normalIndex < strutIndex && strutIndex < dockIndex && dockIndex < popupIndex) - ) - throw new Error( - `Dock stacking is invalid for popup type ${windowType}: ` + - `normal=${normalIndex} strut=${strutIndex} dock=${dockIndex} popup=${popupIndex}`, - ); - } - } finally { - popupActor.destroy(); - } - - global.display.emit('restacked'); - const uiChildren = Main.uiGroup.get_children(); - const windowGroupIndex = uiChildren.indexOf(global.window_group); - const topWindowGroupIndex = uiChildren.indexOf(global.top_window_group); - for (const binding of bindings) { - const strutIndex = uiChildren.indexOf(binding.strutActor); - const dockIndex = uiChildren.indexOf(binding.container); - if ( - binding.strutActor.get_parent() !== Main.uiGroup || - binding.container.get_parent() !== Main.uiGroup || - !( - windowGroupIndex < strutIndex && - strutIndex < dockIndex && - dockIndex < topWindowGroupIndex - ) - ) - throw new Error(`Dock did not restore its chrome layer after popup type ${windowType}`); - } - } - await exerciseRealWaylandPopupStacking(bindings); } finally { - normalActor.destroy(); global.display.emit('restacked'); settings.set_boolean('dock-show-on-all-monitors', originalShowOnAllMonitors); settings.set_boolean('dock-always-show', originalAlwaysShow); @@ -881,6 +945,10 @@ export var METRICS = {}; export function init() { Scripting.defineScriptEvent('dockPresent', 'Dock actor found in stage after enable'); + Scripting.defineScriptEvent( + 'overviewVisibilityValid', + 'Dock overview visibility setting applies live in the window picker and app grid', + ); Scripting.defineScriptEvent( 'dockStackingValid', 'Application popup windows remain above the Dock while normal windows stay below it', @@ -993,6 +1061,7 @@ export async function run() { const originalShowExternalStorage = settings.get_boolean('dock-show-external-storage'); const originalAlwaysShow = settings.get_boolean('dock-always-show'); const originalIntellihide = settings.get_boolean('dock-intellihide'); + const originalShowInOverview = settings.get_boolean('dock-show-in-overview'); const originalShowOnAllMonitors = settings.get_boolean('dock-show-on-all-monitors'); const originalPosition = settings.get_string('dock-position'); const originalIconSize = settings.get_user_value('dock-icon-size'); @@ -1027,6 +1096,9 @@ export async function run() { const dock = getAuroraModule('dock'); + await exerciseOverviewVisibility(settings, dock); + Scripting.scriptEvent('overviewVisibilityValid'); + await exerciseDockStacking(settings, dock); Scripting.scriptEvent('dockStackingValid'); @@ -1274,8 +1346,8 @@ export async function run() { }, ); dash._visibility._applyHiddenState = originalApplyHiddenState; - if (hiddenPoseCalls !== 1) - throw new Error(`Repeated show requests restarted the animation ${hiddenPoseCalls} times`); + if (hiddenPoseCalls !== 0) + throw new Error(`Repeated show requests reapplied the hidden pose ${hiddenPoseCalls} times`); Scripting.scriptEvent('repeatedShowStable'); const originalItemDragHover = dash._visibility._hovered; @@ -1724,6 +1796,7 @@ export async function run() { settings.set_boolean('dock-show-external-storage', originalShowExternalStorage); settings.set_boolean('dock-always-show', originalAlwaysShow); settings.set_boolean('dock-intellihide', originalIntellihide); + settings.set_boolean('dock-show-in-overview', originalShowInOverview); settings.set_boolean('dock-show-on-all-monitors', originalShowOnAllMonitors); settings.set_string('dock-position', originalPosition); if (originalIconSize === null) { @@ -1739,6 +1812,7 @@ export async function run() { } let _dockPresent = false; +let _overviewVisibilityValid = false; let _dockStackingValid = false; let _dockPositionsValid = false; let _panelIntact = false; @@ -1770,6 +1844,10 @@ export function script_dockPresent() { _dockPresent = true; } +export function script_overviewVisibilityValid() { + _overviewVisibilityValid = true; +} + export function script_dockStackingValid() { _dockStackingValid = true; } @@ -1877,6 +1955,8 @@ export function script_windowPreviewsValid() { export function finish() { if (!_dockPresent) throw new Error('Dock actor was not found in the stage after extension enable'); + if (!_overviewVisibilityValid) + throw new Error('Dock overview visibility behavior was not verified'); if (!_dockStackingValid) throw new Error('Application popup stacking relative to the Dock was not verified'); if (!_dockPositionsValid) throw new Error('Dock side placement behavior was not verified'); diff --git a/tests/unit/project/schema.test.ts b/tests/unit/project/schema.test.ts index 499135d..c6d1353 100644 --- a/tests/unit/project/schema.test.ts +++ b/tests/unit/project/schema.test.ts @@ -162,6 +162,10 @@ test('schema: Dock uses always auto-hide by default', () => { assert.equal(schemaDefault('dock-intellihide'), 'false'); }); +test('schema: Dock is visible in the overview by default', () => { + assert.equal(schemaDefault('dock-show-in-overview'), 'true'); +}); + test('schema: Dock window previews are opt-in by default', () => { assert.equal(schemaDefault('dock-window-previews'), 'false'); });