GNOME Javascript (GJS) is HELL, it was a huge mess to write this extension (and maintain it), I had to dig through dozens of Github repos to find code examples of what I wanted to do because GNOME docs are a cursed maze.
A while ago I found an extension that was called Argos, it makes developing extensions easier by handling all of the mess away from you, and I used it a lot... until I got greedy and wanted more, so I went to their repo planning to contrib some code for new features, but turns out that Argos is unmaintained.
Not wanting to give up on my dreams of a more personalized GNOME setup, I decided to go through hell.
Documentation:
Not available through the GNOME Extensions Website
Here's how to install the extension manually:
This only supports the latest version of GNOME (That's 3.36).
git clone https://github.com/ItsKerolos/plug
cd plug
npm install && npm run build && npm run link_gnome
After that just reload the shell and make sure Plug is enabled in the Extensions app.
Plug automatically loads new plugins, don't reload the shell or do anything else.
cd ~/.config/plug
git clone https://github.com/[user]/[plug-in-name]
- Spotify: Shows you what's currently playing and offers some playback controls.
Install Plug then go to ~/.config/plug
and create a directory for your plugin.
Inside the directory create a file called plugin.json
(required).
property | required | type | description | default |
---|---|---|---|---|
execute | required | string | the command that should return an output that Plug can parse then render, this can be can be anything e.g. sh , node , etc. |
null |
main | optional | string | this file path will get passed to the execute command. e.g. main.sh . |
null |
interval | optional | number (milliseconds) | the time between each execution. | -1 |
alignment | optional | "left" | "right" | "center" | the alignment inside the GNOME panel. | set by GNOME. |
priority | optional | number | the priority inside the GNOME panel. | set by GNOME. |
{
"execute": "sh",
"main": "main.sh",
"alignment": "left",
"priority": 2
}
{
"execute": "xclip -selection clipboard -o",
"interval": 1000
}
~Any plugin that takes longer than 5 seconds to finish an execution gets killed, and disabled permanently unless the user enables it again manually.
~Plug automatically handles (re)loading plugins when their files are created, updated, or deleted.
~An interval of -1 means that the plugin only executes once when it's (re)loaded.
If you need more than to just render a plain label in the panel, you need to output some stuff to Plug, you can do that in whatever manner you like, it depends on your choice of config.execute
.
echo "Hello"
console.log('Hello');
print('Hello')
Now before we list all the widgets available, you need to have an understanding of output formatting, so that Plug can understand it.
The first line of output is always what renders inside the plugin's panel button, this line only has limited number of props available, the following examples showcase all possible props that can be used with it.
echo 'Hello'
echo ' | icon(/~config/plug/[plug-in]/icon.svg)'
echo 'Hello | icon(system-search-symbolic)'
echo "Hello | icon(https://fakecdn.io/icon.png) | press(pacman -Su)"
As you can gather:
~the first prop is always the label.
~props must be separated with |
but this can be escaped with a backslash.
All other lines after the first one are rendered inside the menu that appears when the panel button is pressed.
echo "Hello | image(/~config/plug/[plug-in]/white s pace.png)"
echo " | image({ url(/~config/plug/[plug-in]/image.png), width(32), height(48) })"
echo "Hello | vertical | image({ url(system-search-symbolic), width(32) })"
echo "Hello | icon(system-search-symbolic) | press(google-chrome-stable)"
echo "Hello | clipboard(Hello World) | notify(Copied 'Hello World' to clipboard.)"
~Some props like image()
have (optional) parameters like width and height
To use them, surround them with {}
and separate them with ,
and this also this can be escaped with a backslash.
echo " | "
~All the props have examples on this page but if something is giving you trouble, look at some other plugins code.
property | type | type examples | description | parameters |
---|---|---|---|---|
vertical | boolean | none | positions widget vertically instead of horizontally.. | none |
icon | gicon | path | link | name-thing-symbolic /path/name.svg https://website.com/thing.png |
renders an image in a small square. | none |
image | gicon | path | link | name-thing-symbolic /path/name.png https://website.net/thing.svg |
render an image in full (or specified) size. | width height |
press | command | pacman -Su spotify |
emits when the widget is pressed, executes a command. | none |
notify | text | Manjaro is better than Ubuntu. | emits when the widget is pressed, sends a notification. | title message |
clipboard | text | You copied this text because you clicked a button. | emits when the widget is pressed, copies text to the clipboard. | none |
The values in plugin.json are passed to the execution process as environment variables.
{
"greetings": true,
"execute": "sh",
"main": "main.sh"
}
if [[ "$PL_CONFIG_GREETINGS" == true ]]; then
TITLE="Hello"
else
TITLE=""
fi
Of course, you can do the same in any other language that supports environment variables.