Skip to content

Commit 252a61e

Browse files
committed
fix(dash): prevent operations on destroyed instance and enhance menu state checks
1 parent 1e52452 commit 252a61e

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

src/ui/dash.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class AuroraDash extends Dash {
5252
private _targetBox: DashBounds | null = null;
5353
private _blockAutoHide = false;
5454
private _draggingItem = false;
55+
private _isDestroyed = false;
5556
private _targetBoxListener: TargetBoxListener | null = null;
5657
private _pendingShow: { animate: boolean; onComplete?: () => void } | null = null;
5758
private _cycleState: { appId: string; windows: any[]; index: number } | null = null;
@@ -114,6 +115,7 @@ export class AuroraDash extends Dash {
114115
}
115116

116117
override destroy(): void {
118+
this._isDestroyed = true;
117119
this._clearAllTimeouts();
118120

119121
(this as any).showAppsButton?.disconnectObject?.(this);
@@ -133,6 +135,7 @@ export class AuroraDash extends Dash {
133135
}
134136

135137
override _queueRedisplay(): void {
138+
if (this._isDestroyed) return;
136139
super._queueRedisplay();
137140
}
138141

@@ -250,7 +253,25 @@ export class AuroraDash extends Dash {
250253
});
251254
}
252255

253-
// -- Private helpers --
256+
private _isMenuOpen(): boolean {
257+
const dashAny = this as any;
258+
const children = dashAny._box?.get_children?.() ?? [];
259+
260+
for (const child of children) {
261+
const appIcon = child.child?._delegate;
262+
263+
if (appIcon?._menu?.isOpen) {
264+
return true;
265+
}
266+
}
267+
268+
const showApps = dashAny.showAppsButton || dashAny._showAppsIcon?._delegate;
269+
if (showApps?._menu?.isOpen) {
270+
return true;
271+
}
272+
273+
return false;
274+
}
254275

255276
private _performShow(animate = true, onComplete?: () => void): void {
256277
if (this._isFullyShown()) {
@@ -501,6 +522,7 @@ export class AuroraDash extends Dash {
501522

502523
const onAnimationDone = () => {
503524
pendingAnimations--;
525+
if (this._isDestroyed) return;
504526
if (pendingAnimations === 0 && this._workArea) {
505527
this.applyWorkArea(this._workArea);
506528
}
@@ -540,12 +562,15 @@ export class AuroraDash extends Dash {
540562

541563
/** Start or restart the autohide timeout — hides the dock if not hovered/dragging/blocked. */
542564
private _onHover(): void {
565+
if (this._isDestroyed) return;
543566
this._clearTimeout('_autohideTimeoutId');
544567
this._autohideTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, AUTOHIDE_TIMEOUT, () => {
545568
const dashContainer = (this as any)._dashContainer as St.Widget | undefined;
546-
if (dashContainer?.get_hover?.() || this._draggingItem || this._blockAutoHide) {
569+
570+
if (dashContainer?.get_hover?.() || this._draggingItem || this._blockAutoHide || this._isMenuOpen()) {
547571
return GLib.SOURCE_CONTINUE;
548572
}
573+
549574
this.hide(true);
550575
this._autohideTimeoutId = 0;
551576
return GLib.SOURCE_REMOVE;
@@ -554,6 +579,7 @@ export class AuroraDash extends Dash {
554579

555580
/** If the cursor is still over the dash container, ensure the dock stays shown. */
556581
private _ensureHoverState(): void {
582+
if (this._isDestroyed) return;
557583
this._clearTimeout('_blockAutoHideDelayId');
558584
this._blockAutoHideDelayId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
559585
const dashContainer = (this as any)._dashContainer as St.Widget | undefined;
@@ -643,7 +669,7 @@ export class AuroraDash extends Dash {
643669

644670
/** Coalesce work-area resizes into a single deferred update. */
645671
private _queueWorkAreaUpdate(): void {
646-
if (this._workAreaUpdateId) return;
672+
if (this._isDestroyed || this._workAreaUpdateId) return;
647673
this._workAreaUpdateId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
648674
this._workAreaUpdateId = 0;
649675
if (this._workArea) {

0 commit comments

Comments
 (0)