Mysterious Aero Peek Bugs (Part 1)

written 16 Jun 2010
Aero Peek is one of the new Windows 7 features that we are integrating Firefox with. It adds an entry in the taskbar for each tab. Hovering over the entry shows a preview of the tab contents. IE8 and Opera support this (Chrome has it disabled). Though it slipped from the release of 3.6, we intend to ship it in Firefox 4.0. Browsers can implement this feature with varying levels of polish. IE8 was the flashship use case when it shipped with Windows 7 and Microsoft invited other browser vendors to follow along. One of the noticeable drawbacks in the IE8 implementation is that when you preview a tab, the chrome does not change to reflect the tab the user is previewing (ex: the url is that of the whatever tab was last selected instead of the previewed tab). I found this to be unsatisfactory and potentially confusing user experience so in Firefox's implementation, we display the correct chrome when you preview a tab. This has not been without its hardships. I do not know why IE8 does not switch chrome but there are definitely bugs that affect us and not IE8 because we have chosen to switch the chrome for the previews. One of these is that the previewed tab content is blended over the window as it was last drawn. For semi-transparent parts of our new UI like the location bar and unselected tabs, this causes them to look different in the preview. You can see part of the window's current tab's URL when you preview another tab and this is clearly unacceptable. So now we have a choice to make:
  1. We can stop switching chrome for previews.
  2. We disallow semi-transparent parts of our theme
  3. Maybe we can control the window contents when the preview is drawn so that we blend with an empty window
Option 1 is a last resort and option 2 is still pretty undesirable. Option 3 is rather tricky due to the API design. Rather than notify us when preview starts/stops (a "peek session" I'll call it), the API merely asks for bitmaps for live preview so we can't just change our painting when we're in peek. But hey, we have support for custom window previews, not just tab previews. We could set up a custom window preview to draw a transparent black bitmap for the window's preview and then draw our tab preview as expected. In isolation, the window preview code works but when combined with the tab previews, it mysteriously stops working. We get requests for the window preview and the tab preview and we dutifully return the correct bitmaps for those. Windows will display the tab preview's bitmap on top of the "waiting" animation for the window preview. It's really quite strange as all the API calls return success. This bug is possibly related to another one which I think frequently causes woe. The requests for bitmaps are asynchronous - they are posted to the windows' thread queue. Say you have three tabs: A, B and C. If you move quickly from A to C, stopping at B long enough to see the spinning circle animation but before we finish rendering the preview, Windows will forget for the remainder of the peek session that it ever got our rendered preview. It also never asks for it for the remainder of the peek session. If anyone has insight into fixes (either on our end or coming from Microsoft) or workarounds, please let me know.