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

Side by Side Diff: chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.cc

Issue 16035007: Provide the custom thumbnail for live preview of stacked panels (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months 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 | Annotate | Revision Log
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/panels/taskbar_window_thumbnailer_win.h" 5 #include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/win/scoped_hdc.h" 10 #include "base/win/scoped_hdc.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 sizeof(enable_value)); 43 sizeof(enable_value));
44 ::DwmSetWindowAttribute(hwnd, 44 ::DwmSetWindowAttribute(hwnd,
45 DWMWA_HAS_ICONIC_BITMAP, 45 DWMWA_HAS_ICONIC_BITMAP,
46 &enable_value, 46 &enable_value,
47 sizeof(enable_value)); 47 sizeof(enable_value));
48 } 48 }
49 49
50 } // namespace 50 } // namespace
51 51
52 52
53 TaskbarWindowThumbnailerWin::TaskbarWindowThumbnailerWin(HWND hwnd) 53 TaskbarWindowThumbnailerWin::TaskbarWindowThumbnailerWin(
54 : hwnd_(hwnd) { 54 HWND hwnd, TaskbarWindowThumbnailerDelegateWin* delegate)
55 : hwnd_(hwnd),
56 delegate_(delegate) {
55 } 57 }
56 58
57 TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() { 59 TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() {
58 } 60 }
59 61
60 void TaskbarWindowThumbnailerWin::Start( 62 void TaskbarWindowThumbnailerWin::Start(bool should_capture_now) {
61 const std::vector<HWND>& snapshot_hwnds) { 63 if (should_capture_now)
62 snapshot_hwnds_ = snapshot_hwnds; 64 capture_bitmap_.reset(CaptureWindowImage());
63 if (snapshot_hwnds_.empty()) 65
64 snapshot_hwnds_.push_back(hwnd_); 66 EnableCustomThumbnail(hwnd_, true);
65 capture_bitmap_.reset(CaptureWindowImage()); 67
66 if (capture_bitmap_) 68 // The preview image could be cached by the system. Invalidate it to use
67 EnableCustomThumbnail(hwnd_, true); 69 // the fresh one.
70 ::DwmInvalidateIconicBitmaps(hwnd_);
68 } 71 }
69 72
70 void TaskbarWindowThumbnailerWin::Stop() { 73 void TaskbarWindowThumbnailerWin::Stop() {
71 capture_bitmap_.reset(); 74 capture_bitmap_.reset();
72 EnableCustomThumbnail(hwnd_, false); 75 EnableCustomThumbnail(hwnd_, false);
73 } 76 }
74 77
75 bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd, 78 bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd,
76 UINT message, 79 UINT message,
77 WPARAM w_param, 80 WPARAM w_param,
78 LPARAM l_param, 81 LPARAM l_param,
79 LRESULT* l_result) { 82 LRESULT* l_result) {
80 DCHECK_EQ(hwnd_, hwnd); 83 DCHECK_EQ(hwnd_, hwnd);
81 switch (message) { 84 switch (message) {
82 case WM_DWMSENDICONICTHUMBNAIL: 85 case WM_DWMSENDICONICTHUMBNAIL:
83 return OnDwmSendIconicThumbnail(HIWORD(l_param), 86 return OnDwmSendIconicThumbnail(HIWORD(l_param),
84 LOWORD(l_param), 87 LOWORD(l_param),
85 l_result); 88 l_result);
86 case WM_DWMSENDICONICLIVEPREVIEWBITMAP: 89 case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
87 return OnDwmSendIconicLivePreviewBitmap(l_result); 90 return OnDwmSendIconicLivePreviewBitmap(l_result);
88 } 91 }
89 return false; 92 return false;
90 } 93 }
91 94
92 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail( 95 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail(
93 int width, int height, LRESULT* l_result) { 96 int width, int height, LRESULT* l_result) {
94 DCHECK(capture_bitmap_.get()); 97 if (!capture_bitmap_)
98 capture_bitmap_.reset(CaptureWindowImage());
95 99
96 SkBitmap* thumbnail_bitmap = capture_bitmap_.get(); 100 SkBitmap* thumbnail_bitmap = capture_bitmap_.get();
97 101
98 // Scale the image if needed. 102 // Scale the image if needed.
99 SkBitmap scaled_bitmap; 103 SkBitmap scaled_bitmap;
100 if (capture_bitmap_->width() != width || 104 if (capture_bitmap_->width() != width ||
101 capture_bitmap_->height() != height) { 105 capture_bitmap_->height() != height) {
102 double x_scale = static_cast<double>(width) / capture_bitmap_->width(); 106 double x_scale = static_cast<double>(width) / capture_bitmap_->width();
103 double y_scale = static_cast<double>(height) / capture_bitmap_->height(); 107 double y_scale = static_cast<double>(height) / capture_bitmap_->height();
104 double scale = std::min(x_scale, y_scale); 108 double scale = std::min(x_scale, y_scale);
105 width = capture_bitmap_->width() * scale; 109 width = capture_bitmap_->width() * scale;
106 height = capture_bitmap_->height() * scale; 110 height = capture_bitmap_->height() * scale;
107 scaled_bitmap = skia::ImageOperations::Resize( 111 scaled_bitmap = skia::ImageOperations::Resize(
108 *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height); 112 *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height);
109 thumbnail_bitmap = &scaled_bitmap; 113 thumbnail_bitmap = &scaled_bitmap;
110 } 114 }
111 115
112 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap); 116 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap);
113 ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0); 117 ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0);
114 ::DeleteObject(native_bitmap); 118 ::DeleteObject(native_bitmap);
115 119
116 *l_result = 0; 120 *l_result = 0;
117 return true; 121 return true;
118 } 122 }
119 123
120 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap( 124 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap(
121 LRESULT* l_result) { 125 LRESULT* l_result) {
122 scoped_ptr<SkBitmap> live_bitmap(CaptureWindowImage()); 126 if (!capture_bitmap_)
123 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*live_bitmap); 127 capture_bitmap_.reset(CaptureWindowImage());
128
129 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*capture_bitmap_);
124 ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0); 130 ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0);
125 ::DeleteObject(native_bitmap); 131 ::DeleteObject(native_bitmap);
126
127 *l_result = 0; 132 *l_result = 0;
128 return true; 133 return true;
129 } 134 }
130 135
131 SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const { 136 SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const {
137 std::vector<HWND> snapshot_hwnds;
138 if (delegate_)
139 snapshot_hwnds = delegate_->GetSnapshotWindowHandles();
140 if (snapshot_hwnds.empty())
141 snapshot_hwnds.push_back(hwnd_);
142
132 int enclosing_x = 0; 143 int enclosing_x = 0;
133 int enclosing_y = 0; 144 int enclosing_y = 0;
134 int enclosing_right = 0; 145 int enclosing_right = 0;
135 int enclosing_bottom = 0; 146 int enclosing_bottom = 0;
136 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds_.begin(); 147 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
137 iter != snapshot_hwnds_.end(); ++iter) { 148 iter != snapshot_hwnds.end(); ++iter) {
138 RECT bounds; 149 RECT bounds;
139 if (!::GetWindowRect(*iter, &bounds)) 150 if (!::GetWindowRect(*iter, &bounds))
140 continue; 151 continue;
141 if (iter == snapshot_hwnds_.begin()) { 152 if (iter == snapshot_hwnds.begin()) {
142 enclosing_x = bounds.left; 153 enclosing_x = bounds.left;
143 enclosing_y = bounds.top; 154 enclosing_y = bounds.top;
144 enclosing_right = bounds.right; 155 enclosing_right = bounds.right;
145 enclosing_bottom = bounds.bottom; 156 enclosing_bottom = bounds.bottom;
146 } else { 157 } else {
147 if (bounds.left < enclosing_x) 158 if (bounds.left < enclosing_x)
148 enclosing_x = bounds.left; 159 enclosing_x = bounds.left;
149 if (bounds.top < enclosing_y) 160 if (bounds.top < enclosing_y)
150 enclosing_y = bounds.top; 161 enclosing_y = bounds.top;
151 if (bounds.right > enclosing_right) 162 if (bounds.right > enclosing_right)
152 enclosing_right = bounds.right; 163 enclosing_right = bounds.right;
153 if (bounds.bottom > enclosing_bottom) 164 if (bounds.bottom > enclosing_bottom)
154 enclosing_bottom = bounds.bottom; 165 enclosing_bottom = bounds.bottom;
155 } 166 }
156 } 167 }
157 168
158 int width = enclosing_right - enclosing_x; 169 int width = enclosing_right - enclosing_x;
159 int height = enclosing_bottom - enclosing_y; 170 int height = enclosing_bottom - enclosing_y;
160 if (!width || !height) 171 if (!width || !height)
161 return NULL; 172 return NULL;
162 173
163 gfx::Canvas canvas(gfx::Size(width, height), ui::SCALE_FACTOR_100P, false); 174 gfx::Canvas canvas(gfx::Size(width, height), ui::SCALE_FACTOR_100P, false);
164 { 175 {
165 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); 176 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
166 HDC target_dc = scoped_platform_paint.GetPlatformSurface(); 177 HDC target_dc = scoped_platform_paint.GetPlatformSurface();
167 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds_.begin(); 178 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
168 iter != snapshot_hwnds_.end(); ++iter) { 179 iter != snapshot_hwnds.end(); ++iter) {
169 HWND current_hwnd = *iter; 180 HWND current_hwnd = *iter;
170 RECT current_bounds; 181 RECT current_bounds;
171 if (!::GetWindowRect(current_hwnd, &current_bounds)) 182 if (!::GetWindowRect(current_hwnd, &current_bounds))
172 continue; 183 continue;
173 base::win::ScopedGetDC source_dc(current_hwnd); 184 base::win::ScopedGetDC source_dc(current_hwnd);
174 ::BitBlt(target_dc, 185 ::BitBlt(target_dc,
175 current_bounds.left - enclosing_x, 186 current_bounds.left - enclosing_x,
176 current_bounds.top - enclosing_y, 187 current_bounds.top - enclosing_y,
177 current_bounds.right - current_bounds.left, 188 current_bounds.right - current_bounds.left,
178 current_bounds.bottom - current_bounds.top, 189 current_bounds.bottom - current_bounds.top,
179 source_dc, 190 source_dc,
180 0, 191 0,
181 0, 192 0,
182 SRCCOPY); 193 SRCCOPY);
183 ::ReleaseDC(current_hwnd, source_dc); 194 ::ReleaseDC(current_hwnd, source_dc);
184 } 195 }
185 } 196 }
186 return new SkBitmap(canvas.ExtractImageRep().sk_bitmap()); 197 return new SkBitmap(canvas.ExtractImageRep().sk_bitmap());
187 } 198 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698