Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove GSFakeNSMenuItem class #7

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 18 additions & 94 deletions WinNSMenu.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,86 +38,6 @@
static NSLock *menuLock = nil;


@interface GSFakeNSMenuItem : NSObject
{
id _originalItem;
}

- (id) initWithItem: (id)item;
- (id) originalItem;
- (id) target;
- (SEL)action;
- (void) action: (id)sender;
@end

@implementation GSFakeNSMenuItem
- (id) initWithItem: (id)item
{
self = [super init];
if (self)
{
_originalItem = item;
}
return self;
}

- (id) originalItem
{
return _originalItem;
}

- (id)target
{
return self;
}

- (SEL)action
{
return @selector(action:);
}

- (void) action: (id)sender
{
NSMenu *theMenu = [_originalItem menu];
[theMenu performActionForItemAtIndex:[theMenu indexOfItem:_originalItem]];
}

#ifndef GNUSTEP
#pragma mark -
#pragma mark Act as proxy for actual NSMenuItem methods...
#endif
- (id)forwardingTargetForSelector:(SEL)selector
{
if ([_originalItem respondsToSelector:selector])
return _originalItem;
return nil;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL selector = [invocation selector];

// Forward any invocation to the original item if it supports it...
if ([_originalItem respondsToSelector:selector])
[invocation invokeWithTarget:_originalItem];
}

-(NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *signature = [[_originalItem class] instanceMethodSignatureForSelector:selector];
if(signature == nil)
{
signature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return(signature);
}

- (void)doesNotRecognizeSelector:(SEL)selector
{
NSLog(@"%s:selector not recognized: %@", __PRETTY_FUNCTION__, NSStringFromSelector(selector));
}
@end

@interface NSWindow (WinMenuPrivate)
- (GSWindowDecorationView *) windowView;
- (void) _setMenu: (NSMenu *) menu;
Expand Down Expand Up @@ -151,7 +71,7 @@ void initialize_lock()
}

// find all subitems for the given items...
HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL fakeItem, NSMapTable *itemMap)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a great idea to rename the variable fakeItem to notPullDown (or something similar) as this value is initially set to ![cell pullsDown]in displayPopUpMenu (line 554). But I'd suggest we update the name throughout, i.e. rename the fake variable in displayPopUpMenu and any other method that may use that name?

HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL notPullDown, NSMapTable *itemMap)
{
NSArray *array = [menu itemArray];
NSEnumerator *en = [array objectEnumerator];
Expand Down Expand Up @@ -261,7 +181,7 @@ HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL fakeItem, NSMapT
{
NSMenu *smenu = [item submenu];
flags = MF_STRING | MF_POPUP;
s = (UINT)r_build_menu_for_itemmap(smenu, asPopUp, fakeItem, itemMap);
s = (UINT)r_build_menu_for_itemmap(smenu, asPopUp, notPullDown, itemMap);
}
else if([item isSeparatorItem])
{
Expand All @@ -271,11 +191,15 @@ HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL fakeItem, NSMapT
{
flags = MF_STRING;
s = menu_tag++;
if(fakeItem)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gcasa @fredkiefer These lines were actually causing GSFakeMenuItems to replace NSMenuItems in memory leading to crashes when you clicked on a pop up.

{
item = [[GSFakeNSMenuItem alloc] initWithItem: item];
AUTORELEASE(item);
}
if (([item action] == NULL || [item target] == nil) && notPullDown && asPopUp)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gcasa @fredkiefer Once the GSFakeMenuItems were removed we were able to click on pop ups but they were inoperable because there was no action set on them. This change here populates the action.

{
NSPopUpButtonCell *popup = [menu _owningPopUp];
if (popup != nil)
{
[item setAction: @selector(_popUpItemAction:)];
[item setTarget: popup];
}
}
NSMapInsert(itemMap, (const void *)s, item);
}

Expand Down Expand Up @@ -346,9 +270,9 @@ HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL fakeItem, NSMapT
{
flags |= MF_ENABLED; // ([item isEnabled]?MF_ENABLED:MF_GRAYED); // shouldn't this be :MF_GRAYED|MF_DISABLED ?
// For PopUpButtons we don't set the flag on the state but on selection
if (fakeItem && asPopUp)
if (notPullDown && asPopUp)
{
if ([(GSFakeNSMenuItem *)item originalItem] == [[menu _owningPopUp] selectedItem])
if (item == [[menu _owningPopUp] selectedItem])
{
flags |= MF_CHECKED;
}
Expand All @@ -364,9 +288,9 @@ HMENU r_build_menu_for_itemmap(NSMenu *menu, BOOL asPopUp, BOOL fakeItem, NSMapT
return result;
}

HMENU r_build_menu(NSMenu *menu, BOOL asPopup, BOOL fakeItem)
HMENU r_build_menu(NSMenu *menu, BOOL asPopup, BOOL notPullDown)
{
return r_build_menu_for_itemmap(menu, asPopup, fakeItem, itemMap);
return r_build_menu_for_itemmap(menu, asPopup, notPullDown, itemMap);
}

void build_menu(HWND win)
Expand Down Expand Up @@ -542,7 +466,7 @@ - (void) displayPopUpMenu: (NSMenuView *)mr
preferredEdge: (NSRectEdge)edge
selectedItem: (int)selectedItem
{
BOOL fake = NO;
BOOL notPullDown = NO;
NSMenu *menu = [mr menu];

// Need menu for display...
Expand All @@ -551,15 +475,15 @@ - (void) displayPopUpMenu: (NSMenuView *)mr

NSPopUpButtonCell *cell = [menu _owningPopUp];
if (cell)
fake = ![cell pullsDown];
notPullDown = ![cell pullsDown];

// Create a temporary item map for this popup sequence...
NSMapTable *itemMap = NSCreateMapTable(NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 50);

[menu update];

HMENU hmenu = r_build_menu_for_itemmap(menu, YES, fake, itemMap);
HMENU hmenu = r_build_menu_for_itemmap(menu, YES, notPullDown, itemMap);
NSWindow *theWin = ((cvWin == nil) ? [NSApp mainWindow] : cvWin);
HWND win = (HWND)[theWin windowNumber];
NSPoint point = cellFrame.origin;
Expand Down