The words Under construction in black text on a yellow background with diagonal black stipes surrounding it
I'm in the process of moving my site. It's still a work in progress. Please excuse the mess and broken links.

Exmaples Of Sending Simulated Keystrokes To Mac Apps With OSA/JXA JavaScript

TODO: Pull subtitle into page object

Here's a basic example:

code_start_default_section code_end_default_section

Debugging Stuff

I'm moving stuff around right now. All this below is helping me figure out where to put stuff

        -- title

Exmaples Of Sending Simulated Keystrokes To Mac Apps With OSA/JXA JavaScript

One of my favorite little hacks is being able to
send key presses to mac apps from apple's javascript
functions. I used it to put together a script
to automate text for making gifs.

-- p

Here's a basic example:

-- code/
-- js

// File: hello-world.js

  const sys = new Application('System Events')
  const app = new Application('Stickies')

  app.activate()
  sys.keystroke('hello, world')

-- /code

-- p

That script opens the built-in Stickeis app
and types 'hello, world' when you run
it with:

-- code/
-- shell

osascript -l JavaScript hello-world.js

-- /code

-- p

Sending letters with a modifiers (i.e. shift, command,
option, control, or function) is done like this:

-- code/
-- js

// File: upper-case.js

const sys = new Application('System Events')
const app = new Application('Stickies')

app.activate()
sys.keystroke('this is upper case', { using: ['shift down'] })

-- /code

-- code/
-- shell

osascript -l JavaScript upper-case.js

-- /code

-- p

Add multiple modifiers to the array if you need more
than one. For example, `Command` + `Shift` + `c`
opens the colors pallet in the Stickes app. The
scripting approach to that is:

-- code/
-- js

// File: color-pallet.js

  const sys = new Application('System Events')
  const app = new Application('Stickies')

  app.activate()

  sys.keystroke('t', { using: [
      'command down',
      'option down'
  ] })

-- /code

-- code/
-- shell

osascript -l JavaScript color-pallet.js

-- /code

-- p

(TKTKTKT - Test examples of option, control, and the
function key to verify they work as expected.)

-- p

There are some keys (like the arrow keys) that don't
work with the `keystroke()` method. The way to get to
them is to use the internal code for the key with the
`keyCode()` method.

-- p

For example, if you still have the test sticky note
from above open, this will move the cursor back
one chracters.

-- code/
-- js

// File: arrow-press.js

  const sys = new Application('System Events')
  const app = new Application('Stickies')

  app.activate()
  sys.keyCode(123)

-- /code

-- code/
-- shell

osascript -l JavaScript arrow-press.js

-- /code

-- p

For example, this
mimics pressing the F3/Mission Control key.

-- code/
-- js

const sys = new Application('System Events')
  sys.keyCode(160)

-- /code

-- p

** NOTES

-- p

- TKTKTKTK Note the difference between Enter
  and Return (and how that doesn't matter most
  of the time)

-- p

- TKTKTK Note the differences between the function
  keys that have two sets of codes and check to
  see if the other F keys do as well.

-- p

- TKTKTKT Note the media keys that do and don't work.

-- p

- TKTKTK Do examples with "command down" type stuff
  on keyCode() calls to check functionality.

-- p

- Some things don't work the way you'd expect (or don't
  work at all). For example, I can't do the equivelent
  of `Command` + `Shift` + `3` to take a screenshot.
  Seems like that should work, but it doesn't. You'll
  likely run into other things like that were you need
  to find another approach to the automation.

-- p

- These examples are a bit contrived. I don't know why
  you'd want to open the color pallet in the Stickies
  app, but that's not the point. The goal is to show
  how the tools work.

-- p

- While these examples are all JavaScript you can
  also use AppleScript to do the same thing.

-- p

- TODO: Put in AppleScript examples or make a
  version of this page with ApplieScript

-- p

- Sometimes the speed of the keystrokes comes into
  play and goes too fast if you're swithing things
  around. Adding a delay can help alleviate that.

-- code/
-- bash

The code blocks below are only for testing the
  code in the main body of the post.

-- /code

-- code/
-- bash

cat <<- "EOC" > /private/tmp/emacs_tmp_1.txt
  <<source_hello_world>>
  EOC
  osascript -l JavaScript /private/tmp/emacs_tmp_1.txt
            
  osascript -l JavaScript -e "Application('Emacs').activate()"

-- /code

-- code/
-- bash

cat <<- "EOC" > /private/tmp/emacs_tmp_2.txt
  <<source_upper_case>>
  EOC
  osascript -l JavaScript /private/tmp/emacs_tmp_2.txt
            
  osascript -l JavaScript -e "Application('Emacs').activate()"

-- /code

-- code/
-- bash

cat <<- "EOC" > /private/tmp/emacs_tmp_3.txt
  <<source_color_pallet>>
  EOC
  osascript -l JavaScript /private/tmp/emacs_tmp_3.txt
  sleep 0.2
  osascript -l JavaScript -e "Application('Emacs').activate()"

-- /code

-- code/
-- bash

cat <<- "EOC" > /private/tmp/emacs_tmp.txt
  <<source_arrow_press>>
  EOC
  osascript -l JavaScript /private/tmp/emacs_tmp.txt
  sleep 0.2
  osascript -l JavaScript -e "Application('Emacs').activate()"

-- /code



-- categories
-- Apple/OSA Script 
-- JXA (JavaScript For Automation)

-- metadata
-- date: 2023-10-26 17:23:51
-- id: 2xjmcp8h
-- site: aws
-- type: scratch 
-- status: published