NSWindow draw on top of Desktop icons - objective-c

I'm writing an application that is looking to draw a basic NSWindow on top of the Desktop icons (Mac OSX 10.7 Lion).
NSWindow *systemInfoWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
systemInfoWindow.delegate = self;
[systemInfoWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[systemInfoWindow setBackgroundColor:backgroundColorSpace];
[systemInfoWindow makeKeyAndOrderFront:NSApp];
[systemInfoWindow setLevel:kCGDesktopIconWindowLevel];
This part of code works quite well and the NSWindow gets draw on top of the icons.
But if I switch between two spaces my NSWindow stay behind the icons.
/* === Update === */
I think i have problems with my window Level. For better understanding I have uploaded two Screenshots.
Space 1 - window stays like I want on top of the Icons
http://dl.dropbox.com/u/1503795/Space1.png
Space 2 - the window is behind the Desktop icons. They should also stay on top
http://dl.dropbox.com/u/1503795/Space2.png
A further problem I found. If I activated the App and stay on the first Space and everything looks good like on my first Screenshot. If I select the Files on the Desktop the window also jumps to the back:
Sorry, can`t post a nother Screenshot
I hope my problem is a bit more understandably.
I dont`t know how to fix this. Has anybody an idea?
Thanks!

You probably need to register for the space change notification:
NSNotificationCenter* nc = [[NSWorkspace sharedWorkspace] notificationCenter];
[nc addObserver:self
selector:#selector(activeSpaceDidChange:)
name:NSWorkspaceActiveSpaceDidChangeNotification
object:nil];
You can then respond to the notification and update your window:
- (void) activeSpaceDidChange:(NSNotification*)aNotification
{
[[self window] orderFront:self];
}

Related

My iOS app Screen is not auto sizing in iOS 5 dimension

The Screen UI is developed for 3:2, but when I run the app in iOS Simulator for iphone 5 and above, I see there is a white patch below in the bottom of the screen. The rest of the screens are appearing correctly.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self startup];
[window addSubview:loginViewController.view];
//For Eula
NSDictionary *eulaDict = [EULAController getEULADictionary];
if (eulaDict == nil || [ self checkForVersionChange] == TRUE) {
eulaController = [[EULAController alloc] initWithNibName:#"eula"bundle:[NSBundle mainBundle]];
//temp fix as for some reason this is showing up 20 pixels shifted upwards. if this works in your scenario then remove this adjustment
CGRect frame1 = CGRectMake(0,20,320,460);
[eulaController.view setFrame:frame1];
[window addSubview:eulaController.view];
}
[self updateVersionAndBuild];
[window makeKeyAndVisible];
}
Not sure, why its not fitting the entire screen. I didn enable athe AutoLayout option but it didnt help, as during the launch of the app, it stops for iphone 5/6.
Thanks in advance !
I guess you are missing the Default-568h#2x.png default launch image...
If so, just add one to your project and it will work.
You've hardcoded the frame to iPhone 4 size:
CGRect frame1 = CGRectMake(0,20,320,460);
You've said your using autoLayout. I'd remove this and use autoLayout constraints instead and it will scale.

How to resize Window to dimension in VIew Controller for a OSX app?

I'm fairly new to Mac OSX Apps, but I'm trying to build an app with no status bar, and the dimensions are smaller. So what I did in my AppDelegate.m is:
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
self.mainViewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[self.window.contentView addSubview:self.mainViewController.view];
[self.window setOpaque:NO];
[self.window setStyleMask:NSBorderlessWindowMask];
[self.window setBackgroundColor:[NSColor clearColor]];
self.mainViewController.view.frame = ((NSView*)self.window.contentView).bounds;
}
Now, what I really want to do, is to get my window to look like, what I've built in my interface builder (can't post pictures yet). I've tried shutting off all the autosizing elements but when I run the simulator I get a clipped version of my interface (the size changes every run). It seem like the frame size is getting miscalculated, but I've done everything from the interface builder. I can programmatically set the shapes of the view, but is there a way to shut off all resizing and simply portray the xib file as what I see in the interface builder?
There are two ways you could approach this problem.
You add an AutoresizingMask to your ViewController:
[self.mainViewController setAutoresizingMask:NSViewAutoresizingFlexibleWidth|NSViewAutoresizingFlexibleHeigt];
You disable window resizing in the Interface builder like by setting its minimum and maximum size. This can also be done in code.
Edit: Thanks to trojanfoe for pointing out that you can also uncheck Resize in the Attributes Inspector.
You can easily resize your window programatically. Here's how:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSRect frame;
frame.size.height = 200;
frame.size.width = 200;
[window setFrame:frame display:YES animate:YES];
}

Is there Any way to imitate Lion's Launchpad?

I have been struggling to imitate Launchpad.
At the beginning I thought about making NSWindow bgcolor transparent:
//make NSWindow's bgcolor transparent
[window setOpaque:NO];
[window setBackgroundColor:[NSColor clearColor]];
But now I realized it's way more ideal to
capture wallpaper
blur it and make it bg-image for NSWindow or a view
Rather than hiding all the opened windows and menubar, which was the first idea I had have come with (Still not sure with better, if you had any better idea...).
Capture & blur wallpaper used by a user
Make it background image for nswindow or a view
Fade-in to fullscreen view
Click somewhere blank or press ESC to fade-out
Are those possible to achieve without using private APIs?
Sorry if it's not clear my poor English.
Simply I'm trying to imitate Launchpad-styled full screen.
Thanks for any advice.
To get an image of the desktop background, use:
NSURL *imageURL = [[NSWorkspace sharedWorkspace] desktopImageuRLForScreen:[NSScreen mainScreen]
NSImage *theDekstopImage = [[NSImage alloc] initWithContentsOfURL:imageURL];
You can blur the image using CIFilter. Here's a Apple doc describing how to apply filters.
And then you can load that image into a color and set that as the background color for the window. Additionally, set the window to have no style mask (no close buttons, title frame, etc.), cover the screen, and be in front of everything except the dock:
[yourWindow setBackgroundColor:[NSColor colorWithPatternImage:theDesktopImage]];
[yourWindow setStyleMask:NSBorderlessWindowMask];
[yourWindow setLevel:kCGDockWindowLevel - 1];
[yourWindow setFrame:[[NSScreen mainScreen] frame] display:YES];
To have the window fade in, you can use NSWindow's animator proxy. (Replace 1.0 with 0.0 to make it fade out.)
[[yourWindow animator] setAlphaValue:1.0];
Of course you could customize that a bit more with things like CoreAnimation, but this should work just fine.
To handle background clicking, I suggest making a subclass of NSView where you -orderOut: your window on -mouseDown:. Then put an instance of that subclass that spans the entire frame of your window.
Also, NSViews sometimes don't respond to key events, so you can add an event listener to detect any time the escape key is pressed while your app is active:
[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:(NSEvent *ev)^ {
if([ev keyCode] == 0x53) {
[yourWindow orderOut:self];
}
return ev;
}

How would I develop something like DeskLock from Deskshade?

Sorry to be a nuisance, but I have yet ANOTHER question. How would I do something like DeskLock from macrabbit's Deskshade app? I've made the little window and that's as far as I've come. I know how to "lock" the screen in 10.6 with PresentationOptions, but I don't want to risk it because last time it wouldn't let me back in ;]
EDIT: The DeskShade app actually is meant to cover your desktop, hiding all icons. It also allows you to randomize wallpaper patterns with several fade/swipes. There is one extra feature called DeskLock that actually presents a translucent black bevel (similar to AppSwitcher build into Mac) with a lock icon, and you can place personal text. When you click the lock icon, it presents a modal that asks for a password you can set. You can also just type this password without pressing anything, followed by the Enter key, and it unlocks the screen. This uses the DeskShade feature of hiding the desktop as well.
Thanks!
To create the overlay window you have to subclass NSWindow and set its style mask and background color:
#implementation BigTransparentWindow
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation
{
self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask //this makes the window transparent
backing:bufferingType
defer:deferCreation];
if(self)
{
[self setOpaque:NO];
[self setHasShadow:NO];
[self setBackgroundColor:[[NSColor blackColor] colorWithAlphaComponent:0.5]];
}
return self;
}
#end
You then need to set the window's frame so that it covers all screens, and you need to set its window level appropriately:
- (IBAction)showWindow:(id)sender
{
//set the window so it covers all available screens
NSRect screensRect = NSZeroRect;
for(NSScreen* screen in [NSScreen screens])
{
screensRect = NSUnionRect(screensRect,[screen frame]);
}
[yourWindow setFrame:screensRect display:YES];
if(coverScreen)
{
//set the window so it is above all other windows
[yourWindow setLevel:kCGMaximumWindowLevel];
}
else
{
//set the window so it sits just above the desktop icons
[yourWindow setLevel:kCGDesktopIconWindowLevel + 1];
}
}
As you've mentioned, you can use the NSApplicationPresentationOptions settings for NSApp to control how the user can interact with the system. An easy way to test this without locking yourself out is to set an NSTimer that calls a method that pulls the app out of kiosk mode after a timeout period.

iPad keyboard dimensions

I have found the iPhone's keyboard bounds in the apple documentation, but I can't find the iPad's keyboard bounds. Could you please help me?
The entire answer in code looks like this. First you need to register for the notifications:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
and there are more here. Note that you'll need to get rid of them, too (use removeObserver).
Then you need a method that gets the notification to get the size. Note that the size is, at first, not rotated (since the UIWindow doesn't rotate. Its contents do).
- (void) keyboardDidShow:(NSNotification*)notification {
CGRect keyboardFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSLog(#"keyboard frame raw %#", NSStringFromCGRect(keyboardFrame));
UIWindow *window = [[[UIApplication sharedApplication] windows]objectAtIndex:0];
UIView *mainSubviewOfWindow = window.rootViewController.view;
CGRect keyboardFrameConverted = [mainSubviewOfWindow convertRect:keyboardFrame fromView:window];
NSLog(#"keyboard frame converted %#", NSStringFromCGRect(keyboardFrameConverted));
}
Obviously, if you have a reference to your mainSubviewOfWindow by some other means, use it.
For iPhone in portrait 216 pixels, landscape 162 pixels, for iPad in portrait it's 264 pixels and in landscape 352 pixels. This is valid for US keyboard in 2010.
These sizes can be different for other languages, and might change for US as well.
Please note that if user choose to use "split" keyboard on iPad, then UIKeyboardDidShowNotification/*UIKeyboardDidHideNotification* notifications will not be fired. Instead, UIKeyboardDidChangeFrameNotification notification will be fired on both show and hide. You will have to analyze keyboardFrame.origin.y to figure out what exactly happen (show or hide).
I just found it if somebody else needs it.
Keyboard Notification User Info Keys