From 3c02cf5358efef0831517d529892f0fb2eb20f08 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 6 Dec 2025 19:15:59 +0100 Subject: [PATCH] new: Highlight top-level menu item when performing key equivalent --- AppKit/CPMenu/CPMenu.j | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index 6c23e1408..380d3e2d0 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -1062,7 +1062,13 @@ var _CPMenuBarVisible = NO, if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]]) { if ([item isEnabled]) + { + // Flash the top-level item if this is the Main Menu + if (self === [CPApp mainMenu]) + [self _flashItemAtIndex:index]; + [self performActionForItemAtIndex:index]; + } else { //beep? @@ -1072,7 +1078,13 @@ var _CPMenuBarVisible = NO, } if ([[item submenu] performKeyEquivalent:anEvent]) + { + // Flash the top-level item if a submenu handled the event + if (self === [CPApp mainMenu]) + [self _flashItemAtIndex:index]; + return YES; + } } return NO; @@ -1152,6 +1164,25 @@ var _CPMenuBarVisible = NO, return nil; } +// +/* + @ignore +*/ +- (void)_flashItemAtIndex:(int)anIndex +{ + // If we are using a native bridge (like a desktop wrapper), let the OS handle the visual feedback. + if ([CPPlatform supportsNativeMainMenu]) + return; + + [self _highlightItemAtIndex:anIndex]; + [self performSelector:@selector(_stopFlashingItem) withObject:nil afterDelay:0.2]; +} + +- (void)_stopFlashingItem +{ + [self _highlightItemAtIndex:CPNotFound]; +} + @end