Applications scripting

Applications scripting

  • mdo  DigitalBox
  •   Scripting
  •   January 1, 2025

Today we will review how to do applications scripting under Haiku via the "hey" command.

We will focus on StyledEdit scripting, so that you will be more familiar with scripting at the end of this article.

Hey

If you have already looked at the existing "hey" documentation, it's quite brief:

The aim of hey command is to communicate with an opened application through verbs (get / set / do / ...) by indicating specifier(s).

Let's review in details a few use cases.

StyledEdit

In a Terminal, let's open two instances of StyledEdit :

StyledEdit &
StyledEdit &

Now let's check how hey can interact with StyledEdit by getting the suites :

hey StyledEdit getSuites

The result can be confusing, let's clarify it.

What is important here are the properties which are recognized at the application level : Window, Looper, Name, ... which are visible on the left.

Each property can be accessed in various ways as indicated in the "specifiers" column :

  • DIRECT : you can access the property by the name of this property (like "Name" for an Application)
  • NAME : you can access the property by the name of its instance (like "Untitled 1" for a Window named "Untitled 1")
  • INDEX : you can access the property by the index of its instance (like "0" for the first Window)

Let's demonstrate this.

Getter

hey StyledEdit get Name

This will return the application's name (property is "Name").

Don't be afraid about the "error" line : as the result of it is "0", it's a success:)

hey StyledEdit get Window "Untitled 1"

This second command will return the window named "Untitled 1" ie the first visible window which was opened.

hey StyledEdit get Window 0

The third command will return the window which is at index 0 at the application level. Is it "Untitled 1" ?

Let's verify its title :

hey StyledEdit get Title of Window 0
hey StyledEdit get Title of Window 1
hey StyledEdit get Title of Window 2

No : the window with the first index (0) seems to be a kind of "root" window which is not visible.

And the "Untitled 1" window is corresponding to the second index (1).

Now let's list all the windows :

hey StyledEdit get List of Windows

And count them : hey StyledEdit count Window

There's a total of three windows for StyledEdit which is consistent with the previous results.

Setter

We have demonstrated the getter on properties previously, now let's use the setter.

What about changing the title of a window ?

hey StyledEdit set the Title of Window "Untitled 1" to "Wonderful"

One of the window's title has changed as requested by hey :)

Let's modify now the interface and hide the various views :

hey StyledEdit set Hidden of View [0] of Window "Wonderful" to True
hey StyledEdit set Hidden of View [1] of Window "Wonderful" to True

Oh, the menu bar has been hidden but also the text area, making the edition of text now impossible !

Let's fix that :

hey StyledEdit set Hidden of View [0] of Window "Wonderful" to False
hey StyledEdit set Hidden of View [1] of Window "Wonderful" to False

Ok everything is back to normal :)

Doer

What about applying some actions in the GUI ?

Let's do that :)

hey StyledEdit do MenuItem "New" of Menu "File" of MenuBar of Window "Wonderful"

A new text window has been created.

The action requested by hey is as if the user has clicked on the "File> New" menu item :

What about clicking on the last menu item of the file menu ?

Below "-1" means the last menu item of the menu :

hey StyledEdit do MenuItem -1 of Menu "File" of MenuBar of Window "Wonderful"

Maybe you have noticed : the StyledEdit application has been closed.

It's because the last menu item of the file menu is the "Quit" :

If this kind of menu didn't exist, you can do the same with the below (before you need to open again StyledEdit) :

hey StyledEdit quit

More scripting

What about creating a bash script which is using hey to discover the details proposed by the menu of an application ?

Open Pe editor and do a copy/paste of the below code :

#! /bin/sh
# This script will give us a nice, clean list of menu items.

# Create a new function for this script, to collect the menu item's
# name and display it in a nicer fashion than hey's output.

show_result() 
{

# Store hey's output in the "info" variable.
#

info=$(hey $1 get Label of MenuItem [$2] of $3)

# If hey's exit status (in the $? variable) isn't 0, then
# something bad happened.

if [ $? -ne 0 ] ; then

# Print an error message, then return with an
# exit status of 0.

echo "Error getting label: $info"
return 2
fi

# Note that sed is using a regular expression to strip off
# everything which is not needed

info=$(echo $info | sed -n 's/.*"result" (B_STRING_TYPE) : "\([^"]*\)".*/\1/p')

# $2 below is index of the menuitem
echo $2: $info

# Return 0 as our exit status, meaning "all is well".
return 0
}

##
## main
####

if [ $# -ne 2 ] ; then
echo "inspect_menu <appname> <menu index>"
exit
fi

# The next line creates a variable to be used as "shorthand" later.

# StyledEdit
if [ $1 = "StyledEdit" ]; then
target_menu="Menu $2 of MenuBar of Window 1"
# Pe
elif [ $1 = "Pe" ]; then
target_menu="Menu $2 of MenuBar of Window 2"
# Default
else
target_menu="Menu $2 of MenuBar of Window 0"
fi

# Initialize the index variable at zero. Later, we'll increment it
# by 1 for every pass through the loop, so we can get data on each of
# the menu items sequentially.

index=0

menu=$(hey $1 get Label of $target_menu)
menu=$(echo $menu | sed -n 's/.*"result" (B_STRING_TYPE) : "\([^"]*\)".*/\1/p')

echo "Menu '"$menu"'" 

# Now call the show_result function as long as its exit status
# indicates that all is well.

while show_result $1 $index "$target_menu" ; do
# Move on to the next item.
let index=index+1
done


Save the file under "inspect_menu.sh" and make it executable :

chmod +x ./inspect_menu.sh

The syntax to use this script is as below :

Meaning you provide as the first parameter the name of your opened application to be analyzed, and the second parameter the index of the menu to retrieve (0 being the first one).

Let's try it on StyledEdit.

Open the application and in a Terminal type :

./inspect_menu.sh StyledEdit 0

As you can see it's working as expected :

Let's check with Pe on the third menu :

it's working nicely too :

And what about Genio ?

./inspect_menu.sh Genio 3

It's working fine, isn't it ?

Please note that this script is working fine on native applications most of the time (exception on WebPositive), but for non-native it's another story, as the GUI framework do not use the same standard.

Moving forward

Do you want to learn more about scripting ?

You can check the BeOS Bible scripting online page but also the BEOS scripting in PDF format.

The Haiku official website propose also a great article called Scripting the GUI with hey.

What do you think about the possibilities of scripting under Haiku in 2025 ?

Let's share your comment below :)


Powered by Bludit - Hosted by Planet Hoster
© 2025 Haiku Insider