Cocoa - capture mouse just like screencapture utility - mouse

I am trying to find the answer to a topic which has basically driven me insane. Is there a way to capture the mouse pointer much like Apple's screencapture utility works? What I am trying to do requires me to draw a clear window that does not activate my app but instead overlays everything, including the dock. The only software I have seen do this is screencapture by utilizing command+shift+4.
I have tried creating a non-activating NSPanel but it doesn't work with cursor rects unless my app is active (which I don't want it to be). Also the problem with NSPanel is that if I am in Dashboard I cannot activate the window on it.
The requirements for what I am trying to do are this.
• My app must not activate (keep whatever active app as active)
• Must be able to change NSCursor
• Mouse does not trigger dock hiding/unhiding (or any other event)
• Work even in dashboard
I have tried this code before but its limitations are the same as listed above.
NSScreen * s = [NSScreen mainScreen];
[self.window setStyleMask:NSNonactivatingPanelMask];
[self.window setHasShadow:NO];
[self.window setOpaque:NO];
[self.window setBackgroundColor:[NSColor clearColor]];
[self.window setFrame:s.frame display:NO];
[self.window orderFront:self];
[self.window setLevel:NSMainMenuWindowLevel + 1];
[self.trackingView addCursorRect:self.window.frame cursor:[NSCursor closedHandCursor]];

Turns out that using CGEventTap and controlling mouse events before they are distributed to any app works. Unfortunately if you have a Sandboxed app then you can't use CGEventTap. Anyone know if there is a way to gain the same functionality with sandboxing?

Related

iPhone: Stopping a Program from Running in the Background

Right now, I have an application with a single map view. What should I do to stop the app from retrieving new location updates once I hit the home button. My goal is to make that arrow next to the battery symbol disappear when on the main menu page. The app will launch again when the user brings it back to the foreground. This is what I have so far, but it's not working.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
exit(0);
}
What you have should work (in fact, I have used it once for debugging purposes).
However, you should not do that, despite the fact that it works. Simply set the UIApplicationExitsOnSuspend key in the Info.plist file of your application to true.

Return Back To Application From Browser

I'm implementing a website call on button touch(in iPhone), so my browser get called in that case and website get opened.
I'm using following code:
- (IBAction) websiteButtonTouched{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.google.com"]];
}
Now what I want is to COME BACK TO MY APPLICATION FROM BROWSER as In iPhone4.0 and Up the application remain running at background we only have to call that when browser quite...
Thanks In Advance.. :P
Why not create your own in-app browser? Just put a UIWebView inside a navigation controller then put an address bar and a search bar.
Please see this question:
iPhone - Open Application from Web Page
As for returning to application where you left off -- if the device supports backgrounding (iOS4+) and your backgrounded app wasn't unloaded (due to memory shortage), the app will return the point you left it.
However, you also have to handle the returning to correct point in app yourself, in the cases that the device doesn't support backgrounding, or app was unloaded due to memory shortage: you can do this by storing information about current state of the app before it exits.
This web page has some very nice flow charts which describe app backgrounding and foregrounding etc.:
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging

display soft keyboard (iPad) when is connected a bluetooth input device

I'm really bangin' my head because I can't find the way to show the soft keyboard when there's a bluetooth input device connected to the iPad. I made some search on the web and this is the result:
a question on stackoverflow with a very short answer How can I detect if an external keyboard is present on an iPad?
an application developed by erica sadun for the cydia env http://www.tuaw.com/2010/06/02/hacksugar-bringing-back-the-on-screen-keyboard/
Erica said that the trick is to answer to the system that "There's no hardware keyboard attached".
I tried to write a category for UIKeyboardImpl and I overrided:
- (BOOL)isInHardwareKeyboardMode {
DEBUG(#"is called");
return NO;
}
But until now I haven't obtained anything. The overrided method is called but there's no soft keyboard.
Erica also said the application works by dynamic linking but I don't know how can I accomplish it. I don't need to be in the AppStore because this is a private application so I don't bother about rejection.
Thanks in advance
Ok. Finally got it. Many thanks to David, Matthias and Enrico. Here are the steps:
import the private framework GraphicsServices
call GSEventSetHardwareKeyboardAttached(NO) inside the viewDidLoad
add a button that toggles the keyboard by calling
static void toggleKeyboard(UIKeyboardImpl * keyImpl){
if (UIKeyboardAutomaticIsOnScreen()) {
UIKeyboardOrderOutAutomatic();
} else {
UIKeyboardOrderInAutomatic();
}
I've found this function on http://code.google.com/p/btstack/wiki/iPhoneKeyboardHiding
Now I can take input from the soft keyboard and from the bluetooth device at the same time.
To get around it using the apple keyboard you hit the eject key. Perhaps you can implement an action that sends the eject keycode? I think iSSH has a feature where you can tap the onscreen keyboard icon to bring it up even when a bluetooth keyboard is connected.

How to bring NSWindow to front and to the current Space?

I'm using this code to bring up my window:
[self.window makeKeyAndOrderFront:self];
[self.window setOrderedIndex:0];
But often it will be beneath other windows or displayed in other Space desktop that I last open it in. How do I make it always appear "in front" to the user?
Update
I found the answer from previously asked question; make the window show up to the top of other windows:
[NSApp activateIgnoringOtherApps:YES];
But how to move the app to the user's current Space?
To bring your app to the front:
[NSApp activateIgnoringOtherApps:YES];
Swift:
NSApp.activateIgnoringOtherApps(true)
Swift 3:
NSApp.activate(ignoringOtherApps: true)
Perhaps you want:
[self.window setCollectionBehavior: NSWindowCollectionBehaviorCanJoinAllSpaces];
Experiment with the other collection behaviors... I found NSWindowCollectionBehaviorMoveToActiveSpace was a bit buggy in 10.5 but it might be better now.
Swift 5.0 +
NSWindow.orderFrontRegardless()
The syntax seems to be a little different with Swift 2:
NSApplication.sharedApplication().activateIgnoringOtherApps(true)
Swift 3.0
NSApp.activate(ignoringOtherApps: true)
But how to move the app to the user's current Space?
You don't. Spaces hold windows, not applications. (That's why the collectionBehavior property is on NSWindow, not NSApplication.)
If you want to your app to come to the front, even if its minimised and have it activated (given active focus), then use both of these:
NSApp.activate(ignoringOtherApps: true)
NSApp.windows.first?.orderFrontRegardless()
If you only want to bring it to the front, without giving it focus, just use:
NSApp.windows.first?.orderFrontRegardless()
Swift 2.0
NSApp.activateIgnoringOtherApps(true)
Helpful Programming Tips and Hacks

UITextview content moves up when textview is selected

I am pretty new to this iPhone dev thing but so far I have built a pretty good app but I have stumbled into this problem that for the life of me I cannot seem to solve.
Basically the app is a chat application for social site. Everything is working 100% except the input box which currently is a UITextbox. This works fine however I would like the box to grow and be a multiline UITextbox with scroll. I replaced the UITextbox with a UITextview and all is good. I have the UITextview expanding as the user enters text however I have one slight problem that is driving me nuts.
When the UITextview gets focus it shifts the cursor and any text in there up just out of view. The UITextview I have set to display 2 lines by default and then as the height of the text goes beyond those two lines I would like the box to grown (which it does) and the text to remain scrolled up so you can see what you are typing. If you look at the SMS app on the iPhone this is exactly how I would like it work.
Any words of wisdom would be greatly appreciated.
I think Blaenk answered perfectly (that was going to be my answer). But just in case you don't want to include Three20 in your project (it's kinda big), below is the relevant code from TTTextEditor. You should be able to call this from wherever you are expanding the text view.
- (void)scrollContainerToCursor:(UIScrollView*)scrollView {
if (_textView.hasText) {
if (scrollView.contentSize.height > scrollView.height) {
NSRange range = _textView.selectedRange;
if (range.location == _textView.text.length) {
[scrollView scrollRectToVisible:CGRectMake(0,scrollView.contentSize.height-1,1,1)
animated:NO];
}
} else {
[scrollView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
}
}
Check out three20:
Three20 is a collection of iPhone UI classes, like a photo viewer, and general utilities, like an HTTP disk cache. Three20 is derived from the Facebook iPhone app, which is one of the most downloaded iPhone apps ever.
Specifically, you'll want to take a look at TTTextEditor:
TTTextEditor is a UITextView which can grow in height automatically as you type. I use this for entering messages in Facebook Chat, and it behaves similarly to the editor in Apple's SMS app.
You'll find instructions on how to add three20 to your project here.
I made a subclass of UITextView just for that:
https://github.com/MatejBalantic/MBAutoGrowingTextView
It is an auto-layout based light-weight UITextView subclass which automatically grows and shrinks based on the size of user input and can be constrained by maximal and minimal height - all without a single line of code.
The class is made primarily for use in Interface builder and only works with Auto layout.