I started learning how to write Cinnamon extensions. Well, I try to ... While I managed to write a first simple desklet, I still didn't find a really good and up to date documentation and introduction.
I have the following questions and would be very glad to get some hints:
What is the best / suggested development workflow?
For now, I do:
- copy the changed files from my project directory to
.local/share/cinnamon/uuid
, - open Melange / Looking Glass,
- search there for the extension and reload it via right click
- switch to the Log tab and check for errors
Compared to vue.js development with automatic hot-reload of changes in the browser, this seems a bit ... well ... time-consuming.
Where do I find an introduction to the available widgets and widget libraries?
I understood that there is Gtk and St and both have JS / GJS / CJS bindings.
The Gnome Dev Docu doesn't mention St
. And I read in another answer here that it seems that shell extensions doesn't use Gtk
, but rather St
instead (and not in addition?).
I didn't find any documentation for CJS
at all, but as far as I understood so far, it seems to be quite similar to GJS
. Seems that the way desklets and applets are defined is different?
But now, I still would enjoy to have a (at least brief) introduction which widgets are available. While in Gtk there seems to be a whole set of different list-like widgets, I didn't find any list widget in St. And it seems that I can't use Gtk widgets as children of St widgets ...? This St documentation lacks any overview of available widgets and classes and what they can be used for.
Documentation about events
I found that there is the St.Entry widget that can be used for single-line text input. I found somewhere that I can bind functions to key press key release events like this:
this.input.connect('key-release-event', (widget, event) => {
const input = widget.get_text();
// ...
return true; // event has been handled
});
I didn't managed to get some information for the event.
When printing with JSON.stringify(event)
It shows an empty object.
This Gtk documentation looks like there should be fields such as keyval
and state
, but these are undefined.
This is really kind of frustrating when it takes ages for every very small step to understand ... so, I would really appreciate any hints and suggestions!
Firstly I should note I have no idea what's been happening in CJS since it was split from GJS. Things have been moving pretty fast in GJS, so you may have to ask for help from the Cinnamon community if CJS hasn't been tracking upstream GJS.
The first place you should start is gjs.guide, which is the actively maintained portal for GJS and GNOME Shell extension documentation. There is also an Architecture page which briefly describes the relation of GNOME Shell extensions to the GNOME platform.
Workflow
There is a tiny snippet about how to test an extension by either restarting GNOME Shell or running a nested Shell, but it will need to be expanded at some point:
But again, I don't if the above will work with Cinnamon/CJS.
Overview of Widgets
Bindings for GJS are generated from introspection files, which are also used to generate the API documentation. In other words, our "GJS" version of the API documentation will only include material parsed from the C source. In the case of libraries like GLib, Gio, Gtk and so on, you can reference the C documentation for any other material and it should still make sense.
In the case of Clutter, I like to think of it as Gtk if the only widget was
GtkWidget
, with all of it's machinery. When it comes toSt
, almost every class is a direct analog of a Gtk widget, such asGtkButton
andStButton
. If you don't know what a class is for, chances are you can just glance at the Gtk documentation and you'll realize "Oh,StIcon
is basically justGtkImage
".Mutter, on the other hand, there is no such high-level tutorials or overviews. It's best just to join Matrix or discourse.gnome.org and ask the community of extension developers and shell developers.
Events
With regard to
Clutter.KeyEvent
, I had actually forgotten how this situation was a little tricky and non-obvious. Put simply: "events" in this context are sort of polymorphic (I believe they're unions in C) which is why the generated API in GJS is a bit confusing. If you seeClutter.Event.get_key_symbol()
and then browse around that page I think it will become clear and you should find all the accessors you need.Here is the list of key symbol constants and the list of key symbol constans as C definitions in the source might be easier for searching.