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

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

Issue 2263863002: Remove implementation of Panels on OSes other than ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR feedback Created 4 years, 3 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h"
6
7 #include <dwmapi.h>
8
9 #include <algorithm>
10
11 #include "base/logging.h"
12 #include "base/win/scoped_hdc.h"
13 #include "skia/ext/image_operations.h"
14 #include "ui/gfx/canvas.h"
15 #include "ui/gfx/gdi_util.h"
16
17 namespace {
18
19 HBITMAP GetNativeBitmapFromSkBitmap(const SkBitmap& bitmap) {
20 int width = bitmap.width();
21 int height = bitmap.height();
22
23 BITMAPV4HEADER native_bitmap_header;
24 gfx::CreateBitmapV4Header(width, height, &native_bitmap_header);
25
26 HDC dc = ::GetDC(NULL);
27 void* bits;
28 HBITMAP native_bitmap = ::CreateDIBSection(dc,
29 reinterpret_cast<BITMAPINFO*>(&native_bitmap_header),
30 DIB_RGB_COLORS,
31 &bits,
32 NULL,
33 0);
34 DCHECK(native_bitmap);
35 ::ReleaseDC(NULL, dc);
36 bitmap.copyPixelsTo(bits, width * height * 4, width * 4);
37 return native_bitmap;
38 }
39
40 void EnableCustomThumbnail(HWND hwnd, bool enable) {
41 BOOL enable_value = enable;
42 ::DwmSetWindowAttribute(hwnd,
43 DWMWA_FORCE_ICONIC_REPRESENTATION,
44 &enable_value,
45 sizeof(enable_value));
46 ::DwmSetWindowAttribute(hwnd,
47 DWMWA_HAS_ICONIC_BITMAP,
48 &enable_value,
49 sizeof(enable_value));
50 }
51
52 } // namespace
53
54
55 TaskbarWindowThumbnailerWin::TaskbarWindowThumbnailerWin(
56 HWND hwnd, TaskbarWindowThumbnailerDelegateWin* delegate)
57 : hwnd_(hwnd),
58 delegate_(delegate) {
59 ui::HWNDSubclass::AddFilterToTarget(hwnd_, this);
60 }
61
62 TaskbarWindowThumbnailerWin::~TaskbarWindowThumbnailerWin() {
63 ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
64 }
65
66 void TaskbarWindowThumbnailerWin::Start() {
67 EnableCustomThumbnail(hwnd_, true);
68 }
69
70 void TaskbarWindowThumbnailerWin::Stop() {
71 capture_bitmap_.reset();
72 EnableCustomThumbnail(hwnd_, false);
73 }
74
75 void TaskbarWindowThumbnailerWin::CaptureSnapshot() {
76 if (!capture_bitmap_)
77 capture_bitmap_.reset(CaptureWindowImage());
78 }
79
80 void TaskbarWindowThumbnailerWin::InvalidateSnapshot() {
81 capture_bitmap_.reset();
82
83 // The snapshot feeded to the system could be cached. Invalidate it.
84 ::DwmInvalidateIconicBitmaps(hwnd_);
85 }
86
87 void TaskbarWindowThumbnailerWin::ReplaceWindow(HWND new_hwnd) {
88 // Stop serving the custom thumbnail for the old window.
89 EnableCustomThumbnail(hwnd_, false);
90 ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
91
92 hwnd_ = new_hwnd;
93
94 // Start serving the custom thumbnail to the new window.
95 ui::HWNDSubclass::AddFilterToTarget(hwnd_, this);
96 EnableCustomThumbnail(hwnd_, true);
97 }
98
99 bool TaskbarWindowThumbnailerWin::FilterMessage(HWND hwnd,
100 UINT message,
101 WPARAM w_param,
102 LPARAM l_param,
103 LRESULT* l_result) {
104 DCHECK_EQ(hwnd_, hwnd);
105 switch (message) {
106 case WM_DWMSENDICONICTHUMBNAIL:
107 return OnDwmSendIconicThumbnail(HIWORD(l_param),
108 LOWORD(l_param),
109 l_result);
110 case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
111 return OnDwmSendIconicLivePreviewBitmap(l_result);
112 }
113 return false;
114 }
115
116 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicThumbnail(
117 int width, int height, LRESULT* l_result) {
118 CaptureSnapshot();
119
120 SkBitmap* thumbnail_bitmap = capture_bitmap_.get();
121
122 // Scale the image if needed.
123 SkBitmap scaled_bitmap;
124 if (capture_bitmap_->width() != width ||
125 capture_bitmap_->height() != height) {
126 double x_scale = static_cast<double>(width) / capture_bitmap_->width();
127 double y_scale = static_cast<double>(height) / capture_bitmap_->height();
128 double scale = std::min(x_scale, y_scale);
129 width = capture_bitmap_->width() * scale;
130 height = capture_bitmap_->height() * scale;
131 scaled_bitmap = skia::ImageOperations::Resize(
132 *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height);
133 thumbnail_bitmap = &scaled_bitmap;
134 }
135
136 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*thumbnail_bitmap);
137 ::DwmSetIconicThumbnail(hwnd_, native_bitmap, 0);
138 ::DeleteObject(native_bitmap);
139
140 *l_result = 0;
141 return true;
142 }
143
144 bool TaskbarWindowThumbnailerWin::OnDwmSendIconicLivePreviewBitmap(
145 LRESULT* l_result) {
146 CaptureSnapshot();
147
148 HBITMAP native_bitmap = GetNativeBitmapFromSkBitmap(*capture_bitmap_);
149 ::DwmSetIconicLivePreviewBitmap(hwnd_, native_bitmap, NULL, 0);
150 ::DeleteObject(native_bitmap);
151 *l_result = 0;
152 return true;
153 }
154
155 SkBitmap* TaskbarWindowThumbnailerWin::CaptureWindowImage() const {
156 std::vector<HWND> snapshot_hwnds;
157 if (delegate_)
158 snapshot_hwnds = delegate_->GetSnapshotWindowHandles();
159 if (snapshot_hwnds.empty())
160 snapshot_hwnds.push_back(hwnd_);
161
162 int enclosing_x = 0;
163 int enclosing_y = 0;
164 int enclosing_right = 0;
165 int enclosing_bottom = 0;
166 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
167 iter != snapshot_hwnds.end(); ++iter) {
168 RECT bounds;
169 if (!::GetWindowRect(*iter, &bounds))
170 continue;
171 if (iter == snapshot_hwnds.begin()) {
172 enclosing_x = bounds.left;
173 enclosing_y = bounds.top;
174 enclosing_right = bounds.right;
175 enclosing_bottom = bounds.bottom;
176 } else {
177 if (bounds.left < enclosing_x)
178 enclosing_x = bounds.left;
179 if (bounds.top < enclosing_y)
180 enclosing_y = bounds.top;
181 if (bounds.right > enclosing_right)
182 enclosing_right = bounds.right;
183 if (bounds.bottom > enclosing_bottom)
184 enclosing_bottom = bounds.bottom;
185 }
186 }
187
188 int width = enclosing_right - enclosing_x;
189 int height = enclosing_bottom - enclosing_y;
190 if (!width || !height)
191 return NULL;
192
193 gfx::Canvas canvas(gfx::Size(width, height), 1.0f, false);
194 {
195 skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
196 HDC target_dc = scoped_platform_paint.GetPlatformSurface();
197 for (std::vector<HWND>::const_iterator iter = snapshot_hwnds.begin();
198 iter != snapshot_hwnds.end(); ++iter) {
199 HWND current_hwnd = *iter;
200 RECT current_bounds;
201 if (!::GetWindowRect(current_hwnd, &current_bounds))
202 continue;
203 base::win::ScopedGetDC source_dc(current_hwnd);
204 ::BitBlt(target_dc,
205 current_bounds.left - enclosing_x,
206 current_bounds.top - enclosing_y,
207 current_bounds.right - current_bounds.left,
208 current_bounds.bottom - current_bounds.top,
209 source_dc,
210 0,
211 0,
212 SRCCOPY);
213 ::ReleaseDC(current_hwnd, source_dc);
214 }
215 }
216 return new SkBitmap(canvas.ExtractImageRep().sk_bitmap());
217 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h ('k') | chrome/browser/ui/views/panels/x11_panel_resizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698