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

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: Rebase Created 5 years 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 // buttons, but the space will look cluttered if it actually slides under them, 58 // buttons, but the space will look cluttered if it actually slides under them,
59 // so we stop it when the gap between the two is down to 5 px. 59 // so we stop it when the gap between the two is down to 5 px.
60 const int kNewTabCaptionRestoredSpacing = 5; 60 const int kNewTabCaptionRestoredSpacing = 5;
61 // In maximized mode, where the New Tab button and the caption buttons are at 61 // In maximized mode, where the New Tab button and the caption buttons are at
62 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid 62 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
63 // looking too cluttered. 63 // looking too cluttered.
64 const int kNewTabCaptionMaximizedSpacing = 16; 64 const int kNewTabCaptionMaximizedSpacing = 16;
65 65
66 // Converts the |image| to a Windows icon and returns the corresponding HICON 66 // Converts the |image| to a Windows icon and returns the corresponding HICON
67 // handle. |image| is resized to desired |width| and |height| if needed. 67 // handle. |image| is resized to desired |width| and |height| if needed.
68 HICON CreateHICONFromSkBitmapSizedTo(const gfx::ImageSkia& image, 68 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo(
69 int width, 69 const gfx::ImageSkia& image,
70 int height) { 70 int width,
71 if (width == image.width() && height == image.height()) 71 int height) {
72 return IconUtil::CreateHICONFromSkBitmap(*image.bitmap()); 72 return IconUtil::CreateHICONFromSkBitmap(
73 return IconUtil::CreateHICONFromSkBitmap(skia::ImageOperations::Resize( 73 width == image.width() && height == image.height()
74 *image.bitmap(), skia::ImageOperations::RESIZE_BEST, width, height)); 74 ? *image.bitmap()
75 : skia::ImageOperations::Resize(*image.bitmap(),
76 skia::ImageOperations::RESIZE_BEST,
77 width, height));
75 } 78 }
76 79
77 } // namespace 80 } // namespace
78 81
79 /////////////////////////////////////////////////////////////////////////////// 82 ///////////////////////////////////////////////////////////////////////////////
80 // GlassBrowserFrameView, public: 83 // GlassBrowserFrameView, public:
81 84
82 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, 85 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
83 BrowserView* browser_view) 86 BrowserView* browser_view)
84 : BrowserNonClientFrameView(frame, browser_view), 87 : BrowserNonClientFrameView(frame, browser_view),
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 612 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
610 static_cast<WPARAM>(ICON_SMALL), 613 static_cast<WPARAM>(ICON_SMALL),
611 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 614 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
612 } 615 }
613 } 616 }
614 617
615 void GlassBrowserFrameView::StopThrobber() { 618 void GlassBrowserFrameView::StopThrobber() {
616 if (throbber_running_) { 619 if (throbber_running_) {
617 throbber_running_ = false; 620 throbber_running_ = false;
618 621
622 base::win::ScopedHICON previous_small_icon;
623 base::win::ScopedHICON previous_big_icon;
619 HICON small_icon = nullptr; 624 HICON small_icon = nullptr;
620 HICON big_icon = nullptr; 625 HICON big_icon = nullptr;
621 626
622 // Check if hosted BrowserView has a window icon to use. 627 // Check if hosted BrowserView has a window icon to use.
623 if (browser_view()->ShouldShowWindowIcon()) { 628 if (browser_view()->ShouldShowWindowIcon()) {
624 gfx::ImageSkia icon = browser_view()->GetWindowIcon(); 629 gfx::ImageSkia icon = browser_view()->GetWindowIcon();
625 if (!icon.isNull()) { 630 if (!icon.isNull()) {
626 small_icon = CreateHICONFromSkBitmapSizedTo( 631 // Keep previous icons alive as long as they are referenced by the HWND.
627 icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); 632 previous_small_icon = small_window_icon_.Pass();
628 big_icon = CreateHICONFromSkBitmapSizedTo( 633 previous_big_icon = big_window_icon_.Pass();
629 icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); 634
635 // Take responsibility for eventually destroying the created icons.
636 small_window_icon_ =
637 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXSMICON),
638 GetSystemMetrics(SM_CYSMICON))
639 .Pass();
640 big_window_icon_ =
641 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXICON),
642 GetSystemMetrics(SM_CYICON))
643 .Pass();
644
645 small_icon = small_window_icon_.get();
646 big_icon = big_window_icon_.get();
630 } 647 }
631 } 648 }
632 649
633 // Fallback to class icon. 650 // Fallback to class icon.
634 if (!small_icon) { 651 if (!small_icon) {
635 small_icon = reinterpret_cast<HICON>( 652 small_icon = reinterpret_cast<HICON>(
636 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM)); 653 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM));
637 } 654 }
638 if (!big_icon) { 655 if (!big_icon) {
639 big_icon = reinterpret_cast<HICON>( 656 big_icon = reinterpret_cast<HICON>(
640 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON)); 657 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON));
641 } 658 }
642 659
643 // This will reset the icon which we set in the throbber code. 660 // This will reset the icon which we set in the throbber code.
644 // WM_SETICON with null icon restores the icon for title bar but not 661 // WM_SETICON with null icon restores the icon for title bar but not
645 // for taskbar. See http://crbug.com/29996 662 // for taskbar. See http://crbug.com/29996
646 HICON previous_small_icon = reinterpret_cast<HICON>( 663 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
647 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 664 static_cast<WPARAM>(ICON_SMALL),
648 static_cast<WPARAM>(ICON_SMALL), 665 reinterpret_cast<LPARAM>(small_icon));
649 reinterpret_cast<LPARAM>(small_icon)));
650 666
651 HICON previous_big_icon = reinterpret_cast<HICON>( 667 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
652 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 668 static_cast<WPARAM>(ICON_BIG),
653 static_cast<WPARAM>(ICON_BIG), 669 reinterpret_cast<LPARAM>(big_icon));
654 reinterpret_cast<LPARAM>(big_icon)));
655
656 if (previous_small_icon)
657 ::DestroyIcon(previous_small_icon);
658
659 if (previous_big_icon)
660 ::DestroyIcon(previous_big_icon);
661 } 670 }
662 } 671 }
663 672
664 void GlassBrowserFrameView::DisplayNextThrobberFrame() { 673 void GlassBrowserFrameView::DisplayNextThrobberFrame() {
665 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; 674 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
666 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 675 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
667 static_cast<WPARAM>(ICON_SMALL), 676 static_cast<WPARAM>(ICON_SMALL),
668 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 677 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
669 } 678 }
670 679
671 // static 680 // static
672 void GlassBrowserFrameView::InitThrobberIcons() { 681 void GlassBrowserFrameView::InitThrobberIcons() {
673 static bool initialized = false; 682 static bool initialized = false;
674 if (!initialized) { 683 if (!initialized) {
675 for (int i = 0; i < kThrobberIconCount; ++i) { 684 for (int i = 0; i < kThrobberIconCount; ++i) {
676 throbber_icons_[i] = 685 throbber_icons_[i] =
677 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); 686 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i);
678 DCHECK(throbber_icons_[i]); 687 DCHECK(throbber_icons_[i]);
679 } 688 }
680 initialized = true; 689 initialized = true;
681 } 690 }
682 } 691 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/frame/glass_browser_frame_view.h ('k') | chrome/browser/ui/views/frame/taskbar_decorator_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698