I'm trying to create an OSX application which would be a replica of On Screen keyboard. Is it possible to insert some text into the cursor position of another active application? Thanks in advance!
Asked
Active
Viewed 1,935 times
6
-
1FYI, just in case: The answer (whatever the details, sorry I don't know them offhand) is a *qualified* yes - as for example that is how assistive software works. *However* under the sandbox, and hence in the App Store, the general answer is most certainly no - typing into another app is potentially a serious security issue. Of course if your application won't be in the sandbox then its restrictions won't matter. – CRD Apr 29 '13 at 18:55
-
@CRD what do you mean by sandbox. Do you mean that if i submit the app to appstore it wont work? But as a apple developer i would be able to run this app in my system? Can you please elaborate..Thanks. – Selvin Apr 30 '13 at 09:01
-
1the App Sandbox is a security system which limits what an app can do - what files it can access, whether it can make network connections, etc, etc. All iOS apps are sandboxed, for OS X it is optional. However all apps to be sold in the Mac App Store must be sandboxed. Look up App Sandbox in the Apple docs for the details. – CRD Apr 30 '13 at 10:13
2 Answers
10
It is possible. Accessibility enables to change content of other applications, but your app can't be sandboxed and thus not available via AppStore.
CFTypeRef focusedUI;
AXUIElementCopyAttributeValue(AXUIElementCreateSystemWide(), kAXFocusedUIElementAttribute, &focusedUI);
if (focusedUI) {
CFTypeRef textValue, textRange;
// get text content and range
AXUIElementCopyAttributeValue(focusedUI, kAXValueAttribute, &textValue);
AXUIElementCopyAttributeValue(focusedUI, kAXSelectedTextRangeAttribute, &textRange);
NSRange range;
AXValueGetValue(textRange, kAXValueCFRangeType, &range);
// replace current range with new text
NSString *newTextValue = [(__bridge NSString *)textValue stringByReplacingCharactersInRange:range withString:newText];
AXUIElementSetAttributeValue(focusedUI, kAXValueAttribute, (__bridge CFStringRef)newTextValue);
// set cursor to correct position
range.length = 0;
range.location += text.length;
AXValueRef valueRef = AXValueCreate(kAXValueCFRangeType, (const void *)&range);
AXUIElementSetAttributeValue(focusedUI, kAXSelectedTextRangeAttribute, valueRef);
CFRelease(textValue);
CFRelease(textRange);
CFRelease(focusedUI);
}
This code does not check for errors and makes assumption that focused element is text area.

Miroslav Hrivik
- 822
- 13
- 16
-
This way doesn't work on web based app :( e.g: Safari, Slack (Electron) or Skype (React-Native) – Tran Quan Dec 23 '20 at 21:11
-
i'm ending up here because i've reached the same solution but between the time i paste the next and the time i move the caret, the caret flickers and that makes the UX of my app pretty bad. haven't found any solution unfortunately. – godbout May 09 '21 at 18:29
2
Not sure if this helps, but in Applescript you can do something like
tell application "System Events"
keystroke "Stuff here"
end tell
So maybe you can try call that within cocoa using NSApplescript
or using NSTask
and run
osascript -e 'tell application "System Events" to keystroke "Stuff here"'

TheAmateurProgrammer
- 9,252
- 8
- 52
- 71
-
1This won't work on the Mac App Store either, so you'd best clarify this. – SevenBits Feb 26 '14 at 13:41
-
1Adding onto the comment above: most people resort to turning off their app sandboxes. According to https://developer.apple.com/forums/thread/693312, Apple won't allow App Store distribution with it turned off. It may be possible to leave the sandbox on if you use your `info.plist`'s `com.apple.security.temporary-exception.apple-events` array key to grant security exceptions for different apps. I'm not sure though because I haven't tried it. – Xavier L. Apr 29 '23 at 19:07