I like to have a fullscreen background that’s visible when my app is front. That window shall stay behind all other windows of my app, at all times, even when one clicks on it.
The idea is that while my app is active, I want the windows of all other apps to remain hidden under my app’s background window, so that the user is fully focused on the windows my app presents.
Basically, it should behave similar to if you only have the Finder running: There is a background (the Desktop window), on which appear all the Finder’s windows.
While I can initially make such a fullscreen window appear in my app, the problem is that as soon as the user clicks on that background window, it comes to front, hiding all other windows my app is showing.
Simply returning true from the MouseDown event isn’t helping. And trying to bring the window all to the back in its Activate event is a pain, too, as I’d have to go thru all the other windows, calling Show for each, which leads to a lot of flicker.
I’d rather keep the bg window from even coming to front.
I need this only for OSX, so if there’s a Cocoa (MBS, too) way to do it, that’s fine.
Curious if this for your personal use or for a shippable app ?
If its for a shippable app I’d make that a user preference. And make it possible to run full screen.
“MDI for the mac” sounds nasty
Missed the “other apps” part…
But there really is no way to do it… even if you managed to get a window that covered the screen, the taskbar is still there, and clicking on it will bring that “other app” to the forefront… And personally I’d not be happy with an app that commandeered by screen like that. (Oh… another monkey wrench for you , what if there are MULTIPLE monitors???)
Geez guys, please don’t question my UI decisions. It’s for a special application in the vertical market where this is simply necessary. And the app will still have a menu and there’s be the Dock and you can switch using Spotlight or whatever. That’s really not for discussion here. I’m not a newbie to Mac app programming.
Would seem that you want to have these windows in a layer above all others - and your actual window above the “background” one which are both in front of everything else
And yes you can hide other apps
see SharedWorkspace : hideOtherApplications
Using hideOtherApplications won’t work because then the user would see the desktop with its icons, not my clean custom background with the branding logo on it.
hideOtherApplications is also the equivalent of cmd-shift-h which I would not appreciate as a user.
Have you looked at window level settings? Maybe there’s an unclickable back level.
Perhaps addChildWindow:ordered: will work? The child window becomes attached to the parent and moves when the parent moves, but the parent always keeps the child in front, even if the parent has focus, if NSWindowOrderingMode is NSWindowAbove.
[code] Declare sub addChildWindowordered lib “AppKit” selector “addChildWindow:ordered:” (win as ptr, child as ptr, mode as uint32)
You can actually put a window behind the desktop or behind the desktop icons (very funny looking) all the way to above the dock and menubar. Uh, well I see the Dock Level is now deprecated. I’m not sure which level is best for you, maybe NSFloatingWindowLevel for the obscuring window and any higher level for your actual windows.
doc for level which has a link to Window Levels which has a link to Window Level Keys.
Setting child relationships is not a good solution because that will make the child windows immovable. But I want the windows of my app still to be movable as usual.
Changing the level of all but the bg window works somewhat. However, that makes all the windows floaters, which is still a bit odd, but workable (for instance, when debugging, those windows would stay in front of the IDE even when breaking into the debugger - I can avoid this by not changing the level when debugging, though).
However, clicking the background window will then still remove the focus from the previous front window.
Now, if I could just find a way to have clicks to the bg window ignored, then I’d be set.
There is no real solution for what you want (just serarch for it in stackoverflow). It will break the user’s expectations, it will not work with multiple monitors, “fullscreening” two or more windows of your application separately will not work, etc.
The only way I can think of would be to have one regular window and inspector panels as “MDI” windows. But even if that would work: either it’s a Kiosk-worthy application or not.
This is a real hammer but you could install a local event monitor for mousedowns and reject those landing on the bg window. I’ve tried it and it works, but I just filtered any X < 500 for the test.
To do a full window hit test could be involved. NSWindow has
+windowNumberAtPoint:belowWindowWithWindowNumber: but I’m not sure how to use it. (Hmm, I guess a loop over the non-bg windows testing w.Bounds.Contains(point) would work).
Or for a bigger hammer you could run the bg window from a helper app where the local monitor can just filter all mousedowns.
Maybe an NSResponder inserted high in the chain could more easily filter the events. It’s been a long time since I used NSResponders and I’m not sure this idea has merit.