Hi all I am working on a small cross-platform hobby/educational project which takes screenshot of all monitors and overlays all monitors with one wide window. Now on Windows and GTK systems this is no problem. But I am having issues on OSX:
First major issue is that the window is not covering the non-work areas of the dock and the menubar at top.
It won't resize to span multiple monitors.
Is there any programattic way to accomplish this? Users really like when a screenshot is taken that it overlays all monitors with the capture and then they crop and click upload to image service etc. I just want to bring them the same experience on OSX.
Thanks
With OS X 10.9, Apple introduced a feature called "Displays have separate Spaces". See the Mission Control pane of System Preferences. It's on by default.
When that is on, no window can span multiple monitors. Even if it's programmatically set with an frame that does, it will only appear on the screen that contains the most area of the window. The window will be clipped to the frame of that screen.
So, you have to create a separate window for each screen.
From the 10.9 AppKit release notes:
Spaces and Multiple Screens
In 10.9, we have added a feature where
each screen gets its own set of spaces, and it is possible to switch
between spaces on one screen without perturbing the spaces on the
other screens. In this mode, a fullscreen window uses one screen, and
leaves the contents of any other screens unchanged. …
When this feature is enabled, windows may not visibly span displays.
A window will get assigned to the display containing the majority of
its geometry if programmatically positioned in a spanning position. A
window will get assigned to the display containing the mouse if the
window is moved by the user. A window clips to the edge of the
display, whether or not there is another adjacent display.
Also, since the menu bar appears on all screens, Apple changed the way windows are constrained to screens. Also, from the 10.9 AppKit release notes:
constrainFrameRect:toScreen: now invoked for borderless windows
Prior
to 10.9, the NSWindow method -[NSWindow constraintFrameRect:toScreen:]
was invoked only for windows with NSTitledWindowMask set in their
styleMask. In 10.9, this method is invoked for all windows. The
default implementation does a more limited constraining for non-titled
windows, as described in “NSWindows constrained to not intersect the
menu bar” below.
NSWindows constrained to not intersect the menu bar
In 10.9, in
support of the new multi-monitor architecture, windows are now
constrained to not intersect the menu bar on their containing space.
This restriction was already in place for titled windows, but it has
been extended to borderless windows whose level is at least
NSNormalWindowLevel but less than NSMainMenuWindowLevel. This behavior
is implemented in -[NSWindow constraintFrameRect:toScreen:]. You may
override that method in an NSWindow subclass to adjust or prevent this
constraining.
So, you either have to use a custom subclass of NSWindow which overrides -constrainFrameRect:toScreen: to return the unconstrained frame, or you have to set your window's level to NSMainMenuWindowLevel or higher.
Related
I'm trying to create a window that is on the same level as the accessibility keyboard and notifications on High Sierra. My desired result is to get a window that will appear above all other windows, including the screensaver and lock screen.
In el cap/sierra I was able to use window.level = NSWindow.Level(Int(CGWindowLevelForKey(.maximumWindow))) but now in High Sierra my code does not work and I cannot see my window over the screensaver or lock screen.
After some experimenting I noticed that notifications and the accessibility keyboard DO show up over the lock screen/screensaver and was wondering if it is possible to create a window on the same level.
I've included two pictures, one of the lock screen showing both the keyboard/notification. The second image shows what happens when I transition from one window to another - my demo window stays on the desktop but the keyboard/notification is shown above the desktops and transitions over the dividing bar from one to another.
Anyone know of a way I can create this type of behavior in my window?
Is it possible to create a NSWindow that will not only is above all other windows (including other applications) but also able to block windows from going "into" that window. Basically I would like to extend the system's menu bar by having another bar below it, but it stops the user from resizing other windows to occupy that space.
For instance, if the user was to maximize a window, it would only be able to have a height of the screen size minus the system status bar minus my application's window.
I was thinking it may be possible by listening to some sort of window resizing notification and if the user tries to set the frame of that other window to a size that would go inside of my application's window then I would resize the other window, but method seems like such a pain.
I also acknowledge that this may not be possible, but was curious if it is!
Thanks in advance!
It is totally possible to make a window which is above all other windows, just set It's level to NSMainMenuWindowLevel.
But preventing other windows from resizing beyond It, I don't think so.
Even if there is a system API to limit window resizing (I don't think there is), some apps use custom code to control window resizing and would completely ignore the presence of your "special" window. I've seen apps which simply hardcode 22 (the height of the menu bar) when calculating window resizing stuff.
How can I make a sliding menu like (as an example) Sparrow's main email menu?
In the case of Sparrow:
It's a column of buttons that essentially slide to reveal a NSScrollView (with custom NSTableView?) with various folders inside (inbox, sent, etc). Clicking on a different account causes that account to slide up to the top and reveals the various folders inside.
How could I go about doing a menu similar to this?
There is some fairly cool Apple sample code here to deal with table views and animation (uses stuff that is generally only available as of Mac OS X 10.7 however):
https://developer.apple.com/library/mac/#samplecode/AnimatedTableView/Listings/ATPopupWindow_m.html%23//apple_ref/doc/uid/DTS40008863-ATPopupWindow_m-DontLinkElementID_26
Also, for basic window resize animation you can use the setFrame:display:animate: method of NSWindow.
We have 4 monitors on a wall for graphing. Looking to put them all into use in fullscreen mode. Right now if I do it it just uses one. Just looking to see if it is possible to create an app that allows me to use all 4 with like a simple uiwebview for each monitor.
Should of mentioned this.. Looking for a simple code sample of how to do this or pointers on where to get answers.
Yes, it is possible.
Standard Lion fullscreen mode allows for one "primary window", which is sized to take up the entire main screen, and as many "auxiliary windows" (inspector panels, etc.) as you want, which are not automatically sized in any way.
Go into Xcode, create a simple project, and edit the xib. For the existing window, go to the Attributes Inspector and make sure that Full Screen is set to "Primary Window". Now in the object browser, drag three Panels into the app. Go through them and make sure each one has "Utility Panel" for Style, "Auxiliary Window" for Full Screen, and either "Inferred Behavior" or "Transient Behavior" for Exposé. Now, when the first window goes into full screen mode (e.g., when you get the appropriate notification or NSWindowDelegate method), size and move the other three windows to take over the other three screens.
This is all documented pretty well in the Implementing the Full-Screen Experience section of the "Mac App Programming Guide" in the 10.7 Core Library.
If you're just looking to put a web view on each screen, it may be easier to use -[NSView enterFullScreenMode:withOptions:]. This isn't Lion's new full-screen mode, it's the earlier technique. It has different behavior in terms of whether the app is in a separate space, etc.
I want to create a full Screen Cocoa application, however my app is slightly different from a conventional fullscreen app.
This app would be below everything else, so underneath the menu bar and the Dock, etc. It would have a large image covering up the Desktop and icons, with a custom NSView in the middle with a table view, etc. If this concept is hard to understand then here is an image:
http://img10.imageshack.us/img10/6308/mockupo.png
The only part that might be a bit confusing is the background image. This background image is NOT the wallpaper of the computer, but part of the app. So when the app is launched, it goes into full screen mode and puts itself underneath the dock and the menu bar, and underneath all other windows too. So it draws the background image to cover the screen (including Desktop and icons). Then has a custom NSView in the middle containing my controls.
What's the best way to go about doing this?
Thanks
Make a borderless window, the size of the menu-bar screen (screen 0—not [NSScreen mainScreen]), positioned at 0,0, with window level kCGDesktopWindowLevel.
Remember that you will need to observe for screen frame-change notifications (when the user changes the screen dimensions), and that you should correctly handle the case of no screen at all (headless Mac).
I think #Peter Hosey’s solution should work, but to make other windows go on top, you will probably need to change the window level to something else.
But, I implore you, do not do this. This will be the most bugly application the Macintosh has ever seen. There are a lot of really good user interface paradigms that you can use, and "replicating" the main desktop interface of Mac OS X is generally not one of them. That is, unless you are reimplementing Time Machine or something like that.