| Index: chrome/browser/ui/views/avatar_menu_button.cc
|
| ===================================================================
|
| --- chrome/browser/ui/views/avatar_menu_button.cc (revision 98998)
|
| +++ chrome/browser/ui/views/avatar_menu_button.cc (working copy)
|
| @@ -11,19 +11,67 @@
|
| #include "ui/gfx/canvas_skia.h"
|
| #include "views/widget/widget.h"
|
|
|
| +
|
| +#if defined(OS_WIN)
|
| +#include <shobjidl.h>
|
| +#include "base/win/scoped_comptr.h"
|
| +#include "base/win/windows_version.h"
|
| +#include "skia/ext/image_operations.h"
|
| +#include "ui/gfx/icon_util.h"
|
| +#endif
|
| +
|
| static inline int Round(double x) {
|
| return static_cast<int>(x + 0.5);
|
| }
|
|
|
| +// The Windows 7 taskbar supports dynamic overlays and effects, we use this
|
| +// to ovelay the avatar icon there. The overlay only applies if the taskbar
|
| +// is in "default large icon mode". This function is a best effort deal so
|
| +// we bail out silently at any error condition.
|
| +// See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for
|
| +// more information.
|
| +void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) {
|
| +#if defined(OS_WIN)
|
| + if (base::win::GetVersion() < base::win::VERSION_WIN7)
|
| + return;
|
| +
|
| + base::win::ScopedComPtr<ITaskbarList3> taskbar;
|
| + HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL,
|
| + CLSCTX_INPROC_SERVER);
|
| + if (FAILED(result) || FAILED(taskbar->HrInit()))
|
| + return;
|
| + gfx::NativeWindow window = browser->window()->GetNativeHandle();
|
| + if (!window)
|
| + return;
|
| + HICON icon = NULL;
|
| + if (bitmap) {
|
| + // Since the target size is so small, we use our best resizer.
|
| + SkBitmap sk_icon = skia::ImageOperations::Resize(
|
| + *bitmap,
|
| + skia::ImageOperations::RESIZE_LANCZOS3,
|
| + 16, 16);
|
| + icon = IconUtil::CreateHICONFromSkBitmap(sk_icon);
|
| + if (!icon)
|
| + return;
|
| + }
|
| + taskbar->SetOverlayIcon(window, icon, L"");
|
| + if (icon)
|
| + DestroyIcon(icon);
|
| +#endif
|
| +}
|
| +
|
| AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu)
|
| : MenuButton(NULL, std::wstring(), this, false),
|
| browser_(browser),
|
| - has_menu_(has_menu) {
|
| + has_menu_(has_menu),
|
| + set_taskbar_decoration_(false) {
|
| // In RTL mode, the avatar icon should be looking the opposite direction.
|
| EnableCanvasFlippingForRTLUI(true);
|
| }
|
|
|
| -AvatarMenuButton::~AvatarMenuButton() {}
|
| +AvatarMenuButton::~AvatarMenuButton() {
|
| + DrawTaskBarDecoration(browser_, NULL);
|
| +}
|
|
|
| void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) {
|
| const SkBitmap& icon = GetImageToPaint();
|
| @@ -50,6 +98,13 @@
|
|
|
| canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(),
|
| dst_x, dst_y, dst_width, dst_height, false);
|
| +
|
| + if (set_taskbar_decoration_) {
|
| + // Drawing the taskbar decoration uses lanczos resizing so we really
|
| + // want to do it only once.
|
| + DrawTaskBarDecoration(browser_, &icon);
|
| + set_taskbar_decoration_ = false;
|
| + }
|
| }
|
|
|
| bool AvatarMenuButton::HitTest(const gfx::Point& point) const {
|
| @@ -58,6 +113,12 @@
|
| return views::MenuButton::HitTest(point);
|
| }
|
|
|
| +// If the icon changes, we need to set the taskbar decoration again.
|
| +void AvatarMenuButton::SetIcon(const SkBitmap& icon) {
|
| + views::MenuButton::SetIcon(icon);
|
| + set_taskbar_decoration_ = true;
|
| +}
|
| +
|
| // views::ViewMenuDelegate implementation
|
| void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
|
| if (!has_menu_)
|
|
|