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

Side by Side Diff: mojo/views/native_widget_mojo.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 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
« no previous file with comments | « mojo/views/native_widget_mojo.h ('k') | mojo/views/native_widget_view_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "mojo/views/native_widget_mojo.h"
6
7 #include "base/bind.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "mojo/aura/surface_context_factory.h"
10 #include "mojo/converters/geometry/geometry_type_converters.h"
11 #include "mojo/converters/input_events/input_events_type_converters.h"
12 #include "ui/compositor/compositor.h"
13 #include "ui/events/event.h"
14 #include "ui/native_theme/native_theme_aura.h"
15 #include "ui/views/ime/input_method.h"
16 #include "ui/views/views_delegate.h"
17 #include "ui/views/widget/native_widget_delegate.h"
18 #include "ui/views/widget/widget_delegate.h"
19
20 namespace gfx {
21 class Canvas;
22 }
23
24 namespace mojo {
25
26 ////////////////////////////////////////////////////////////////////////////////
27 // NativeWidgetMojo, public:
28
29 NativeWidgetMojo::NativeWidgetMojo(
30 views::internal::NativeWidgetDelegate* delegate,
31 mojo::Shell* shell,
32 mojo::View* view)
33 : delegate_(delegate),
34 ownership_(views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
35 view_(view),
36 destroying_(false),
37 close_widget_factory_(this) {
38 context_factory_.reset(new SurfaceContextFactory(shell, view));
39 compositor_.reset(new ui::Compositor(gfx::kNullAcceleratedWidget,
40 context_factory_.get(),
41 base::ThreadTaskRunnerHandle::Get()));
42
43 gfx::Size size = view->bounds().To<gfx::Rect>().size();
44 compositor_->SetScaleAndSize(1.0f, size);
45 }
46
47 ////////////////////////////////////////////////////////////////////////////////
48 // NativeWidgetMojo, internal::NativeWidgetPrivate implementation:
49
50 void NativeWidgetMojo::InitNativeWidget(
51 const views::Widget::InitParams& params) {
52 ownership_ = params.ownership;
53
54 SetLayer(new ui::Layer(ui::LAYER_TEXTURED));
55 layer()->SetVisible(true);
56 layer()->set_delegate(this);
57 compositor_->SetRootLayer(layer());
58
59 // TODO(erg): The aura version sets shadows types on their window here.
60 if (params.type == views::Widget::InitParams::TYPE_CONTROL)
61 view_->SetVisible(true);
62
63 delegate_->OnNativeWidgetCreated(false);
64
65 gfx::Rect window_bounds = params.bounds;
66 // TODO(erg): Handle params.child once we have child widgets, along with
67 // params.parent.
68
69 // Set properties before adding to the parent so that its layout manager sees
70 // the correct values.
71 OnSizeConstraintsChanged();
72
73 // TODO(erg): Handle parent relations here.
74
75 // Start observing property changes.
76 view_->AddObserver(this);
77
78 // TODO(erg): Do additional things related to the restore bounds and
79 // maximization. See NWA.
80 SetBounds(window_bounds);
81 }
82
83 views::NonClientFrameView* NativeWidgetMojo::CreateNonClientFrameView() {
84 return nullptr;
85 }
86
87 bool NativeWidgetMojo::ShouldUseNativeFrame() const {
88 // TODO(erg): We can probably remove this method; it's only used in windows
89 // for Aero frames.
90 return false;
91 }
92
93 bool NativeWidgetMojo::ShouldWindowContentsBeTransparent() const {
94 return false;
95 }
96
97 void NativeWidgetMojo::FrameTypeChanged() {
98 // This is called when the Theme has changed; forward the event to the root
99 // widget.
100 GetWidget()->ThemeChanged();
101 GetWidget()->GetRootView()->SchedulePaint();
102 }
103
104 views::Widget* NativeWidgetMojo::GetWidget() {
105 return delegate_->AsWidget();
106 }
107
108 const views::Widget* NativeWidgetMojo::GetWidget() const {
109 return delegate_->AsWidget();
110 }
111
112 gfx::NativeView NativeWidgetMojo::GetNativeView() const {
113 // TODO(erg): Actually implementing this will require moving off aura
114 // entirely because of the NativeView typedefs. (Those will need to be
115 // changed to mojo::View being the native view/window.)
116 return nullptr;
117 }
118
119 gfx::NativeWindow NativeWidgetMojo::GetNativeWindow() const {
120 return nullptr;
121 }
122
123 views::Widget* NativeWidgetMojo::GetTopLevelWidget() {
124 NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
125 return native_widget ? native_widget->GetWidget() : nullptr;
126 }
127
128 const ui::Compositor* NativeWidgetMojo::GetCompositor() const {
129 return compositor_.get();
130 }
131
132 ui::Compositor* NativeWidgetMojo::GetCompositor() {
133 return compositor_.get();
134 }
135
136 ui::Layer* NativeWidgetMojo::GetLayer() {
137 return layer();
138 }
139
140 void NativeWidgetMojo::ReorderNativeViews() {
141 // TODO(erg): Punting on this until we actually have something that uses
142 // ui::Layer or NativeViewHost.
143 NOTIMPLEMENTED();
144 }
145
146 void NativeWidgetMojo::ViewRemoved(views::View* view) {
147 NOTIMPLEMENTED();
148 }
149
150 void NativeWidgetMojo::SetNativeWindowProperty(const char* name, void* value) {
151 // TODO(erg): "Native Window" properties do not actually set things on the
152 // system's native window; in mojo::View parlance, this is actually a local
153 // property, not a shared one.
154 NOTIMPLEMENTED();
155 }
156
157 void* NativeWidgetMojo::GetNativeWindowProperty(const char* name) const {
158 NOTIMPLEMENTED();
159 return nullptr;
160 }
161
162 views::TooltipManager* NativeWidgetMojo::GetTooltipManager() const {
163 NOTIMPLEMENTED();
164 return nullptr;
165 }
166
167 void NativeWidgetMojo::SetCapture() {
168 NOTIMPLEMENTED();
169 }
170
171 void NativeWidgetMojo::ReleaseCapture() {
172 NOTIMPLEMENTED();
173 }
174
175 bool NativeWidgetMojo::HasCapture() const {
176 NOTIMPLEMENTED();
177 return false;
178 }
179
180 views::InputMethod* NativeWidgetMojo::CreateInputMethod() {
181 // TODO(erg): Implement this; having a NOTIMPLEMENTED() spews too much.
182 return nullptr;
183 }
184
185 views::internal::InputMethodDelegate*
186 NativeWidgetMojo::GetInputMethodDelegate() {
187 NOTIMPLEMENTED();
188 return nullptr;
189 }
190
191 ui::InputMethod* NativeWidgetMojo::GetHostInputMethod() {
192 NOTIMPLEMENTED();
193 return nullptr;
194 }
195
196 void NativeWidgetMojo::CenterWindow(const gfx::Size& size) {
197 NOTIMPLEMENTED();
198 }
199
200 void NativeWidgetMojo::GetWindowPlacement(
201 gfx::Rect* bounds,
202 ui::WindowShowState* show_state) const {
203 // The interface specifies returning restored bounds, not current bounds.
204 *bounds = GetRestoredBounds();
205 // TODO(erg): Redo how we encode |show_state|.
206 }
207
208 bool NativeWidgetMojo::SetWindowTitle(const base::string16& title) {
209 NOTIMPLEMENTED();
210 return true;
211 }
212
213 void NativeWidgetMojo::SetWindowIcons(const gfx::ImageSkia& window_icon,
214 const gfx::ImageSkia& app_icon) {
215 // TODO(erg): If we add an interface for this, we should change the method
216 // type to pass a representation of different icon sizes. The current
217 // signature is a legacy of how Windows passes icons around.
218 }
219
220 void NativeWidgetMojo::InitModalType(ui::ModalType modal_type) {
221 NOTIMPLEMENTED();
222 }
223
224 gfx::Rect NativeWidgetMojo::GetWindowBoundsInScreen() const {
225 NOTIMPLEMENTED();
226 return gfx::Rect();
227 }
228
229 gfx::Rect NativeWidgetMojo::GetClientAreaBoundsInScreen() const {
230 // View-to-screen coordinate system transformations depend on this returning
231 // the full window bounds, for example View::ConvertPointToScreen().
232 NOTIMPLEMENTED();
233 return gfx::Rect();
234 }
235
236 gfx::Rect NativeWidgetMojo::GetRestoredBounds() const {
237 NOTIMPLEMENTED();
238 return gfx::Rect();
239 }
240
241 void NativeWidgetMojo::SetBounds(const gfx::Rect& bounds) {
242 if (!view_)
243 return;
244
245 view_->SetBounds(*mojo::Rect::From(bounds));
246
247 gfx::Size size = bounds.size();
248 compositor_->SetScaleAndSize(1.0f, size);
249 layer()->SetBounds(gfx::Rect(size));
250 delegate_->OnNativeWidgetSizeChanged(size);
251 }
252
253 void NativeWidgetMojo::SetSize(const gfx::Size& size) {
254 NOTIMPLEMENTED();
255 }
256
257 void NativeWidgetMojo::StackAbove(gfx::NativeView native_view) {
258 NOTIMPLEMENTED();
259 }
260
261 void NativeWidgetMojo::StackAtTop() {
262 NOTIMPLEMENTED();
263 }
264
265 void NativeWidgetMojo::StackBelow(gfx::NativeView native_view) {
266 NOTIMPLEMENTED();
267 }
268
269 void NativeWidgetMojo::SetShape(gfx::NativeRegion region) {
270 // TODO(erg): This is incomplete here. We also need to set the shape on the
271 // mojo::View.
272 NOTIMPLEMENTED();
273 if (view_)
274 layer()->SetAlphaShape(make_scoped_ptr(region));
275 else
276 delete region;
277 }
278
279 void NativeWidgetMojo::Close() {
280 // |window_| may already be deleted by parent window. This can happen
281 // when this widget is child widget or has transient parent
282 // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
283 DCHECK(view_ ||
284 ownership_ == views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
285 if (view_) {
286 Hide();
287 // TODO(erg): Undo window modality here.
288 }
289
290 if (!close_widget_factory_.HasWeakPtrs()) {
291 base::MessageLoop::current()->PostTask(
292 FROM_HERE, base::Bind(&NativeWidgetMojo::CloseNow,
293 close_widget_factory_.GetWeakPtr()));
294 }
295 }
296
297 void NativeWidgetMojo::CloseNow() {
298 view_->Destroy();
299 }
300
301 void NativeWidgetMojo::Show() {
302 ShowWithWindowState(ui::SHOW_STATE_NORMAL);
303 }
304
305 void NativeWidgetMojo::Hide() {
306 if (view_)
307 view_->SetVisible(false);
308 }
309
310 void NativeWidgetMojo::ShowMaximizedWithBounds(
311 const gfx::Rect& restored_bounds) {
312 // TODO(erg): Save the restored bounds.
313 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED);
314 }
315
316 void NativeWidgetMojo::ShowWithWindowState(ui::WindowShowState state) {
317 if (!view_)
318 return;
319
320 // TODO(erg): Set |show_state|, if it still makes sense.
321 view_->SetVisible(true);
322 if (delegate_->CanActivate()) {
323 if (state != ui::SHOW_STATE_INACTIVE)
324 Activate();
325 // SetInitialFocus() should be always be called, even for
326 // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
327 // do the right thing.
328 SetInitialFocus(state);
329 }
330 }
331
332 bool NativeWidgetMojo::IsVisible() const {
333 return view_ && view_->visible();
334 }
335
336 void NativeWidgetMojo::Activate() {
337 // TODO(erg): Need to plumb activation to the window manager here.
338 NOTIMPLEMENTED();
339 }
340
341 void NativeWidgetMojo::Deactivate() {
342 // TODO(erg): Need to plumb deactivation to the window manager here.
343 NOTIMPLEMENTED();
344 }
345
346 bool NativeWidgetMojo::IsActive() const {
347 return true;
348 }
349
350 void NativeWidgetMojo::SetAlwaysOnTop(bool on_top) {
351 // TODO(erg): Plumb this to the window manager.
352 NOTIMPLEMENTED();
353 }
354
355 bool NativeWidgetMojo::IsAlwaysOnTop() const {
356 return false;
357 }
358
359 void NativeWidgetMojo::SetVisibleOnAllWorkspaces(bool always_visible) {
360 // Not implemented on chromeos or for child widgets.
361 }
362
363 void NativeWidgetMojo::Maximize() {
364 // TODO(erg): Everything about minimization/maximization should really be
365 // part of the window manager; these methods should be replaced with
366 // something like "RequestMaximize()".
367 NOTIMPLEMENTED();
368 }
369
370 void NativeWidgetMojo::Minimize() {
371 NOTIMPLEMENTED();
372 }
373
374 bool NativeWidgetMojo::IsMaximized() const {
375 return false;
376 }
377
378 bool NativeWidgetMojo::IsMinimized() const {
379 return false;
380 }
381
382 void NativeWidgetMojo::Restore() {
383 NOTIMPLEMENTED();
384 }
385
386 void NativeWidgetMojo::SetFullscreen(bool fullscreen) {
387 NOTIMPLEMENTED();
388 }
389
390 bool NativeWidgetMojo::IsFullscreen() const {
391 return false;
392 }
393
394 void NativeWidgetMojo::SetOpacity(unsigned char opacity) {
395 // TODO(erg): Also need this on mojo::View.
396 if (layer())
397 layer()->SetOpacity(opacity / 255.0);
398 }
399
400 void NativeWidgetMojo::SetUseDragFrame(bool use_drag_frame) {
401 NOTIMPLEMENTED();
402 }
403
404 void NativeWidgetMojo::FlashFrame(bool flash) {
405 NOTIMPLEMENTED();
406 }
407
408 void NativeWidgetMojo::RunShellDrag(views::View* view,
409 const ui::OSExchangeData& data,
410 const gfx::Point& location,
411 int operation,
412 ui::DragDropTypes::DragEventSource source) {
413 NOTIMPLEMENTED();
414 }
415
416 void NativeWidgetMojo::SchedulePaintInRect(const gfx::Rect& rect) {
417 layer()->SchedulePaint(rect);
418 }
419
420 void NativeWidgetMojo::SetCursor(gfx::NativeCursor cursor) {
421 // TODO(erg): Requires a cursor client. Is so spammy that we don't put down a
422 // NOTIMPLEMENTED().
423 }
424
425 bool NativeWidgetMojo::IsMouseEventsEnabled() const {
426 // TODO(erg): Requires a cursor client.
427 NOTIMPLEMENTED();
428 return true;
429 }
430
431 void NativeWidgetMojo::ClearNativeFocus() {
432 // TODO(erg): Requires an aura::client::FocusClient equivalent.
433 }
434
435 gfx::Rect NativeWidgetMojo::GetWorkAreaBoundsInScreen() const {
436 // TODO(erg): Requires a gfx::Screen equivalent.
437 return gfx::Rect();
438 }
439
440 views::Widget::MoveLoopResult NativeWidgetMojo::RunMoveLoop(
441 const gfx::Vector2d& drag_offset,
442 views::Widget::MoveLoopSource source,
443 views::Widget::MoveLoopEscapeBehavior escape_behavior) {
444 // TODO(erg): This is really complicated. Requires an
445 // aura::client::WindowMoveClient equivalent.
446 NOTIMPLEMENTED();
447 return views::Widget::MOVE_LOOP_CANCELED;
448 }
449
450 void NativeWidgetMojo::EndMoveLoop() {
451 // TODO(erg): Requires an aura::client::WindowMoveClient equivalent.
452 NOTIMPLEMENTED();
453 }
454
455 void NativeWidgetMojo::SetVisibilityChangedAnimationsEnabled(bool value) {
456 NOTIMPLEMENTED();
457 }
458
459 ui::NativeTheme* NativeWidgetMojo::GetNativeTheme() const {
460 // TODO(erg): NativeThemeAura does not actually use aura. When we remove
461 // aura, this should be renamed to not be confusing.
462 return ui::NativeThemeAura::instance();
463 }
464
465 void NativeWidgetMojo::OnRootViewLayout() {
466 }
467
468 bool NativeWidgetMojo::IsTranslucentWindowOpacitySupported() const {
469 return true;
470 }
471
472 void NativeWidgetMojo::OnSizeConstraintsChanged() {
473 // TODO(erg): In the aura version, we set Can{Maximize,Minimize,Resize}
474 // properties on our backing window from the widget_delegate(). Figure out
475 // what we do policy wise here.
476 }
477
478 void NativeWidgetMojo::RepostNativeEvent(gfx::NativeEvent native_event) {
479 // TODO(erg): Remove this method from the whole views system. The one caller
480 // is in WebDialogView, which I assume we'll never use in mojo.
481 NOTREACHED();
482 }
483
484 ////////////////////////////////////////////////////////////////////////////////
485 // NativeWidgetMojo, ui::EventHandler implementation:
486
487 void NativeWidgetMojo::OnKeyEvent(ui::KeyEvent* event) {
488 // TODO(erg): Key event handling is a pile of hurt. Rebuilding all of this
489 // means dealing with the IME. For now, punt.
490 NOTIMPLEMENTED();
491 }
492
493 void NativeWidgetMojo::OnMouseEvent(ui::MouseEvent* event) {
494 DCHECK(view_);
495 DCHECK(view_->visible());
496 if (event->type() == ui::ET_MOUSEWHEEL) {
497 delegate_->OnMouseEvent(event);
498 if (event->handled())
499 return;
500 }
501
502 // TODO(erg): In the aura version, we do something with the
503 // ToopltipManagerAura here.
504 delegate_->OnMouseEvent(event);
505 }
506
507 void NativeWidgetMojo::OnScrollEvent(ui::ScrollEvent* event) {
508 delegate_->OnScrollEvent(event);
509 }
510
511 void NativeWidgetMojo::OnGestureEvent(ui::GestureEvent* event) {
512 DCHECK(view_);
513 DCHECK(view_->visible() || event->IsEndingEvent());
514 delegate_->OnGestureEvent(event);
515 }
516
517 ////////////////////////////////////////////////////////////////////////////////
518 // NativeWidgetMojo, ViewObserver implementation:
519
520 void NativeWidgetMojo::OnViewDestroying(View* view) {
521 view->RemoveObserver(this);
522 delegate_->OnNativeWidgetDestroying();
523 }
524
525 void NativeWidgetMojo::OnViewDestroyed(View* view) {
526 DCHECK_EQ(view, view_);
527 view_ = nullptr;
528 delegate_->OnNativeWidgetDestroyed();
529 if (ownership_ == views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
530 delete this;
531 }
532
533 void NativeWidgetMojo::OnViewBoundsChanged(View* view,
534 const Rect& mojo_old_bounds,
535 const Rect& mojo_new_bounds) {
536 gfx::Rect old_bounds = mojo_old_bounds.To<gfx::Rect>();
537 gfx::Rect new_bounds = mojo_new_bounds.To<gfx::Rect>();
538
539 gfx::Size size = new_bounds.size();
540 compositor_->SetScaleAndSize(1.0f, size);
541 layer()->SetBounds(gfx::Rect(size));
542
543 // Assume that if the old bounds was completely empty a move happened. This
544 // handles the case of a maximize animation acquiring the layer (acquiring a
545 // layer results in clearing the bounds).
546 if (old_bounds.origin() != new_bounds.origin() ||
547 (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) {
548 delegate_->OnNativeWidgetMove();
549 }
550 if (old_bounds.size() != new_bounds.size())
551 delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
552 }
553
554 void NativeWidgetMojo::OnViewFocusChanged(View* gained_focus,
555 View* lost_focus) {
556 if (view_ == gained_focus) {
557 if (GetWidget()->GetInputMethod()) // Null in tests.
558 GetWidget()->GetInputMethod()->OnFocus();
559
560 // TODO(erg): We need to set mojo::View* as the gfx::NativeView. Once that
561 // is done, we can uncomment the line below.
562 //
563 // delegate_->OnNativeFocus(lost_focus);
564 } else if (view_ == lost_focus) {
565 // GetInputMethod() recreates the input method if it's previously been
566 // destroyed. If we get called during destruction, the input method will be
567 // gone, and creating a new one and telling it that we lost the focus will
568 // trigger a DCHECK (the new input method doesn't think that we have the
569 // focus and doesn't expect a blur). OnBlur() shouldn't be called during
570 // destruction unless WIDGET_OWNS_NATIVE_WIDGET is set (which is just the
571 // case in tests).
572 if (!destroying_) {
573 if (GetWidget()->GetInputMethod())
574 GetWidget()->GetInputMethod()->OnBlur();
575 } else {
576 DCHECK_EQ(ownership_,
577 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
578 }
579
580 // TODO(erg): We need to set mojo::View* as the gfx::NativeView. Once that
581 // is done, we can uncomment the line below.
582 //
583 // delegate_->OnNativeBlur(gained_focus);
584 }
585 }
586
587 void NativeWidgetMojo::OnViewInputEvent(View* view, const EventPtr& event) {
588 scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event>>());
589 if (ui_event)
590 OnEvent(ui_event.get());
591 }
592
593 // TODO(erg): Add an OnViewActivationChanged() method and plumb that from the
594 // window manager through the view manager to here.
595
596 ////////////////////////////////////////////////////////////////////////////////
597 // NativeWidgetMojo, LayerDelegate:
598
599 void NativeWidgetMojo::OnPaintLayer(gfx::Canvas* canvas) {
600 delegate_->OnNativeWidgetPaint(canvas);
601 }
602
603 void NativeWidgetMojo::OnDelegatedFrameDamage(
604 const gfx::Rect& damage_rect_in_dip) {
605 NOTIMPLEMENTED();
606 }
607
608 void NativeWidgetMojo::OnDeviceScaleFactorChanged(float device_scale_factor) {
609 NOTIMPLEMENTED();
610 }
611
612 base::Closure NativeWidgetMojo::PrepareForLayerBoundsChange() {
613 // TODO(erg): This needs a real implementation, but we don't NOTIMPLEMENTED()
614 // because spam.
615 return base::Closure();
616 }
617
618 ////////////////////////////////////////////////////////////////////////////////
619 // NativeWidgetMojo, protected:
620
621 NativeWidgetMojo::~NativeWidgetMojo() {
622 destroying_ = true;
623 if (ownership_ == views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
624 delete delegate_;
625 else
626 CloseNow();
627 }
628
629 ////////////////////////////////////////////////////////////////////////////////
630 // NativeWidgetMojo, private:
631
632 void NativeWidgetMojo::SetInitialFocus(ui::WindowShowState show_state) {
633 NOTIMPLEMENTED();
634 }
635
636 namespace internal {
637
638 ////////////////////////////////////////////////////////////////////////////////
639 // internal::NativeWidgetPrivate, public:
640
641 // TODO(erg): Re-implement the static NativeWidgetPrivate interface here. This
642 // is already implemented in NativeWidgetAura, and we can't reimplement it here
643 // until we delete it there.
644
645 } // namespace internal
646 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/views/native_widget_mojo.h ('k') | mojo/views/native_widget_view_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698