@@ -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