I'm making an application, in which I need to run a code that will tell system events to keystroke a certain phrase. Like in an AppleScript, I would do:
Tell Application "System Events" to keystroke "This is a test"
I don't know how to do this from Xcode, and I would really appreciate any help. Thank you!
You can run an AppleScript from code, e.g., using OSACompileExecute. Also see QA1026.
Alternately, you can post keyboard events using the CGEvent APIs. With recent OSes, you may be able to avoid posting each letter individually using CGEventKeyboardSetUnicodeString.
Related
I try to make a code assembly to create my own applescript to create an image in Photoshop but unfortunately I have an error and I can't find where it comes from.
The first part of the script works, the random image is well copied to the clipboard but the rest is problematic.
-- Select random image
tell application "Finder"
set bg_img to file (random number from 1 to (count files of folder "HD:Works:Club:LAYERS:0-BG")) of folder "HD:Works:Club:LAYERS:0-BG"
end tell
tell application "Preview"
activate
open bg_img
end tell
-- Select and copy image to clipboard
tell application "System Events"
tell process "Preview"
keystroke "a" using command down
keystroke "c" using command down
end tell
end tell
-- Quit Preview Application
tell application "Preview" to quit
tell application "Adobe Photoshop 2022"
-- Create a new document
set docRef to make new document with properties {width:1200, height:1200, resolution:72}
tell docRef
-- Unlock the background layer and fill it with gray color
set background layer of layer 1 of docRef to false
fill selection with contents {class:RGB color, red:200, green:200, blue:200}
end tell
end tell
-- Paste image to new layer
tell application "System Events"
tell process "Adobe Photoshop 2022"
set newLayer to make art layer with properties {name:"LayerA"}
keystroke "v" using command down
end tell
end tell
Ok, a compilation error; I got it now. Try this:
-- Paste image to new layer
tell application "Adobe Photoshop 2022"
activate
set newLayer to make art layer with properties {name:"LayerA"}
end tell
tell application "System Events"
tell process "Adobe Photoshop 2022"
keystroke "v" using command down
end tell
end tell
Remember, you use a tell application "NAME" … end tell block to 1. tell AppleScript which app to send commands to, and 2. the app from which to get the custom terminology (keywords) for commands and objects.
Thus your tell application "System Events"…end tell block uses SE terminology and commands. The tell process "Photoshop"…end tell block inside it is still addressed to System Events. process is an SE-defined keyword for an SE-specific object. Likewise keystroke is an SE-specific command.
To make a new art layer in Photoshop, you have to put that command inside its own tell application block which is targeted at PS.
Yeah, AppleScript is often confusing. And System Events is 10× more confusing than that, thanks to it being not-obvious what is GUI Scripting and what isn’t. Good luck.
--
p.s. I’ve a feeling the tell process block is totally redundant, and is only necessary when using GUI Scripting to manipulate an app’s windows. IIRC the keystroke command doesn’t know or care what app receives those keys, in which case what’s important is that you activate Photoshop before you start “pressing” keys. I’ll leave it to you to determine if you can discard the tell process.
p.p.s. AppleScriptable apps usually don’t include cut and paste commands, usually ’cos they already provide far better ways of getting and setting content. Photoshop, however, does. So if you’ve not already tried it, try inserting a paste command at the end of your “tell Photoshop” block, then comment out the “tell System Events” block, and see if that works for you. If so, you can get rid of that System Events block entirely!
p.p.p.s. It’s also worth investigating PS’s dictionary further, to see if it can open and place your “bg_file” directly. If so, you can eliminate the “tell Preview” and the rest of that System Events horridness too!!
I am trying to simulate pressing the key 1 within a Java application. I have tried using key code 18, text to type, key down and keystrokes but whatever I try, the application displays the a character. Even when the script types into applescript window I just get aaaaaaa.
What am I doing wrong and how to properly simulate keypresses with AppleScript?
Did you try anything like the following?
tell application "System Events"
keystroke "1"
end tell
You can pass string literals to System Events keystroke-Handler
Is there a way to programmatically turn on and off the Bluetooth connection on OSX in a way that will be accepted by the Mac App Store?
From my previous question, I've found about blueutil, but it uses private APIs.
It would be somewhat surprising if Apple approved an app that modified the user's antenna settings. It sounds like the kind of thing they typically frown on, no matter how you do it. But then, sometimes I get surprised.
You can definitely do it through Applescript:
tell application "System Preferences"
set current pane to pane "com.apple.preferences.Bluetooth"
tell application "System Events"
tell process "System Preferences"
set isOnCheckbox to checkbox "On" of window "Bluetooth"
if value of isOnCheckbox is 0 then
click isOnCheckbox
end if
end tell
end tell
quit
end tell
Note that this will take over System Preferences and at the end close it even if the user was running it. That's not the best user experience, and I definitely wouldn't do it without first warning the user. But of course, I wouldn't recommend modifying the bluetooth settings without warning the user.
EDIT
Because you asked, I'll take a moment to rant here....
Regarding how to learn to read and write the above, first note that it, like most AppleScript I write professionally, was cobbled together from google searches and experimentation. I'm a purist programmer at heart, and I believe in really understanding the technology you use. Even I cobble together things in AppleScript until they "kind of work."
I wish there were a really good document. Of course there's the language guide, but it's kind of like learning Cocoa from the ObjC language definition. My current recommendations are Beginning AppleScript and then AppleScript: The Definitive Guide. Neuburg in particular does not sugarcoat the language or pretend that it makes sense. Applescript, even worse than the original COBOL (ADD X TO Y GIVING Z), is very hard to write because it tries so hard to be easy. I love and respect many languages. AppleScript is crap.
It is, however, the most supported way to interact with most of the Mac system functions, so a good Mac developer needs to at least be able to get by in it. Even if you use the new ScriptingBridge via ObjC (or MacRuby), the underlying object model is still AppleScript based. In my experience, to get ScriptingBridge code to work well, you generally have to write it first in AppleScript and then translate it into Cocoa.
This worked for me in 10.15.6, I might have over complicated my solution which is running script 1 (turn bluetooth off) and then script 2 (turn bluetooth on).
Script 1. This is for turning bluetooth OFF
tell application "System Events" to tell process "SystemUIServer"
tell (menu bar item 1 of menu bar 1 where description is "bluetooth")
click
click menu item "Turn Bluetooth Off" of menu 1
end tell
tell window 1
click button "Turn Bluetooth Off"
end tell
end tell
Script 2. This is for turning bluetooth ON
tell application "System Events" to tell process "SystemUIServer"
tell (menu bar item 1 of menu bar 1 where description is "bluetooth")
click
click menu item "Turn Bluetooth On" of menu 1
end tell
end tell
So I execute one command which will run one script after the other, the sleep is for the UI to update properly.
osascript bluetooth_off.scpt && sleep 3s && osascript bluetooth_on.scpt
You can just save the command in a file and execute it using: (they have to be in the same directory).
~ bash <fileName>
Note: You will need to give access to the terminal on Preferences > Security & Privacy
I was wondering if there was a way to write a Cocoa app that listened for OS system events such as an application launching, a window switches, etc, etc. My thought was to watch [NSNotficationCenter default] for messages but so far I haven't been able to find much. Does anyone have any suggestions?
Thanks!
Some messages that might interest you would be provided to [NSWorkspace notificationCenter], such as when apps launch, come to the front, or quit.
I'm not sure what you mean by "window switches". If you mean changing which window is in front without changing which app is in front, that's generally considered "none of your business" on the Mac.
I am trying to send keystrokes to the application VisualBoyAdvance using AppleScript, but I cannot get it to work.
My code, so far, is this:
tell application "VisualBoyAdvance"
activate
tell application "System Events"
keystroke "k"
end tell
end tell
When I tell VisualBoyAdvance directly, I get this error:
error "VisualBoyAdvance got an error: Can’t get keystroke \"k\"." number -1728 from keystroke "k"
I have tried telling VisualBoyAdvance directly, and I have also tried using key code 40, but I still cannot get it to work. Strangely enough, this does work:
tell application "VisualBoyAdvance"
activate
tell application "System Events"
keystroke "d" using {command down}
end tell
end tell
But that is a keyboard shortcut that shows up in the menu bar, so I guess it would be a bit different.
How can I use AppleScript to simulate a keypress and make the application respond to it? If I cannot use AppleScript for this, what else could I use?
I think you're almost there. Here's something I used for Safari; in this example, I send key code 48 (tab).
tell application "Safari"
activate
tell application "System Events" to tell process "Safari" to key code 48
end tell
AFAICS this ought to be largely independent of AppleScript support in the target process as you're asking System Events to simulate the key press via Universal Access.
For help with key codes, see this useful application: http://manytricks.com/keycodes/
It's the developer's choice to make an application fully Applescript aware. Menu items are Applescriptable from the Finder's point of view, but other UI options may or may not be. See UIElementInspector to examine that application for scriptable elements.
I can't garuntee anything as I don't have this app but here is some things to try
tell application "VisualBoyAdvance"
activate
tell application "System Events"
tell application process "VisualBoyAdvance"
try
keystroke "k"
on error
try
keystroke (ASCII character 75)
end try
end try
end tell
end tell
end tell