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

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: Use ScopedHICON instead of HICON. 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 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))
77 .Pass();
grt (UTC plus 2) 2015/11/10 16:44:43 can this be removed?
74 } 78 }
75 79
76 } // namespace 80 } // namespace
77 81
78 /////////////////////////////////////////////////////////////////////////////// 82 ///////////////////////////////////////////////////////////////////////////////
79 // GlassBrowserFrameView, public: 83 // GlassBrowserFrameView, public:
80 84
81 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, 85 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
82 BrowserView* browser_view) 86 BrowserView* browser_view)
83 : BrowserNonClientFrameView(frame, browser_view), 87 : BrowserNonClientFrameView(frame, browser_view),
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 571 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
568 static_cast<WPARAM>(ICON_SMALL), 572 static_cast<WPARAM>(ICON_SMALL),
569 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 573 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
570 } 574 }
571 } 575 }
572 576
573 void GlassBrowserFrameView::StopThrobber() { 577 void GlassBrowserFrameView::StopThrobber() {
574 if (throbber_running_) { 578 if (throbber_running_) {
575 throbber_running_ = false; 579 throbber_running_ = false;
576 580
581 base::win::ScopedHICON previous_small_icon;
582 base::win::ScopedHICON previous_big_icon;
577 HICON small_icon = nullptr; 583 HICON small_icon = nullptr;
578 HICON big_icon = nullptr; 584 HICON big_icon = nullptr;
579 585
580 // Check if hosted BrowserView has a window icon to use. 586 // Check if hosted BrowserView has a window icon to use.
581 if (browser_view()->ShouldShowWindowIcon()) { 587 if (browser_view()->ShouldShowWindowIcon()) {
582 gfx::ImageSkia icon = browser_view()->GetWindowIcon(); 588 gfx::ImageSkia icon = browser_view()->GetWindowIcon();
583 if (!icon.isNull()) { 589 if (!icon.isNull()) {
584 small_icon = CreateHICONFromSkBitmapSizedTo( 590 // Keep previous icons alive as long as they are referenced by the HWND.
585 icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); 591 previous_small_icon = small_window_icon_.Pass();
586 big_icon = CreateHICONFromSkBitmapSizedTo( 592 previous_big_icon = big_window_icon_.Pass();
587 icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); 593
594 // Take responsibility for eventually destroying the created icons.
595 small_window_icon_ =
596 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXSMICON),
597 GetSystemMetrics(SM_CYSMICON))
598 .Pass();
599 big_window_icon_ =
600 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXICON),
601 GetSystemMetrics(SM_CYICON))
602 .Pass();
603
604 small_icon = small_window_icon_.get();
605 big_icon = big_window_icon_.get();
588 } 606 }
589 } 607 }
590 608
591 // Fallback to class icon. 609 // Fallback to class icon.
592 if (!small_icon) { 610 if (!small_icon) {
593 small_icon = reinterpret_cast<HICON>( 611 small_icon = reinterpret_cast<HICON>(
594 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM)); 612 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM));
595 } 613 }
596 if (!big_icon) { 614 if (!big_icon) {
597 big_icon = reinterpret_cast<HICON>( 615 big_icon = reinterpret_cast<HICON>(
598 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON)); 616 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON));
599 } 617 }
600 618
601 // This will reset the icon which we set in the throbber code. 619 // 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 620 // WM_SETICON with null icon restores the icon for title bar but not
603 // for taskbar. See http://crbug.com/29996 621 // for taskbar. See http://crbug.com/29996
604 HICON previous_small_icon = reinterpret_cast<HICON>( 622 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
605 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 623 static_cast<WPARAM>(ICON_SMALL),
606 static_cast<WPARAM>(ICON_SMALL), 624 reinterpret_cast<LPARAM>(small_icon));
607 reinterpret_cast<LPARAM>(small_icon)));
608 625
609 HICON previous_big_icon = reinterpret_cast<HICON>( 626 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
610 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 627 static_cast<WPARAM>(ICON_BIG),
611 static_cast<WPARAM>(ICON_BIG), 628 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 } 629 }
620 } 630 }
621 631
622 void GlassBrowserFrameView::DisplayNextThrobberFrame() { 632 void GlassBrowserFrameView::DisplayNextThrobberFrame() {
623 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; 633 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount;
624 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, 634 SendMessage(views::HWNDForWidget(frame()), WM_SETICON,
625 static_cast<WPARAM>(ICON_SMALL), 635 static_cast<WPARAM>(ICON_SMALL),
626 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); 636 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_]));
627 } 637 }
628 638
629 // static 639 // static
630 void GlassBrowserFrameView::InitThrobberIcons() { 640 void GlassBrowserFrameView::InitThrobberIcons() {
631 static bool initialized = false; 641 static bool initialized = false;
632 if (!initialized) { 642 if (!initialized) {
633 for (int i = 0; i < kThrobberIconCount; ++i) { 643 for (int i = 0; i < kThrobberIconCount; ++i) {
634 throbber_icons_[i] = 644 throbber_icons_[i] =
635 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); 645 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i);
636 DCHECK(throbber_icons_[i]); 646 DCHECK(throbber_icons_[i]);
637 } 647 }
638 initialized = true; 648 initialized = true;
639 } 649 }
640 } 650 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698