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

Side by Side Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 283053002: Add compositing, layers to app_list_demo Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase onto master -- probably slightly broken Created 6 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/test/test_views_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_native_widget.h" 5 #import "ui/views/cocoa/bridged_native_widget.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ui/base/ime/input_method.h" 8 #include "ui/base/ime/input_method.h"
9 #include "ui/base/ime/input_method_factory.h" 9 #include "ui/base/ime/input_method_factory.h"
10 #include "ui/base/ui_base_switches_util.h" 10 #include "ui/base/ui_base_switches_util.h"
11 #include "ui/gfx/display.h"
12 #import "ui/gfx/mac/coordinate_conversion.h"
13 #include "ui/gfx/screen.h"
11 #import "ui/views/cocoa/bridged_content_view.h" 14 #import "ui/views/cocoa/bridged_content_view.h"
12 #import "ui/views/cocoa/views_nswindow_delegate.h" 15 #import "ui/views/cocoa/views_nswindow_delegate.h"
13 #include "ui/views/widget/native_widget_mac.h" 16 #include "ui/views/widget/native_widget_mac.h"
14 #include "ui/views/ime/input_method_bridge.h" 17 #include "ui/views/ime/input_method_bridge.h"
15 #include "ui/views/ime/null_input_method.h" 18 #include "ui/views/ime/null_input_method.h"
16 #include "ui/views/view.h" 19 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h" 20 #include "ui/views/widget/widget.h"
18 21
22 #include "cc/output/copy_output_request.h"
23 #include "cc/output/copy_output_result.h"
24
25 #include "third_party/skia/include/core/SkBitmap.h"
26 #include "ui/gfx/codec/png_codec.h"
27 #include "ui/gfx/image/image_skia_rep.h"
28 #include "ui/gfx/canvas.h"
29
30 namespace {
31
32 float GetDeviceScaleFactorFromDisplay(NSView* view) {
33 gfx::Display display = gfx::Screen::GetScreenFor(view)->
34 GetDisplayNearestWindow(view);
35 DCHECK(display.is_valid());
36 return display.device_scale_factor();
37 }
38
39 } // namespace
40
19 namespace views { 41 namespace views {
20 42
21 BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent) 43 BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent)
22 : native_widget_mac_(parent), focus_manager_(NULL) { 44 : native_widget_mac_(parent), focus_manager_(NULL) {
23 DCHECK(parent); 45 DCHECK(parent);
24 window_delegate_.reset( 46 window_delegate_.reset(
25 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]); 47 [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
26 } 48 }
27 49
28 BridgedNativeWidget::~BridgedNativeWidget() { 50 BridgedNativeWidget::~BridgedNativeWidget() {
(...skipping 28 matching lines...) Expand all
57 79
58 if (focus_manager_) 80 if (focus_manager_)
59 focus_manager_->RemoveFocusChangeListener(this); 81 focus_manager_->RemoveFocusChangeListener(this);
60 82
61 if (focus_manager) 83 if (focus_manager)
62 focus_manager->AddFocusChangeListener(this); 84 focus_manager->AddFocusChangeListener(this);
63 85
64 focus_manager_ = focus_manager; 86 focus_manager_ = focus_manager;
65 } 87 }
66 88
89 void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) {
90 [window_ setFrame:gfx::ScreenRectToNSRect(new_bounds)
91 display:YES
92 animate:NO];
93 if (layer())
94 SetLayerSize(new_bounds.size());
95 }
96
67 void BridgedNativeWidget::SetRootView(views::View* view) { 97 void BridgedNativeWidget::SetRootView(views::View* view) {
68 if (view == [bridged_view_ hostedView]) 98 if (view == [bridged_view_ hostedView])
69 return; 99 return;
70 100
101 // If this is ever false, the compositor will need to be properly torn down
102 // and replaced, pointing at the new view.
103 DCHECK(!view || !compositor_view_);
104
71 [bridged_view_ clearView]; 105 [bridged_view_ clearView];
72 bridged_view_.reset(); 106 bridged_view_.reset();
73 // Note that there can still be references to the old |bridged_view_| 107 // Note that there can still be references to the old |bridged_view_|
74 // floating around in Cocoa libraries at this point. However, references to 108 // floating around in Cocoa libraries at this point. However, references to
75 // the old views::View will be gone, so any method calls will become no-ops. 109 // the old views::View will be gone, so any method calls will become no-ops.
76 110
77 if (view) { 111 if (view) {
78 bridged_view_.reset([[BridgedContentView alloc] initWithView:view]); 112 bridged_view_.reset([[BridgedContentView alloc] initWithView:view]);
79 // Objective C initializers can return nil. However, if |view| is non-NULL 113 // Objective C initializers can return nil. However, if |view| is non-NULL
80 // this should be treated as an error and caught early. 114 // this should be treated as an error and caught early.
(...skipping 17 matching lines...) Expand all
98 132
99 ui::InputMethod* BridgedNativeWidget::GetHostInputMethod() { 133 ui::InputMethod* BridgedNativeWidget::GetHostInputMethod() {
100 if (!input_method_) { 134 if (!input_method_) {
101 // Delegate is NULL because Mac IME does not need DispatchKeyEventPostIME 135 // Delegate is NULL because Mac IME does not need DispatchKeyEventPostIME
102 // callbacks. 136 // callbacks.
103 input_method_ = ui::CreateInputMethod(NULL, nil); 137 input_method_ = ui::CreateInputMethod(NULL, nil);
104 } 138 }
105 return input_method_.get(); 139 return input_method_.get();
106 } 140 }
107 141
142 ui::Layer* BridgedNativeWidget::GetOrCreateLayer() {
143 if (!bridged_view_)
144 return NULL;
145
146 if (layer())
147 return layer();
148
149 [bridged_view_ setWantsLayer:YES];
150 // Next line does nothing.
151 [[bridged_view_ layer]
152 setBackgroundColor:CGColorGetConstantColor(kCGColorClear)];
153
154 SetLayer(new ui::Layer());
155 layer()->set_delegate(this);
156 DCHECK_EQ(0u, [[bridged_view_ subviews] count]);
157 compositor_view_.reset(new content::BrowserCompositorViewMac(this));
158
159 DCHECK(compositor_view_->GetCompositor());
160 DCHECK_EQ(compositor_view_->GetCompositor(), layer()->GetCompositor());
161
162 [window_ setOpaque:NO];
163 layer()->GetCompositor()->SetHostHasTransparentBackground(true);
164 layer()->SetFillsBoundsCompletely(true);
165
166 SetLayerSize(native_widget_mac_->GetWindowBoundsInScreen().size());
167 return layer();
168 }
169
108 //////////////////////////////////////////////////////////////////////////////// 170 ////////////////////////////////////////////////////////////////////////////////
109 // BridgedNativeWidget, internal::InputMethodDelegate: 171 // BridgedNativeWidget, internal::InputMethodDelegate:
110 172
111 void BridgedNativeWidget::DispatchKeyEventPostIME(const ui::KeyEvent& key) { 173 void BridgedNativeWidget::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
112 // Mac key events don't go through this, but some unit tests that use 174 // Mac key events don't go through this, but some unit tests that use
113 // MockInputMethod do. 175 // MockInputMethod do.
114 DCHECK(focus_manager_); 176 DCHECK(focus_manager_);
115 native_widget_mac_->GetWidget()->OnKeyEvent(const_cast<ui::KeyEvent*>(&key)); 177 native_widget_mac_->GetWidget()->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
116 if (!key.handled()) 178 if (!key.handled())
117 focus_manager_->OnKeyEvent(key); 179 focus_manager_->OnKeyEvent(key);
118 } 180 }
119 181
182 ////////////////////////////////////////////////////////////////////////////////
183 // BridgedNativeWidget, content::BrowserCompositorViewMacClient:
184
185 void BridgedNativeWidget::BrowserCompositorViewFrameSwapped(
186 const std::vector<ui::LatencyInfo>& latency_info) {
187 }
188
189 NSView* BridgedNativeWidget::BrowserCompositorSuperview() {
190 return bridged_view_;
191 }
192
193 ui::Layer* BridgedNativeWidget::BrowserCompositorRootLayer() {
194 return layer();
195 }
196
197 ////////////////////////////////////////////////////////////////////////////////
198 // BridgedNativeWidget, FocusChangeListener:
199
120 void BridgedNativeWidget::OnWillChangeFocus(View* focused_before, 200 void BridgedNativeWidget::OnWillChangeFocus(View* focused_before,
121 View* focused_now) { 201 View* focused_now) {
122 } 202 }
123 203
124 void BridgedNativeWidget::OnDidChangeFocus(View* focused_before, 204 void BridgedNativeWidget::OnDidChangeFocus(View* focused_before,
125 View* focused_now) { 205 View* focused_now) {
126 ui::TextInputClient* input_client = 206 ui::TextInputClient* input_client =
127 focused_now ? focused_now->GetTextInputClient() : NULL; 207 focused_now ? focused_now->GetTextInputClient() : NULL;
128 [bridged_view_ setTextInputClient:input_client]; 208 [bridged_view_ setTextInputClient:input_client];
129 } 209 }
130 210
131 //////////////////////////////////////////////////////////////////////////////// 211 ////////////////////////////////////////////////////////////////////////////////
212 // BridgedNativeWidget, LayerDelegate:
213
214 static bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path ,
215 bool discard_transparency) {
216 std::vector<unsigned char> png_data;
217 if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
218 discard_transparency,
219 &png_data) &&
220 base::CreateDirectory(file_path.DirName())) {
221 char* data = reinterpret_cast<char*>(&png_data[0]);
222 int size = static_cast<int>(png_data.size());
223 bool result = base::WriteFile(file_path, data, size) == size;
224 return result;
225 }
226 return false;
227 }
228
229 static void ReadbackResult(scoped_ptr<cc::CopyOutputResult> result) {
230 DLOG(INFO) << "result!";
231 scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap().Pass();
232 static int filectr = 0;
233 std::ostringstream oss;
234 oss << "file" << filectr++ << ".png";
235 WritePNGFile(*result_bitmap, base::FilePath().AppendASCII(oss.str().c_str()), false);
236 }
237
238 void BridgedNativeWidget::OnPaintLayer(gfx::Canvas* canvas) {
239 layer()->RequestCopyOfOutput(cc::CopyOutputRequest::CreateBitmapRequest(base:: Bind(&ReadbackResult)));
240 native_widget_mac_->GetWidget()->OnNativeWidgetPaint(canvas);
241
242 gfx::ImageSkiaRep image = canvas->ExtractImageRep();
243 static int filectr = 0;
244 std::ostringstream oss;
245 oss << "bpass" << filectr++ << ".png";
246 WritePNGFile(image.sk_bitmap(), base::FilePath().AppendASCII(oss.str().c_str() ), false);
247
248 }
249
250 void BridgedNativeWidget::OnDeviceScaleFactorChanged(
251 float device_scale_factor) {
252 }
253
254 base::Closure BridgedNativeWidget::PrepareForLayerBoundsChange() {
255 return base::Bind(&BridgedNativeWidget::OnWindowBoundsChanged,
256 base::Unretained(this));
257 }
258
259 ////////////////////////////////////////////////////////////////////////////////
132 // BridgedNativeWidget, private: 260 // BridgedNativeWidget, private:
133 261
134 void BridgedNativeWidget::RemoveOrDestroyChildren() { 262 void BridgedNativeWidget::RemoveOrDestroyChildren() {
135 // TODO(tapted): Implement unowned child windows if required. 263 // TODO(tapted): Implement unowned child windows if required.
136 base::scoped_nsobject<NSArray> child_windows( 264 base::scoped_nsobject<NSArray> child_windows(
137 [[NSArray alloc] initWithArray:[window_ childWindows]]); 265 [[NSArray alloc] initWithArray:[window_ childWindows]]);
138 [child_windows makeObjectsPerformSelector:@selector(close)]; 266 [child_windows makeObjectsPerformSelector:@selector(close)];
139 } 267 }
140 268
269 void BridgedNativeWidget::SetLayerSize(const gfx::Size& size_in_dip) {
270 DCHECK(layer());
271
272 layer()->SetBounds(gfx::Rect(size_in_dip));
273
274 float scale_factor = GetDeviceScaleFactorFromDisplay(bridged_view_);
275 gfx::Size size_in_pixels(size_in_dip.width() * scale_factor,
276 size_in_dip.height() * scale_factor);
277 compositor_view_->GetCompositor()->SetScaleAndSize(scale_factor,
278 size_in_pixels);
279 }
280
281 void BridgedNativeWidget::OnWindowBoundsChanged() {
282 }
283
141 } // namespace views 284 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/test/test_views_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698