Hooking Event at NSWindow - cocoa

I'm making popup tooltip in NSWindow, like following XCode tooltip
If user press a button, popup is shown. It is easy.
But after that, if user press any button in this window, popup should be hidden.
But if user press button, nswindow's mousedown: isn't be called. so nswindowcontroller can not receive that event.
How can nswindow can detect all event in window's region?

You can create a contextMenu for small window, that opens on your action.
*NOTE: in the image, that is a custom view, not a contextMenu.*
- (IBAction)button:(id)sender {
NSRect frame = [(NSButton *)sender frame];
NSPoint menuOrigin = [[(NSButton *)sender superview] convertPoint:NSMakePoint(frame.origin.x+80, frame.origin.y+frame.size.height-10)
toView:nil];
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDown
location:menuOrigin
modifierFlags:NSLeftMouseDownMask // 0x100
timestamp:0.0
windowNumber:[[(NSButton *)sender window] windowNumber]
context:[[(NSButton *)sender window] graphicsContext]
eventNumber:0
clickCount:1
pressure:1];
NSMenu *menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:NO];
[menu insertItemWithTitle:#"Add Favorite"
action:#selector(addFavorite:)
keyEquivalent:#""
atIndex:0];
[menu insertItem:[NSMenuItem separatorItem] atIndex:1];
[menu insertItemWithTitle:#"Manage Favorite"
action:#selector(manageFavorite:)
keyEquivalent:#""
atIndex:2];
[NSMenu popUpContextMenu:menu withEvent:event forView:(NSButton *)sender];
}
-(IBAction)addFavorite:(id)sender{
NSLog(#"add");
}
-(IBAction)manageFavorite:(id)sender{
NSLog(#"mangage");
}

Related

How to get the selected NSMenuItem from a submenu?

I have an API that allows users to create popup menus with sub menus, and I'm having problems detecting the selected item when the user clicks on an option that belongs to a sub menu.
So, the display and "construction" of the popup menu is correct and it works fine. Starting from a NSMenu I add a few NSMenuItems, then for some NSMenuItems I add a new NSMenu with a few NSMenuItems more.
The problem begins when I click on an item that belongs to a submenu, the selectedItem I get is always nil. It works fine for the main menu. Here's how I show the menu:
NSRect frame = NSMakeRect(mp.origin.x + 10, mp.origin.y + 10, 1, 1);
NSPopUpButtonCell *cell = [[NSPopUpButtonCell alloc] initTextCell: #"" pullsDown: NO];
[cell setAutoenablesItems: NO];
[cell setAltersStateOfSelectedItem: NO];
[cell setMenu: mainMenu];
[cell selectItem: Nil];
[cell performClickWithFrame: frame inView: [window initialFirstResponder]];
NSMenuItem *xpto = [cell selectedItem];

Is there any way to open App when user click any button on Status bar Icon In Mac Desktop App

Is there any way to open my App when user click Open App button on Status bar Icon In Mac Desktop App?
NSStatusBar *systemStatusBar = [NSStatusBar systemStatusBar];
_statusItem = [systemStatusBar statusItemWithLength:NSVariableStatusItemLength];
[_statusItem setHighlightMode:NO];
[_statusItem setMenu:self.statusMenu];
[_statusItem setTarget:self];
NSMenu *menu = [[NSMenu alloc] init];
[menu addItemWithTitle:#"Open App" action:#selector(OpenAPp:) keyEquivalent:#""];
[menu addItem:[NSMenuItem separatorItem]]; // A thin grey line
[menu addItemWithTitle:#"Quit" action:#selector(terminate:) keyEquivalent:#""];
_statusItem.menu = menu;
-(IBAction)OpenAPp:(id)sender
{
NSLog(#"here");
[NSApp activateIgnoringOtherApps:YES];
}
i want to lunch app when user click OpenApp button even if app is closed or even App is running in background thanks
[NSApp activateIgnoringOtherApps:YES];
With the Above line i only able to make Application Window Active
I am able to solve my problem by adding these line
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
[_window makeKeyAndOrderFront:self];

How can i pop up NSMenu at mouse cursor position?

I want to react on hot key press by displaying NSMenu at mouse cursor position.
My application is UIElement and doesn't have its own window.
I know there is method of NSMenu :
-(void)popUpContextMenu:(NSMenu *)menu
withEvent:(NSEvent *)event
forView:(NSView *)view;
But it seems it doesn't work when there is no view :(.
Should I create a fake transparent view at mouse cursor position, and then display there NSMenu, or there is better way?
May it can be implemented using Carbon?
Use this instead:
[theMenu popUpMenuPositioningItem:nil atLocation:[NSEvent mouseLocation] inView:nil];
Here is solution which uses transparent window:
+ (NSMenu *)defaultMenu {
NSMenu *theMenu = [[[NSMenu alloc] initWithTitle:#"Contextual Menu"] autorelease];
[theMenu insertItemWithTitle:#"Beep" action:#selector(beep:) keyEquivalent:#"" atIndex:0];
[theMenu insertItemWithTitle:#"Honk" action:#selector(honk:) keyEquivalent:#"" atIndex:1];
return theMenu;
}
- (void) hotkeyWithEvent:(NSEvent *)hkEvent
{
NSPoint mouseLocation = [NSEvent mouseLocation];
// 1. Create transparent window programmatically.
NSRect frame = NSMakeRect(mouseLocation.x, mouseLocation.y, 200, 200);
NSWindow* newWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
[newWindow setAlphaValue:0];
[newWindow makeKeyAndOrderFront:NSApp];
NSPoint locationInWindow = [newWindow convertScreenToBase: mouseLocation];
// 2. Construct fake event.
int eventType = NSLeftMouseDown;
NSEvent *fakeMouseEvent = [NSEvent mouseEventWithType:eventType
location:locationInWindow
modifierFlags:0
timestamp:0
windowNumber:[newWindow windowNumber]
context:nil
eventNumber:0
clickCount:0
pressure:0];
// 3. Pop up menu
[NSMenu popUpContextMenu:[[self class]defaultMenu] withEvent:fakeMouseEvent forView:[newWindow contentView]];
}
It works, but i'm still looking for more elegant solution.

NSTextField not active in NSPopOver

I have a menubar application, which open a popover. That popover contains NSTextField and few buttons. The problem is that the NSTextField is non-selectable, it's impossible to type anything in it. However, it's possible to click on it with mouse right button and paste something. Well, that's definitely odd behavior. Buttons works without any problems in that popover, btw.
Here's the code i use:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[NSApp activateIgnoringOtherApps:YES];
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setAction:#selector(showPopOver:)];
[statusItem setImage:[[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"icon" ofType:#"png"]]];
[statusItem setHighlightMode:YES];
}
and:
- (IBAction)showPopOver:(id)sender {
popover = [[NSPopover alloc] init];
[popover setContentViewController:popOverController];
popover.animates = YES;
popover.delegate = self;
[popover showRelativeToRect:[sender bounds]
ofView:sender
preferredEdge:NSMaxYEdge];
}
}
Any ideas what the problem exactly and how to fix it?
Seems is a bug.
http://openradar.appspot.com/9722231

Hide NSMenu programmatically from NSStatusItem

I have this application that shows an item in the system's status bar, and one of the items is a custom view with a NSTextField and a NSButton. When the user clicks on the status bar item, it shows the menu, the user inputs some text and presses the button. This triggers an action that displays a window.
The problem I'm having now is, when the button is pressed it does trigger the action, but the menu remains visible. I want to hide the menu, because the action has already been processed.
I've searched through the API, but couldn't find how to do it.
Any ideas?
This is how I'm creating the menu:
NSStatusBar *bar = [NSStatusBar systemStatusBar];
self.statusItem = [bar statusItemWithLength:NSVariableStatusItemLength];
[statusItem setImage:[NSImage imageNamed:#"icon_status_bar.png"]];
[statusItem setHighlightMode:YES];
NSMenuItem *textInputItem = [[NSMenuItem alloc] initWithTitle:#"" action:nil keyEquivalent:#""];
[textInputItem setView:myCustomView]; // created on the Nib file...
NSMenu *menu = [[NSMenu alloc] initWithTitle:NSLocalizedString(#"statusBarMenuTitle", #"")];
[menu addItem:textInputItem];
[statusItem setMenu:menu];
[textInputItem release];
[menu release];
It's not obvious in the docs, but [menu cancelTracking] is what you want.
cancelTracking
Dismisses the menu and ends all menu tracking.
- (void)cancelTracking

Resources