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

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: Patch to land 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
« no previous file with comments | « chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
57 ui::HWNDSubclass::AddFilterToTarget(hwnd_, this);
55 } 58 }
56 59
57 TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() { 60 TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() {
61 ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
58 } 62 }
59 63
60 void TaskbarWindowThumbnailerWin::Start( 64 void TaskbarWindowThumbnailerWin::Start() {
61 const std::vector<HWND>& snapshot_hwnds) { 65 EnableCustomThumbnail(hwnd_, true);
62 snapshot_hwnds_ = snapshot_hwnds;
63 if (snapshot_hwnds_.empty())
64 snapshot_hwnds_.push_back(hwnd_);
65 capture_bitmap_.reset(CaptureWindowImage());
66 if (capture_bitmap_)
67 EnableCustomThumbnail(hwnd_, true);
68 } 66 }
69 67
70 void TaskbarWindowThumbnailerWin::Stop() { 68 void TaskbarWindowThumbnailerWin::Stop() {
71 capture_bitmap_.reset(); 69 capture_bitmap_.reset();
72 EnableCustomThumbnail(hwnd_, false); 70 EnableCustomThumbnail(hwnd_, false);
73 } 71 }
74 72
73 void TaskbarWindowThumbnailerWin::CaptureSnapshot() {
74 if (!capture_bitmap_)
75 capture_bitmap_.reset(CaptureWindowImage());
76 }
77
78 void TaskbarWindowThumbnailerWin::InvalidateSnapshot() {
79 capture_bitmap_.reset();
80
81 // The snapshot feeded to the system could be cached. Invalidate it.
82 ::DwmInvalidateIconicBitmaps(hwnd_);
83 }
84
75 bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd, 85 bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd,
76 UINT message, 86 UINT message,
77 WPARAM w_param, 87 WPARAM w_param,
78 LPARAM l_param, 88 LPARAM l_param,
79 LRESULT* l_result) { 89 LRESULT* l_result) {
80 DCHECK_EQ(hwnd_, hwnd); 90 DCHECK_EQ(hwnd_, hwnd);
81 switch (message) { 91 switch (message) {
82 case WM_DWMSENDICONICTHUMBNAIL: 92 case WM_DWMSENDICONICTHUMBNAIL:
83 return OnDwmSendIconicThumbnail(HIWORD(l_param), 93 return OnDwmSendIconicThumbnail(HIWORD(l_param),
84 LOWORD(l_param), 94 LOWORD(l_param),
85 l_result); 95 l_result);
86 case WM_DWMSENDICONICLIVEPREVIEWBITMAP: 96 case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
87 return OnDwmSendIconicLivePreviewBitmap(l_result); 97 return OnDwmSendIconicLivePreviewBitmap(l_result);
88 } 98 }
89 return false; 99 return false;
90 } 100 }
91 101
92 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail( 102 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail(
93 int width, int height, LRESULT* l_result) { 103 int width, int height, LRESULT* l_result) {
94 DCHECK(capture_bitmap_.get()); 104 CaptureSnapshot();
95 105
96 SkBitmap* thumbnail_bitmap = capture_bitmap_.get(); 106 SkBitmap* thumbnail_bitmap = capture_bitmap_.get();
97 107
98 // Scale the image if needed. 108 // Scale the image if needed.
99 SkBitmap scaled_bitmap; 109 SkBitmap scaled_bitmap;
100 if (capture_bitmap_->width() != width || 110 if (capture_bitmap_->width() != width ||
101 capture_bitmap_->height() != height) { 111 capture_bitmap_->height() != height) {
102 double x_scale = static_cast<double>(width) / capture_bitmap_->width(); 112 double x_scale = static_cast<double>(width) / capture_bitmap_->width();
103 double y_scale = static_cast<double>(height) / capture_bitmap_->height(); 113 double y_scale = static_cast<double>(height) / capture_bitmap_->height();
104 double scale = std::min(x_scale, y_scale); 114 double scale = std::min(x_scale, y_scale);
105 width = capture_bitmap_->width() * scale; 115 width = capture_bitmap_->width() * scale;
106 height = capture_bitmap_->height() * scale; 116 height = capture_bitmap_->height() * scale;
107 scaled_bitmap = skia::ImageOperations::Resize( 117 scaled_bitmap = skia::ImageOperations::Resize(
108 *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height); 118 *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height);
109 thumbnail_bitmap = &scaled_bitmap; 119 thumbnail_bitmap = &scaled_bitmap;
110 } 120 }
111 121
112 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap); 122 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap);
113 ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0); 123 ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0);
114 ::DeleteObject(native_bitmap); 124 ::DeleteObject(native_bitmap);
115 125
116 *l_result = 0; 126 *l_result = 0;
117 return true; 127 return true;
118 } 128 }
119 129
120 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap( 130 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap(
121 LRESULT* l_result) { 131 LRESULT* l_result) {
122 scoped_ptr<SkBitmap> live_bitmap(CaptureWindowImage()); 132 CaptureSnapshot();
123 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*live_bitmap); 133
134 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*capture_bitmap_);
124 ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0); 135 ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0);
125 ::DeleteObject(native_bitmap); 136 ::DeleteObject(native_bitmap);
126
127 *l_result = 0; 137 *l_result = 0;
128 return true; 138 return true;
129 } 139 }
130 140
131 SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const { 141 SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const {
142 std::vector<HWND> snapshot_hwnds;
143 if (delegate_)
144 snapshot_hwnds = delegate_->GetSnapshotWindowHandles();
145 if (snapshot_hwnds.empty())
146 snapshot_hwnds.push_back(hwnd_);
147
132 int enclosing_x = 0; 148 int enclosing_x = 0;
133 int enclosing_y = 0; 149 int enclosing_y = 0;
134 int enclosing_right = 0; 150 int enclosing_right = 0;
135 int enclosing_bottom = 0; 151 int enclosing_bottom = 0;
136 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds_.begin(); 152 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
137 iter != snapshot_hwnds_.end(); ++iter) { 153 iter != snapshot_hwnds.end(); ++iter) {
138 RECT bounds; 154 RECT bounds;
139 if (!::GetWindowRect(*iter, &bounds)) 155 if (!::GetWindowRect(*iter, &bounds))
140 continue; 156 continue;
141 if (iter == snapshot_hwnds_.begin()) { 157 if (iter == snapshot_hwnds.begin()) {
142 enclosing_x = bounds.left; 158 enclosing_x = bounds.left;
143 enclosing_y = bounds.top; 159 enclosing_y = bounds.top;
144 enclosing_right = bounds.right; 160 enclosing_right = bounds.right;
145 enclosing_bottom = bounds.bottom; 161 enclosing_bottom = bounds.bottom;
146 } else { 162 } else {
147 if (bounds.left < enclosing_x) 163 if (bounds.left < enclosing_x)
148 enclosing_x = bounds.left; 164 enclosing_x = bounds.left;
149 if (bounds.top < enclosing_y) 165 if (bounds.top < enclosing_y)
150 enclosing_y = bounds.top; 166 enclosing_y = bounds.top;
151 if (bounds.right > enclosing_right) 167 if (bounds.right > enclosing_right)
152 enclosing_right = bounds.right; 168 enclosing_right = bounds.right;
153 if (bounds.bottom > enclosing_bottom) 169 if (bounds.bottom > enclosing_bottom)
154 enclosing_bottom = bounds.bottom; 170 enclosing_bottom = bounds.bottom;
155 } 171 }
156 } 172 }
157 173
158 int width = enclosing_right - enclosing_x; 174 int width = enclosing_right - enclosing_x;
159 int height = enclosing_bottom - enclosing_y; 175 int height = enclosing_bottom - enclosing_y;
160 if (!width || !height) 176 if (!width || !height)
161 return NULL; 177 return NULL;
162 178
163 gfx::Canvas canvas(gfx::Size(width, height), ui::SCALE_FACTOR_100P, false); 179 gfx::Canvas canvas(gfx::Size(width, height), ui::SCALE_FACTOR_100P, false);
164 { 180 {
165 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); 181 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
166 HDC target_dc = scoped_platform_paint.GetPlatformSurface(); 182 HDC target_dc = scoped_platform_paint.GetPlatformSurface();
167 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds_.begin(); 183 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
168 iter != snapshot_hwnds_.end(); ++iter) { 184 iter != snapshot_hwnds.end(); ++iter) {
169 HWND current_hwnd = *iter; 185 HWND current_hwnd = *iter;
170 RECT current_bounds; 186 RECT current_bounds;
171 if (!::GetWindowRect(current_hwnd, &current_bounds)) 187 if (!::GetWindowRect(current_hwnd, &current_bounds))
172 continue; 188 continue;
173 base::win::ScopedGetDC source_dc(current_hwnd); 189 base::win::ScopedGetDC source_dc(current_hwnd);
174 ::BitBlt(target_dc, 190 ::BitBlt(target_dc,
175 current_bounds.left - enclosing_x, 191 current_bounds.left - enclosing_x,
176 current_bounds.top - enclosing_y, 192 current_bounds.top - enclosing_y,
177 current_bounds.right - current_bounds.left, 193 current_bounds.right - current_bounds.left,
178 current_bounds.bottom - current_bounds.top, 194 current_bounds.bottom - current_bounds.top,
179 source_dc, 195 source_dc,
180 0, 196 0,
181 0, 197 0,
182 SRCCOPY); 198 SRCCOPY);
183 ::ReleaseDC(current_hwnd, source_dc); 199 ::ReleaseDC(current_hwnd, source_dc);
184 } 200 }
185 } 201 }
186 return new SkBitmap(canvas.ExtractImageRep().sk_bitmap()); 202 return new SkBitmap(canvas.ExtractImageRep().sk_bitmap());
187 } 203 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698