Setting initial position of NSWindow only works the first time - macos

I'm trying to set my NSWindow to be in the center of the screen, but I'm noticing that when I quit and reopen the app, it takes the position that the window was in when the app closed. Is this expected behavior?

If you selected "Restorable" window behaviour then it's the correct behaviour.
You can disable this by behaviour by unchecking restorable and also leave your autosave name empty.
Your application saves the state into "~/Library/Saved Application State/com.identifier.appName.savedState" folder and loads on launch
Also one hidden hack to help:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[[NSUserDefaults standardUserDefaults] setObject:#NO forKey:#"NSQuitAlwaysKeepsWindows"];
}

Related

NSWindowController displays nib before windowDidLoad finishes

When I try launching my app through Spotlight without building it through XCode, the NSWindowController displays the unmodified nib (with the standard gray background color, etc) for a split second before windowDidLoad finishes. This looks awful, since views are in the wrong places and aren't colored correctly.
I tried removing everything from windowDidLoad to see if something in there was slowing it down, but that didn't improve things. I also tried moving the setting of the background color to initWithWindowNibName, but that didn't help either.
Is there a way to delay showing the window while it finishes loading?
Here's the code I'm using to initialize the NSWindowController:
self.windowController = [[WindowController alloc] initWithWindowNibName:#"WindowController"];
[self.windowController showWindow:self];
[[self.windowController window] makeKeyAndOrderFront:nil];
Disable NSWindowController's "visible at launch" property in Interface Builder.
(Of course, I post the question then immediately figure out the answer.)

Mac App Store Dialogs vs Full Screen Window

My app got rejected because the dialogs to handle in-app purchases are behind my transparent full screen window. You can still click them, but it's not user-friendly.
How would I handle this? Is there a way to alter the way these dialogs are presented, or should I change the properties of my own window?
I'm talking about these dialogs (the grid is what's drawn on my main window) :
You can set the window level to a lower value so the dialogs appear on top when starting the store request and reset it to it's previous value after the request completes. Or you could exit full screen mode to make the store request. They may be more annoyed by the transparent window which can be confusing more than the window order.
This works for me
#interface FullscreenWindow : NSWindow
#end
#implementation FullscreenWindow
-(id) init
{
// some init code here...
[self setLevel:NSMainMenuWindowLevel+1];
return self;
}
#end

How to change the NSScreen a NSWindow appears on

I have an application that will load a couple of windows depending on which button is pressed. All except one of these open on the mainScreen (the screen in which the main window is open in). One of them (the preference window) opens on the first screen (the screen with the menu bar). I cannot understand way it is doing this, is there a way to change the screen that a NSWindow opens on?
I could not get toohtik's answer to work. What I ended up doing was subclassing NSWindow and then overriding constrainFrameRect: toScreen:. This will automatically open the new window on the "main screen" of the application.
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
{
AppDelegate *delegate = [[NSApplication sharedApplication] delegate];
return [super constrainFrameRect:frameRect toScreen:delegate.window.screen];
}
I dont't know why you have that behaviour but you can change it through initWithFrame method that takes NSScreen argument.

Cocoa screen saver config panel floating freely

I'm writing a screen saver using Cocoa's ScreenSaver API. It's compiled for 64-bit arch and I'm running it on Lion.
In order to enable configuration, I have added the following to the main view:
- (BOOL)hasConfigureSheet
{
return YES;
}
- (NSWindow*)configureSheet
{
if (configureSheet == nil) {
if (![NSBundle loadNibNamed: #"WTConfigureSheet" owner: self]) {
NSLog(#"Failed to load config sheet");
return nil;
}
}
ScreenSaverDefaults *defaults =
[ScreenSaverDefaults defaultsForModuleWithName: WTModuleName];
backgroundColorWell.color = [defaults objectForKey: #"BackgroundColor"];
lightLetterColorWell.color = [defaults objectForKey: #"LightLetterColor"];
darkLetterColorWell.color = [defaults objectForKey: #"DarkLetterColor"];
return configureSheet;
}
After installing the saver freshly, clicking "Options" makes the config sheet appear not as a sheet, but floating freely on the screen, without a border. Otherwise, it works correctly and disappears after being dismissed.
When I click "Options" a second time, the config sheet appears again, this time correctly as a sheet of the preferences window. It then immediately freezes, so that I can't click any of its controls.
Does anyone have an idea what causes this behavior?
I had the same problem as you today and it took me quite some time to figure this one out, so here's my solution:
I discovered that the NSWindow appears as soon as you call loadNibNamed:owner:. So there had to be some sort of mechanism to automatically open windows from nibs.
So I re-checked the nib and saw that there is an option called "Visible At Launch" on the attribute inspector pane which is checked by default.
The solution is very simple: just uncheck that checkbox and it works as expected.
I find it easy to overlook since you expect the window to open, but it actually opens twice (once automatically and a second time because System Preferences.app shows it as a sheet) which leads to the glitches.
Another problem that could happen, depending on how you defined the ivar / property on your class is that after the first close and re-open of the window it just freezes.
This is because per default the window releases itself when closed.
So be sure to also uncheck "Release When Closed" in interface builder.
For this code to work as written, you need to create an IBOutlet of type NSWindow* named configureSheet in your main view's header file, save that file so Interface Builder can see the change, then load WTConfigureSheet.xib in Interface Builder and connect up the toplevel window component to Files Owner -> configureSheet.

I've built my app for OSX Lion but when i run it is always on bottom of the screen

I've built my app for OSX Lion but when i run it is always on bottom of the screen.
What could be the reason ??
thanks!
ps. The current position of the window is restored.. so the window position is restored but the window is always on the back, the assigned layer is wrong, it wasn't on the bottom when it was close.
ps2. Is maybe because the main file of my app is the mainMenu.xib and not document.xib ? I can't change that.
Assuming you're talking about your application window, its position is taken either from your XIB/NIB file (if that's what you use) or you specify it in the code as the frame for the window. In a XIB/NIB you can specify a name in the "Autosave" field (under Window attributes) which will cause your app to remember the last window size and position across launches so it doesn't always start at the place you defined in the XIB/NIB.
EDIT: since you mean bottom layer, try calling [window makeKeyAndOrderFront:self], e.g. in applicationDidFinishLaunching:.
Solved with
//disable Lion resume
if([[NSUserDefaults standardUserDefaults] objectForKey: #"ApplePersistenceIgnoreState"] == nil)
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"ApplePersistenceIgnoreState"];

Resources