How to change the NSScreen a NSWindow appears on - cocoa

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.

Related

Why is the NSStatusItem displaying multiple times?

A NSStatusItem has a NSMenu attached, and one of the buttons of the NSMenu opens a NSWindow. Whenever one of these buttons is clicked, the window opens as expected and works properly, but another display of the NSStatusItem is opened.
The NSStatusItem is a clock, so I can see that it is updating correctly. However, the cloned NSStatusItem doesn't have its own menu. If I push the button that makes the window more times, more cloned versions of the NSStatusItem pop up.
Everything works fine except for this.
That's not a whole lot of information to go off of, but there's nothing else I can think of that could potentially help you. I would be happy to provide more information or try something.
EDIT: Every time the button is clicked, awakeFromNib is somehow called, which is why another half-working NSStatusItem happens.
EDIT: Temporary workaround is to put the awakeFromNib method in a dispatch_once.
EDIT: Added method that is triggered when button is clicked, as suggested by #zpasternack
- (IBAction)preferences:(id)sender {
self.windowController = [[NSWindowController alloc] initWithWindowNibName:#"PreferencesWindow"];
[[self windowController] showWindow:self];
}
Is the NSStatusItem contained in the PreferencesWindow nib? That might explain it, since you're loading the nib each time the button is clicked.
Also, is there a reason you need to recreate that window each time the button is clicked? Maybe you could only do it the first time?
- (IBAction)preferences:(id)sender {
if( self.windowController == nil ) {
self.windowController = [[NSWindowController alloc] initWithWindowNibName:#"PreferencesWindow"];
}
[[self windowController] showWindow:self];
}

Is it possible to force control to an NSWindowController Subclass?

I am creating a cocoa application and I am loading a preference window with a NSWindowController.
When the user selected the prefs button and the preference window opens
I want the application to force the user to finish what they are doing with the newly opened window controller before going back to the application in the background.
Is there anyway to block out whats happening in the background and force the user to complete there interactions with the foreground?
Thakns
Perhaps this works? Create a subclass of the HUD window and implement
- (BOOL)resignFirstResponder {
if (userMayLeave) return YES;
return NO;
}
You can use the following method to achieve this and display your window as a modal:
[[NSApplication sharedApplication] runModalForWindow:aWindow];
Then you need to use one of the following methods in your modal window in order to dismiss it:
[[NSApplication sharedApplication] stopModal];
[[NSApplication sharedApplication] abortModal];
[[NSApplication sharedApplication] stopModalWithCode:anInteger];

beginSheet method not working for me

I have saveWindowController (NSWindowController subclass object). I use initWithWindowNibName: method to init the controller.
I set File's owner in xib to SaveWindowController. I connect delegate (from window) to File's owner and window (from controller) to NSWindow in xib file.
[NSApp beginSheet:[self.saveWindowController window]
modalForWindow:[self window]
modalDelegate:nil didEndSelector:nil contextInfo:nil];
After executing this method I see modal window without titlebar and it appears not like normal sheet. It just appears in left bottom corner of first window.
Could you help me, what I'm doing wrong?
Do you have your SaveWindowController's window set to "Visible at Launch" in the XIB? You must uncheck that option, or your window will try to display as soon as the XIB is loaded, and will not be positioned correctly.
I had a lot of trouble before realizing I declared my sheet window in IB without title bar. Does yours has one? If not, check the "title bar" option.
B.

How to give focus to NSWindow loaded from NIB?

I'm using NSWindowController to load a window from a NIB. However, when I call showWindow:, the window is visually topmost, but the focus remains where it was (instead of moving it to the new window).
It's easy to see this happening when the first window (with keyboard focus) is moved slightly, before creating the new window (via cmd+n). This is the result:
The bottom, focused window is the original window. The unfocused window on top is the newly created window.
This is the relevant code:
AppDelegate.h:
- (IBAction)newDocument:(id) sender;
AppDelegate.m:
- (IBAction)newDocument:(id) sender {
[[[FooController alloc] init] showWindow:self];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[self newDocument:self];
}
FooController.h:
#interface FooController : NSWindowController { }
#end
FooController.m:
- (id)init {
self = [super initWithWindowNibName:#"FooWindow"];
return self;
}
FooWindow.xib:
A freshly created Window xib, without modifications.
MainMenu.xib:
The default MainMenu.xib, with its window deleted.
Calling makeKeyAndOrderFront: on the window in the controller's windowDidLoad method does not appear to focus the new window. Setting the File's owner of FooWindow.xib to FooController also did not appear to help.
What is the correct way to load and show a window from a NIB so that it does receive keyboard focus?
Edit: It looks like NSWindowController's window method returns nil, which explains why calling methods on window doesn't do anything. But why is it nil?
Okay, I found the cause of this problem.
The xib's File's owner must be set to the controller, and (this is the part I didn't know about) you have to connect the controller's window outlet to the window itself.
Having done that, it just works. No makeKeyWindow, makeMainWindow or makeKeyAndOrderFront: needed.
Perhaps makeMainWindow: or makeKeyWindow: helps

Hide a window in cocoa from awakeFromNib

I have a NIB with two NSWindow objects. The controller class has two IBOutlets, one for each NSWindow (windowLogin and windowMain).
I only want one of the windows visible on launch. Insdide awakeFromNib I am using:
[windowMain orderOut:self];
which is having no effect. However, if I try:
[windowMain setTitle:#"Renamed Title"];
It works as expected.
Thoughts?
Look for the "Visible At Launch" property in the attributes inspector for the window in Interface Builder.
Alternatively, in ApplicationDidFinishLoading, you can call [window setIsVisible:NO]

Resources