27 December 2007

The twin floating toolbar predicament

Hope everyone had a great Christmas! With the holidays winding down, and me not being in much of a mood to participate in the Boxing Day consumerism frenzy, it's time to dive back into Clippings.

Earlier, I wrote about the problem where it's impossible to determine which host application the floating toolbar palette is originating from, if both Firefox and Thunderbird are running and the toolbar was invoked from both host apps.

The ideal solution is to make the floating toolbar disappear whenever the host application window loses focus, and make it reappear, if it was hidden, when the user restores focus to the host app window. This behaviour is the same as that found in Microsoft Word. Another idea is to put an icon in the floating toolbar's title bar to indicate which host app the toolbar was invoked from. But trademark concerns would prevent me from using the official Firefox or Thunderbird logos in Clippings, and any kind of substitute would be unrecognizable by most users. Plus, the latter idea didn't address the issue of two floating toolbar windows appearing simultaneously if the toolbar was invoked from both host apps -- and that just looks silly, as the following screen shot illustrates:

The rather silly result of invoking the Clippings floating toolbar from both Firefox and Thunderbird.

The first solution was clearly the ideal, and one I tried to get it to work. The key to it is to be able to determine when the host app window loses or gains its focus so that the floating toolbar can be hidden. Unfortunately, there is no way to determine if the host app window has lost focus. The activeWindow property of the nsIWindowWatcher interface always refers to an open window -- even if that window doesn't have focus! Another approach was to hide the toolbar if the blur event on the XUL window is fired, and show the toolbar (if it was hidden) when the focus event is fired. While it is possible to handle a focus event, that isn't the case with the blur event; I tried putting an onblur event handler on the XUL window element, as well as using addEventListener() to register a blur event handler, but to no avail. A seemingly promising newsgroup discussion that I found only lead me to a dead end.

Rather than hiding the toolbar when the host app window loses focus and restoring it when the host app window regains focus, why not hide it when the user moves the mouse out of the host app window, and show it again when the mouse moves into the host app window? Seemed like a great idea... except that the mouseout and mouseover events are fired not just on the window, but on any element contained in it that can trigger mouseout and mouseover events. And when I say this, I don't just mean the XUL elements that define the host app window UI -- but the HTML elements in the Web page displayed in Firefox's browser content area, or the content area of Thunderbird's message compose window! There was no pattern that I could find to help me filter out unwanted event invocations, and at this point I knew that this wasn't going to work, either.

Sadly, the Clippings toolbar isn't ready for prime time, and having worked on this for some time with no results that's really usable, I decided that it's time to move on. The toolbar is still there, but it is now disabled by default. The boolean preference "clippings.toolbar.enabled" needs to be created and set to true in about:config to make the Clippings Toolbar command visible in the Clippings status bar icon menu in the host app.

Users itching to try it out now can do so by downloading and installing the latest experimental snapshot release from http://downloads.mozdev.org/clippings/experimental/. Look for the XPI file named clippings-2.99.3+_20071227.xpi.

No comments: