diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index fc935f471..059c918b7 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -851,7 +851,7 @@ var _CPMenuBarVisible = NO, // Handling Tracking /*! - Cancels tracking. + Cancels tracking. */ - (void)cancelTracking { @@ -972,8 +972,8 @@ var _CPMenuBarVisible = NO, if (_highlightedIndex !== CPNotFound) [[_items[_highlightedIndex] _menuItemView] highlight:YES]; - if (_highlightedIndex !== CPNotFound && _menuWindow) - [_menuWindow._menuView scrollRectToVisible:[[_items[_highlightedIndex] _menuItemView] frame]]; + if (_highlightedIndex !== CPNotFound && _menuWindow) + [_menuWindow._menuView scrollRectToVisible:[[_items[_highlightedIndex] _menuItemView] frame]]; } - (void)_setMenuName:(CPString)aName diff --git a/AppKit/CPMenu/_CPMenuManager.j b/AppKit/CPMenu/_CPMenuManager.j index 773f67811..32c9177f1 100644 --- a/AppKit/CPMenu/_CPMenuManager.j +++ b/AppKit/CPMenu/_CPMenuManager.j @@ -100,31 +100,34 @@ var SharedMenuManager = nil; [CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES]; if(type === CPKeyDown) - { var menu = trackingMenu, - submenu = [[menu highlightedItem] submenu]; + { + var menu = trackingMenu, + submenu = [[menu highlightedItem] submenu]; - // get the current active menu - while(submenu && [submenu._menuWindow isVisible]) - { menu = submenu; - submenu = [[menu highlightedItem] submenu]; - } - if([menu numberOfItems]) - [self interpretKeyEvent:anEvent forMenu:menu]; - return; - } - if(_keyBuffer) - { - if(([CPDate date] - _startTime) > STICKY_TIME_INTERVAL) - [self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES]; - if(type === CPPeriodic) - return; - } + // get the current active menu + while(submenu && [submenu._menuWindow isVisible]) + { menu = submenu; + submenu = [[menu highlightedItem] submenu]; + } + if([menu numberOfItems]) + [self interpretKeyEvent:anEvent forMenu:menu]; + return; + } + if(_keyBuffer) + { + if(([CPDate date] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems]/2)) + [self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES]; + if(type === CPPeriodic) + return; + } // Periodic events don't have a valid location. var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation]; // Remember this for the next periodic event. _lastGlobalLocation = globalLocation; + if(!_lastGlobalLocation) + return; // Find which menu window the mouse is currently on top of var activeMenuContainer = [self menuContainerForPoint:globalLocation], @@ -207,7 +210,7 @@ var SharedMenuManager = nil; [CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04]; } } - else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL)) + else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems]*5))) [trackingMenu cancelTracking]; } @@ -391,159 +394,164 @@ var SharedMenuManager = nil; /// handle keyboard navigation - (void)interpretKeyEvent:(CPEvent)anEvent forMenu:(CPMenu)menu { - var modifierFlags = [anEvent modifierFlags], - character = [anEvent charactersIgnoringModifiers], - selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags]; + var modifierFlags = [anEvent modifierFlags], + character = [anEvent charactersIgnoringModifiers], + selectorNames = [CPKeyBinding selectorsForKey:character modifierFlags:modifierFlags]; - if(selectorNames) - { var iter = [selectorNames objectEnumerator], - obj; - while(obj = [iter nextObject]) - { - var aSelector = CPSelectorFromString(obj); - if ([self respondsToSelector:aSelector]) - [self performSelector:aSelector withObject:menu]; - } - } - else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask))) - { - if(!_keyBuffer) - { - _startTime = [CPDate date]; - _keyBuffer = character; - [CPEvent startPeriodicEventsAfterDelay:0.1 withPeriod:0.1]; - } - else - _keyBuffer += character; - - [self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:NO]; - } + if(selectorNames) + { var iter = [selectorNames objectEnumerator], + obj; + while(obj = [iter nextObject]) + { + var aSelector = CPSelectorFromString(obj); + if ([self respondsToSelector:aSelector]) + [self performSelector:aSelector withObject:menu]; + } + } + else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask))) + { + if(!_keyBuffer) + { + _startTime = [CPDate date]; + _keyBuffer = character; + [CPEvent stopPeriodicEvents]; + [CPEvent startPeriodicEventsAfterDelay:0.1 withPeriod:0.1]; + } + else + _keyBuffer += character; + + [self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:NO]; + _lastGlobalLocation = Nil; + } } - (void)selectNextItemBeginningWith:(CPString)characters inMenu:(CPMenu)menu clearBuffer:(BOOL)shouldClear { - var iter = [[menu itemArray] objectEnumerator], - obj; - while(obj = [iter nextObject]) - { - if([[[obj title] commonPrefixWithString:characters options:CPCaseInsensitiveSearch] length] == [characters length]) - { - [menu _highlightItemAtIndex:iter._index]; - break; - } - } - if(shouldClear) - { - [CPEvent stopPeriodicEvents]; - _keyBuffer = Nil; - } - else - _startTime = [CPDate date]; + var iter = [[menu itemArray] objectEnumerator], + obj; + while(obj = [iter nextObject]) + { + if([[[obj title] commonPrefixWithString:characters options:CPCaseInsensitiveSearch] length] == [characters length]) + { + if(![obj isHidden] && [obj isEnabled]) + { + [menu _highlightItemAtIndex:iter._index]; + break; + } + } + } + if(shouldClear) + { + [CPEvent stopPeriodicEvents]; + _keyBuffer = Nil; + } + else + _startTime = [CPDate date]; } - (void)moveToBeginningOfDocument:(CPMenu)menu { - [self scrollPageUp:menu]; + [self scrollPageUp:menu]; } - (void)moveToEndOfDocument:(CPMenu)menu { - [self scrollPageDown:menu]; + [self scrollPageDown:menu]; } - (void)scrollPageUp:(CPMenu)menu { - [menu _highlightItemAtIndex:0]; + [menu _highlightItemAtIndex:0]; } - (void)scrollPageDown:(CPMenu)menu { - [menu _highlightItemAtIndex:[menu numberOfItems] - 1]; + [menu _highlightItemAtIndex:[menu numberOfItems] - 1]; } - (void)moveLeft:(CPMenu)menu -{ - if([menu supermenu]) - { - if([menu supermenu] == [CPApp mainMenu]) - { - [self showMenu:nil fromMenu:[menu supermenu] atPoint:CGPointMakeZero()]; - [self moveUp:[CPApp mainMenu]]; +{ + if([menu supermenu]) + { + if([menu supermenu] == [CPApp mainMenu]) + { + [self showMenu:nil fromMenu:[menu supermenu] atPoint:CGPointMakeZero()]; + [self moveUp:[CPApp mainMenu]]; - var activeItem = [[CPApp mainMenu] highlightedItem], - menuLocation = CGPointMake([[activeItem _menuItemView] frameOrigin].x , [[activeItem _menuItemView] frameSize].height); - [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:menuLocation]; - } - else - [self showMenu:nil fromMenu:[menu supermenu] atPoint:CGPointMakeZero()]; - } + var activeItem = [[CPApp mainMenu] highlightedItem], + menuLocation = CGPointMake([[activeItem _menuItemView] frameOrigin].x , [[activeItem _menuItemView] frameSize].height); + [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:menuLocation]; + } + else + [self showMenu:nil fromMenu:[menu supermenu] atPoint:CGPointMakeZero()]; + } } - (void)moveRight:(CPMenu)menu { - var activeItem = [menu highlightedItem]; + var activeItem = [menu highlightedItem]; if ([activeItem hasSubmenu]) - { if([[activeItem submenu] numberOfItems]) - { - var activeItemIndex = [menu indexOfItem:activeItem], - activeMenuContainer = menu._menuWindow; - activeItemRect = [activeMenuContainer rectForItemAtIndex:activeItemIndex]; - - if ([activeMenuContainer isMenuBar]) - var newMenuOrigin = CGPointMake(CGRectGetMinX(activeItemRect), CGRectGetMaxY(activeItemRect)); - else - var newMenuOrigin = CGPointMake(CGRectGetMaxX(activeItemRect), CGRectGetMinY(activeItemRect)); - - newMenuOrigin = [activeMenuContainer convertBaseToGlobal:newMenuOrigin]; - - [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:newMenuOrigin]; - [self moveDown:[activeItem submenu]]; - } + { if([[activeItem submenu] numberOfItems]) + { + var activeItemIndex = [menu indexOfItem:activeItem], + activeMenuContainer = menu._menuWindow; + activeItemRect = [activeMenuContainer rectForItemAtIndex:activeItemIndex]; + + if ([activeMenuContainer isMenuBar]) + var newMenuOrigin = CGPointMake(CGRectGetMinX(activeItemRect), CGRectGetMaxY(activeItemRect)); + else + var newMenuOrigin = CGPointMake(CGRectGetMaxX(activeItemRect), CGRectGetMinY(activeItemRect)); + + newMenuOrigin = [activeMenuContainer convertBaseToGlobal:newMenuOrigin]; + + [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:newMenuOrigin]; + [self moveDown:[activeItem submenu]]; + } } else if([self trackingMenu] == [CPApp mainMenu]) - { - [self showMenu:nil fromMenu:menu atPoint:CGPointMakeZero()]; - [self moveDown:[CPApp mainMenu]]; + { + [self showMenu:nil fromMenu:menu atPoint:CGPointMakeZero()]; + [self moveDown:[CPApp mainMenu]]; - var activeItem = [[CPApp mainMenu] highlightedItem], - menuLocation = CGPointMake([[activeItem _menuItemView] frameOrigin].x , [[activeItem _menuItemView] frameSize].height); - - [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:menuLocation]; - } + var activeItem = [[CPApp mainMenu] highlightedItem], + menuLocation = CGPointMake([[activeItem _menuItemView] frameOrigin].x , [[activeItem _menuItemView] frameSize].height); + + [self showMenu:[activeItem submenu] fromMenu:[activeItem menu] atPoint:menuLocation]; + } } - (void)moveDown:(CPMenu)menu -{ - var index = menu._highlightedIndex + 1; - - [menu _highlightItemAtIndex:(index==[menu numberOfItems]?0:index)]; - - var item = [menu highlightedItem]; - if([item isSeparatorItem] || [item isHidden] || ![item isEnabled]) - [self moveDown:menu]; +{ + var index = menu._highlightedIndex + 1; + if(index < [menu numberOfItems]) + { + [menu _highlightItemAtIndex:index]; + var item = [menu highlightedItem]; + if([item isSeparatorItem] || [item isHidden] || ![item isEnabled]) + [self moveDown:menu]; + } } - (void)moveUp:(CPMenu)menu { - var index = menu._highlightedIndex - 1; - [menu _highlightItemAtIndex:(index<0?[menu numberOfItems]-1:index)]; - - var item = [menu highlightedItem]; - if([item isSeparatorItem] || [item isHidden] || ![item isEnabled]) - [self moveUp:menu]; + var index = menu._highlightedIndex - 1; + if(index < 0) + return; + + [menu _highlightItemAtIndex:index]; + var item = [menu highlightedItem]; + if([item isSeparatorItem] || [item isHidden] || ![item isEnabled]) + [self moveUp:menu]; } - (void)insertNewline:(CPMenu)menu { - if([[menu highlightedItem] hasSubmenu]) - [self moveRight:menu]; - else - { - [menu cancelTracking] - [menu performActionForItemAtIndex:[menu indexOfItem:[menu highlightedItem]]]; - } + if([[menu highlightedItem] hasSubmenu]) + [self moveRight:menu]; + else + [menu cancelTracking] }