My application has two windows(main and video) and both can enter the Full-Screen mode independently. And the main window has a button to toggle the video window's visibility. When the video window is visible, the button simply sends close message like this:
[theVideoWindow close];
It works perfectly when the video window is not in the Full-Screen mode.
But when the video window is running in the Full-Screen mode, the window looks like being ordered out (closed), but it is still alive (like an invisible window) and accepts mouse event. The user cannot interact with other applications because the invisible window eats up all the mouse events and cannot close it because the title bar and menu are gone.
Are there any best practices to close a Full-Screen mode window programmatically other than exiting from the Full-Screen mode first and then closing it in NSWindowDidExitFullScreenNotification notification handler?
Thanks in advance.
It seems to be my mistake. The other developer, explicitly send orderFront: in the NSWindowDidExitFullScreenNotification notification handler to make the window visible just after exiting from the Full-Screen mode and it made the window was still alive.
On my app, I check if window is on Fullscreen and then I use ToogleFullScreen method
- (BOOL)isFullScreen {
return ((self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask);
}
if([self isFullscreen]) {
[self.window toggleFullScreen:nil];
}
#Saul's solution in Swift 4:
func isFullScreen() -> Bool {
guard let window = view.window else { return false }
return window.styleMask.contains(.fullScreen)
}
if isFullscreen() {
view.window?.toggleFullScreen(nil)
}
Related
I want to create a borderless window floating above the main window. The main window should be the key window (I want it to handle the keyboard and mouse events). Also, the floating window should close as the user clicks outside of it. Basically, I'm creating a very custom context menu, just like NSMenu. It should behave likewise.
So I created my window this way:
NSWindow *menuWindow = [NSWindow windowWithContentViewController:menuViewController];
menuWindow.styleMask = NSBorderlessWindowMask;
menuWindow.level = NSFloatingWindowLevel;
[menuWindow makeKeyAndOrderFront:self];
That works perfectly, but how do I handle clicks outside to close it? The window doesn't invoke delegate's windowDidResignKey, because it's not a key window. If it does overload canBecomeKeyWindow (so that it returns YES), then the floating window grabs the user input, which is not what I want.
So, is there any way to automatically close a borderless window? Can NSPanel help? I tried using it, but with no success (the becomesKeyOnlyIfNeeded selector doesn't do what I need).
To detect clicks outside the window but within your app, you could install an event monitor using +[NSEvent addLocalMonitorForEventsMatchingMask:handler:]. If you also want to close the window when the user clicks in a different app, you could observe the NSApplicationDidResignActiveNotification notification.
NSWindow has a property hidesOnDeactivate that should do this for you.
From the Apple Docs:
The value of this property is true if the window is removed from the
screen when its application is deactivated; false if it remains
onscreen. The default value for NSWindow is false; the default value
for NSPanel is true.
I am trying to build an animation using spriteKit and that could be controlled via keyboard (arrow keys to speed up, slow down, rewind the animation).
Also I need this application to have a completely transparent background, this I managed using :
scene?.backgroundColor = NSColor.clearColor()
as well as :
self.window.opaque = false
Up until now everything is working fine and I am able to control my animation. But as soon as I try to remove the title bar in Interface Builder by unchecking the box for my window on the right panel the keyboard capture stops working.
keyDown: is not called anymore and I get that 'dong' sound characteristic of when your mac tells you that keyboard input is not an option. Even though I still have the name of my app on the menu bar.
Is there any way to still be able to receive keyboard input when the title is off ?
By default NSWindow instances return false from canBecomeKeyWindow if the window has no title bar. The following quote is from the relevant section in the NSWindow class reference.
Attempts to make the window the key window are abandoned if this method returns false. The NSWindow implementation returns true if the window has a title bar or a resize bar, or false otherwise.
So, to get the behaviour you're after you need to subclass NSWindow, and return true from canBecomeKeyWindow.
As pointed out by Paul Pattersion (accepted answer) the trick was to subclass NSWindow in order to return true for canBecomeKeyWindow. For anyone wondering how to do that, here is the code:
import Cocoa
class CustomWindow: NSWindow {
override var canBecomeKeyWindow: Bool {
get { return true }
}
}
I want to restore a window position of my Cocoa app whenever an user launches the app. This feature is implemented in default in Cocoa. However, I also want to make my app terminated by tapping the red x button on the top-left corner on the toolbar, so I wrote the following in AppDelegate.swift:
func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
return true
}
This makes the app quit immediately by tapping the red x button. However, if you terminate the app in this way, the window doesn't restore to the previous state the next time you open the app.
Why does the app not restore when you terminate the app by closing the window? And how can I restore even if the user terminates the app by closing the window?
You can do it in 2 ways
1) You can save the window's frame to plist when window's delegate fire the close and reposition the window in that frame when its open again.
2) This way like Zeppenwolf comment , you can return NO to windowShouldClose and call the app terminate in a delay.
Based on the comment of zeppenwolf I implemented the following in my NSWindowDelegate
- (BOOL)windowShouldClose:(NSWindow *)sender {
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
[NSApp terminate:sender];
}];
return NO;
}
I have noticed when an apps window contains an Outline view (such as XCode) it changes color when that window is in focus. With XCode for example, if the window is current then the outline view has a blueish background, if it looses focus it goes grey,
Can anyone help me to replicate this? I presume its something to do with drawRect: but can only manage to get the color to change when the window loads.
Maybe its a built in function and I'm just missing something?
All you have to do in your -drawRect: is check whether the window has main status and draw accordingly:
- (void)drawRect:(NSRect)rect
{
if ([[self window] isMainWindow]) {
// draw active appearance
} else {
// draw inactive appearance
}
}
A window's delegate gets messages whenever a window gets or resigns main or key window status. You can implement the appropriate methods (like -windowDidBecomeMain: and -windowDidResignMain:) in your window delegate to update the window and its subviews as necessary.
I am trying to write a Mac application which runs in the menubar, which when clicked, displays an iOS-like popover. Similar to Flexibit's Fantastical, or The Iconfactory's Take Five.
I am using INPopoverController which seems to work great.
My problem is that when the user clicks on anything in the popover view, the popover becomes the key window. Is there a way to stop this from happening?
In INPopoverWindow:
- (BOOL)canBecomeKeyWindow
{
return YES;
}
means that the popover can become a key window. You can either change it to return NO, or subclass INPopoverWindow and override that method to return NO.