Command-W closes whichever window is active

I have an app with 3 windows. I would like the user to be able to hit command-W in whatever window they have active and have only that window close.

I was wondering:

  1. Is this possible in Interface Builder? I can make a menu item named “Close WIndow” and control drag it to one of the windows to attach a closeWindow event to it, but is it possible to tie the event to the active window using Interface Builder only?

  2. What would the most efficient approach be to setting this up using scripting in XCode? I have some ideas but though I would get some input.

  3. Another option is that I already have a menu item for each window so that the user can show any of the three windows by hitting command-1 or command-2 or command-3. Can those events be turned into a toggle so command-1 would show the window and if you hit command-1 again it would close.

Thanks.

Model: iMacintel
AppleScript: xCode 3.0
Browser: Safari 525.20.1
Operating System: Mac OS X (10.5)

So, it looks pretty simple to make a menu item “Close” with a keyboard shortcut command-W, but now all I need is a way to get the name of the window that is in currently in front (or active) so I can say to make that window not visible anymore in the on choose menu item handler.

Anyone?

Got It!

I made a property called “nameOfActiveWindow” and attached a “became main” event to all of the windows. That way I can keep track of the current window with a variable.

on choose menu item theObject
	if name of theObject is "menu_CloseWindow" then
		set visible of window nameOfActiveWindow to false
	end if
end choose menu item

on became main theObject
	set nameOfActiveWindow to name of theObject
end became main

In your nib file in interface builder there’s something called a “first responder”. That represents the frontmost active object at any point in your program. You can make a lot of connections to it and you can even use it programmatically in your code. For example, control-drag from the close menu item to the first responder in your nib file. In the menu that pops up, choose “perform close:”. The perform close command will ask the “first responder” which window is active and then close it. You can see there’s many things hooked to first responder… most of them are text editing stuff like copy/paste because you would want those commands to work with whatever text field is currently active. First responder always knows what is active.

Here’s another first responder tip. Suppose when you opened a window in your project, you wanted a certain text field to be the active one when the window opened. The “initial first responder” is actually a property of a window, so if you control-drag from the window object in a nib file to a text field in that window… choose “initialFirstResponder” as the outlet and that object will be frontmost and ready to be typed in every time the window activates.

I hope that helps.

That’s exactly what I was looking for actually. Thanks. Looks like I came up with a more code-heavy way of doing it when it could be done in Interface Builder. THanks for the explanation as well.

I thought you might like that. Here’s one final tip. Do you know how to set the tab order of your objects in a window? That’s another first responder type task. Suppose you had a text view and 2 buttons (OK and Cancel) like in a home made dialog box. Suppose you wanted the text view to be the initial first responder, then when you hit tab the focus would go to the “OK” button, then another tab would go to the “Cancel” button, then the final tab would bring you back to the original text field. Then you have a nice loop you can tab through. It’s very easy to set up.

First control-drag from the window object to the text field and make it initial first responder. Then control-drag from the text field to the OK button and choose “nextKeyView”. Then control-drag from the OK button to the Cancel button again choosing “nextKeyView”, and finally control-drag from Cancel to the text field to complete the loop and choose “nextKeyView”.

As you can tell I like the things you can do with the first responder in interface builder. Having less code to maintain while gaining functionality is always better.

Nice. Thanks again. Yeah, I like doing as much as possible in IB as well.