I have an NS panel that is the child of an NS Window; the panel is set to floating window level. The parent window has an NSView that is in full screen mode, so the NSPanel, is floating on top of the full screened NSView. Anytime I click the panel, it brings the parent window into floating mode as well, such that it renders on top of the movie. Is there any way for me to prevent this?
Whenever you enter fullscreen mode, why don't you just remove the panel as a child window? It should still be displayed and function, but then it won't bring the other window forward. Then when you exit fullscreen mode, add it back as a child window.
Related
I have an app with a popover that appears on a status bar item. The thing is, when you click on the icon while you're in a full screen app, then move the mouse away from the menu bar to click on something in the popup, the menu bar moves up, and so does the popup. It's annoying.
Anyone know of any way to solve this? I've tried attaching an invisible menu to the popup, but I can't get the menu to be invisible.
Screenshot for clarity, the annoying part is where I wave my mouse around:
The popover window is moving because its parent window is the status item window, and when the parent window moves, the child moves with it. (Before I investigated this, I didn't even know Cocoa had parent and child windows.) I solved the problem with this code immediately after showing the popover:
NSWindow *popoverWindow = self.popup.contentViewController.view.window;
[popoverWindow.parentWindow removeChildWindow:popoverWindow];
Now, the menu bar still moves up, but at least the popup stays in the same place.
Either use Carbon events or watch for things happening to the menu bar (window of type NSStatusBarWindow):
Notifications of type
NSWindowDidChangeOcclusionStateNotification
NSWindowDidMoveNotification
NSWindowWillCloseNotification
NSWindowDidCloseNotification
with an object of class NSStatusBarWindow should give you enough information about the menu bar showing or hiding to add proper handling.
Super-hacky approach:
Custom window with some super-high window level to make it appear over the menu bar, then add a transparent custom view to the new window that catches and handles/blocks mouse clicks according to your needs.
Or:
Get the window instance the popover is using to display and track/handle NSWindowWillMoveNotification / NSWindowDidMoveNotification.
I converted #tbodt's answer to Swift 4 and confirmed that is resolves this issue:
let popoverWindow = popup.contentViewController.view.window as? NSWindow
popoverWindow?.parent?.removeChildWindow(popoverWindow!)
I want to show a new window when an user taps on a button in the main window, but when I called the separate window using makeKeyAndOrderFront, the window popped up far away from the main window.
Here's what I wrote, in a subclass of NSViewController:
myWindow = NSWindow()
myWindow.setFrame(myView.frame, display: true)
myWindow.contentView = myView
myWindow.makeKeyAndOrderFront(self)
However, this opens a new window outside of the main window. I want to display it within the main window, possibly in the center of the main window (I set the .frame value of myView to be positioned on the center).
So how can I call the new window within the main window? In other words, can I specify where the new window shows up?
You'll need to convert the coordinates and or rect to screen space.
NSView and NSWindow provide methods that begin with "convert" take a look at those.
Sometimes you'll need to chain to convert from view space to window then window to screen.
Keep in mind that a window has an NSScreen screen method and that a window could appear on many different size screens and potentially span multiple screens.
Button which show the popover lay on the button left corner of window.
How to show popover only in window bounds?
Attention! Mac OS.
This is not possible. NSPopover is a floating window that is connected to a certain other window but otherwise stays completely on its own. You can however try manually to keep it within certain bounds on screen by calculating a popup position that keeps the popover bounds with that area. But this won't work in all cases anyway (e.g. if the user moves the app window so that there's simply not enough room for the popover).
I have a semi-transparent NSView subclass that acts as a kind of tooltip. When the tooltip is drawn on the screen it draws on top of a form and so it covers a couple of NSTextField's.
When I hover the mouse over the tooltip at the spots where a NSTextField exists, the cursor changes to the input style cursor.
How can I prevent the cursor from changing?
Overlapping views are not really supported very well in Cocoa and the behaviour is undefined.
Instead, your tooltip view should be in its own borderless window, large enough to contain your view. The tooltip window should be a child window of the main window it's attached to. To make a window a child of another window, you use the addChildWindow:ordered: method of NSWindow.
Child windows are attached to the parent window and will move with their parent window when the parent window moves. If you just open a new window without making it a child window, it will be "left behind" if the other window is moved.
To make a borderless window, pass NSBorderlessWindowMask as the styleMask to the initWithContentRect:styleMask:backing:defer: method of NSWindow.
in windows, how can make a 'child' window beyond the parent window, and the parent window always in active status (GetActiveWindow() return parent), just like the combobox dropdown window.
I think these are the main points when trying to do this:
The pop-up is a top-level window which has the same parent as the control. (i.e. The pop-up is not a child of the control. It's not a child-window at all; it's a top-level window, but one without a thick window border etc. so it doesn't look like a normal top-level window.) That's why it can extend outside of the control's boundaries.
When the pop-up is created it is shown using ShowWindow(hWndPopup, SW_SHOWNA) so that it does not take the input focus. This prevents the parent window from going inactive.
When the pop-up is created you capture the mouse using SetCapture. You then track where the mouse is and highlight items within the pop-up when the mouse overlaps them. When the mouse button is clicked you act on whatever is under the mouse (or cancel the pop-up if the mouse isn't over it at all). Remember to respond to WM_CAPTURECHANGED, in case something else captures the mouse. And remember to ReleaseCapture when you are done.
The popup should handle WM_MOUSEACTIVATE by returning MA_NOACTIVATEANDEAT.