@@ -54,6 +54,7 @@ export class AuroraDash extends Dash {
5454 private _draggingItem = false ;
5555 private _targetBoxListener : TargetBoxListener | null = null ;
5656 private _pendingShow : { animate : boolean ; onComplete ?: ( ) => void } | null = null ;
57+ private _cycleState : { appId : string ; windows : any [ ] ; index : number } | null = null ;
5758 private _isDestroyed = false ;
5859
5960 _init ( params : AuroraDashParams = { } ) : void {
@@ -130,6 +131,7 @@ export class AuroraDash extends Dash {
130131 this . _container = null ;
131132 this . _targetBox = null ;
132133 this . _pendingShow = null ;
134+ this . _cycleState = null ;
133135
134136 super . destroy ( ) ;
135137 }
@@ -399,10 +401,15 @@ export class AuroraDash extends Dash {
399401
400402 /**
401403 * 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+ * on this monitor and active workspace cycles through them in MRU
405+ * (Most Recently Used) order. A snapshot of the MRU list is taken on the
406+ * first click and reused for subsequent clicks so the order stays stable
407+ * while cycling. The snapshot resets automatically when the focused
408+ * window no longer matches the last cycled-to window (e.g. the user
409+ * clicked a window directly or switched apps).
404410 */
405411 private _overrideIconActivation ( ) : void {
412+ const self = this ;
406413 const children = ( this as any ) . _box ?. get_children ?.( ) ?? [ ] ;
407414 for ( const child of children ) {
408415 const appIcon = child . child ?. _delegate ;
@@ -420,24 +427,58 @@ export class AuroraDash extends Dash {
420427 const isCtrlPressed = ( modifiers & Clutter . ModifierType . CONTROL_MASK ) !== 0 ;
421428
422429 if ( isCtrlPressed || isMiddleButton ) {
430+ self . _cycleState = null ;
423431 originalActivate ( button ) ;
424432 return ;
425433 }
426434
427435 const windows = appIcon . app . get_windows ( ) . filter ( isRelevant ) ;
428436
429437 if ( windows . length <= 1 ) {
438+ self . _cycleState = null ;
430439 originalActivate ( button ) ;
431440 return ;
432441 }
433442
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 ] ;
443+ const focusedWindow = global . display . focus_window ;
444+ const isFocused = windows . some ( ( w : any ) => w === focusedWindow ) ;
445+ const appId = appIcon . app . get_id ( ) ;
446+
447+ if ( ! isFocused ) {
448+ // App not focused: activate the most recently used window
449+ self . _cycleState = null ;
450+ const win = windows [ 0 ] ;
438451 if ( win . minimized ) win . unminimize ( ) ;
439- win . activate ( global . get_current_time ( ) ) ;
452+ Main . activateWindow ( win ) ;
453+ return ;
440454 }
455+
456+ // Check if we can continue an existing MRU cycle: the focused
457+ // window must match the last window we cycled to.
458+ if (
459+ self . _cycleState ?. appId === appId &&
460+ self . _cycleState . windows [ self . _cycleState . index ] === focusedWindow
461+ ) {
462+ // Advance to the next window in the snapshot
463+ const nextIndex = ( self . _cycleState . index + 1 ) % self . _cycleState . windows . length ;
464+ const next = self . _cycleState . windows [ nextIndex ] ;
465+
466+ // Validate the window still exists on this monitor/workspace
467+ if ( windows . some ( ( w : any ) => w === next ) ) {
468+ self . _cycleState . index = nextIndex ;
469+ if ( next . minimized ) next . unminimize ( ) ;
470+ Main . activateWindow ( next ) ;
471+ return ;
472+ }
473+ // Window was closed — fall through to start a fresh cycle
474+ }
475+
476+ // Start a new MRU cycle: snapshot the current order and activate
477+ // the second entry (the first is the already-focused window).
478+ self . _cycleState = { appId, windows : [ ...windows ] , index : 1 } ;
479+ const next = windows [ 1 ] ;
480+ if ( next . minimized ) next . unminimize ( ) ;
481+ Main . activateWindow ( next ) ;
441482 } ;
442483 }
443484 }
0 commit comments