Index: Source/NSMenu.m =================================================================== --- Source/NSMenu.m (revision 31909) +++ Source/NSMenu.m (working copy) @@ -647,6 +647,8 @@ _menu.needsSizing = YES; // According to the spec, menus do autoenable by default. _menu.autoenable = YES; + //By default we display transient menus from left to right. + _submenusToLeft = NO; /* Please note that we own all this menu network of objects. So, @@ -1045,7 +1047,27 @@ - (NSPoint) locationForSubmenu: (NSMenu*)aSubmenu { - return [_view locationForSubmenu: aSubmenu]; + NSPoint location; + + location = [_view locationForSubmenu: aSubmenu]; + /* If there isn't enough space at right, we display the submenus from + right to left. */ + if (_submenusToLeft || [_superMenu _displayToLeft]) + { + NSRect submenuFrame = [[aSubmenu window] frame]; + NSRect frame = [_aWindow frame]; + + location.x = location.x - + submenuFrame.size.width - + frame.size.width; + + if (!_submenusToLeft) + { + _submenusToLeft = YES; + } + } + + return location; } - (NSMenu *) supermenu @@ -1875,27 +1897,58 @@ } else { - NSRect frame = [_aWindow frame]; + NSRect frame = [_aWindow frame]; + NSRect screen = [[NSScreen mainScreen] visibleFrame]; NSInterfaceStyle style; location = [_aWindow mouseLocationOutsideOfEventStream]; location = [_aWindow convertBaseToScreen: location]; - location.y -= frame.size.height; + if (location.x > screen.size.width/2) + { + _submenusToLeft = YES; + } + /* When using the standard NextStep/OpenStep interface style, the center of the menu's title view is placed below the mouse cursor. However, in Macintosh and Windows95 styles, menus have no visible title. To prevent the user from accidentally selecting the first - item, the top left edge is placed below the mouse cursor for them. */ + item, the top left edge is placed below the mouse cursor for them. + If this is not possible (in any interface style), because the mouse + cursor is near of bottom, one of the bottom corners of the menu + is placed below the mouse cursor. */ style = NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", nil); if (style != NSWindows95InterfaceStyle && style != NSMacintoshInterfaceStyle) { - location.x -= frame.size.width/2; - if (location.x < 0) - location.x = 0; - location.y += 10; + if (location.y > frame.size.height) + { + location.y -= frame.size.height; + location.x -= frame.size.width/2; + if (location.x < 0) + location.x = 0; + location.y += 10; + } + else + { + if (frame.size.width > (screen.size.width - location.x)) + { + location.x -= frame.size.width; + } + } } + else + { + if (location.y > frame.size.height) + { + location.y -= frame.size.height; + } + + if (frame.size.width > (screen.size.width - location.x)) + { + location.x -= frame.size.width; + } + } } [_bWindow setFrameOrigin: location]; @@ -2160,6 +2213,11 @@ } } +- (BOOL)_displayToLeft +{ + return _submenusToLeft; +} + - (BOOL)_ownedByPopUp { return _popUpButtonCell != nil; Index: Source/NSMenuView.m =================================================================== --- Source/NSMenuView.m (revision 31909) +++ Source/NSMenuView.m (working copy) @@ -1658,7 +1658,7 @@ in a window*/ if (NSInterfaceStyleForKey(@"NSMenuInterfaceStyle", self) == NSWindows95InterfaceStyle && - anAttachedMenu != nil) + ![[self menu] isTransient]) { if ([self hitTest: location] == nil) { Index: Headers/AppKit/NSMenu.h =================================================================== --- Headers/AppKit/NSMenu.h (revision 31909) +++ Headers/AppKit/NSMenu.h (working copy) @@ -357,6 +357,7 @@ NSMenu *_oldAttachedMenu; int _oldHiglightedIndex; NSString *_name; + BOOL _submenusToLeft; } /** Returns the memory allocation zone used to create instances of this class. @@ -750,6 +751,9 @@ */ - (NSWindow*) window; +/* Direction to display submenus */ +- (BOOL) _displayToLeft; + /* Popup behaviour */ - (BOOL) _ownedByPopUp; - (NSPopUpButtonCell *)_owningPopUp;