Jannis Pohlmann Personal website

Jannis

I am an open source enthusiast, student and musician from L├╝beck, Germany. In my free time I enjoy hacking on Xfce and Lunar Linux. I've been a member of both teams since about 2005. Besides developing software, I love to listen to and play music (Guitar, Bass and Drums) and hang out with friends.

Contact me via jannis@xfce.org. My public PGP key is 0x354AFBA6. You can download it from here.

My CV is also available for download.

Tag - thunar

Entries feed - Comments feed

Sunday, January 17 2010

Thunar-volman and the deprecation of HAL in Xfce

Last week I started looking at thunar-volman (a program that performs certain actions when new devices are plugged in) with the goal to make it compatible with the latest release of thunar which uses GIO instead of ThunarVFS for almost everything that takes place under the hood.

Until now, volume management (monitoring and mounting) in Xfce was done through HAL, the hardware abstraction layer that is currently being deprecated and dropped by major distributions. The functionality previously provided by HAL has been moved into udev, udisks (formerly known as DeviceKit-disks) and upower (formerly known as DeviceKit-power).

Volume management is transparently supported by GIO, meaning that applications don’t have to worry about the backend implementation. It should, in theory, not matter whether HAL is used or udev/udisks. Unsurprisingly, in reality, things are not that trivial, mainly for two reasons:

  1. Due to its focus on file management, GIO only supports monitoring and detecting storage devices (DVD drives, USB sticks etc.). There is no way to be notified when e.g. a digital camera or a portable media player is plugged in. This is critical for the functionality of thunar-volman which until now supported everything from cameras, media players, blank CDs/DVDs, audio CDs, PDAs and printers to input devices like keyboards, mice and tablets.
  2. Mounting volumes with udisks seems to be somewhat incompatible with HAL. I tried to mount volumes with thunar-volman and exo-mount (both implemented on top of HAL) and was for the root password upon unmounting in Thunar (using GIO and gnome-disk-utility/DeviceKit-disks). It seems like volumes mounted with HAL are assumed to be mounted by a different than the current user and thus, require root privileges to be unmounted.

HAL being deprecated and somewhat incompatible with udisks, what are the consequences for Xfce, and for thunar and thunar-volman in particular?

Let us, for a moment, assume Xfce 4.8 and thunar 1.0 were released as they are today, with thunar using GIO (and udisks instead of HAL in all major Linux distributions) and the rest (like thunar-volman and exo-mount) depending on HAL. As mentioned before, exo-mount and thunar wouldn’t work together in multi-user setups. Thunar would no longer detect cameras, PDAs, audio CDs, blank disks, mice, keyboards, tablets, media players and thunar-volman would end up being completely useless, as it is not detecting devices by itself. I think it is safe to say that this is not what we want.

In the following, I will focus on how to deal with thunar-volman. The rest of Xfce faces a similar roadmap, however. With regards to thunar-volman, there are (at least) three sane options:

  1. Drop thunar-volman and only support auto-mounting storage devices from now on, directly implemented in thunar. What is very obvious about this solution is that a lot of possibly useful functionality is lost.
  2. Port thunar-volman to (g)udev/udisks/GIO and make it a standalone daemon so that thunar no longer has to spawn it when new devices are plugged in. The advantage of this approach is that thunar only needs to depend on GIO and doesn’t have to implement the device detection part.
  3. Port thunar-volman to (g)udev/udisks/GIO as described above and make thunar depend on (g)udev for device detection. Spawn thunar-volman when devices are added/removed. The advantage over the previous approach is that thunar-volman doesn’t have to run permanently as a daemon. The additional thunar dependency on (g)udev could be seen as a disadvantage but on the other hand, it basically replaces another (HAL).

Now, everyone knows that programmers are lazy people. So, in the hope of being able to save some work, I started a survey on the usage of thunar-volman. The idea was to find out which of its features are used most and whether there are some that nobody really cares about. Here are the results:

=======================================================================================
                                                        Feature   #Users   Percentage 
---------------------------------------------------------------------------------------
                        Mount removable drives when hot-plugged       86        92.5%
                            Mount removable media when inserted       83        89.2%
                           Browse removable media when inserted       69        74.2%
             Cameras: Import digital photographs when connected       31        33.3%
                          Play video CDs and DVDs when inserted       31        33.3%
                                   Play audio CDs when inserted       30        32.3%
                 Burn a CD or DVD when a blank disc is inserted       21        22.6%
        Portable Media Players: Play music files when connected       11        11.8%
                      Auto-run programs on new drives and media        7         7.5%
        Automatically run a program when a printer is connected        7         7.5%
                        Auto-open files on new drives and media        6         6.5%
                               Sync Palm devices when connected        5         5.4%
  Automatically run a program when an USB keyboard is connected        3         3.2%
     Automatically run a program when an USB mouse is connected        3         3.2%
         Automatically run a program when a tabled is connected        2         2.2%
                          Sync Pocket PC devices when connected        2         2.2%
=======================================================================================
                Thunar Volume Manager Usage Survey with 93 participants

According to the results of this survey, auto-mounting and browsing of removable drives and media have highest priority among the 93 participating thunar-volman users. This more or less covers the functionality we could cover with GIO alone (plus automatically running a program when new drives and media are inserted). However, a third of the users also use thunar-volman for importing photographs from digital cameras and for playing video and audio CDs as well as DVDs automatically. Almost a 25 percent of all users use thunar-volman to start their favorite burning software when a blank CD or DVD is inserted. Slightly more than 10 percent want thunar-volman to start playing music on portable media players when they are plugged in. Printers and Palms are also somewhat relevant.

This survey confirms my expectations that handling storage devices alone is not enough even though they clearly are the most important use case for thunar-volman. Our users seem to like the flexibility of thunar-volman and make use of it. This disqualifies option 1 and leaves us with options 2 and 3. I’m inclined to avoid another daemon and go for number 3.

In preparation for porting thunar and thunar-volman to udev/udisks/GIO, I’ve created a wiki page to collect information about how we can reliably distinguish the different device types based on udev properties: http://wiki.xfce.org/dev/thunar-volman-udev. If you have blue-ray disks, video CDs, a digital camera, a Pocket PC, a Palm, a USB printer or a graphics tablet, you could make me very happy if you inserted them or plugged them in and sent me the output of udevadm info --export-db to my Xfce email address together with a short hint what devices you’ve plugged in. Alternatively, you can paste/upload the output somewhere on the internet and comment on this blog post, and thereby help making future versions of Xfce better.

Cheers!

Wednesday, November 25 2009

News From Busyland

This is just a short heads up concerning Tumbler. I just merged Philip’s last critical commit to complete support for specialized thumbnailer services into master. We’ll have to give this some testing but I’m quite optimistic that we’ll be able to release 0.1.0 this weekend or next week. A new release of Thunar will follow shortly after that in preparation for 1.2 (to be released along with Xfce 4.8), supporting virtual and remote file systems based on GIO.

I’ve been pretty occupied lately. Aside from learning for my final university exams I finished my short thesis on porting Thunar to GIO. I already got the very positive results back and I’m going to publish the official version of the thesis soon. Unfortunately, being busy has started to cause not-so-positive developments as well. I haven’t had much time to hack on anything lately and my attendence of FOSDEM 2010 is uncertain. I might still go but I failed to organize anything related to Xfce this year, leaving us without a devroom and talks. So it’d be more like a private meetup rather than an organized team trip with the goal to represent Xfce.

Another consequence of me being busy is that Xfce 4.8 might include less features than planned, at least with regards to the ones I had in mind. For now let’s just hope that I’ll find a little more time for hacking the next months. It doesn’t look too well right now but who knows…

Sunday, November 1 2009

Things I Miss on Maemo

After hacking on Tumbler for a while, I decided to install the Maemo SDK and see how Maemo runs in Xephyr. I have to say it runs nicely and I really like the interface. The three level zooming interface from application overview to window overview to panorama desktop works well for me. The conversations view and IM notifications make it easy to concentrate on what you want to do without being interrupted too much. I’m chatting with a friend via Jabber at this very moment. Running apps in parallel rocks too.

Now, I’m a rather unorganized person and I’ve always wanted to keep track of meetings and other events using some kind of tool in order to get them out of my head. So, after playing with the Maemo interface for a few hours, I’m considering buying an N900. I’d love to get it at a discount but that doesn’t seem to be easy and I’m not sure my work on Tumbler for Harmattan qualifies enough for that.

Even though I’m considering the N900, there are things that I’d like to see improved. Here’s a list of what I’d consider worth improving. I might even start hacking on one or two of them over the next weeks.

File Manager

The file manager is very basic. No typeahead and global search, no bookmarks, no remote file systems, weird label alignment. I tried running Thunar but its interface is too complex of course. It ran well though which makes me think that there is room for improvement. I could imagine a main view listing entries point on the built-in storage, the SD card and bookmarks (which would then be more than just local bookmarks, it could be anything from local to SFTP to SMB). GIO makes it easy. For the browsing interface something like the browser interface might be nice, except that there is no need for the URI input field. Instead, maybe one could make the bottom bar display the folder name.

Chat Rooms

Chat Rooms like on Jabber conference services don’t seem to be supported. At least there’s an open bug for it on bugs.maemo.org. I’ve been thinking about how this could be implemented without breaking out of the Maemo conversations concept too much. The best idea I came up with within a few minutes would be a separate Chats application where you can define chat rooms, plus a “New Chat” button in the conversations overview. The chats could then show up in the conversations overview and the only that would be different in chat rooms would be that there needs to be a way to show who’s online in the room (maybe with privilege status). This could be done via the pull-down title menu or an additional button next to the smilies or send button, I guess.

I don’t know about the internals and available APIs yet, so these ideas might be impossible to implement. Dunno yet.

eMail

I’m writing plain text mails only and it’s really annoying that I have no control over newlines. This might be a problem with Xephyr, I’m not sure. Also, when replying to someone on a mailing list “- Original Message —” is not enough to mark quotes. I need at least the name of the original author there. This shouldn’t be too hard to implement but of course I first need to find out whom to convince about this. ;)

So, these are just a few ideas. What do you think of them? The next step will be to find out how to get started, investigate what components and APIs are affected and whether these improvements (you may disagree here) are possible or not.

Cheers.

Friday, October 30 2009

Using Tumbler in Client Applications

Yesterday, Philip briefly wrote about Tumbler, the new D-Bus thumbnailing service that is going to be used on Xfce 4.8 and Maemo 6. Today, I'd like to explain how to use this service in client applications. Depending on the application type, the usage varies a little, so I'll focus on the basics here. I'll discuss some tricks at the end of this post though. What I'm not going to do is to talk about how to connect to D-Bus, how to call methods on D-Bus objects and so on. See the D-Bus tutorial or toolkit-specific documentation for more information about that.

A separate post with information on how to extend the thumbnail service will hopefull follow soon.

The Service Architecture

The thumbnailer specification defines four D-Bus service APIs. For most client applications only two of these are interesting: org.freedesktop.thumbnails.Thumbnailer1 (the thumbnailing service) and org.freedesktop.thumbnails.Cache1 (the thumbnail cache manager). The thumbnailing service can be used to request thumbnails and get feedback on the progress of requests. The cache manager can be used to keep the cache synchronized with the hard drive contents by notifying it when files are deleted, copied or renamed.

Thumbnail Request Workflow

Thumbnail requests include the following information:

  1. An array of URIs for which thumbnails should be generated
  2. An array of MIME types for these URIs (each element corresponding to the URI with the same index in the URI array)
  3. The thumbnail flavor to generate for the URIs (normal is 128x128px, large is 256x256px, ...)
  4. The scheduling mechanism to be used for the request (foreground, background, ...)
  5. An optional handle of a previous request that should now be cancelled

Because the service implementation might vary depending on the system (right now there's only Tumbler, but who knows about the future...) there is no fixed set of thumbnail flavors and schedulers. The specification is supposed to define a standard set of flavors and schedulers that all implementations have to support (like a normal flavor and the scheduler default). The URI schemes and MIME types supported by the thumbnailing service also depend on the implementation and the availability of thumbnailer plugins and applications extendending the thumbnailing service via D-Bus. So, the first thing an application should do is to to determine which flavors, schedulers, URI schemes and MIME types are supported.

Determine flavors, schedulers, URI schemes and MIME types supported by the service

The thumbnailer service provides the methods GetFlavors, GetSchedulers and GetSupported for this. They all return string arrays with supported flavors, schedulers and URI scheme and MIME type pairs. GetSupported is a bit special, as it returns two arrays (one with URI schemes, the other with MIME types). These are to be interpreted as arrays of scheme/type pairs, each pair of which means that files with both the scheme and the MIME type at a certain index are supported. Applications can use this information to avoid requests for unsupported files. Once all this information is collected, we can continue with...

Requesting Thumbnails

Let us assume for a moment that only one thumbnail is needed and that the flavor we want is normal, the scheduler is foreground, the URI is file:///tmp/foo.png and the MIME type obviously is image/png. We can request a thumbnail to be created for this URI by calling the Queue method of ...thumbnails.Thumbnailer1 like this (written in some kind of fantasy language with dynamic D-Bus bindings ;)):

 handle = service.Queue ("file:///tmp/foo.png", "image/png", "normal", "foreground", 0)

As you can see here, requesting thumbnails for more than this one URI is simple: just append one more URI to the first array and one more MIME type to the second array.

If you perhaps need to cancel the request later, remember the handle returned by the service. In complex applications with asynchronous APIs you'll sometimes need to link internal request handle to thumbnailer service handles, so the handle returned by the service is not only useful for canceling requests.

Being Notified About the Progress of a Thumbnail Request

Once you have requested one or more thumbnails, you'll probably want to be notified about the progress of your request. Tumbler will emit D-Bus signals for the following status updates:

  1. Started is emitted together with the request handle as soon as the service starts processing the URIs of the request.
  2. Ready is emitted together with the request handle and an array of URIs whenever the thumbnail for one or more of the URIs of the request were generated and can now be used. The array passed to you contains the source URIs, not the URIs of the thumbnail files.
  3. Error is emitted together with the request handle, an array of URIs, an error message and an error code whenever the generation of a thumbnail for one or more URIs of the request failed.
  4. Finished is emitted together with the request handle once the thumbnail service has finished processing the request. This can happen when all URIs have been looked at or when the request was cancelled.

Please note that there is no guarantee for the Ready and Error signal to be emitted for all URIs of the request if the request is cancelled. So, if you maintain an internal thumbnail state for URIs depending on the thumbnail progress, you'll have to remember which URIs were queued. In any case you're advised to make sure to free up your own resources in case the service dies or D-Bus crashes. This can be achieved using a timeout (which will also be helpful if the service hangs) or by connecting to the destroy signal of the DBusGProxy (or whatever equivalent D-Bus API is used in your application).

Cancelling Requests

If you want to cancel certain requests, all you need to do is to call the Dequeue method of the service and pass the correct request handle to it.

Loading the Thumbnails

Where to look for the actual thumbnail files after they have been generated depends on the platform. If Tumbler is built with the default cache backend (which should be built on normal desktop systems), files are stored according to the thumbnail managing standard. On Maemo, files are stored as JPEGs. Philip might be able to give a more detailed description about how to access them.

Thumbnail Cache Synchronization and Cleanup

Some applications like file managers or image viewers allow users to rename, copy, move or delete files on the disk. Since renaming, copying and moving doesn't affect the contents of a file, you can avoid to regenerate its thumbnail by notifying the thumbnail cache of this change. When a file is deleted the thumbnail is no longer needed, so in order to prevent the cache from being polluted with dead thumbnails, you can notify it as well.

This is what the ...thumbnails.Cache1 service interface is for. It provides the following D-Bus methods for the above scenarios:

  • Copy (string array from_uris, string array to_uris)
  • Move (string array from_uris, string array to_uris) (this one is useful for both moving and renaming)
  • Delete (string array uris)

If you want to clean up the cache in a more general sense by deleting very old thumbnails you can do this via the following method which deletes all thumbnail whose original files have not been modified in a long time and have a certain URI prefix (which may be empty):

  • Cleanup (string uri_prefix, uint64 original_mtime_threshold)

The above should give you an insight into how the thumbnail service can be used in applications. If you have any questions about this, please let me know. Ok, now let's reveal some tricks to perform optimization on the client side.

Tips and Tricks

  • Use asynchronous D-Bus calls in your application to avoid your application to block. A separate worker thread might also be useful.
  • It's wise to cache the arrays returned from GetSupported, GetFlavors and GetSchedulers. A SupportedChanged signal is planned to allow applications to update their cached information when the thumbnailer is extended by additional URI schemes or MIME types at runtime.
  • If your application generates a lot of thumbnail requests, as file managers and picture viewers with gallery support usually do, you'll probably want to reduce the amount of messages being sent over D-Bus. You can do this by grouping individual requests. Often when you use a GtkTreeView or something similar involving stateless cell renderers, the easiest way to generate thumbnail requests is when the cell renderer renders a file icon. If you don't group these individual requests, the system might go nuts. So, to group these requests you could use a worker thread with a wait queue that is flushed (URIs in it are sent to the thumbnail service as a single request) at most every X milliseconds. When the first thumbnail is needed, you start a one-shot timeout handler that is executed after X milliseconds, grouping all URIs added to the wait queue in the meantime. I do this in Thunar and it has proven to work well. It also scales nicely by grouping more efficiently the more thumbnails are needed in the time slot. Heavier user scrolling won't make things worse.

I guess that's it for now. I hope you enjoyed reading this first real post about Tumbler coming from me (which is also pushed to Planet Maemo by the way). Again, if you have any questions, please let me know.

Monday, September 14 2009

Design of the Thunar Progress Dialog

Today, I merged the shared progress dialog into Thunar. I can be seen on vimeo. This evening I started thinking about the waste of space in it. For each copy/move/link/delete/trash operation we have: one icon and two lines of text, followed by another line with a progress bar (with text) and a cancel button. That's not too much and it looks kinda clean. Thunar has always hidden too detailed information from the user, like the size of the files, how many megabytes have already been transfered/deleted or what the MB/s rate is. But still, three lines of widgets for each operation is a waste of space. And the more space we waste for each operation, the earlier we have to add something like scrollbars around the widgets, as can be seen in the video.So I've made a few mockups to test alternatives. But first, let's have a look at how other file managers do it.

Nautilus / Finder

The progress dialog used in Nautilus is almost a 1:1 copy of the OS X Finder progress dialog. It too follows a three-line design with the first line either showing how many files are being transfered (e.g. Copying 2 files to "Desktop") or what files is transfered at the moment (this is what you can see in the screenshot below, which I am shameless linking here from Bob Peers' weblog). The second line contains the progress bar and a cancel button without any text and the third line shows some stats, again shown in the screenshot.

Now, the problems of this dialog are quite obvious (although not everything can be seen in the screenshot). If you're transfering more than one file, it will be almost impossible to figure out which of the progress views corresponds to this operation unless you know exactly how many files you're transfering and/or how large these are in total. Another problem is that the dialog grows and grows with each operation added to it until it finally grows beyond the height of the screen. Last but not least the progress bar and button heights are different, making the dialog look slightly unpolished.

Dolphin

I have to admit, this is a poor comparison. I couldn't find a screenshot of Dolphin's progress dialog on the net and I'm too lazy to install KDE in a virtual machine. Suffice it to say that I'm not a big fan of KDE GUIs in general. I think the KDE folks have a lot of great ideas but as nice as plasma and all that 4.x goodness may be, most of the windows and dialogs are too busy and cluttered for my taste.

Thunar Experiments

The original design can be seen on vimeo.

The first attempt of an improvement is the equivalent to Nautilus and Finder omitting the statistics by replacing them with a simple <time> remaining text on the progress bar. Like the Nautilus dialog it doesn't display the name of the current file when an operation includes multiple files. This is not shown in the screenshot, because that one is just a hard-coded mockup. All in all, this design makes it even more unlikely to find a job with multiple files again at a later point due to the left out stats.

The second mockup appends the number of files involved to the title (e.g. (1 of 2)) and because of that, it can always display the name of the file being transfered at the moment. The downside is that this of course requires the user to read more text.

Ideas and Opinions?

I'm not 100% sure which way to go here. I kinda lean towards the second mockup but since Thunar is designed to have no redundant options/elements in the GUI, I'm wondering whether the (1 of 2) isn't too much already.

What do you think? Any opinions or ideas for improvements? Sketches and descriptions are very welcome!

- page 2 of 5 -