Review: GNOME 3 Application Development: Beginner’s Guide

GNOME 3 Application DevelopmentThe folk at Packt Publishing sent me an e-copy of GNOME 3 Application Development Beginners Guide a month or so ago.

I’ve been putting off this review because I don’t think this is an very good book and it’s hard to write bad reviews.

First off, the book’s Javascript sections use Seed. I think this is an unconventional choice given that the shell and most of GNOME uses gjs. It had been my experience with the Javascript bindings that gjs was significantly more mature, a view which is confirmed by the fact that Seed has had very little development in the last 18 months.

The book does not seem to use GTK+ best practice, like using Gtk.Grid or Gtk.Application and not using c_new constructor. It is full of things like use of Vala’s [CCode] pragma, but I don’t see why. I felt important and powerful facilities in GLib like properties were not properly explained, especially property binding. There was also a lack of understanding, for example, referring to Timeout objects, which don’t exist (the structure you’re looking for is a Source).

I do like that it uses Anjuta. It’s a shame that it requires unexplained hacks to get things building.

The Clutter section was very poor. Comparing Clutter to GTK+ is simply not reasonable. Clutter is a scene graph API, which doesn’t really have a comparison in the GTK+ stack, which goes from drawing layer to widget layer with no intermediate layer. I immediately noticed the Clutter examples hardcoded layout instead of using a layout manager.

The multimedia section had the user installing non-free codecs. Then it uses alsasink and not auto*sink. It spends a lot of time setting up GStreamer pipelines, rather than using decodebin and playbin, maybe this improves understanding, but I think it mostly will lead to the creation of very rigid apps.

I stopped reading and started skimming at this point. I did again notice weird things like creating JSON using append methods and not the handy JSON-GLib. The examples of HTML5 applications with WebKit perhaps would explain why Seed, except the wrapper is written in Vala, so there’s no problem of conflicting JS engines (I think it works fine anyway, right?). Similarly the application accesses applications by looking in /usr/share/applications rather than libgnome-menus. Again, this will lead to very rigid apps that don’t work very well and doesn’t teach beginners the best practice for GNOME development.

There’s stuff that’s just weird, the system requirements are significantly more powerful than my last computer, on which I was doing GNOME development just fine. There is discussion of how to switch to GNOME Shell, as if it’s required, whereas you can develop GNOME apps in Unity and XFCE just fine.

The typesetting of the book is poor. The source code is weirdly indented and I feel like it lacked readability (there’s great syntax highlighting available for printed text). There are grammatical mistakes that really should have been picked up in editing. The screenshots are blurry in the PDF (looks like some kind of busted bilinear filtering?). Also I can see the resize indicator on the mouse. Generally these serve to make the book look unprofessional.

Finally I don’t think the book really leads the new developer into the community as the best source to get help, which they will undoubtedly need. Of course, the community has already produced some excellent tutorials, which I think new developers would be much better off with.

All up I’m giving it 1 star.

GNOME 3 Application Development: Beginner’s Guide: ★☆☆☆☆

Reviewing GNOME3 App Development Beginners Guide

GNOME 3 Application DevelopmentThe folk at Packt Publishing sent me an e-copy of GNOME 3 Application Development Beginners Guide the other day. Since I find myself with a couple of weeks off (more on that another time) I’m going to be reading it and writing a review.

The book weighs in at 366 pages and purports to cover GLib, GTK+, GStreamer, E-D-S, WebKit, desktop D-Bus APIs, i18n and unit testing in both Javascript (via Seed) and Vala.

Hopefully I will get it read in the next couple of weeks and get my thoughts jotted down. I am not getting anything except an e-copy of the book for my trouble so you can trust me to be brutally honest 😛

now everyone should use their hackergotchi as their avatar

I was doing the work to close #645921, so we can finally remove the legacy theme code from Empathy. This required rewriting the legacy themes as Adium themes, which once I came to understand how Adium themes work, was really not that difficult.

Then I started thinking what else could I do… so I decided to do this:

Planet GNOME Empathy Theme

It could stand for a little bit of tweaking, but that should be easy for someone to do. I realised what’s especially nice about using WebKit is that we’ve opened ourselves up to the whole world of HTML5 and CSS3 in our themes. Chat themes animated by CSS transitions anyone?

We’re still looking for someone to make a good default Empathy theme for GNOME 3 (#645920). I’m hoping that having ported the default themes to HTML should make it easier for someone to use one of them as a launching point.

For reference, Adium theme documentation:

workaround for gnome-keyring ssh auth bug in Fedora 17

So if you upgraded to Fedora 17 the other day you have probably been hit by #662528, which means gnome-keyring’s SSH agent isn’t exported into the environment, which means no SSH agent, and sadness.

Until the fix is out of updates-pending, you can work around this by adding:

export $(gnome-keyring-daemon -s)

To your .bashrc or similar.

Getting the GLib gdb macros with your own installed GLib

So there are these really cool debugging macros for GLib/GObject that do things like let you iterate GLists and pretty print GObjects and GHashTables and stuff that should nowadays be available in most distros.

Unfortunately when you build your own GLib to develop against, it all breaks.

It turns out, gdb locates when to load these things by looking in $prefix/share/gdb/auto-load/ and matching the sonames, so if you have libraries with a different soname (cause they’re new versions), or in a different prefix, it just doesn’t work.

Damien Lespiau has a workaround for this that adds a command to load them from a path you can control with sys.path; which works. I looked a little for a generic solution to feed the autoloader from my GLib build prefix, but I haven’t found one yet.

Having now looked at this. I’m also excited about possibilities for combining this with GObject-Introspection to potentially do some useful things. I don’t know what the caveats are here yet, what’s safe to call and what’s not.

Gtk.ListStores and Clutter.ListModels in Javascript/gjs

It’s surprisingly hard to find this, and the generated documentation is actually misleaingly wrong ((The n_columns parameter is a lie, and will be inferred by gjs from the array size.)), so here’s how to create ListStores and ListModels in Javascript with gjs.

let store = new Gtk.ListStore();
store.set_column_types([GObject.TYPE_STRING, GObject.TYPE_INT]);
store.insert_with_valuesv(-1, [ 0, 1 ], [ "test", 42 ]);
let model = Clutter.ListModel.newv(
    [ GObject.TYPE_STRING, GObject.TYPE_STRING ],
    [ 'Column Name 1', 'Column Name 2' ]);
model.appendv([ 0, 1 ], [ "String 1", "String 2" ]);

The first array is the column numbers you wish to assign, the second array is the values for those columns.

Fundamental GTypes are available as GObject.TYPE_*. You can specify non-basic types using the class, e.g. Clutter.Text.

There are other variations possible, but this should provide the basics required to figure out the rest. ((You’re welcome.))

libpeas

Seriously impressed with libpeas.

I think about my previous work adding plugins to things (some of them involved Bonobo) and I think how much easier it would have been if this technology was around back then.

It was very simple to put together some plugin GObject interfaces, annotate and add introspection for them, and then write some Javascript plugins that implement the interface. It looks like C on the C side, and Javascript on the Javascript side. No weird IDLs or custom file formats or generated bindings, just regular gobject-introspection.

Here’s an example of what I mean (needs to be run from the src/ dir, cause I was lazy about paths).

more on DPI

Daniel Stone recently wrote this amusing summary of why saying OMG I ABSOLUTELY MUST HAVE MY DPI CORRECT is rarely, if ever, correct.

Since most people who say this aren’t considering the two monitor case, I thought I’d provide a illustrative screenshot.

GTK+ resolution independence

This is an old screenshot of the resolution-independence branch of GTK+ running the demo program on two different monitors. It shows that both apps the physical same size, with the same physical size fonts (ignore the size of the title bars, those are provided by Metacity, which is using the system GTK+).

However, the font rendering looks different. This is because of the amount of anti-aliasing that goes into making fonts look smooth when you have less pixels to play with. Notice how in the title bars the font looks the same, even though they’re different sizes. That’s because they’re using the same number of pixels, and thus the same amount of anti-aliasing.

I couldn’t find a screenshot of what happens when you have a window that crosses between two monitors. [Perhaps it’s a nonsense case, but it can come up.] At this point everything just looks like crap. We have to choose the scaling of one monitor or the other. It will look wrong on one monitor or the other. It will be a different size to everything else on that monitor. [Before you suggest it; we can’t divide the window and calculate the scaling separately for each monitor across single widgets].

The thing is, for day to day computing, you don’t really care about the DPI, you care about having readable, attractive fonts and visible, clickable icons. So Federico is right. For some specific applications, you do care about DPI, but those applications can already use the XRandR data to take care of themselves [I have written visualisation apps which do this, presenting a scale on the screen of millimetres on screen to metres in the real world. ((And in using these apps, I’ve found plenty of monitors that return nonsense DPIs, forcing me to hardcode the monitor size in X11.))]

This said, I’m not sure why the only font size settings now in GNOME is a quantised Small, Normal, Large, Larger setting in the Universal Access settings pane. gnome-tweak-tool includes a scaling slider. The slider is hard to use though, especially when your text reflows while using it. Federico’s idea seems better.

As DPI continues to increase, it’s probably worth also applying scaling factors to our scalable window graphics, lest icons and the like become increasingly harder to hit. At this point we will likely need to adopt a resolution independent GTK+. However, again what will matter will be readable fonts and visible icons. Using the actual monitor DPIs will likely not be that important.

mistakes with g_value_set_boxed()

In today’s PSA, mistakes with g_value_set_boxed(). A mistake that’s been made several times by yours truly, and only realised today thanks to Xavier.

At some point in the GLib 2.22 cycle, types such as GArray, GPtrArray, GByteArray and GHashTable ((You can discover what g_boxed_copy() and g_boxed_free() will do for a type by looking for its G_DEFINE_BOXED_TYPE in GLib, which is probably in gobject/gboxed.c.)) gained ref() and unref() methods, which allowed things like g_boxed_copy() and g_boxed_free() to be a stack faster for those types. This was mid-2008.

Danni, who didn’t get the memo, had been occasionally writing bits of code like this:

GArray *array = g_array_new (...);

g_value_set_boxed (value, array);
g_array_free (array, TRUE);

Which, if you read the code, will keep the wrapper alive, so your code won’t crash, but will release all the data the array contains. Similarly for g_ptr_array_free() etc. It nicely zeros out the length of the array, so when you come to read it in your GValue, it looks empty.

The correct thing to do (of course) is unref your data, which will then free the memory and the wrapper when the refcount reaches zero.

GArray *array = g_array_new (...);

g_value_set_boxed (value, array);
g_array_unref (array);

Update: As pointed out in this simple example, you can replace this with the following pattern:

GArray *array = g_array_new (...);

g_value_take_boxed (value, array);

Which passes your ownership to the GValue. Where this falls down is for more complex values built for dbus-glib, where the ownership isn’t clear-cut, and so you need to free the components separately afterwards.

gnome-terminal menubar issue in Ubuntu 11.10

I upgraded to Ubuntu 11.10 today, which seems to have done a nice enough job of integrating GNOME 3.2, but I was instantly driven mad by all of my GNOME Terminals showing their menubars, in what appeared to be direct contravention of what the setting appeared to be (or even what GTK+ thought the visibility status of the widget was!). This was GNOME bug #658760.

After a stack of debugging and one lucky break, I discovered the culprit was infact Ubuntu’s appmenu module.

[The lucky break was that while setting up a bisect, I realised I could replicate the bug only in the GTK+ 3 build of the terminal, which was printing out warnings about appmenu, something I’d already uninstalled for GTK+ 2.]

Anyway, you can fix the problem by removing appmenu-gtk3 (personally I’d remove appmenu-*) or unsetting the environment variable UBUNTU_MENUPROXY which is set in /etc/Xsession.d/80appmenu or something. The Ubuntu bug is #879190.

~

Random side note: can someone update my hackergotchi please?

Creative Commons Attribution-ShareAlike 2.5 Australia
This work by Danielle Madeley is licensed under a Creative Commons Attribution-ShareAlike 2.5 Australia.