NEWS

Writing extensions for the new Gnome Shell

By César García Tapia | May 16, 2011

One of the features that includes the new Gnome Shell is the ability to create  extensions. Those are plugins to add new functionalities to the Shell, or alter the default ones. It’s a natural evolution of the former panel applets, but far more powerful, since you can create almost anything you can imagine, not only these little apps for the panel.

The first thing you must know is that everything related to Shell is Javascript and CSS. Yeah, Javascript. Everybody knows Javascript, so it’s a great starting point. All we have to do to create a Shell extension is write down a JS file, create a CSS stylesheet, and it’s done. Easy, isn’t it?

Gnome Shell is a big thing, so explaining all you can do with the extensions isn’t the point of this post. For the moment, we’ll just play with the upper panel, but it’s possible to expand the Shell in many many ways. For example, you can add new sections in the Activities menu (by default only Windows and Applications are shown), add new search engines (besides the Google and Wikipedia ones), add new items in the user menu (A Shutdown menu entry, and not only the Suspend one!), and tons of other stuff. Just think about what would be great to have in the Shell, and go for it.

HOW TO CREATE AN EXTENSION?

Although it’s not mandatory to use it (you can write your extension completely from scratch), Gnome 3 includes a bash comand to help us to create new extensions: gnome-shell-extension-tool. We’ll use it to create the draft of our extension:

$ gnome-shell-extension-tool --create-extension

The command will ask us for some basic metadata:

  • Name: A name for the extension.
  • Description: A more detailed explanation for the extension functionality.
  • Uuid: An unique identifier for the extension. It must be in a email address format, say foo@bar.com. By example, if your extension is named WorldDomination, and you work in DevilCorp Inc, a good Uuid should be world_domination@extensions.devilcorp.com.

Once you’ve filled that steps, the command will create some files in this path:

$HOME/.local/share/gnome-shell/extensions/world_domination@extensions.devilcorp.com/

Now we can edit that files to do what we want.

HOW TO LOAD THE EXTENSION?

When a user starts a Gnome session, the Shell will load all the extensions located in the following places:

  • ~/.local/share/gnome-shell/extensions
  • /usr/share/gnome-shell/extensions
  • /usr/local/share/gnome-shell/extensions

But if we are developing an extension, it’s boring and time-wasting to log out and in every time we want to reload the shell. Instead of that, we can reload just the Shell, in a very easy way: Enter Alt+F2 and write “r” (reload).

OK, SHOW ME THE CODE!

If we’ve created the extension with gnome-shell-extension-tool, we can edit the extension.js file it has created:

$HOME/.local/share/gnome-shell/extensions/world.domination@extensions.devilcorp.com/extension.js

It contains a very simple extension that shows a “Hello world” message when clicking in the top bar:

// Sample extension code, makes clicking on the panel show a message

const St = imports.gi.St;
const Mainloop = imports.mainloop;

const Main = imports.ui.main;

function _showHello() {
    let text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" });
    let monitor = global.get_primary_monitor();
    global.stage.add_actor(text);
    text.set_position(Math.floor (monitor.width / 2 - text.width / 2), Math.floor(monitor.height / 2 - text.height / 2));
    Mainloop.timeout_add(3000, function () { text.destroy(); });
}

// Put your extension initialization code here
function main() {
    Main.panel.actor.reactive = true;
    Main.panel.actor.connect('button-release-event', _showHello);
}

When we reload the Shell and click the panel, we can see this:

Our first gnome shell extension

When Gnome Shell loads the extension, it searches the main() function. In the above code, we make the panel to be responsive to events (Main.panel.actor.reactive = true;) and connect the panel’s event ‘button-release-event‘ to execute the funcion _showHello() when the user clicks the panel.

Let’s see step by step what _showHello does:

let text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" });

Here we create a label, with the text “Hello, world!”, and set it to use the CSS class ‘helloworld-label’. That class is defined in the ‘stylesheet.css’ file, and we can modify it if we want.

let monitor = global.get_primary_monitor();
global.stage.add_actor(text);
text.set_position(Math.floor (monitor.width / 2 - text.width / 2), Math.floor(monitor.height / 2 - text.height / 2));

Now we set the label position in the center of the main screen (we specify the main screen because we can have two or more monitors in our computer).

Mainloop.timeout_add(3000, function () { text.destroy(); });

Three seconds after the label is shown, we destroy it, so it will dissapear.

HOW CAN WE ADD ELEMENTS TO THE PANEL?

Let’s modify the extension to add a button to the panel. When the user clicks the button, the “Hello World” message will be shown.

const St = imports.gi.St;
const Mainloop = imports.mainloop;
const Lang = imports.lang;
const Main = imports.ui.main;

function PanelButton() {
    this._init();
}

PanelButton.prototype = {
    _init: function() {
        this.actor = new St.Button();
        this._label = new St.Label({ text: "HelloWorld Button" });
        this.actor.set_child(this._label);
        Main.panel._centerBox.add(this.actor, { y_fill: true });

        this.actor.connect('clicked', Lang.bind(this, _showHello));
    },

    _onDestroy: function() {}
};

function _showHello() {
    let text = new St.Label({ style_class: 'helloworld-label', text: "Hello, world!" });
    let monitor = global.get_primary_monitor();
    global.stage.add_actor(text);
    text.set_position(Math.floor (monitor.width / 2 - text.width / 2), Math.floor(monitor.height / 2 - text.height / 2));
    Mainloop.timeout_add(3000, function () { text.destroy(); });
}

// Put your extension initialization code here
function main() {
    let _panelButton = new PanelButton();
}

The button will be placed in the center of the panel, at the right side of the Calendar button. This is what will be shown when we load the extension and click the new button:

Adding a button to the extension

The _showHello() function remains the same. We’ve only changed the code to execute that function when we click on the button, instead of the panel.

HOW CAN I LEARN MORE?

It’s a really good question. Up to now, Gnome Shell has very few official documentation. But, as usual, you always can read some code, and search the Internet. In the Gnome’s GIT you can find a module called gnome-shell-extensions. These are some functional extensions, where you can learn how things work. It’s a good starting point. Read the README to get a description on what each extension does. But this lack of documentation isn’t going to be forever. I’m sure that soon there will be good documentation, as in every part of the Gnome desktop. Be aware of news in developer.gnome.org

The posibilities with Gnome Shell extensions are huge. Hurry up and create some of them!

Posted in Gnome | Tagged , , | Leave a comment

Primeras impresiones de Gnome 3.0

By César García Tapia | April 13, 2011

La salida de Gnome 3.0 ha sido esperada con impaciencia durante tres años por todos los que usamos software libre en nuestros entornos personales y profesionales. Y por fin ya está aquí. Ha supuesto un rediseño de prácticamente toda la plataforma, desde la renovación de las librerías de desarrollo hasta el cambio radical del aspecto del escritorio. Llevo usándolo unos días, y el cambio en la experiencia de usuario es realmente enorme. Me gustaría hacer aquí algunos comentarios con mis primeras impresiones.

Gnome 3 logo

Colega, ¿dónde están mis applets?

La primera sensación que tuve, tras unos cuantos minutos explorando el nuevo escritorio, es que en Gnome se han dado cuenta de que su misión es pasar desapercibido para el usuario mientras éste no lo necesite. No hay apenas barras, salvo una pequeña banda negra con la fecha y hora y poco más, los applets han desaparecido, la zona de notificaciones es mucho menos intrusiva que la de Gnome2… El escritorio llevado a su mínima expresión.

En general, estoy de acuerdo con la decisión de que así sea. Por supuesto, echo de menos algunos applets que solía usar, como le pasará a todo el mundo que lleve tiempo usando Gnome. Sin embargo, el sistema de extensiones de Gnome Shell permite crear nuevas utilidades para el escritorio. El sistema de desarrollo para estas extensiones es javascript y CSS, ambos viejos conocidos para prácticamente cualquier programador, por lo que espero que sea cuestión de tiempo que empecemos a ver sorprendentes nuevos usos del Shell.

Gestión de ventanas

El nuevo sistema para visualizar las ventanas que tenemos abiertas también es un cambio importante respecto a versiones anteriores. Como ya no existe la lista de ventanas en la barra de tareas, cuando estamos trabajando con una aplicación no podemos saber cuántas ventanas tenemos abiertas. Para ello tenemos que ir a la “Vista de Actividades”, donde tenemos algo parecido al Exposé de MacOSX, aunque más evolucionado. Quizá sea más espectacular que útil, pero si no nos convence seguimos tenemos el clásico Alt+Tab, que sigue funcionando igual que siempre.

expose screenshot

La nueva barra de título de las ventanas, sin los botones de minimizar/maximizar también ha sido una decisión polémica. Yo personalmente estoy de acuerdo con ella. Siempre he utilizado la minimización con una única finalidad: acceder al escritorio. Con Gnome3 ya no hay escritorio al que acceder, por lo que realmente, en mi caso al menos, dejan de tener utilidad (Aunque quizá para el futuro sí que convenga tener una forma de acceder al escritorio de manera rápida . Es probable que vayan apareciendo extensiones que le vuelvan a dar una utilidad).

Nueva barra de título

Aplicaciones

Y llegamos al sitio donde, lamentable, no estoy del todo de acuerdo con las decisiones tomadas en Gnome3: La Vista de Actividades. Supongo que la idea en esta vista es tener un único sitio al que acceder para hacer cualquier cosa. El problema es que, normalmente, cuando se tiene mucha funcionalidad acumulada en un mismo sitio suele ser más complicado encontrar lo que andas buscando.

El ejemplo más obvio es el menú de aplicaciones. Para ver la lista de aplicaciones ahora hay que hacer dos clicks (Actividades -> Aplicaciones). Y lo que obtenemos es un listado completo de todas las aplicaciones que tenemos instaladas. Si queremos ver, por ejemplo, los juegos, necesitaremos otro click adicional. Poco práctico para quien no tiene perfectamente claro qué tiene instalado. Además, si quieres lanzar más de una aplicación a la vez (algo bastante habitual al iniciar sesión), tendrás que acceder varias veces seguidas a la Vista de Actividades. Es un poco incómodo si lo tienes que hacer todos los días al empezar tu jornada.

Otro punto en el que creo que se han pasado de simplificación es en la Configuración del Sistema. Exceptuando el fondo de pantalla, no se puede personalizar el escritorio en ningún aspecto: Ni cambiar el tema de GTK, ni cambiar los tipos de fuentes, ni elegir el salvapantallas… ¿Será algo permanente, o simplemente una omisión temporal para poder cumplir con los plazos de publicación?

¡Viva Gnome!

Realmente, me ha costado trabajo dar con las tres o cuatro cosas que no me han gustado de Gnome3. El trabajo realizado por las cientos de personas implicadas ha sido prácticamente impecable. En general, la nota que le doy sería un sobresaliente bajo, pero estoy absolutamente convencido de que será un sobresaliente completo en muy poco tiempo.

Me queda explorar las novedades de Gnome3 para los desarrolladores: la nueva introspección de GObject, las novedades de GTK+ 3.0, etcétera. Pero lo haré en otro post más adelante.

Posted in Gnome | Tagged , , | Leave a comment