Skip to content

Commit 5a09651

Browse files
committed
feat: override app icon activation to raise all windows for multi-window apps
1 parent 5c1d14f commit 5a09651

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

src/ui/dash.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ export class AuroraDash extends Dash {
349349
// app has no windows on this monitor even if the app is globally running.
350350
this._updatePerMonitorRunningDots();
351351

352+
// Patch icon activation so clicking an app with multiple windows on
353+
// this monitor raises all of them instead of only the most recent one.
354+
this._overrideIconActivation();
355+
352356
if (dashAny.iconSize !== oldIconSize) {
353357
this._animateIconResize();
354358
} else if (this._workArea) {
@@ -393,6 +397,51 @@ export class AuroraDash extends Dash {
393397
}
394398
}
395399

400+
/**
401+
* Override app icon activation so clicking an app with multiple windows
402+
* on this monitor and active workspace raises all of them instead of
403+
* only the most recently used one.
404+
*/
405+
private _overrideIconActivation(): void {
406+
const children = (this as any)._box?.get_children?.() ?? [];
407+
for (const child of children) {
408+
const appIcon = child.child?._delegate;
409+
if (!appIcon?.app || appIcon._auroraActivatePatched) continue;
410+
411+
appIcon._auroraActivatePatched = true;
412+
const originalActivate = appIcon.activate.bind(appIcon);
413+
const isRelevant = (w: any) => this._isWindowRelevant(w);
414+
415+
appIcon.activate = function (button: number) {
416+
// Ctrl+click or middle-click opens a new window — keep default behavior
417+
const event = Clutter.get_current_event();
418+
const modifiers = event ? event.get_state() : 0;
419+
const isMiddleButton = button && button === Clutter.BUTTON_MIDDLE;
420+
const isCtrlPressed = (modifiers & Clutter.ModifierType.CONTROL_MASK) !== 0;
421+
422+
if (isCtrlPressed || isMiddleButton) {
423+
originalActivate(button);
424+
return;
425+
}
426+
427+
const windows = appIcon.app.get_windows().filter(isRelevant);
428+
429+
if (windows.length <= 1) {
430+
originalActivate(button);
431+
return;
432+
}
433+
434+
// Raise all windows: iterate in reverse MRU order so the most
435+
// recently used window ends up focused on top.
436+
for (let i = windows.length - 1; i >= 0; i--) {
437+
const win = windows[i];
438+
if (win.minimized) win.unminimize();
439+
win.activate(global.get_current_time());
440+
}
441+
};
442+
}
443+
}
444+
396445
/**
397446
* Animate all dock icons to the current icon size after a size change.
398447
* Re-applies the work area once all animations finish to resize the

0 commit comments

Comments
 (0)