Saturday, 19 Dec 2009
Lovely Inconsolata
Federico writes that he’s recently discovered Raph Levien’s Inconsolata font and really liking it.
I likewise discovered Inconsolata not too long ago (it was packaged in Gentoo and I was really pleased to discover it also available in Debian), and have been using it as the constant-width font in Quill and Parchment for program listings in technical writing.

We all tend to get obsessive about things we like, and so of course I tried it as a terminal console font. Interestingly, after a brief consideration, I decided not to use it for terminals and gedit and such. Deja Vu Sans Mono is still the king for that, especially if you’re using Deja Vu Sans and Deja Vu Serif for the rest of your UI; it means that the visual consistency across your desktop is really awesome.

Inconsolata doesn’t have anything even remotely close to the kind of Unicode coverage you need in your full-time constant-width font, and when fontconfig does a fallback it looks awful because Inconsolata’s metrics are so different from others. That’s all ok; Inconsolata is meant for program listings, and looks incredible on paper.
Anyway, Federico noted that bold didn’t work when specified as a FontDescription, it doesn’t come up bold me either when I tried to do so via a bold PangoAttribute. But if you use Wouter’s Specimen, it shows up fine (on an Ubuntu box, anyway):

So there’s a bug in our stack somewhere.
AfC
Update
Or not. I just reread the JavaDoc for the FontDescription constructor, and lo and behold relearned what I wrote there in the first place. To get bold Inconsolata you just need to use a ',' in the right place:
desc = new FontDescription("Inconsolata, Bold 8.0");
...
and my Cairo drawing code on screen in a XlibSurface shows bold. Great.
But nothing is ever simple. I ran the same drawing code out through to a PdfSurface, and no bold. What the hell? There’s a bug in our stack somewhere. {sigh}
In my original post, I misattributed Specimen… it’s written by our very excellent Wouter Bolsterlee, uws on IRC. Sorry!
Friday, 11 Dec 2009
Get your icons back
We recently upgraded a number of systems, and after a few days the (previously happy GNOME users) started to notice the dialog buttons were all lacking their icons. How did that break? At first I assumed it was a bug in Canonical’s then pending Linux release, “Karmic”. But the problem didn’t go away, and suddenly I noticed a fair bit of email and bug traffic about the issue.
It turns out that someone removed the icons on purpose!
It didn’t attract that much attention at the time, but this setting was changed by the small group who maintain GNOME Control Center. They claimed that text-only interfaces were better. Hm. That doesn’t seem right, but interesting choice on their part. Fine. So you start hunting around in System -> Preferences to find the place where you can return your GNOME desktop to normal.
There isn’t one.
The usability of icons
In the GNOME community, we’ve gone to immense effort over the years to get people to use the proper stock GTK icons in menus and buttons so that the user experience is consistent across applications. They’re a significant cue that aids navigation. Meanwhile non-GNOME applications poorly ported from other platforms often violate this consistency (Eclipse {cough}). So suddenly lacking icons the entire desktop looked ghetto.
The whole debate about what the user experience should be was an interesting one, but it seems a user experience change of this magnitude qualifies as just the sort of thing we don’t do to the huge communities of people using our Desktop during a stable release series. We have GTK 3.0 and “GNOME 3.0” coming up, and surely those would have been the appropriate contexts to propose such change, and the right place to trial landing it.
The part that really puzzles me, though, is that after the people who made this change were (politely) asked if they could point to the usability research that makes them think that text only menus are better, they (politely) replied with reference to a respected source in HMI design, Jared Spool. Reading that page it indeed says that text only is better than icon only. But right before that, however, he indicates that the combination of icons-and-text is more usable than text-only, with the further emphasis being that consistent positioning (ordering in menus) of those illustrative aides being what really what matters. Which seems to make it strange that text-only was just rammed down users’ throats.
Find out what’s broken and fix it
That they changed something is NOT the issue; at the end of the day it’s the people who do the work and write the software who set the agenda. But something this widespread seems like it ought to have been discussed on the usability and accessibility lists. And that’s the problem; there’s no mechanism requiring that.
It’s not the GNOME Control Center hacker’s fault that this became such a sore point for the rest of us; they were in a position to change something they wanted to change and so they did so. That’s just another day in Open Source land. But in GNOME there’s nothing that enforces the GNOME Human Interface Guidelnes. If a change like this had been proposed as a change to the HIG and if following the HIG was mandatory then clearly people would have had a good focused discussion about user experience, we could have come to a consensus (or “Usability Team” could have made a decision), the HIG documents would have been patched as a part of that, and then we could all get with the program.
The GNOME “Release Team” puts new module proposals through hell to be accepted as a part of GNOME, with endless discussions about what the user experience will be. Libraries underneath the desktop work incredibly hard to maintain API and ABI compatibility across releases. We try to remember that corporate IT departments just want gentle improvement between their upgrade decisions, rather than having to deal with a wrecking ball every six months. So we all know the importance of not screwing the user around.
But unless we find a way to apply the same rigour to maintaining UI standards like we do to managing the internal technical aspects of our platform, it seems we’re doomed to keep breaking the consistency of our users’ experience (and more to the point, jerking the chain of all the people who work hard to install and support the systems that our users run). How to do that while still enabling people to innovate is the hard part, but surely requiring people to follow the HIG and making that document the heart of user experience debate would be a step in the right direction.
Meanwhile, lets fix your desktop:
Workaround: users
The Control Center hackers removed the “Interface” tab from gnome-appearance-properties which is a shame since it would have been a lovely place for the user to say whether or not they wish icons in their menus and buttons.
It was pointed out that this is all still controllable by the user… by changing GConf settings. I think most of us would agree that is the very definition of what normal users aren’t expected to be doing.
The GConf keys are:
/desktop/gnome/interface/buttons_have_icons
and
/desktop/gnome/interface/menus_have_icons
So to fix your desktop to be consistent with previous GNOME releases, you need to run:
$ gconftool-2 --type bool --set /desktop/gnome/interface/buttons_have_icons true $ gconftool-2 --type bool --set /desktop/gnome/interface/menus_have_icons true
You’ll definitely need to repair your system like this if you’re working in applications such as Inkscape that have huge numbers of items in their menus; they become really difficult to tell apart if you don’t have the pictorial aides to help you identify the action you’re looking for.
Workaround: code
It turns out GtkImageMenuItem has a new property "always-show-image" for really important icons, ie where “the menu item would be useless or hard to use without it”. The idea is that application programmers using GTK manually need to call this for all the menu items where the icons is really important and you actually want the icon shown in the menu item (Given that you have to go some trouble to construct a GtkImageMenuItem rather than just a normal GtkMenuItem, I would have thought that that emphasis would have been a given. Alas).
I just added a setter to java-gnome:
quit = new ImageMenuItem(Stock.QUIT);
quit.setAlwaysShowImage(true);
There are also GtkSettings "gtk-menu-images" and "gtk-button-images" which can be used to set the property globally in an application programatically or via .gtkrc:
settings.setMenuImages(true);
settings.setButtonImages(true);
Judging by the howls of protest, not too many people had noticed the importance of these properties, and so no one was setting it in their code. Assuming that the new default is likely to stand in the GNOME >= 2.28 era, then indeed we’ll all have to be doing this a lot.
Setting defaults
Thinking about this from the perspective of a bindings hacker and sometimes application developer, it all makes me realize the importance of exposing setters for properties, and calling setters even when the value you are setting is the default. It’s tempting to think “oh, I don’t need to call that method, it’s set by default”, but as episodes like this demonstrate, relying on defaults isn’t very reliable.
AfC
Saturday, 07 Mar 2009
3 mobile broadband on Linux
I had to get a mobile broadband gizmo this week. It’s something I’ve been avoiding (not having internet access while sitting at a cafe by the beach is a feature, not a bug), but I need it for a current client. After advice from one of my colleagues that “3” (one of the carriers here and the first that did 3G digital phones in Australia) was reliable and, more importantly, that their device worked with Linux, I went and picked one up along with a prepay SIM.
3’s offering has two devices at the same price right now; the Huawei E160G and the ZTE MF627. I thought my friend had the latter and so bought that one. Big mistake.
| E160G Bit older works great |
MF627 Brand new doesn’t work |
![]() |
![]() |
Do not get the ZTE MF627 device if running Linux. Stay away from it. Even after trying the usb_modeswitch hassles, it still does not present as the device as a GSM modem like it is supposed to. Tried it on two separate laptops; one running Gentoo, the other with Ubuntu’s “J” version on it. Spent the better part of a day researching and debugging the issue, but no joy on either. One person in London claims to have a similar device working, but comparing their lsusb and dmesg output, I’m not convinced the electronics in the one available here were the same; after doing a mode switch the miniSD adapter presents, but not the modem. Anyway, sure, maybe someday someone will figure out how to make it work here, but that’s not right now.
Even worse, people writing in places like Whirlpool cite chronic quality problems with ZTE devices. Clearly this is something to avoid.
I took the thing back to the store the next day and finally managed to get a refund which I promptly used to buy their other device (why they couldn’t just do an exchange was as puzzling to the poor guy in the store as it was to me. Whatever; they kept him on the phone for almost an hour while the corporate drones he had to call for permission made up their minds that it was ok to give me my money back).
So home I went with a Huawei E160G (which is what Peter had) and it worked perfectly, right out of the box, literally. Plugged it in, device properly recognized by USB subsystem and, after adding a “mobile broadband” connection with NetworkManager 0.7, it immediately started working. Pretty amazing.
You need to have the PPP stack built into your kernel and pppd installed (once upon a time we all had that, but most of us haven’t needed to do point-to-point over a dialup modem for years, so if you’re running a modern system with a custom Linux kernel you might not have it). The relevant kernel modules are “ppp_async“, “usbserial“, and “option“.
So a big hooray to the NetworkManager team and all the people working on the drivers that made this magic work. That NetworkManager seamlessly handles all the PPP configuration and dialing is brilliant.
Neat connection active icon.
And as for the lovely staff in the store, don’t let them tell you that their service doesn’t work on Linux — but do get a device that does.
AfC
Tuesday, 03 Feb 2009
Miraculous
While at linux.conf.au a few weeks ago, my laptop decided to blow. It had been twitchy with suspend and resume for about a day, and then Tuesday, not 48 hours until I was scheduled to give the GTK & GNOME tutorial, the thing quite petulantly decided to stop booting. No POST. Nothing. Zap.
Eeek!
Now, laptops breaking are nothing special, and I do keep fairly regular backups. So I wasn’t that concerned about data loss. But in so far as the live-action style tutorials I give are less about formal presentation slides (though I do have lots of those as backdrop) and instead more “everyone gather around and watch Andrew play in his happy place”, suddenly losing my development meant that actually coding live in front of people was looking to be a bit of a problem.
My current laptop is from ASUS, and I’ve been very happy with it. That it fried, ok, fine whatever. But as we were now in Hobart, Tasmania I had a real problem. I needed a mainboard replacement. Fast. ASUS has service centres in Perth, Brisbane, Sydney, and Melbourne. But not Hobart.
Several people offered to lend me a laptop “for the presentation” which was lovely of them, but given that it wasn’t just me playing a slide deck but rather me needing my full development stack on board such a machine — and more to the point, me needing my system so I could get back to real work during and after the conference — my option space was very limited. Indeed, it took me all of about 3 seconds to realize that I was going to be on a flight (to Melbourne, probably) in about 90 minutes. Sure I could have couriered it and had it back in a “few days” but I patently did not have that kind of time.
Steve to the rescue
I was in the process of booking my flight out when Steve Walsh suggested that he might have a system I could use. At first it was borrowing one of the desktop machines they had around (yup, would have worked), but then he realized he might be able to lend me “the conference laptop”, which was a computer that Hewlett-Packard had donated to linux.conf.au a year or so ago. Josh wasn’t using it anymore, and Ben agreed I could use it. You guys are awesome.
As I was thinking about what I’d have to do to bootstrap and restore off of my closest available backup (on an SD card, but that’s a story for another day), I saw one of these lying on the table

and we suddenly had a very bright idea. Why not pop the hard drive out of my laptop and put it in that thing?
I had already considered putting my hard drive into the new laptop, but only for a brief moment. Even assuming it fit, I happen to have a very tightly tuned kernel and I knew was unlikely to have enough drivers to get booted on foreign hardware. Besides, the Linux installation on the new laptop was already running great.
But why not try putting my drive into Steve’s external USB enclosure? Would that even be possible?
Steve cracked his enclosure open and carefully extracted his drive. Then we started removing endless screws from my system and found our way down to the harddisk compartment and pulled my drive out:

To be honest, I would never have attempted such a thing, but Steve knew what he was doing (and more importantly, had all his tools handy). So, having taken the cradle off of my drive, we even more delecately then attached the enclosure’s logic board to my drive.
- Miracle #1: the connector from my drive fit the one in the enclosure.
(I gather that these things are “standardized” but still. The hardware you find in your average laptop is always wacky and weird. So I was pretty excited) With that done, we plugged it into the new system:

and to my supreme happiness,
- Miracle #2: the drive’s filesystems mounted to
/media/disk
Hooray for the Linux kernel, HAL, the GNOME automounter, Nautilus, and everything else that made that work.
And then, even better,
- Miracle #3: whatever it was that took out my laptop’s mainboard did not zorch my hard drive.
Hooray! My data was all ok!
A little fiddling about to make sure there was now a user andrew with a matching UID on the Ubuntu system, and then, very simply:
$ rsync -av... /media/disk /home/andrew
Outstanding.
So thanks to the help of Steve and the others, I had my /home on this new system. And one of the magic things about the GNOME Desktop for the last few years has been them safely writing down everything you need to run, so pretty much instantly I had my happy place back.
The data, at least.
Comparing distros; comparing laptops
The one problem I still faced was that the system in hand was not configured as a development machine. I had to work out what the appropriate packages were for all the different bits and pieces I was accustomed to having.
One thing I really like about Gentoo is that they clued in long ago that disk space is cheap and that things like .h files don’t take up that much room. So when you install a package on Gentoo you get development tools, header files, debug symbols [if so configured], compilers, documentation, the works. I had forgotten that Debian and Debian derived systems like Ubuntu do not install all the development libraries and tools. So I proceeded to tear my hair out for over a day wading through endless package lists trying to find what I would need to get development headers and the various tools necessary to build software (the morning of the tutorial I discovered the laptop didn’t have any man pages. What the hell?)
Granted, such things are essentially trivialities, and I accept that they were the sort of thing that one runs into when working on a new system. No big deal. Sure I could easily have built a Gentoo system in less time, but it’s not my machine and in any case I was enjoying the learning experience.
Far more interesting was living on a new distro for a few weeks. It was nice to experience all this “polish” that I’ve heard people going on about, and I was indeed duly impressed. After a while, though, I started to notice all kinds of little changes that Canonical has made to the Desktop that are really cool, but which have not been contributed back upstream to GNOME. That bothers me a little bit, but I’m hopeful that in time this sort of practise will fade in favour of them working more closely with the upstream projects they are using.
Meanwhile I also got to trial a new laptop brand. I gotta say I was really impressed with the build quality, robustness, and power efficiency of the HP corporate laptop line. This one is a couple model-years old, but I was able to have a few good chats with Bdale Garbee about it and he walked me through their current line up. After this experience I can definitely say that we will be getting HP laptops in the future.
Drove me nuts having a different keyboard layout to deal with for a few weeks. And having just about spent enough time on it to get it in my fingers, now my laptop is repaired and I’m once again mistyping everything… :)
Again, thanks to Steve who totally saved the day. And thanks to everyone anywhere who ever contributed to all the wonderful software that made the transfer from one system to another miraculous — and easy.
What about next time?
So what I have I learned?
I travel a huge amount, and having my laptop blow up is clearly something I need to be more prepared for. Remote backups are still necessary, of course, and the SD card I carry around with more or less continues snapshots of my critical files is also clearly going to continue.
But it’s kinda obvious to me now that it would be a good idea to carry around an external USB enclosure with a hard drive big enough to back up my entire system — nice encrypted partition and all set, just rsync the whole damn thing. Disk space is cheap. Along with a boot partition holding a nice generic runs-everywhere kernel, that would be enough to not only recover from, but also boot from live the next time my computer fries.
AfC
Friday, 01 Aug 2008
Swat!
Huge kudos are due to Cody Russell for having fixed one of the longest-standing bugs in GTK. 11 June 2001!
Cody only got involved in this issue recently, but he took the time to really dig into it, examine different hypothesises, and test like crazy. This was remarkable: it’s not every day you see someone wade into a bug that’s been open for over half a decade and with over a hundred comments, and then persist for over a year to get it solved.
Way to go!
AfC
Thursday, 07 Jun 2007
New GTK in GNOME 2.20
I’m glad to hear that the release-team has decided to push ahead and approve Glib 2.14 and GTK+ 2.12 for the next GNOME release. Awesome!
One of the diseases that arises in group psychology is that sometimes it is hard to say “yes”. It looked for a while like people on one side or the other (or both) were going to flinch. I’m glad that didn’t happen. I know there was some proactive negotiation and give-and-take on the part of both the GTK hackers and of the release-team. Well done everyone.
AfC
Wednesday, 23 May 2007
Multi-threaded GTK applications - Part 1: Misconceptions
I think my favourite message of the last year has to be something Tristan wrote:
“it is really plain and simple thread programming, you just have to really know what you’re doing.”
One of the most frequently asked questions in the GTK mailing lists is “How do I use threads with GTK”. Actually, the question is more often “I’ve started writing a GTK program, and it doesn’t work. What the hell?” and it quickly emerges that they’re trying to do a multi-threaded GTK app, and doing it wrong.
The conventional answer has long been that “you must only make GTK library calls from the main thread” (that is, the thread that executed gtk_main() and is therefore the one running the GTK main loop). What usually follows is advice to create a producer-consumer relationship to dispatch requests from the worker threads to the main [loop] thread and have the code to actually do the UI updates in separate code there. Frankly, this is rather cumbersome when all you want to do is a quick worker thread so you don’t freeze the UI by blocking the main loop, and then a couple of quick (but very case specific) UI updates to report the result. Non-trivial validation and then a database commit upon pressing “OK” is a classic example.
So, I’ve been studying this carefully for the last several months. Searching the GNOME archives turns up any number of fascinating threads on the topic. (ooof, bad pun, sorry) and there is frequent reference across GTK documentation and tutorials about the necessity to guard all GTK calls.
And yet: despite all the traffic and opinion that you must only make GTK calls from the main thread, this is not actually correct. At least I don’t think it is. Perhaps you can tell me if my conclusions are correct.
As you dig further, you start to realize that the requirement is not that you make calls from the main thread only, but that all GTK calls must be made within the main lock (the GDK lock actually). This is stated quite clearly on the canonical GDK Threads page which cites:
GTK+ is “thread aware” but not thread safe — it provides a global lock controlled by
gdk_threads_enter()andgdk_threads_leave()which protects all use of GTK+. That is, only one thread can use GTK+ at any given time.
You’ll note that it doesn’t say anything about the “main loop thread”. And this is where the confusion sets in.
Convenience APIs shield you from the truth
People get the message that they have to put gdk_threads_enter()/leave() around their GTK calls from other threads pretty quickly. But two things tend to be overlooked:
It turns out that you’re supposed to put gdk_threads_enter()/leave() around the call you make to gtk_main(). I suppose that this is implicit in the injunction to protect all GTK calls, but I know I’m not the only one to have had the impression that the main loop was special somehow. It certainly isn’t explicit on the GDK threads API page, and although it turns up (sort of) in the code examples there, the number of people that get this wrong is staggering. So I think we’ll need to improve that documentation a bit. (I’ll submit a patch depending on the feedback I get after this series of posts)
So now with the lightest of refactoring, C side we have this:
int main(int argc, char** argv) {
g_threads_init()
gdk_threads_init()
gtk_init()
...
gdk_threads_enter()
gtk_main()
gdk_threads_leave()
}
The second problem is more subtle. Because signal callbacks happen from within the main loop (blocking it), and since the thread running the main loop has traditionally been though of as “special”, people quickly forget that they need to protect the GTK calls in their callbacks, especially if the bulk of their GTK programming has been single threaded C code. This is dramatically exacerbated by the fact that if you properly did gtk_threads_enter() before calling gtk_main(), then when you get a callback you are already in the GDK lock and you don’t even have to think about it. So people don’t.
This is a massive convenience, of course. GTK programming in C is already ridiculously verbose, and if people had to manually surround every individual GTK call with the enter()/leave() functions like this:
void clicked_cb(GtkButton* button, gpointer data) {
gdk_threads_enter();
gtk_widget_set_sensitive(button, TRUE);
gdk_threads_leave();
gdk_threads_enter();
gtk_button_set_label(GTK_BUTTON(button), "Blah");
gdk_threads_leave();
...
}
they’d go slightly crazy. Even having to do it at the beginning and end of a callback function:
void clicked_cb(GtkButton* button, gpointer data) {
gdk_threads_enter();
gtk_widget_set_sensitive(button, TRUE);
gtk_button_set_label(GTK_BUTTON(button), "Blah");
...
gdk_threads_leave();
}
would still be way too cumbersome. But because GTK callbacks are within the main loop and from the main thread, no one ever has to think much about it, because we all just do this:
void clicked_cb(GtkButton* button, gpointer data) {
gtk_widget_set_sensitive(button, TRUE);
gtk_button_set_label(GTK_BUTTON(button), "Blah");
...
}
In fact, the first two examples were wrong because the default implementation of the GDK lock functions is a mutex that is not reentrant, and that would have deadlocked! So not only do we not have to think about the thread safety issue, C side we can’t think about it. Bad.
But wait a minute. If the main loop is in the lock, how can any other thread run?
This is the question that finally got me on the right track. How can any other thread ever execute a GTK call?
It took me overriding the GDK lock grab and release functions with gdk_threads_set_lock_functions() and sticking in some g_debug()s to find this out, but there’s a little detail that no one tells you: the GTK main loop releases its lock as it cycles, and it turns out that GTK itself is properly written to call the enter() and release() functions (via the macros GDK_THREADS_ENTER() and GDK_THREADS_LEAVE()).
So GTK is indeed thread-aware, if not quite thread-safe without a little help from the programmer.
Thus you don’t need to go through the nightmare of setting up a dispatcher mechanism just to make changes to the UI. From any other thread, you just surround your GTK calls with the grab and release functions, and you’re on your way.
In hindsight, all this information was out there; I just came across this which, now that I understand it, clearly says what the main loop is up to. Still, though, there’s a lot of context. As Tristan said, you have to know what you’re doing.
Implications
There’s a shining possibility lurking within all this: what happens if you replace the simplistic GDK lock with a reentrant (aka recursive) one? You’re not going to believe this, but it works, and it works well. And the implication for a language binding like java-gnome is extraordinary: by combining a reentrant monitor with something that automatically locks all the GTK calls, it looks like our Java bindings might be able to be thread safe! That would really be something.
I’ll show you what I’ve found tomorrow.
AfC
Monday, 30 Apr 2007
Fascinating thread: GtkCanvas requirements
A discussion has been taking place on gtk-devel-list this month as a number of GNOME hackers discuss the requirements that a future GtkCanvas widget might have.
A canvas widget is all about drawing; while many requirements for customized user interface don’t need such a thing (because you can always pack together various other widgets into a new composite widget that achieves the effect you’re aiming for), in the more general case you need to start drawing lines and shapes — and this is where people usually run into trouble. For one thing, drawing of any kind is generally fairly complicated, but most of the pain comes as a result of drawing things at bitmap (pixel by pixel) level — later on, anything that needs to scale (zoom in, zoom out) the resultant pixmaps is bound to look terrible.
That, of course, is what vector graphics are all about, and so the obvious thing is to use such mechanisms to do the low level drawing. For a while now, we’ve had an outstanding vector drawing library in freedesktop land, and that’s Cairo. And while Cairo is already used for quite a number of things in GTK, and while there are various higher level Canvas widgets floating around, the most interesting part of the whole thread to me was when it was pointed out that if a new GtkCanvas (in the form of a slightly lower level artifact) was used to render all the [standard] Widgets provided by GTK, then suddenly the zooming, resizing, and other warping that accessibility tools need would all be fait accompli in the toolkit itself. And it’s not just accessibility: someone pointed out that if we made it this far, then at last we’d have high resolution screen shots to paper which would make printed documentation look stunning.
Fascinating thread.
AfC
Friday, 22 Jul 2005
Audio snippets when hovering
I was waving my mouse over my desktop where I’d downloaded a few recent episodes of LugRadio and suddenly when a few seconds of babble with a British accent bubbled out of my speakers.
Stunned silence.
I didn’t think I’d clicked on the file to actually open it, but ok, fine. Wait
for totem to fire up to play the .ogg. Waiting, waiting. Hm. totem
didn’t fire up. I hadn’t double clicked on it. Huh?
So I waved my mouse back over one of the .oggs, and then another sound bite
(the first few seconds of the episode) came out of my speakers.
Whoa!
So just as the GNOME desktop (ok, nautilus presumably) does a thumbnail of an
image (ok, no biggie) or from a video clip (hey, neat), it does an audible
thumbnail to help you know identify what a given audio file is.
Cool!
AfC
Material on this site copyright © 2002-2009 Operational Dynamics Consulting Pty Ltd, unless otherwise noted. All rights reserved. Not for redistribution or attribution without permission in writing.
We make this service available to our staff in order to promote the discourse of ideas especially as relates to the development of Open Source worldwide. Blog entries on this site, however, are the musings of the authors as individuals and do not represent the views of Operational Dynamics. All times UTC.





