Objective-C NSWindow remove window from key - objective-c

Hi need a little help, i have a window which is set to always show in the top right corner but it is not set to always key. The window has a few buttons on it and when a button is clicked the window becomes key, but what i want it to do is when a button is clicked i want the window to remove itself from being key.
So ideally the window becomes key when a button is clicked and in the method which the button calls i want to write a statement which will then perform the action of the button and remove the window from key.
However the window is declared under the app delegate and the method linked to the button is declared in a separate header file.
Anyone have any ideas how i can do this, any help would be much appreciated.
Thanks in advance, Sami.

There are a few solutions depending on the architecture of your application.
Send [[NSApp mainWindow] makeKeyWindow], which will make the main window become key.
Your application delegate could have a reference to the main window. In the action method that handles the button click, you could ask the application delegate to make the main window become key. The application delegate would send [mainWindow makeKeyWindow].
Your application delegate could have a reference to the window controller that manages the main window. In the action method that handles the button click, you could ask the application delegate to make the main window become key. The application delegate would ask the main window controller to do that, and the main window controller would send [[self window] makeKeyWindow].
Your application delegate could listen to the NSWindowDidResignKeyNotification notification and keep a reference to the last window that resigned being key. In the action method that handles the button click, you could ask the application delegate to return key status to that previous window. The application delegate would need to ignore NSWindowDidResignKeyNotification notifications when the window is your auxiliary window. This solution is better when there’s no single main window.
If the first solution is not applicable, a) your application delegate could conform to a protocol that declares a method responsible for restoring key status to the proper window, or b) your action method could post a notification informing the application that your action method has completed, and have the application delegate listen to that notification and restore key status to the proper window.
Note that even though I’ve suggested that the application delegate would implement the behaviour of restoring key status, other objects could be responsible for that. This is particularly easier when notifications are used since there’s no need to grab a reference to the object that will restore key status due to the inherent loose coupling provided by notifications.

Related

Is there a way to disable sounds (such as "beeps") in my mac app?

I know I need to dig the reason why my app is beeping in the code, etc.
But I was wondering, is there a global setting to disable sounds all over my app screens?
this is very little information to go on, but usually your application is beeping when the responder chain comes up with no object that can respond to an event on the screen or keyboard.
For instance, if you type text in an active view and the view doesn't allow for text editing, the view sends the key down event to its super view. For a view this can end by the NSPanel or NSWindow or BSWindow controller. The last responder in the chain invokes the noResponderFor: method, which, when not implemented, will give a beep. If you don't want it to beep, override this method to do something else.
Based on your information I can't give you any other information.

What is the event in cocoa for NSWindow that tells that NSWindow is now displayed after first run?

I need to show a sheet dialog soon after the main window has been shown after first run. If I do it in the init or awake from nib , it does not seem to work right (sheet show as window detached from main window if I do it in the init method). I guess I have to show sheet once the parent window has shown. I have an appcontroller class which has a window pointer. So I guess I need to register as a delegate or something with window ? and implement some method to receive that call ?
Thanks,
There is no reliable event, notification, or delegate method call. It is expected that your code is responsible for showing the window, so it should already know when the window is shown.
Are you relying on the Visible at Launch property set in Interface Builder? If so, what you using to load the NIB? Hopefully, a window controller. In that case, you should be calling the -window method to load the NIB and obtain the window. The resulting window reference is what you would pass to the method that begins the sheet.
If not relying on Visible at Launch, what code are you using to show the window? For example, invoking -showWindow: on the window controller? So, put the code to show the sheet right after that.
applicationDidFinishLaunching: is your entry point. It is sent to your app delegate after the app is all set up, but before the user has had a chance to interact with it.

Growl notification like nswindow level

I am writing a notification system just like growl. The notification is a window and it's level is set to NSModalPanelWindowLevel. The only problem is, I have a button in that window and when the user wants to click that button, he/she has to click it twice. But, for example, in growl, no matter what window you have opened, you just simply click the notification and it registers a click.
So is it a level problem? If so, what should I set it to? Thanks
In your custom controls that make up the view content of the window, you will likely want to override NSView's -acceptsFirstMouse: method to return YES:
Discussion
The receiver can either
return a value unconditionally or use
the location of theEvent to determine
whether or not it wants the event. The
default implementation ignores
theEvent and returns NO.
Override this method in a subclass to
allow instances to respond to
click-through. This allows the user to
click on a view in an inactive window,
activating the view with one click,
instead of clicking first to make the
window active and then clicking the
view. Most view objects refuse a
click-through attempt, so the event
simply activates the window. Many
control objects, however, such as
instances of NSButton and NSSlider, do
accept them, so the user can
immediately manipulate the control
without having to release the mouse
button.
Not sure if this is what Growl does, but you might be able to listen for mouse over events in the window and use them to activate/deactivate the window prior to the click. I suspect your issue is that the first click is being eaten by the activation of the window.
Just a guess on that though.
To learn how to handle mouse over events, check out this documentation:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/TrackingAreaObjects/TrackingAreaObjects.html

How to connect a button to a method on Mac OS X

I am used to programming for the iPhone. There, I would connect a button to an action, and then a method by creating the method like so: -(IBAction) DoStuff{…}. Then I would make an outlet for the button, and then the actual button in Interface Builder. I would then connect the button to the outlet, and then connect the button to the action by clicking on the circle next to Touch Up Inside and drag it over to File's Owner and select my action.
I am new to programming for the Mac, so I tried to drag from performClick to the file I wanted, but it wouldn't let me make the connection. Do I have to do this programmatically or what? How do I get this button to trigger an action in my code?
The fundamental difference is that iOS controls can have multiple actions for different events, but Mac OS X controls only have one primary action (in some cases, there are others that can be set up programatically).
When you right-click on a button in a Mac nib, performClick: is under Received Actions; it’s not an event. The only entry under Sent Actions is “selector”, which is the only thing you can connect to an action on another object.
Because there is only one “sent event”, you’ll normally just control-drag/right-drag from the control to the target and select the action rather than control-clicking, selecting the event and dragging from that.
It works much the same, but unlike UIKit there is only one signature for actions:
- (IBAction)actionName:(id)sender;
See Communicating with Objects and Target/Action in Interface Builder for more.
I like to Control-Click on the button and then drag to the object that I want to recieve the action. I then select the method of possible choices from the popup menu.

Enabling open file menu item in a non-document-based application

I would like to enable the grayed out open file menu item within a non-document-based application. Document-based applications automatically give you a nice open file dialog with file extension filters based on plist entries etc... Surely, a simple elegant method exist to re-enable this functionality.
I have...
Added document types to the project properties window
Assigned my controller class as the application delegate
Added the delegate application:openFile: to my controller class
First, make sure your File->Open menu item's selector is connected to the openDocument: action of the First Responder.
Second, make sure you are responding to the action. Take a look at the Responder chain of a non-document application with an NSWindowController object. Any object within your responder chain can respond to the message, but it is best to pick the object which is the most capable and appropriate. Once you have decided which class in your responder chain is the most appropriate to handle the message, add the openDocument: action to it's implementation and write your code to respond to it accordingly.
The key is that something along the menu item's responder chain has to respond to the -openDocument: action. Normally it's the NSDocumentController. I'd take a look at how an empty document-based application sets up that menu item.