The thoughts, opinions, happenings, and just plain ramblings of a seemingly boring person.

Experimenting with GNOME Shell Extensions

After using Fedora 17 and 18 as my OS at work for the past few months, I've been getting to know the somewhat controversial GNOME Shell. Although recent googling has found that a lot gripes with GNOME Shell may be addressed in the recently released GNOME 3.8 (which will be included in the upcoming Fedora 19), I thought I might share a few things that I have done to make my desktop environment in GNOME 3.6 a little more usable without having to switch to other environments like Cinammon or Xfce.

Like with Chrome and Firefox as browsers, GNOME and a few other desktop environments have 'extensions' that can extend or add different functionality. Among  the extensions that I use in GNOME 3.6 are WindowOverlay Icons (adds application icons to windows shown on the overlay), Battery remaining time and percentage (adds useful battery information to the panel), and most of all Frippery Bottom Panel (adds a basic taskbar/bottom panel).

The last of which was something that I definitely needed. In my opinion, having to Alt-Tab or go to the overlay to simply switch between windows is just so time-consuming and inefficient; often requiring multiple key presses or mouse gestures/clicks when the same action using a taskbar is usually quicker and easier with one click.

However the extension was missing some functionality that I am used to. The first was the ability to middle-click on a taskbar item to close that window,  which is something that I have used for ages on Windows (provided by the fantastic 7+ Taskbar Tweaker program).

It turns out that the GNOME extensions are essentially just JavaScript and CSS files. I found this strange, as previously I'd never seen JavaScript used for anything outside of a web browser. Anywho, the extension files are located in ~/.local/share/gnome-shell/extensions, and in this case, the extension I'm editing is in the folder.

In the extension.js file I found the function responsible for handling mouse clicks, and modified it to handle a middle-click that closed the current window, as highlighted at the bottom of the function below:

_onButtonPress: function(actor, event) {
    let button = event.get_button();
    if ( this.rightClickMenu.isOpen ) {
    else if ( button == 1 ) {
        if ( this.metaWindow.has_focus() ) {
        else {
    else if ( button == 3 ) {
    // LUCAS added below clause for middle-click to close
    else if ( button == 2) {

The next thing was a tad more difficult. We use IRC pretty heavily at work, and my IRC client (Pidgin), does not do great job of notifications for pings and mentions in GNOME 3. There is a Pidgin plugin that allows you to change the window title text as part of a notification, and I thought a good way of alerting me would be to change the colour of the Pidgin taskbar item when that happens.

Firstly, in stylesheet.css I added a new pseudo-class style (called 'alert') to the .window-list-item-box class which defines the alert as having white text on a bluey background:

.window-list-item-box:alert {
    color: white;
    background: #144C9D;

Secondly, in extension.js I modified the existing WindowListItem _onTitleChanged function to detect the window title change (which for the alert I configured to be '!!' at the beginning of the title), and change the style of the taskbar item accordingly:

_onTitleChanged: function(w) {
    let title = w.title;
    if ( !w.showing_on_its_workspace() ) {
        title = '[' + title + ']';

    // Lucas added below for pidgin alerting on title change
    if (title.substr(0,2)=="!!") {
    else {
    // END Lucas

So now I get much better notifications of IRC pings on the taskbar too, as shown below :D.

Pidgin Notification

There's a few other things that I wouldn't mind for the taskbar (especially drag-and-drop reordering), but given that GNOME 3.8 is probably going to mix everything up again, complex stuff like that might have to wait until I see what it will be like.

Leave a comment