Cleanup: Update the path to gfx size headers.
[chromium-blink-merge.git] / ui / views / widget / desktop_aura / desktop_native_widget_aura.cc
blob88c60906b7268d02bffd85fdb683ef05c9bca77a
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.
5 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/client/cursor_client.h"
11 #include "ui/aura/client/focus_client.h"
12 #include "ui/aura/client/window_tree_client.h"
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_observer.h"
15 #include "ui/aura/window_property.h"
16 #include "ui/aura/window_tree_host.h"
17 #include "ui/base/hit_test.h"
18 #include "ui/base/ui_base_switches_util.h"
19 #include "ui/compositor/layer.h"
20 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/display.h"
22 #include "ui/gfx/geometry/point_conversions.h"
23 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/geometry/size_conversions.h"
25 #include "ui/gfx/screen.h"
26 #include "ui/native_theme/native_theme.h"
27 #include "ui/views/corewm/tooltip.h"
28 #include "ui/views/corewm/tooltip_controller.h"
29 #include "ui/views/drag_utils.h"
30 #include "ui/views/ime/input_method_bridge.h"
31 #include "ui/views/ime/null_input_method.h"
32 #include "ui/views/view_constants_aura.h"
33 #include "ui/views/widget/desktop_aura/desktop_capture_client.h"
34 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
35 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
36 #include "ui/views/widget/desktop_aura/desktop_event_client.h"
37 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h"
38 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
39 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
40 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
41 #include "ui/views/widget/drop_helper.h"
42 #include "ui/views/widget/native_widget_aura.h"
43 #include "ui/views/widget/root_view.h"
44 #include "ui/views/widget/tooltip_manager_aura.h"
45 #include "ui/views/widget/widget.h"
46 #include "ui/views/widget/widget_aura_utils.h"
47 #include "ui/views/widget/widget_delegate.h"
48 #include "ui/views/widget/window_reorderer.h"
49 #include "ui/views/window/native_frame_view.h"
50 #include "ui/wm/core/compound_event_filter.h"
51 #include "ui/wm/core/cursor_manager.h"
52 #include "ui/wm/core/focus_controller.h"
53 #include "ui/wm/core/input_method_event_filter.h"
54 #include "ui/wm/core/native_cursor_manager.h"
55 #include "ui/wm/core/shadow_controller.h"
56 #include "ui/wm/core/shadow_types.h"
57 #include "ui/wm/core/visibility_controller.h"
58 #include "ui/wm/core/window_animations.h"
59 #include "ui/wm/core/window_modality_controller.h"
60 #include "ui/wm/public/activation_client.h"
61 #include "ui/wm/public/drag_drop_client.h"
63 #if defined(OS_WIN)
64 #include "ui/base/win/shell.h"
65 #include "ui/gfx/win/dpi.h"
66 #endif
68 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT,
69 views::DesktopNativeWidgetAura*);
71 namespace views {
73 DEFINE_WINDOW_PROPERTY_KEY(DesktopNativeWidgetAura*,
74 kDesktopNativeWidgetAuraKey, NULL);
76 namespace {
78 // This class provides functionality to create a top level widget to host a
79 // child window.
80 class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver {
81 public:
82 // This function creates a widget with the bounds passed in which eventually
83 // becomes the parent of the child window passed in.
84 static aura::Window* CreateParentWindow(aura::Window* child_window,
85 const gfx::Rect& bounds,
86 bool full_screen,
87 bool root_is_always_on_top) {
88 // This instance will get deleted when the widget is destroyed.
89 DesktopNativeWidgetTopLevelHandler* top_level_handler =
90 new DesktopNativeWidgetTopLevelHandler;
92 child_window->SetBounds(gfx::Rect(bounds.size()));
94 Widget::InitParams init_params;
95 init_params.type = full_screen ? Widget::InitParams::TYPE_WINDOW :
96 Widget::InitParams::TYPE_POPUP;
97 init_params.bounds = bounds;
98 init_params.ownership = Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
99 init_params.layer_type = aura::WINDOW_LAYER_NOT_DRAWN;
100 init_params.activatable = full_screen ?
101 Widget::InitParams::ACTIVATABLE_YES :
102 Widget::InitParams::ACTIVATABLE_NO;
103 init_params.keep_on_top = root_is_always_on_top;
105 // This widget instance will get deleted when the window is
106 // destroyed.
107 top_level_handler->top_level_widget_ = new Widget();
108 top_level_handler->top_level_widget_->Init(init_params);
110 top_level_handler->top_level_widget_->SetFullscreen(full_screen);
111 top_level_handler->top_level_widget_->Show();
113 aura::Window* native_window =
114 top_level_handler->top_level_widget_->GetNativeView();
115 child_window->AddObserver(top_level_handler);
116 native_window->AddObserver(top_level_handler);
117 top_level_handler->child_window_ = child_window;
118 return native_window;
121 // aura::WindowObserver overrides
122 void OnWindowDestroying(aura::Window* window) override {
123 window->RemoveObserver(this);
125 // If the widget is being destroyed by the OS then we should not try and
126 // destroy it again.
127 if (top_level_widget_ &&
128 window == top_level_widget_->GetNativeView()) {
129 top_level_widget_ = NULL;
130 return;
133 if (top_level_widget_) {
134 DCHECK(top_level_widget_->GetNativeView());
135 top_level_widget_->GetNativeView()->RemoveObserver(this);
136 // When we receive a notification that the child of the window created
137 // above is being destroyed we go ahead and initiate the destruction of
138 // the corresponding widget.
139 top_level_widget_->Close();
140 top_level_widget_ = NULL;
142 delete this;
145 void OnWindowBoundsChanged(aura::Window* window,
146 const gfx::Rect& old_bounds,
147 const gfx::Rect& new_bounds) override {
148 if (top_level_widget_ && window == child_window_)
149 top_level_widget_->SetSize(new_bounds.size());
152 private:
153 DesktopNativeWidgetTopLevelHandler()
154 : top_level_widget_(NULL),
155 child_window_(NULL) {}
157 ~DesktopNativeWidgetTopLevelHandler() override {}
159 Widget* top_level_widget_;
160 aura::Window* child_window_;
162 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetTopLevelHandler);
165 class DesktopNativeWidgetAuraWindowTreeClient :
166 public aura::client::WindowTreeClient {
167 public:
168 explicit DesktopNativeWidgetAuraWindowTreeClient(
169 aura::Window* root_window)
170 : root_window_(root_window) {
171 aura::client::SetWindowTreeClient(root_window_, this);
173 ~DesktopNativeWidgetAuraWindowTreeClient() override {
174 aura::client::SetWindowTreeClient(root_window_, NULL);
177 // Overridden from client::WindowTreeClient:
178 aura::Window* GetDefaultParent(aura::Window* context,
179 aura::Window* window,
180 const gfx::Rect& bounds) override {
181 bool is_fullscreen = window->GetProperty(aura::client::kShowStateKey) ==
182 ui::SHOW_STATE_FULLSCREEN;
183 bool is_menu = window->type() == ui::wm::WINDOW_TYPE_MENU;
185 if (is_fullscreen || is_menu) {
186 bool root_is_always_on_top = false;
187 internal::NativeWidgetPrivate* native_widget =
188 DesktopNativeWidgetAura::ForWindow(root_window_);
189 if (native_widget)
190 root_is_always_on_top = native_widget->IsAlwaysOnTop();
192 return DesktopNativeWidgetTopLevelHandler::CreateParentWindow(
193 window, bounds, is_fullscreen, root_is_always_on_top);
195 return root_window_;
198 private:
199 aura::Window* root_window_;
201 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetAuraWindowTreeClient);
204 } // namespace
206 class FocusManagerEventHandler : public ui::EventHandler {
207 public:
208 FocusManagerEventHandler(DesktopNativeWidgetAura* desktop_native_widget_aura)
209 : desktop_native_widget_aura_(desktop_native_widget_aura) {}
211 // Implementation of ui::EventHandler:
212 void OnKeyEvent(ui::KeyEvent* event) override {
213 Widget* widget = desktop_native_widget_aura_->GetWidget();
214 if (widget && widget->GetFocusManager()->GetFocusedView() &&
215 !widget->GetFocusManager()->OnKeyEvent(*event)) {
216 event->SetHandled();
220 private:
221 DesktopNativeWidgetAura* desktop_native_widget_aura_;
223 DISALLOW_COPY_AND_ASSIGN(FocusManagerEventHandler);
226 class RootWindowDestructionObserver : public aura::WindowObserver {
227 public:
228 explicit RootWindowDestructionObserver(DesktopNativeWidgetAura* parent)
229 : parent_(parent) {}
230 ~RootWindowDestructionObserver() override {}
232 private:
233 // Overridden from aura::WindowObserver:
234 void OnWindowDestroyed(aura::Window* window) override {
235 parent_->RootWindowDestroyed();
236 window->RemoveObserver(this);
237 delete this;
240 DesktopNativeWidgetAura* parent_;
242 DISALLOW_COPY_AND_ASSIGN(RootWindowDestructionObserver);
245 ////////////////////////////////////////////////////////////////////////////////
246 // DesktopNativeWidgetAura, public:
248 int DesktopNativeWidgetAura::cursor_reference_count_ = 0;
249 DesktopNativeCursorManager* DesktopNativeWidgetAura::native_cursor_manager_ =
250 NULL;
251 wm::CursorManager* DesktopNativeWidgetAura::cursor_manager_ = NULL;
253 DesktopNativeWidgetAura::DesktopNativeWidgetAura(
254 internal::NativeWidgetDelegate* delegate)
255 : desktop_window_tree_host_(NULL),
256 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
257 content_window_container_(NULL),
258 content_window_(new aura::Window(this)),
259 native_widget_delegate_(delegate),
260 last_drop_operation_(ui::DragDropTypes::DRAG_NONE),
261 restore_focus_on_activate_(false),
262 cursor_(gfx::kNullCursor),
263 widget_type_(Widget::InitParams::TYPE_WINDOW),
264 close_widget_factory_(this) {
265 aura::client::SetFocusChangeObserver(content_window_, this);
266 aura::client::SetActivationChangeObserver(content_window_, this);
269 DesktopNativeWidgetAura::~DesktopNativeWidgetAura() {
270 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
271 delete native_widget_delegate_;
272 else
273 CloseNow();
276 // static
277 DesktopNativeWidgetAura* DesktopNativeWidgetAura::ForWindow(
278 aura::Window* window) {
279 return window->GetProperty(kDesktopNativeWidgetAuraKey);
282 void DesktopNativeWidgetAura::OnHostClosed() {
283 // Don't invoke Widget::OnNativeWidgetDestroying(), its done by
284 // DesktopWindowTreeHost.
286 // The WindowModalityController is at the front of the event pretarget
287 // handler list. We destroy it first to preserve order symantics.
288 if (window_modality_controller_)
289 window_modality_controller_.reset();
291 // Make sure we don't have capture. Otherwise CaptureController and
292 // WindowEventDispatcher are left referencing a deleted Window.
294 aura::Window* capture_window = capture_client_->GetCaptureWindow();
295 if (capture_window && host_->window()->Contains(capture_window))
296 capture_window->ReleaseCapture();
299 // DesktopWindowTreeHost owns the ActivationController which ShadowController
300 // references. Make sure we destroy ShadowController early on.
301 shadow_controller_.reset();
302 tooltip_manager_.reset();
303 if (tooltip_controller_.get()) {
304 host_->window()->RemovePreTargetHandler(tooltip_controller_.get());
305 aura::client::SetTooltipClient(host_->window(), NULL);
306 tooltip_controller_.reset();
309 root_window_event_filter_->RemoveHandler(input_method_event_filter_.get());
311 window_tree_client_.reset(); // Uses host_->dispatcher() at destruction.
313 capture_client_.reset(); // Uses host_->dispatcher() at destruction.
315 // FocusController uses |content_window_|. Destroy it now so that we don't
316 // have to worry about the possibility of FocusController attempting to use
317 // |content_window_| after it's been destroyed but before all child windows
318 // have been destroyed.
319 host_->window()->RemovePreTargetHandler(focus_client_.get());
320 aura::client::SetFocusClient(host_->window(), NULL);
321 aura::client::SetActivationClient(host_->window(), NULL);
322 focus_client_.reset();
324 host_->RemoveObserver(this);
325 host_.reset(); // Uses input_method_event_filter_ at destruction.
326 // WindowEventDispatcher owns |desktop_window_tree_host_|.
327 desktop_window_tree_host_ = NULL;
328 content_window_ = NULL;
330 native_widget_delegate_->OnNativeWidgetDestroyed();
331 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
332 delete this;
335 void DesktopNativeWidgetAura::OnDesktopWindowTreeHostDestroyed(
336 aura::WindowTreeHost* host) {
337 // |dispatcher_| is still valid, but DesktopWindowTreeHost is nearly
338 // destroyed. Do cleanup here of members DesktopWindowTreeHost may also use.
339 aura::client::SetDispatcherClient(host->window(), NULL);
340 dispatcher_client_.reset();
342 // We explicitly do NOT clear the cursor client property. Since the cursor
343 // manager is a singleton, it can outlive any window hierarchy, and it's
344 // important that objects attached to this destroying window hierarchy have
345 // an opportunity to deregister their observers from the cursor manager.
346 // They may want to do this when they are notified that they're being
347 // removed from the window hierarchy, which happens soon after this
348 // function when DesktopWindowTreeHost* calls DestroyDispatcher().
349 native_cursor_manager_->RemoveHost(host);
351 aura::client::SetScreenPositionClient(host->window(), NULL);
352 position_client_.reset();
354 aura::client::SetDragDropClient(host->window(), NULL);
355 drag_drop_client_.reset();
357 aura::client::SetEventClient(host->window(), NULL);
358 event_client_.reset();
361 void DesktopNativeWidgetAura::HandleActivationChanged(bool active) {
362 native_widget_delegate_->OnNativeWidgetActivationChanged(active);
363 aura::client::ActivationClient* activation_client =
364 aura::client::GetActivationClient(host_->window());
365 if (!activation_client)
366 return;
367 if (active) {
368 if (GetWidget()->HasFocusManager()) {
369 // This function can be called before the focus manager has had a
370 // chance to set the focused view. In which case we should get the
371 // last focused view.
372 View* view_for_activation =
373 GetWidget()->GetFocusManager()->GetFocusedView() ?
374 GetWidget()->GetFocusManager()->GetFocusedView() :
375 GetWidget()->GetFocusManager()->GetStoredFocusView();
376 if (!view_for_activation)
377 view_for_activation = GetWidget()->GetRootView();
378 activation_client->ActivateWindow(
379 view_for_activation->GetWidget()->GetNativeView());
381 } else {
382 // If we're not active we need to deactivate the corresponding
383 // aura::Window. This way if a child widget is active it gets correctly
384 // deactivated (child widgets don't get native desktop activation changes,
385 // only aura activation changes).
386 aura::Window* active_window = activation_client->GetActiveWindow();
387 if (active_window)
388 activation_client->DeactivateWindow(active_window);
392 ////////////////////////////////////////////////////////////////////////////////
393 // DesktopNativeWidgetAura, internal::NativeWidgetPrivate implementation:
395 void DesktopNativeWidgetAura::InitNativeWidget(
396 const Widget::InitParams& params) {
397 ownership_ = params.ownership;
398 widget_type_ = params.type;
400 NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_);
401 // Animations on TYPE_WINDOW are handled by the OS. Additionally if we animate
402 // these windows the size of the window gets augmented, effecting restore
403 // bounds and maximized windows in bad ways.
404 if (params.type == Widget::InitParams::TYPE_WINDOW &&
405 !params.remove_standard_frame) {
406 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, true);
408 content_window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
409 content_window_->Init(params.layer_type);
410 wm::SetShadowType(content_window_, wm::SHADOW_TYPE_NONE);
412 content_window_container_ = new aura::Window(NULL);
413 content_window_container_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
414 content_window_container_->Show();
415 content_window_container_->AddChild(content_window_);
417 desktop_window_tree_host_ = params.desktop_window_tree_host ?
418 params.desktop_window_tree_host :
419 DesktopWindowTreeHost::Create(native_widget_delegate_, this);
420 host_.reset(desktop_window_tree_host_->AsWindowTreeHost());
421 desktop_window_tree_host_->Init(content_window_, params);
423 host_->InitHost();
424 host_->window()->AddChild(content_window_container_);
425 host_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this);
427 host_->window()->AddObserver(new RootWindowDestructionObserver(this));
429 // The WindowsModalityController event filter should be at the head of the
430 // pre target handlers list. This ensures that it handles input events first
431 // when modal windows are at the top of the Zorder.
432 if (widget_type_ == Widget::InitParams::TYPE_WINDOW)
433 window_modality_controller_.reset(
434 new wm::WindowModalityController(host_->window()));
436 // |root_window_event_filter_| must be created before
437 // OnWindowTreeHostCreated() is invoked.
439 // CEF sets focus to the window the user clicks down on.
440 // TODO(beng): see if we can't do this some other way. CEF seems a heavy-
441 // handed way of accomplishing focus.
442 // No event filter for aura::Env. Create CompoundEventFilter per
443 // WindowEventDispatcher.
444 root_window_event_filter_.reset(new wm::CompoundEventFilter);
445 host_->window()->AddPreTargetHandler(root_window_event_filter_.get());
447 // The host's dispatcher must be added to |native_cursor_manager_| before
448 // OnNativeWidgetCreated() is called.
449 cursor_reference_count_++;
450 if (!native_cursor_manager_) {
451 native_cursor_manager_ = new DesktopNativeCursorManager(
452 DesktopCursorLoaderUpdater::Create());
454 if (!cursor_manager_) {
455 cursor_manager_ = new wm::CursorManager(
456 scoped_ptr<wm::NativeCursorManager>(native_cursor_manager_));
458 native_cursor_manager_->AddHost(host());
459 aura::client::SetCursorClient(host_->window(), cursor_manager_);
461 desktop_window_tree_host_->OnNativeWidgetCreated(params);
463 UpdateWindowTransparency();
465 capture_client_.reset(new DesktopCaptureClient(host_->window()));
467 wm::FocusController* focus_controller =
468 new wm::FocusController(new DesktopFocusRules(content_window_));
469 focus_client_.reset(focus_controller);
470 aura::client::SetFocusClient(host_->window(), focus_controller);
471 aura::client::SetActivationClient(host_->window(), focus_controller);
472 host_->window()->AddPreTargetHandler(focus_controller);
474 dispatcher_client_.reset(new DesktopDispatcherClient);
475 aura::client::SetDispatcherClient(host_->window(),
476 dispatcher_client_.get());
478 position_client_.reset(new DesktopScreenPositionClient(host_->window()));
480 InstallInputMethodEventFilter();
482 drag_drop_client_ = desktop_window_tree_host_->CreateDragDropClient(
483 native_cursor_manager_);
484 aura::client::SetDragDropClient(host_->window(),
485 drag_drop_client_.get());
487 static_cast<aura::client::FocusClient*>(focus_client_.get())->
488 FocusWindow(content_window_);
490 OnHostResized(host());
492 host_->AddObserver(this);
494 window_tree_client_.reset(
495 new DesktopNativeWidgetAuraWindowTreeClient(host_->window()));
496 drop_helper_.reset(new DropHelper(GetWidget()->GetRootView()));
497 aura::client::SetDragDropDelegate(content_window_, this);
499 if (params.type != Widget::InitParams::TYPE_TOOLTIP) {
500 tooltip_manager_.reset(new TooltipManagerAura(GetWidget()));
501 tooltip_controller_.reset(
502 new corewm::TooltipController(
503 desktop_window_tree_host_->CreateTooltip()));
504 aura::client::SetTooltipClient(host_->window(),
505 tooltip_controller_.get());
506 host_->window()->AddPreTargetHandler(tooltip_controller_.get());
509 if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) {
510 visibility_controller_.reset(new wm::VisibilityController);
511 aura::client::SetVisibilityClient(host_->window(),
512 visibility_controller_.get());
513 wm::SetChildWindowVisibilityChangesAnimated(host_->window());
514 wm::SetChildWindowVisibilityChangesAnimated(
515 content_window_container_);
518 if (params.type == Widget::InitParams::TYPE_WINDOW) {
519 focus_manager_event_handler_.reset(new FocusManagerEventHandler(this));
520 host_->window()->AddPreTargetHandler(focus_manager_event_handler_.get());
523 event_client_.reset(new DesktopEventClient);
524 aura::client::SetEventClient(host_->window(), event_client_.get());
526 aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
528 aura::client::SetActivationDelegate(content_window_, this);
530 shadow_controller_.reset(new wm::ShadowController(
531 aura::client::GetActivationClient(host_->window())));
533 OnSizeConstraintsChanged();
535 window_reorderer_.reset(new WindowReorderer(content_window_,
536 GetWidget()->GetRootView()));
539 NonClientFrameView* DesktopNativeWidgetAura::CreateNonClientFrameView() {
540 return ShouldUseNativeFrame() ? new NativeFrameView(GetWidget()) : NULL;
543 bool DesktopNativeWidgetAura::ShouldUseNativeFrame() const {
544 return desktop_window_tree_host_->ShouldUseNativeFrame();
547 bool DesktopNativeWidgetAura::ShouldWindowContentsBeTransparent() const {
548 return desktop_window_tree_host_->ShouldWindowContentsBeTransparent();
551 void DesktopNativeWidgetAura::FrameTypeChanged() {
552 desktop_window_tree_host_->FrameTypeChanged();
553 UpdateWindowTransparency();
556 Widget* DesktopNativeWidgetAura::GetWidget() {
557 return native_widget_delegate_->AsWidget();
560 const Widget* DesktopNativeWidgetAura::GetWidget() const {
561 return native_widget_delegate_->AsWidget();
564 gfx::NativeView DesktopNativeWidgetAura::GetNativeView() const {
565 return content_window_;
568 gfx::NativeWindow DesktopNativeWidgetAura::GetNativeWindow() const {
569 return content_window_;
572 Widget* DesktopNativeWidgetAura::GetTopLevelWidget() {
573 return GetWidget();
576 const ui::Compositor* DesktopNativeWidgetAura::GetCompositor() const {
577 return content_window_ ? content_window_->layer()->GetCompositor() : NULL;
580 const ui::Layer* DesktopNativeWidgetAura::GetLayer() const {
581 return content_window_ ? content_window_->layer() : NULL;
584 void DesktopNativeWidgetAura::ReorderNativeViews() {
585 window_reorderer_->ReorderChildWindows();
588 void DesktopNativeWidgetAura::ViewRemoved(View* view) {
589 DCHECK(drop_helper_.get() != NULL);
590 drop_helper_->ResetTargetViewIfEquals(view);
593 void DesktopNativeWidgetAura::SetNativeWindowProperty(const char* name,
594 void* value) {
595 if (content_window_)
596 content_window_->SetNativeWindowProperty(name, value);
599 void* DesktopNativeWidgetAura::GetNativeWindowProperty(const char* name) const {
600 return content_window_ ?
601 content_window_->GetNativeWindowProperty(name) : NULL;
604 TooltipManager* DesktopNativeWidgetAura::GetTooltipManager() const {
605 return tooltip_manager_.get();
608 void DesktopNativeWidgetAura::SetCapture() {
609 if (!content_window_)
610 return;
612 content_window_->SetCapture();
615 void DesktopNativeWidgetAura::ReleaseCapture() {
616 if (!content_window_)
617 return;
619 content_window_->ReleaseCapture();
622 bool DesktopNativeWidgetAura::HasCapture() const {
623 return content_window_ && content_window_->HasCapture() &&
624 desktop_window_tree_host_->HasCapture();
627 InputMethod* DesktopNativeWidgetAura::CreateInputMethod() {
628 if (switches::IsTextInputFocusManagerEnabled())
629 return new NullInputMethod();
631 ui::InputMethod* host = input_method_event_filter_->input_method();
632 return new InputMethodBridge(this, host, false);
635 internal::InputMethodDelegate*
636 DesktopNativeWidgetAura::GetInputMethodDelegate() {
637 return this;
640 ui::InputMethod* DesktopNativeWidgetAura::GetHostInputMethod() {
641 return input_method_event_filter_->input_method();
644 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
645 if (content_window_)
646 desktop_window_tree_host_->CenterWindow(size);
649 void DesktopNativeWidgetAura::GetWindowPlacement(
650 gfx::Rect* bounds,
651 ui::WindowShowState* maximized) const {
652 if (content_window_)
653 desktop_window_tree_host_->GetWindowPlacement(bounds, maximized);
656 bool DesktopNativeWidgetAura::SetWindowTitle(const base::string16& title) {
657 if (!content_window_)
658 return false;
659 return desktop_window_tree_host_->SetWindowTitle(title);
662 void DesktopNativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
663 const gfx::ImageSkia& app_icon) {
664 if (content_window_)
665 desktop_window_tree_host_->SetWindowIcons(window_icon, app_icon);
668 void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type) {
669 // 99% of the time, we should not be asked to create a
670 // DesktopNativeWidgetAura that is modal. We only support window modal
671 // dialogs on the same lines as non AURA.
672 desktop_window_tree_host_->InitModalType(modal_type);
675 gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
676 return content_window_ ?
677 desktop_window_tree_host_->GetWindowBoundsInScreen() : gfx::Rect();
680 gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
681 return content_window_ ?
682 desktop_window_tree_host_->GetClientAreaBoundsInScreen() : gfx::Rect();
685 gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
686 return content_window_ ?
687 desktop_window_tree_host_->GetRestoredBounds() : gfx::Rect();
690 void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
691 if (!content_window_)
692 return;
693 // TODO(ananta)
694 // This code by default scales the bounds rectangle by 1.
695 // We could probably get rid of this and similar logic from
696 // the DesktopNativeWidgetAura::OnWindowTreeHostResized function.
697 float scale = 1;
698 aura::Window* root = host_->window();
699 if (root) {
700 scale = gfx::Screen::GetScreenFor(root)->
701 GetDisplayNearestWindow(root).device_scale_factor();
703 gfx::Rect bounds_in_pixels =
704 gfx::ScaleToEnclosingRect(bounds, scale, scale);
705 desktop_window_tree_host_->AsWindowTreeHost()->SetBounds(bounds_in_pixels);
708 void DesktopNativeWidgetAura::SetSize(const gfx::Size& size) {
709 if (content_window_)
710 desktop_window_tree_host_->SetSize(size);
713 void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view) {
716 void DesktopNativeWidgetAura::StackAtTop() {
717 if (content_window_)
718 desktop_window_tree_host_->StackAtTop();
721 void DesktopNativeWidgetAura::StackBelow(gfx::NativeView native_view) {
724 void DesktopNativeWidgetAura::SetShape(gfx::NativeRegion shape) {
725 if (content_window_)
726 desktop_window_tree_host_->SetShape(shape);
729 void DesktopNativeWidgetAura::Close() {
730 if (!content_window_)
731 return;
733 content_window_->SuppressPaint();
734 content_window_->Hide();
736 desktop_window_tree_host_->Close();
739 void DesktopNativeWidgetAura::CloseNow() {
740 if (content_window_)
741 desktop_window_tree_host_->CloseNow();
744 void DesktopNativeWidgetAura::Show() {
745 if (!content_window_)
746 return;
747 desktop_window_tree_host_->AsWindowTreeHost()->Show();
748 content_window_->Show();
751 void DesktopNativeWidgetAura::Hide() {
752 if (!content_window_)
753 return;
754 desktop_window_tree_host_->AsWindowTreeHost()->Hide();
755 content_window_->Hide();
758 void DesktopNativeWidgetAura::ShowMaximizedWithBounds(
759 const gfx::Rect& restored_bounds) {
760 if (!content_window_)
761 return;
762 desktop_window_tree_host_->ShowMaximizedWithBounds(restored_bounds);
763 content_window_->Show();
766 void DesktopNativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
767 if (!content_window_)
768 return;
769 desktop_window_tree_host_->ShowWindowWithState(state);
770 content_window_->Show();
773 bool DesktopNativeWidgetAura::IsVisible() const {
774 return content_window_ && desktop_window_tree_host_->IsVisible();
777 void DesktopNativeWidgetAura::Activate() {
778 if (content_window_)
779 desktop_window_tree_host_->Activate();
782 void DesktopNativeWidgetAura::Deactivate() {
783 if (content_window_)
784 desktop_window_tree_host_->Deactivate();
787 bool DesktopNativeWidgetAura::IsActive() const {
788 return content_window_ && desktop_window_tree_host_->IsActive();
791 void DesktopNativeWidgetAura::SetAlwaysOnTop(bool always_on_top) {
792 if (content_window_)
793 desktop_window_tree_host_->SetAlwaysOnTop(always_on_top);
796 bool DesktopNativeWidgetAura::IsAlwaysOnTop() const {
797 return content_window_ && desktop_window_tree_host_->IsAlwaysOnTop();
800 void DesktopNativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) {
801 if (content_window_)
802 desktop_window_tree_host_->SetVisibleOnAllWorkspaces(always_visible);
805 void DesktopNativeWidgetAura::Maximize() {
806 if (content_window_)
807 desktop_window_tree_host_->Maximize();
810 void DesktopNativeWidgetAura::Minimize() {
811 if (content_window_)
812 desktop_window_tree_host_->Minimize();
815 bool DesktopNativeWidgetAura::IsMaximized() const {
816 return content_window_ && desktop_window_tree_host_->IsMaximized();
819 bool DesktopNativeWidgetAura::IsMinimized() const {
820 return content_window_ && desktop_window_tree_host_->IsMinimized();
823 void DesktopNativeWidgetAura::Restore() {
824 if (content_window_)
825 desktop_window_tree_host_->Restore();
828 void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen) {
829 if (content_window_)
830 desktop_window_tree_host_->SetFullscreen(fullscreen);
833 bool DesktopNativeWidgetAura::IsFullscreen() const {
834 return content_window_ && desktop_window_tree_host_->IsFullscreen();
837 void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity) {
838 if (content_window_)
839 desktop_window_tree_host_->SetOpacity(opacity);
842 void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
845 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
846 if (content_window_)
847 desktop_window_tree_host_->FlashFrame(flash_frame);
850 void DesktopNativeWidgetAura::RunShellDrag(
851 View* view,
852 const ui::OSExchangeData& data,
853 const gfx::Point& location,
854 int operation,
855 ui::DragDropTypes::DragEventSource source) {
856 views::RunShellDrag(content_window_, data, location, operation, source);
859 void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
860 if (content_window_)
861 content_window_->SchedulePaintInRect(rect);
864 void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
865 cursor_ = cursor;
866 aura::client::CursorClient* cursor_client =
867 aura::client::GetCursorClient(host_->window());
868 if (cursor_client)
869 cursor_client->SetCursor(cursor);
872 bool DesktopNativeWidgetAura::IsMouseEventsEnabled() const {
873 if (!content_window_)
874 return false;
875 aura::client::CursorClient* cursor_client =
876 aura::client::GetCursorClient(host_->window());
877 return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
880 void DesktopNativeWidgetAura::ClearNativeFocus() {
881 desktop_window_tree_host_->ClearNativeFocus();
883 if (ShouldActivate()) {
884 aura::client::GetFocusClient(content_window_)->
885 ResetFocusWithinActiveWindow(content_window_);
889 gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const {
890 return desktop_window_tree_host_ ?
891 desktop_window_tree_host_->GetWorkAreaBoundsInScreen() : gfx::Rect();
894 Widget::MoveLoopResult DesktopNativeWidgetAura::RunMoveLoop(
895 const gfx::Vector2d& drag_offset,
896 Widget::MoveLoopSource source,
897 Widget::MoveLoopEscapeBehavior escape_behavior) {
898 if (!content_window_)
899 return Widget::MOVE_LOOP_CANCELED;
900 return desktop_window_tree_host_->RunMoveLoop(drag_offset, source,
901 escape_behavior);
904 void DesktopNativeWidgetAura::EndMoveLoop() {
905 if (content_window_)
906 desktop_window_tree_host_->EndMoveLoop();
909 void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled(
910 bool value) {
911 if (content_window_)
912 desktop_window_tree_host_->SetVisibilityChangedAnimationsEnabled(value);
915 void DesktopNativeWidgetAura::SetVisibilityAnimationDuration(
916 const base::TimeDelta& duration) {
917 wm::SetWindowVisibilityAnimationDuration(content_window_, duration);
920 void DesktopNativeWidgetAura::SetVisibilityAnimationTransition(
921 Widget::VisibilityTransition transition) {
922 wm::WindowVisibilityAnimationTransition wm_transition = wm::ANIMATE_NONE;
923 switch (transition) {
924 case Widget::ANIMATE_SHOW:
925 wm_transition = wm::ANIMATE_SHOW;
926 break;
927 case Widget::ANIMATE_HIDE:
928 wm_transition = wm::ANIMATE_HIDE;
929 break;
930 case Widget::ANIMATE_BOTH:
931 wm_transition = wm::ANIMATE_BOTH;
932 break;
933 case Widget::ANIMATE_NONE:
934 wm_transition = wm::ANIMATE_NONE;
935 break;
937 wm::SetWindowVisibilityAnimationTransition(content_window_, wm_transition);
940 ui::NativeTheme* DesktopNativeWidgetAura::GetNativeTheme() const {
941 return DesktopWindowTreeHost::GetNativeTheme(content_window_);
944 void DesktopNativeWidgetAura::OnRootViewLayout() {
945 if (content_window_)
946 desktop_window_tree_host_->OnRootViewLayout();
949 bool DesktopNativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
950 return content_window_ &&
951 desktop_window_tree_host_->IsTranslucentWindowOpacitySupported();
954 void DesktopNativeWidgetAura::OnSizeConstraintsChanged() {
955 content_window_->SetProperty(aura::client::kCanMaximizeKey,
956 GetWidget()->widget_delegate()->CanMaximize());
957 content_window_->SetProperty(aura::client::kCanMinimizeKey,
958 GetWidget()->widget_delegate()->CanMinimize());
959 content_window_->SetProperty(aura::client::kCanResizeKey,
960 GetWidget()->widget_delegate()->CanResize());
961 desktop_window_tree_host_->SizeConstraintsChanged();
964 void DesktopNativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event) {
965 OnEvent(native_event);
968 ////////////////////////////////////////////////////////////////////////////////
969 // DesktopNativeWidgetAura, aura::WindowDelegate implementation:
971 gfx::Size DesktopNativeWidgetAura::GetMinimumSize() const {
972 return native_widget_delegate_->GetMinimumSize();
975 gfx::Size DesktopNativeWidgetAura::GetMaximumSize() const {
976 return native_widget_delegate_->GetMaximumSize();
979 gfx::NativeCursor DesktopNativeWidgetAura::GetCursor(const gfx::Point& point) {
980 return cursor_;
983 int DesktopNativeWidgetAura::GetNonClientComponent(
984 const gfx::Point& point) const {
985 return native_widget_delegate_->GetNonClientComponent(point);
988 bool DesktopNativeWidgetAura::ShouldDescendIntoChildForEventHandling(
989 aura::Window* child,
990 const gfx::Point& location) {
991 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
992 return !widget_delegate ||
993 widget_delegate->ShouldDescendIntoChildForEventHandling(child, location);
996 bool DesktopNativeWidgetAura::CanFocus() {
997 return true;
1000 void DesktopNativeWidgetAura::OnCaptureLost() {
1001 native_widget_delegate_->OnMouseCaptureLost();
1004 void DesktopNativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
1005 native_widget_delegate_->OnNativeWidgetPaint(canvas);
1008 void DesktopNativeWidgetAura::OnDeviceScaleFactorChanged(
1009 float device_scale_factor) {
1012 void DesktopNativeWidgetAura::OnWindowDestroying(aura::Window* window) {
1013 // Cleanup happens in OnHostClosed().
1016 void DesktopNativeWidgetAura::OnWindowDestroyed(aura::Window* window) {
1017 // Cleanup happens in OnHostClosed(). We own |content_window_| (indirectly by
1018 // way of |dispatcher_|) so there should be no need to do any processing
1019 // here.
1022 void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
1025 bool DesktopNativeWidgetAura::HasHitTestMask() const {
1026 return native_widget_delegate_->HasHitTestMask();
1029 void DesktopNativeWidgetAura::GetHitTestMask(gfx::Path* mask) const {
1030 native_widget_delegate_->GetHitTestMask(mask);
1033 ////////////////////////////////////////////////////////////////////////////////
1034 // DesktopNativeWidgetAura, ui::EventHandler implementation:
1036 void DesktopNativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
1037 if (event->is_char()) {
1038 // If a ui::InputMethod object is attached to the root window, character
1039 // events are handled inside the object and are not passed to this function.
1040 // If such object is not attached, character events might be sent (e.g. on
1041 // Windows). In this case, we just skip these.
1042 return;
1044 // Renderer may send a key event back to us if the key event wasn't handled,
1045 // and the window may be invisible by that time.
1046 if (!content_window_->IsVisible())
1047 return;
1049 native_widget_delegate_->OnKeyEvent(event);
1050 if (event->handled())
1051 return;
1053 if (GetWidget()->HasFocusManager() &&
1054 !GetWidget()->GetFocusManager()->OnKeyEvent(*event))
1055 event->SetHandled();
1058 void DesktopNativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
1059 DCHECK(content_window_->IsVisible());
1060 if (tooltip_manager_.get())
1061 tooltip_manager_->UpdateTooltip();
1062 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
1063 native_widget_delegate_->OnMouseEvent(event);
1064 // WARNING: we may have been deleted.
1067 void DesktopNativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
1068 if (event->type() == ui::ET_SCROLL) {
1069 native_widget_delegate_->OnScrollEvent(event);
1070 if (event->handled())
1071 return;
1073 // Convert unprocessed scroll events into wheel events.
1074 ui::MouseWheelEvent mwe(*static_cast<ui::ScrollEvent*>(event));
1075 native_widget_delegate_->OnMouseEvent(&mwe);
1076 if (mwe.handled())
1077 event->SetHandled();
1078 } else {
1079 native_widget_delegate_->OnScrollEvent(event);
1083 void DesktopNativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
1084 native_widget_delegate_->OnGestureEvent(event);
1087 ////////////////////////////////////////////////////////////////////////////////
1088 // DesktopNativeWidgetAura, aura::client::ActivationDelegate implementation:
1090 bool DesktopNativeWidgetAura::ShouldActivate() const {
1091 return native_widget_delegate_->CanActivate();
1094 ////////////////////////////////////////////////////////////////////////////////
1095 // DesktopNativeWidgetAura, aura::client::ActivationChangeObserver
1096 // implementation:
1098 void DesktopNativeWidgetAura::OnWindowActivated(aura::Window* gained_active,
1099 aura::Window* lost_active) {
1100 DCHECK(content_window_ == gained_active || content_window_ == lost_active);
1101 if (gained_active == content_window_ && restore_focus_on_activate_) {
1102 restore_focus_on_activate_ = false;
1103 GetWidget()->GetFocusManager()->RestoreFocusedView();
1104 } else if (lost_active == content_window_ && GetWidget()->HasFocusManager()) {
1105 DCHECK(!restore_focus_on_activate_);
1106 restore_focus_on_activate_ = true;
1107 // Pass in false so that ClearNativeFocus() isn't invoked.
1108 GetWidget()->GetFocusManager()->StoreFocusedView(false);
1112 ////////////////////////////////////////////////////////////////////////////////
1113 // DesktopNativeWidgetAura, aura::client::FocusChangeObserver implementation:
1115 void DesktopNativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
1116 aura::Window* lost_focus) {
1117 if (content_window_ == gained_focus) {
1118 desktop_window_tree_host_->OnNativeWidgetFocus();
1119 native_widget_delegate_->OnNativeFocus(lost_focus);
1121 // If focus is moving from a descendant Window to |content_window_| then
1122 // native activation hasn't changed. Still, the InputMethod must be informed
1123 // of the Window focus change.
1124 InputMethod* input_method = GetWidget()->GetInputMethod();
1125 if (input_method)
1126 input_method->OnFocus();
1127 } else if (content_window_ == lost_focus) {
1128 desktop_window_tree_host_->OnNativeWidgetBlur();
1129 native_widget_delegate_->OnNativeBlur(gained_focus);
1133 ////////////////////////////////////////////////////////////////////////////////
1134 // DesktopNativeWidgetAura, views::internal::InputMethodDelegate:
1136 void DesktopNativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
1137 FocusManager* focus_manager =
1138 native_widget_delegate_->AsWidget()->GetFocusManager();
1139 native_widget_delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
1140 if (key.handled() || !focus_manager)
1141 return;
1142 focus_manager->OnKeyEvent(key);
1145 ////////////////////////////////////////////////////////////////////////////////
1146 // DesktopNativeWidgetAura, aura::WindowDragDropDelegate implementation:
1148 void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
1149 DCHECK(drop_helper_.get() != NULL);
1150 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
1151 event.location(), event.source_operations());
1154 int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
1155 DCHECK(drop_helper_.get() != NULL);
1156 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
1157 event.location(), event.source_operations());
1158 return last_drop_operation_;
1161 void DesktopNativeWidgetAura::OnDragExited() {
1162 DCHECK(drop_helper_.get() != NULL);
1163 drop_helper_->OnDragExit();
1166 int DesktopNativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) {
1167 DCHECK(drop_helper_.get() != NULL);
1168 if (ShouldActivate())
1169 Activate();
1170 return drop_helper_->OnDrop(event.data(), event.location(),
1171 last_drop_operation_);
1174 ////////////////////////////////////////////////////////////////////////////////
1175 // DesktopNativeWidgetAura, aura::WindowTreeHostObserver implementation:
1177 void DesktopNativeWidgetAura::OnHostCloseRequested(
1178 const aura::WindowTreeHost* host) {
1179 GetWidget()->Close();
1182 void DesktopNativeWidgetAura::OnHostResized(const aura::WindowTreeHost* host) {
1183 // Don't update the bounds of the child layers when animating closed. If we
1184 // did it would force a paint, which we don't want. We don't want the paint
1185 // as we can't assume any of the children are valid.
1186 if (desktop_window_tree_host_->IsAnimatingClosed())
1187 return;
1189 gfx::Rect new_bounds = gfx::Rect(host->window()->bounds().size());
1190 content_window_->SetBounds(new_bounds);
1191 // Can be NULL at start.
1192 if (content_window_container_)
1193 content_window_container_->SetBounds(new_bounds);
1194 native_widget_delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
1197 void DesktopNativeWidgetAura::OnHostMoved(const aura::WindowTreeHost* host,
1198 const gfx::Point& new_origin) {
1199 TRACE_EVENT1("views", "DesktopNativeWidgetAura::OnHostMoved",
1200 "new_origin", new_origin.ToString());
1202 native_widget_delegate_->OnNativeWidgetMove();
1205 ////////////////////////////////////////////////////////////////////////////////
1206 // DesktopNativeWidgetAura, private:
1208 void DesktopNativeWidgetAura::InstallInputMethodEventFilter() {
1209 DCHECK(!input_method_event_filter_.get());
1211 input_method_event_filter_.reset(new wm::InputMethodEventFilter(
1212 host_->GetAcceleratedWidget()));
1213 input_method_event_filter_->SetInputMethodPropertyInRootWindow(
1214 host_->window());
1215 root_window_event_filter_->AddHandler(input_method_event_filter_.get());
1218 void DesktopNativeWidgetAura::UpdateWindowTransparency() {
1219 content_window_->SetTransparent(
1220 desktop_window_tree_host_->ShouldWindowContentsBeTransparent());
1221 // Regardless of transparency or not, this root content window will always
1222 // fill its bounds completely, so set this flag to true to avoid an
1223 // unecessary clear before update.
1224 content_window_->SetFillsBoundsCompletely(true);
1227 void DesktopNativeWidgetAura::RootWindowDestroyed() {
1228 cursor_reference_count_--;
1229 if (cursor_reference_count_ == 0) {
1230 // We are the last DesktopNativeWidgetAura instance, and we are responsible
1231 // for cleaning up |cursor_manager_|.
1232 delete cursor_manager_;
1233 native_cursor_manager_ = NULL;
1234 cursor_manager_ = NULL;
1238 } // namespace views