Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: chrome/browser/ui/views/frame/glass_browser_frame_view.cc

Issue 1406403007: Eliminate HICON leaks caused by creating icons from bitmap image. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nullptr issue in ScopedGDIObject. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" 5 #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h"
6 6
7 #include "base/prefs/pref_service.h" 7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "base/win/windows_version.h" 9 #include "base/win/windows_version.h"
10 #include "chrome/app/chrome_command_ids.h" 10 #include "chrome/app/chrome_command_ids.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // buttons, but the space will look cluttered if it actually slides under them, 57 // buttons, but the space will look cluttered if it actually slides under them,
58 // so we stop it when the gap between the two is down to 5 px. 58 // so we stop it when the gap between the two is down to 5 px.
59 const int kNewTabCaptionRestoredSpacing = 5; 59 const int kNewTabCaptionRestoredSpacing = 5;
60 // In maximized mode, where the New Tab button and the caption buttons are at 60 // In maximized mode, where the New Tab button and the caption buttons are at
61 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid 61 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
62 // looking too cluttered. 62 // looking too cluttered.
63 const int kNewTabCaptionMaximizedSpacing = 16; 63 const int kNewTabCaptionMaximizedSpacing = 16;
64 64
65 // Converts the |image| to a Windows icon and returns the corresponding HICON 65 // Converts the |image| to a Windows icon and returns the corresponding HICON
66 // handle. |image| is resized to desired |width| and |height| if needed. 66 // handle. |image| is resized to desired |width| and |height| if needed.
67 HICON CreateHICONFromSkBitmapSizedTo(const gfx::ImageSkia& image, 67 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo(
68 int width, 68 const gfx::ImageSkia& image,
69 int height) { 69 int width,
70 if (width == image.width() && height == image.height()) 70 int height) {
71 return IconUtil::CreateHICONFromSkBitmap(*image.bitmap()); 71 return base::win::ScopedHICON(IconUtil::CreateHICONFromSkBitmap(
72 return IconUtil::CreateHICONFromSkBitmap(skia::ImageOperations::Resize( 72 width == image.width() && height == image.height()
73 *image.bitmap(), skia::ImageOperations::RESIZE_BEST, width, height)); 73 ? *image.bitmap()
74 : skia::ImageOperations::Resize(*image.bitmap(),
75 skia::ImageOperations::RESIZE_BEST,
76 width, height)));
74 } 77 }
75 78
76 } // namespace 79 } // namespace
77 80
78 /////////////////////////////////////////////////////////////////////////////// 81 ///////////////////////////////////////////////////////////////////////////////
79 // GlassBrowserFrameView, public: 82 // GlassBrowserFrameView, public:
80 83
81 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, 84 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
82 BrowserView* browser_view) 85 BrowserView* browser_view)
83 : BrowserNonClientFrameView(frame, browser_view), 86 : BrowserNonClientFrameView(frame, browser_view),
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 570 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
568 static_cast<WPARAM>(ICON_SMALL), 571 static_cast<WPARAM>(ICON_SMALL),
569 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 572 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
570 } 573 }
571 } 574 }
572 575
573 void GlassBrowserFrameView::StopThrobber() { 576 void GlassBrowserFrameView::StopThrobber() {
574 if (throbber_running_) { 577 if (throbber_running_) {
575 throbber_running_ = false; 578 throbber_running_ = false;
576 579
580 base::win::ScopedHICON previous_small_icon;
581 base::win::ScopedHICON previous_big_icon;
577 HICON small_icon = nullptr; 582 HICON small_icon = nullptr;
578 HICON big_icon = nullptr; 583 HICON big_icon = nullptr;
579 584
580 // Check if hosted BrowserView has a window icon to use. 585 // Check if hosted BrowserView has a window icon to use.
581 if (browser_view()->ShouldShowWindowIcon()) { 586 if (browser_view()->ShouldShowWindowIcon()) {
582 gfx::ImageSkia icon = browser_view()->GetWindowIcon(); 587 gfx::ImageSkia icon = browser_view()->GetWindowIcon();
583 if (!icon.isNull()) { 588 if (!icon.isNull()) {
584 small_icon = CreateHICONFromSkBitmapSizedTo( 589 // Keep previous icons alive as long as they are referenced by the HWND.
585 icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); 590 previous_small_icon = small_window_icon_.Pass();
586 big_icon = CreateHICONFromSkBitmapSizedTo( 591 previous_big_icon = big_window_icon_.Pass();
587 icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); 592
593 // Take responsibility for eventually destroying the created icons.
594 small_window_icon_ =
595 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXSMICON),
596 GetSystemMetrics(SM_CYSMICON))
597 .Pass();
598 big_window_icon_ =
599 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXICON),
600 GetSystemMetrics(SM_CYICON))
601 .Pass();
602
603 small_icon = small_window_icon_.Get();
604 big_icon = big_window_icon_.Get();
588 } 605 }
589 } 606 }
590 607
591 // Fallback to class icon. 608 // Fallback to class icon.
592 if (!small_icon) { 609 if (!small_icon) {
593 small_icon = reinterpret_cast<HICON>( 610 small_icon = reinterpret_cast<HICON>(
594 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM)); 611 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM));
595 } 612 }
596 if (!big_icon) { 613 if (!big_icon) {
597 big_icon = reinterpret_cast<HICON>( 614 big_icon = reinterpret_cast<HICON>(
598 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON)); 615 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON));
599 } 616 }
600 617
601 // This will reset the icon which we set in the throbber code. 618 // This will reset the icon which we set in the throbber code.
602 // WM_SETICON with null icon restores the icon for title bar but not 619 // WM_SETICON with null icon restores the icon for title bar but not
603 // for taskbar. See http://crbug.com/29996 620 // for taskbar. See http://crbug.com/29996
604 HICON previous_small_icon = reinterpret_cast<HICON>( 621 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
605 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 622 static_cast<WPARAM>(ICON_SMALL),
606 static_cast<WPARAM>(ICON_SMALL), 623 reinterpret_cast<LPARAM>(small_icon));
607 reinterpret_cast<LPARAM>(small_icon)));
608 624
609 HICON previous_big_icon = reinterpret_cast<HICON>( 625 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
610 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 626 static_cast<WPARAM>(ICON_BIG),
611 static_cast<WPARAM>(ICON_BIG), 627 reinterpret_cast<LPARAM>(big_icon));
612 reinterpret_cast<LPARAM>(big_icon)));
613
614 if (previous_small_icon)
615 ::DestroyIcon(previous_small_icon);
616
617 if (previous_big_icon)
618 ::DestroyIcon(previous_big_icon);
619 } 628 }
620 } 629 }
621 630
622 void GlassBrowserFrameView::DisplayNextThrobberFrame() { 631 void GlassBrowserFrameView::DisplayNextThrobberFrame() {
623 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; 632 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
624 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 633 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
625 static_cast<WPARAM>(ICON_SMALL), 634 static_cast<WPARAM>(ICON_SMALL),
626 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 635 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
627 } 636 }
628 637
629 // static 638 // static
630 void GlassBrowserFrameView::InitThrobberIcons() { 639 void GlassBrowserFrameView::InitThrobberIcons() {
631 static bool initialized = false; 640 static bool initialized = false;
632 if (!initialized) { 641 if (!initialized) {
633 for (int i = 0; i < kThrobberIconCount; ++i) { 642 for (int i = 0; i < kThrobberIconCount; ++i) {
634 throbber_icons_[i] = 643 throbber_icons_[i] =
635 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); 644 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i);
636 DCHECK(throbber_icons_[i]); 645 DCHECK(throbber_icons_[i]);
637 } 646 }
638 initialized = true; 647 initialized = true;
639 } 648 }
640 } 649 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698