Thomas Tempelmann
Thomas Tempelmann

Reputation: 12125

Ensuring windows are on-screen on OS X Cocoa

Imagine I save my window's position in my preferences file. Now, the user moves the window to a second monitor, then quits my app. Then he disconnects the second monitor and launches my app again. Now my app wants to restore the window's saved location. But if it blindly restores the old window coordinates, the window will be off-screen.

I used to use ConstrainWindowToScreen for my Carbon app, but now that I'm porting it to Cocoa, I can not find an equivalent for this.

The docs suggest that, somehow, Cocoa would automatically prevent this from happening. While that might be the case when the monitors change while the window is open, in my case where I've stored the window location myself and restore them when I re-open the window at launch, this isn't going to work. I need to invoke Cocoa's magic functionality on demand, but how?

(Note: I am aware that I could iterate over all available screens, but that's quite a pain to write myself if I want to get this foolproof. Still, if you can present a complete C or ObjC function that solve it this way, that'd be appreciated, too.)

Upvotes: 2

Views: 683

Answers (2)

Ken Thomases
Ken Thomases

Reputation: 90701

I agree with Darren's suggestion to use the built-in mechanism for restoring window positions. Really, it's as easy as setting a window's frame autosave name in IB (or with -setFrameAutosaveName:).

That said, if a window has a title bar, then all of the methods which order it onto the screen (e.g. -orderFront: or -makeKeyAndOrderFront:) will automatically reposition it to make sure at least the title bar and a significant chunk of the window is on the screen. It's honestly difficult to get a titled window to be theoretically visible but actually off-screen.

Upvotes: 1

Darren
Darren

Reputation: 25619

See the "Managing Window Frames in User Defaults" section in the NSWindow Class Reference. Those methods ensure that a window will be placed entirely on screen.

If you want to save and restore the window location yourself (as a string), use -stringWithSavedFrame and -setFrameFromString:.

Use -saveFrameUsingName: and -setFrameUsingName to have NSWindow save and restore its frame in the user defaults, given a window name.

Upvotes: 1

Related Questions