Non modal dialog has to appear as modal window - objective-c

I can show my custom NSWindowController as modal window by code:
TSAppDelegate* appDelegate = (TSAppDelegate*) [[NSApplication sharedApplication] delegate];
NSWindow* mainWindow = appDelegate.window;
[NSApp beginSheet: [self window]
modalForWindow: mainWindow
modalDelegate: NULL
didEndSelector: NULL
contextInfo: NULL];
int acceptedModal = (int)[NSApp runModalForWindow: [self window]];
[NSApp endSheet: [self window]];
[[self window] close];
It works. But I need non modal window. It has to appear as modal (see pic) and be NON MODAL.
I tried
TSAppDelegate* appDelegate = (TSAppDelegate*) [[NSApplication sharedApplication] delegate];
NSWindow* mainWindow = appDelegate.window;
[[self window] setParentWindow: mainWindow];
or
[mainWindow addChildWindow: [self window] ordered: NSWindowAbove];
It works as non modal but appears as normal popup window.
Is it possible?

It seems that you just want a window to come down over your view but not be modal.
Rather than use a sheet, you could just use a separate view that you animate into and out of position.
You'll have to do some work yourself: setting the correct position, animating the view, responding to events, etc.

Related

Open NSMenu from NSButton with storyboard

Without storyboard this code works perfectly. It opens NSMenu
-(IBAction)openExportCompletePaletteMenu:(id)sender {
NSPoint point = [self.window convertRectToScreen:((NSButton*)sender).frame].origin;
[self.menu popUpMenuPositioningItem:nil atLocation:point inView:nil];
}
With storyboard in a ViewController obviously I changed self.window whit:
[[NSApplication sharedApplication].windows objectAtIndex:0]
or
[[NSApplication sharedApplication] mainWindow]
but doesn't seem right choices. Is it possible that with storyboard this is no longer possible? This sounds bad.
You get the parent window of a view controller in a storyboard with
self.view.window;

Unable to focus on NSTextFields from Modal window

I currently have a window open which was opened via:
// FirstWindowController
[self showWindow:self];
[[self window] makeKeyAndOrderFront:self];
[NSApp runModalForWindow:[self window]];
And upon click of a button I'd like to hide FirstWindowController via:
// FirstWindowController
[self.window orderOut:self];
And then show my second window:
// SecondWindowController
[self showWindow:self];
[[self window] makeKeyAndOrderFront:self];
[NSApp runModalForWindow:[self window]];
The first window disappears correctly, and the second window appears. But I can't actually use the NSTextFields in the input. But I can click the cancel button to hide SecondWindowController and give focus back to FirstWindowController.
Why can't I click any of the NSTextField elements?
I had the same problem. It worked when the window had a title bar and otherwise not. It seems like that a window needs to have a title to become a keyWindow.
The workaround for this is to make a subclass of NSWindow and override -canBecomeKeyWindow:
(BOOL)canBecomeKeyWindow {
return YES;
}

How to change NSCarbonWindow visibility?

I'm using ::RunAppModalLoopForWindow(WindowPtr) to run a carbon window as modal. But at some point I need to show/hide all application's windows with:
NSArray* windowNumbers = [NSWindow windowNumbersWithOptions:0];
for (NSNumber* windowNumber in windowNumbers)
{
NSWindow* window = [[NSApplication sharedApplication] windowWithWindowNumber:[windowNumber integerValue]];
[window setAlphaValue:CGFloat(showFlag)];
}
But window is NSCarbonWindow* that does not respond to setAlphaValue, and thus, the window is not changing its visibility.
Also, I don't know where NSCarbonWindow is defined so I can cast from NSWindow to NSCarbonWindow.
How about:
if ([window respondsToSelector: #selector(setAlphaValue:)])
[window setAlphaValue:CGFloat(showFlag)];
else if (showFlag)
ShowWindow( [window windowRef] );
else
HideWindow( [window windowRef] );

Losing focus of NSView after setFrame of NSWindow

I am switching my NSWindow from normal mode to fullscreen, by setting its frame (I know there is a method for the view to go fullscreen, but it needs to be this way)
In my NSOpenGLView I am tracking the onMouseMove event...
After switching to fullscreen (or back), I have to click the view (inside window), to receive the mouseMove event. It looks like it is going out of focus, but I don't understand why (I am just using setFrame) and how to make it focused again, without the user needing to click the window.
Code in my NSOpenGLView (NSView):
if (!fullscreenOn) {
//!switch to fullscreen mode
NSRect mainDisplayRect = [[[self window] screen] frame];
[[self window] setStyleMask:NSBorderlessWindowMask];
[[self window] setFrame:[[self window] frameRectForContentRect:mainDisplayRect] display:YES animate:NO];
[[NSApplication sharedApplication] setPresentationOptions: NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock];
fullscreenOn = YES;
} else {
[[self window] setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask];
[[NSApplication sharedApplication] setPresentationOptions: NSApplicationPresentationDefault];
... some code for the right size ...
[[self window] setFrame:frame display: YES animate: YES];
fullscreenOn = NO;
}
the problem was with setting [[self window] setStyleMask:NSBorderlessWindowMask]; which cause this behaviour... making the window borderless by default fixed the problem

NSWindow windowDidResignKey not getting invoked after redisplaying window

I have a custom NSWindow subclass that the user can toggle the display of with the click of a button. I'd also like the window to disappear when the window resigns key status (e.g. by the user clicking outside the window).
I have a delegate that implements windowDidResignKey: but I find that this delegate method is only invoked the first time the window resigns key.
Here's how I toggle the display of the window (via user action or windowDidResignKey):
- (void) toggleWindowAtPoint:(NSPoint)point
{
// Attach/detach window.
if (!attachedWindow)
{
attachedWindow = [[CustomWindow alloc] attachedToPoint:point];
attachedWindow.delegate = self;
[attachedWindow setLevel:NSMainMenuWindowLevel+1]; // show window in front of all other apps on desktop
[attachedWindow makeKeyAndOrderFront:self];
}
else
{
attachedWindow.delegate = nil;
[attachedWindow orderOut:self];
[attachedWindow release];
attachedWindow = nil;
}
}
Here's my implementation of windowDidResignKey:
- (void) windowDidResignKey:(NSNotification *)note
{
[self toggleWindowAtPoint:NSMakePoint(0, 0)];
}
I'm finding that the first time the custom window is displayed, windowDidResignKey: gets called. Every time the custom window is re-displayed after that, windowDidResignKey: is not getting invoked.
The issue was that in some cases, the custom window was not actually becoming the key window after calling [attachedWindow makeKeyAndOrderFront:self].
I fixed this by adding the following line before re-creating the window:
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
In the context of the code snippet above:
- (void) toggleWindowAtPoint:(NSPoint)point
{
// Attach/detach window.
if (!attachedWindow)
{
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
attachedWindow = [[CustomWindow alloc] attachedToPoint:point];
....
Have you tried calling [attachedWindow makeFirstResponder:attachedWindow] in your toggle method?
If you want to activate a window without using activateIgnoringOtherApps: you should use a NSPanel with a NSNonactivatingPanelMask:
[[CustomPanel alloc]
initWithContentRect: NSZeroRect
styleMask: NSNonactivatingPanelMask
backing: NSBackingStoreBuffered
defer: NO];