Greetings Chromium developers,

(Please feel free to ignore this e-mail if you are not interested in Windows
7.)
To celebrate the launch of Windows 7, I have written a document that
describes my prototype implementation that integrates Tab Thumbnails and
Aero Peek into Chromium. (My current prototype has some problems, though.)Your
comments and suggestions are definitely welcome.

Sorry for sending a huge e-mail in advance.

Regards,

Hironori Bono
E-mail: hb...@chromium.org

*Tab Thumbnails and Aero Peek*
 Objective

This document is a report of my prototype implementation that integrates two
new features of Windows 7 (Tab Thumbnails and Aero Peek) into Chromium.
Background

Windows 7, the new operating system from Microsoft, has added some new
features to its
taskbar[1]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn1>:
JumpList, Tab Thumbnails, Aero Peek, etc.

Among these new features, Tab Thumbnails and Aero Peek are designed for
improving the user experiences of TDI (Tab-Document-Interface) applications.
In fact, users want for Chrome to support them and filed an issue to our
buganizer (Issue
6337[2]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn2>
).

* What are Tab Thumbnails and Aero Peek?*

In Windows 7, an application can add (or remove) thumbnails for each
application so that hovering over its taskbar button to display them as
shown in Figure 1. Each thumbnail can have its own title and icon. (A
thumbnail can also have its own buttons even though this example doesn’t use
them.) The focused tab is shown as a high-lighted thumbnail in this
thumbnail list.

Figure 1 Tab Thumbnails



As shown in Figure 2, hovering a mouse cursor onto a thumbnail shows the
preview image of the corresponding tab, and clicking a thumbnail selects the
tab, respectively. (This feature is called as Aero Peek.)

Figure 2 Aero Peek



Also, clicking the close button of a thumbnail (shown at the top-right
corner of the focused thumbnail) closes the corresponding tab.

Figure 3 Close button of a thumbnail

 * *
Implementing Tab Thumbnails and Aero Peek

Unfortunately, without using new APIs provided by Windows 7, Windows 7 just
shows the thumbnail of the application window. This section provides a
generic overview about implementing Tab Thumbnails and Aero Peek. (The
information in this section is just the result of my investigation, and
maybe incorrect.)
How to add a custom thumbnail?

At first, we need to add a custom thumbnail to the Tab-Thumbnail list of
Windows 7.

To add a custom thumbnail, we need a (tool)
window[3]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn3>that
receives messages from Windows 7. Windows 7 sends the following
messages to notify thumbnail-specific events. So, we need to create a
place-holder window that handles these events for each tab.

1.    * WM_CREATE (0x0001)
This message is sent when a window has been created. An application has to
call DwmSetWindowAttribute() to notify Windows 7 that this window can handle
WM_DWMSENDICONICTHUMBNAIL and WM_DWMSENDICONICLIVEPREVIEWBITMAP
messages[4]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn4>.
Also, an application needs to call ITaskbarList3::RegisterTab() to add this
window to the Tab-Thumbnail list of an
application[5]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn5>
.

2.    * WM_ACTIVATE (0x0006)
This message is sent when a user clicks the thumbnail image to select its
corresponding tab.

3.    * WM_CLOSE (0x0010)
This message is sent when a user clicks the close button of a thumbnail. An
application has to call ITaskbarList3::UnregisterTab() to remove this window
from the Tab-Thumbnail list before calling DestroyWindow().

4.    * WM_DWMSENDICONICTHUMBNAIL (0x0323)
This message is sent when Windows 7 needs the thumbnail image of the
corresponding tab. An application has to create a thumbnail bitmap (whose
size is given as the LPARAM parameter of this
message[6]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn6>)
and send it to Windows 7 through a DwmSetIconicThumbnail() call. (Windows 7
shows a “loading” animation before sending a bitmap to Windows 7.)

5.    * WM_DWMSENDICONICLIVEPREVIEWBITMAP (0x0326)
This message is sent when Windows 7 needs the preview image of the
corresponding tab.  An application has to create a preview bitmap and send
it to Windows 7 through a DwmSetIconicLivePreviewBitmap() call.
How to update the thumbnail image of a tab?

Windows 7 can send WM_DWMSENDICONICTHUMBNAIL messages to a place-holder
window when it needs its thumbnail image. On the other hand, when an
application needs to update the thumbnail image of a tab, it has to call
DwmInvalidateIconicBitmaps() and let Windows 7 send a
WM_DWMSENDICONICTHUMBNAIL message. It makes Windows 7 unhappy and usually
returns E_FAIL to call DwmSetIconicThumbnail() directly.
How to set the title of a thumbnail?

Windows 7 uses GetWindowText() to retrieve the title text from a
place-holder window. So, an application has to call SetWindowText() and
update the title of a place-holder window.
How to set the custom icon for a thumbnail?

Windows 7 uses WM_GETICON messages to retrieve the icon from a place-holder
window. Unlike DwmSetIconicThumbnail(), Windows does NOT create a copy of an
icon retrieved through the WM_GETICON message. So, an application has to
keep the HICON object while it is used by a place-holder window and delete
it when it is not used any longer.

*Integrating Tab Thumbnails and Aero Peek into Chromium*

When we understand how to implement Tab Thumbnails and Aero Peek, we need to
find the best design to integrate Tab Thumbnails and Aero Peek into
Chromium. This section provides an overview about my design which integrates
them into Chromium.
Design Concept

After some investigation, my current prototype *creates a proxy class which
implements the TabStripModelObserver interface and adds it to the
TabStripModel object of a browser process*. Even though I chose this design
mainly because Tab Thumbnails are very similar with
TabStrip[7]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn7>,
this design has the following *pro et contra* (for and against).

·         Pros

o    It is easy to synchronize with TabStrip.

o    We don’t need to change the existing code so much (just creating the
new class and add it to the observer list.)

·         Cons

o    It is hard to get some events related to a tab (e.g. scrolling a page,
resizing a browser window, etc.)

The major functionalities of this proxy class are listed below:

·         Create a place-holder window;

·         Maintain the list of place-holder windows;

·         Translate events received through the TabStripModelObserver
interface to native tasks for Windows 7 (e.g. DwmSetIconicThumbnails(),
DwmSetIconicLivePreviewBitmap(), etc.);

·         Translate window messages (e.g. WM_CLOSE, WM_ACTIVATE, etc.)
received by a place-holder window to tasks of TabStripModel (or
TabContents), and;

·         Activate (or close) the corresponding tab through a
TabContentsDelegate interface.

Implementation Tips
How to find “the corresponding tab”?

Each TabContents object has an ID, which can be retrieved through a
“controller().session_id().id()”
call[8]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftn8>.
My implementation uses this ID to attach a place-holder window and a
TabContents object.
How to create the thumbnail image?

Each tab (i.e. TabContents) has a BackingStore object, which has the
rendering result of the tab. Fortunately, the BackingStore object has a HDC
handle to keep the bitmap. So, my implementation retrieves this HDC handle
from a BackingStore object and copies its image. Unfortunately, it seems
Chromium does not redraw inactive tabs when we resize a browser window.
Since my prototype uses the rendered results of Chromium, it updates only
the thumbnail of the focused tab when we resize a browser window.

Figure 4 Thumbnails when resizing a browser window
How to create the preview image used by Aero Peek?

A preview image used by Aero Peek has to be a complete image of an
application window, i.e. it has to include images of TabStrip, omnibox, etc.
On the other hand, a BackingStore object only has an image inside a tab. So,
we need to create an appropriate preview image from them especially when we
need a preview image of a background tab.

My current prototype uses very simple approach as listed below:

1.    1. Retrieve the image of a browser window.

2.    2. Retrieve the image of a BackingStore object.

3.    3. Paste the BackingStore image onto the image of the frame window

.

Unfortunately, this approach also causes a problem when we resize a browser
window. As I wrote above, Chromium does not redraw its background tabs when
we resize a browser window. So, when my prototype creates a preview image of
a background tab after we resize a browser window. It makes a broken image
as shown in Figure 5.

Figure 5 Preview image of a background tab when resizing a browser window
My Prototype Code

I have uploaded the whole code of my prototype onto Rietveld: <
http://codereview.chromium.org/303033/show>.

Any comments or suggestions are welcome.
Challenges How to treat resize events of a browser window?

The biggest problems of my current prototype are caused by my prototype that
doesn’t handle resize events of a browser window. (Figure 4 may be
acceptable. But, I think Figure 5 is unacceptable for many users.) The
easiest solution for this problem is forcing a background tab to redraw when
we need an image used for Aero Peek or Tab Thumbnails. Unfortunately, this
solution probably hurts the rendering performance of Chromium. Another
solution (or a workaround) is displaying a message “the preview image for
the selected tab is not available” instead of showing a broken image. Any
opinions or suggestions are definitely helpful.

------------------------------

[1]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref1>
http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx

[2]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref2>
http://crbug.com/6337

[3]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref3>When
I implemented a prototype, this window must be a tool window.

[4]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref4>Without
calling DwmSetWindowAttribute(), Windows 7 doesn’t send the
messages.

[5]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref5>Without
calling this function, all DwmSetIconicThumbnail() and
DwmSetIconicLivePreviewBitmap() calls return E_FAIL.

[6]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref6>When
an application sends a larger image than this size,
DwmSetIconicThumbnail() returns E_FAIL.

[7]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref7>In
brief, I thought “like dissolves like”.

[8]<file:///C:/Users/hBono/Documents/Google/Chrome/Tab%20Thumbnails%20and%20Aero%20Peek.docx#_ftnref8>I
just copied this call from “extension_tabs_module.cc”. Please correct
me
if I’m wrong.

--~--~---------~--~----~------------~-------~--~----~
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
    http://groups.google.com/group/chromium-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to