How to force an NSWindow to be in front of every app? Even fullscreen apps - objective-c

I have an NSWindow that i would like to have it in front of everything (every app of the computer, fullscreen apps, etc..). Even if i click in a background app, the NSWindow cant go to background. And the NSWindow must follow the user screen if, for example, the user switches the desktop to desktop2, and so on...
How can i do that?
Thanks!

If you don't need to be visible with other apps' full-screen windows, it's not too hard.
First, to stay in front of everything else, just setLevel: with NSFloatingWindowLevel or higher. Experiment with the different values to see which seems appropriate to your needs.
Next, to stay in front even when the user changes Spaces, possibly including Exposé/Mission Control, setCollectionBehavior: with the appropriate pair of flags, or use the corresponding Spaces and Exposé settings in the Attributes Inspector if you're creating the window in the nib. Either Can Join All Spaces or Move to Active Space will make sure you stay visible on every space, in slightly different ways. You'll probably want Exposé set to Stationary, or possibly Transient, too. Again, try both ways and see.
However, Lion will hide both all-spaces and move-to-active-space windows when the user switches to a full-screen space or to Dashboard or Launchpad. And if you watch, you'll see that it does this in different ways for each of the three cases. And that Snow Leopard does things a little differently, and so does Mountain Lion.
If you want to solve that last problem, you need a bit of hackery—and different forms of hackery for each case and for each OS version. The basic trick is to catch the hide-related notifications and unhide yourself at the appropriate time.

You should modify your info.plist and set the Application is Agent flag to YES. An agent's window can be displayed in front of fullscreen windows.

Setting both,
"Application is agent (UIElement)" to "YES" in info.plist
&
window level :
self.view.window?.level = NSWindow.Level(rawValue: kCGMainMenuWindowLevel.hashValue - 1)
self.view.window?.collectionBehavior = [.stationary, .canJoinAllSpaces, .fullScreenAuxiliary]
helped me.

Related

Showing the keyboard in a Microsoft Surface application

I am creating an application that has multipile browsers open.
Each browser has its own keyboard to type with but I don't know how to show the keyboard in this application. When the user wants to type any URL, I have to show keyword for each user.
The normal keyboard should - at least in the surface mode - appear as soon as a textbox gets a focus. The drawback: there is only on open at a time.
If you really need to have multiple touch-keyboards, you would need to implement a custom control displaying and emulating a keyboard (you would need to handle different layouts on your own!). Basically it could be implemented as a bunch of buttons, each one adding a letter to a label. A delete button would delete the last letter. Marking, copying, deleting and so one would be interesting parts to be implementing.
We have done something similar (although only one keyboard) to emulate a handy keyboard for a promotion. To be honest: it wasn't the best experience in terms of usability (a bit worse than the included keyboard). It has fit it's need, and on screen keyboards aren't best in class experience at all (you could argue, but I like my mechanical keyboard a lot more than any virtual keyboard, so this might be a matter of taste)

Change to other space (MacOSX) programmatically

I am making a customised window (a NSWindow with NSBorderlessWindowMask) So far I have been able to handle dragging, resizing, cmd+click and even miniaturize with double click if allowed (see here) so my window resembles as much as possible to a normal NSWindow.
However when I drag my window to the corner of my screen the user will expect to move that window to the next space. (In case you have Spaces enabled in "SystemPreferences" > "Expose and Spaces" > "Spaces" > "Enable Spaces")
I wonder how can I change to other space programmatically and move my window there?
Unfortunately there's no public API which allows you to do this, but if you're willing to use the Private API it's possible. Take a look at CGSPrivate.h and you'll see you can make a call like this:
CGSConnection connection = _CGSDefaultConnection();
CGSMoveWorkspaceWindowList(connection, &windowNumber, 1, newSpaceNumber);
Note that using this private API will cause your app to be rejected from Apple's Mac App Store though.
Finally I found a solution.
I can't change to a certain space programmatically but I can make my window behave like other non NSBorderlessWindowMask if [window setMovableByWindowBackground:YES] is done. That was the final purpose of this question :)
The solution is written (with some detail) here because that question seems to be older (or maybe a duplicate of this question?)
Is there a way to make a custom NSWindow work with Spaces

Remove OS X Application Toolbar in XCode

My application is such that it does not require the tool-bar. It is very simple in nature and is controlled 100% by keyboard actions (one at a time, even). So while I know it's generally accepted that you should leave the toolbar in place, this time I feel that it actually hampers the UX of the program. So, I was wondering if it's possible to actually remove the tool-bar from my program?
It's easy to remove the traffic lights [ o o o ] from the bar, and there's no Title, but the space is still there, and the application simple looks 'off' with the extra space.
Any pointers are much appreciated, as I've looked around with the following queries:
How to remove the toolbar in an OSX application in XCode / Objective-C.
How do I remove the toolbar in an OSX application in XCode / Objective-C?
and a few others without much success.
You say toolbar, but I think you mean the window's title bar. This previous answer should work for you. The top answer is the way to do it, and the second answer is an argument against doing it.
Hide NSWindow Title Bar
If you want to keep title bar, but just want to customize it (including close, minimize and maximize buttons), you can use INAppStoreWindow component.

Make an NSWindow (or something else) appear above the menubar

I want to create an NSWindow (or something else) that can appear above the mac menubar. I know this is possible because TeamViewer does it with their "mouse" image.
Example: http://i.stack.imgur.com/6iZbG.png
How do they do it? (or, how can I do it?)
You want to check out window levels, as alluded to in moritz' comment. Any level above NSMainMenuWindowLevel should appear above the menu bar.
If you really want to be above everything else, you can use a shielding window level (not technically part of the regular NSWindow window level). Shielding windows are intended for full screen apps which take over the screen, but you can use a regular window which does this. I have a magnifying glass type app that uses this to good affect.
[myWindow setWindowLevel:CGShieldingWindowLevel()];
Also as alluded to moritz' comment, doing this is generally a bad idea, so make sure you've a good reason for doing so.

How do I use an indeterminate status indicator as the image for an NSStatusItem?

I have an application that is an NSStatusItem.
It has a few different modes, each of which require an external process to be launched, during which the icon is simply highlighted, and appears to be frozen.
I want to use the -setImage: method (or reasonable facsimile) to display something along the lines of a "spinner" commonly seen in web applications and all over OS X.
Is there any native method for accomplishing this (e.g. some instance of NSProgressIndicator?) or must I manually display an animation by cycling through a set of images?
In either case, how would I implement?
In order to have it be animated (and not just a static image), you'll probably need to use -setView: and give it a custom view (which then animates itself). You might be able to get away with using a suitably-configured standard NSProgressIndicator (i.e. set to NSProgressIndicatorSpinningStyle style, etc.) as that "custom view".
But, if the NSProgressIndicator standard sizes don't work well, then you can check out my YRKSpinningProgressIndicator (BSD-licensed), which is a clone of the spinning NSProgressIndicator that can be set to arbitrary size and colors.