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"
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/point_conversions.h"
23 #include "ui/gfx/screen.h"
24 #include "ui/gfx/size_conversions.h"
25 #include "ui/native_theme/native_theme.h"
26 #include "ui/views/corewm/tooltip.h"
27 #include "ui/views/corewm/tooltip_controller.h"
28 #include "ui/views/drag_utils.h"
29 #include "ui/views/ime/input_method_bridge.h"
30 #include "ui/views/ime/null_input_method.h"
31 #include "ui/views/view_constants_aura.h"
32 #include "ui/views/widget/desktop_aura/desktop_capture_client.h"
33 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
34 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
35 #include "ui/views/widget/desktop_aura/desktop_event_client.h"
36 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h"
37 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
38 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
39 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
40 #include "ui/views/widget/drop_helper.h"
41 #include "ui/views/widget/native_widget_aura.h"
42 #include "ui/views/widget/root_view.h"
43 #include "ui/views/widget/tooltip_manager_aura.h"
44 #include "ui/views/widget/widget.h"
45 #include "ui/views/widget/widget_aura_utils.h"
46 #include "ui/views/widget/widget_delegate.h"
47 #include "ui/views/widget/window_reorderer.h"
48 #include "ui/views/window/native_frame_view.h"
49 #include "ui/wm/core/compound_event_filter.h"
50 #include "ui/wm/core/cursor_manager.h"
51 #include "ui/wm/core/focus_controller.h"
52 #include "ui/wm/core/input_method_event_filter.h"
53 #include "ui/wm/core/native_cursor_manager.h"
54 #include "ui/wm/core/shadow_controller.h"
55 #include "ui/wm/core/shadow_types.h"
56 #include "ui/wm/core/visibility_controller.h"
57 #include "ui/wm/core/window_modality_controller.h"
58 #include "ui/wm/public/activation_client.h"
59 #include "ui/wm/public/drag_drop_client.h"
62 #include "ui/base/win/shell.h"
63 #include "ui/gfx/win/dpi.h"
66 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT,
67 views::DesktopNativeWidgetAura*);
71 DEFINE_WINDOW_PROPERTY_KEY(DesktopNativeWidgetAura*,
72 kDesktopNativeWidgetAuraKey, NULL);
76 // This class provides functionality to create a top level widget to host a
78 class DesktopNativeWidgetTopLevelHandler : public aura::WindowObserver {
80 // This function creates a widget with the bounds passed in which eventually
81 // becomes the parent of the child window passed in.
82 static aura::Window* CreateParentWindow(aura::Window* child_window,
83 const gfx::Rect& bounds,
85 bool root_is_always_on_top) {
86 // This instance will get deleted when the widget is destroyed.
87 DesktopNativeWidgetTopLevelHandler* top_level_handler =
88 new DesktopNativeWidgetTopLevelHandler;
90 child_window->SetBounds(gfx::Rect(bounds.size()));
92 Widget::InitParams init_params;
93 init_params.type = full_screen ? Widget::InitParams::TYPE_WINDOW :
94 Widget::InitParams::TYPE_POPUP;
95 init_params.bounds = bounds;
96 init_params.ownership = Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
97 init_params.layer_type = aura::WINDOW_LAYER_NOT_DRAWN;
98 init_params.activatable = full_screen ?
99 Widget::InitParams::ACTIVATABLE_YES :
100 Widget::InitParams::ACTIVATABLE_NO;
101 init_params.keep_on_top = root_is_always_on_top;
103 // This widget instance will get deleted when the window is
105 top_level_handler->top_level_widget_ = new Widget();
106 top_level_handler->top_level_widget_->Init(init_params);
108 top_level_handler->top_level_widget_->SetFullscreen(full_screen);
109 top_level_handler->top_level_widget_->Show();
111 aura::Window* native_window =
112 top_level_handler->top_level_widget_->GetNativeView();
113 child_window->AddObserver(top_level_handler);
114 native_window->AddObserver(top_level_handler);
115 top_level_handler->child_window_ = child_window;
116 return native_window;
119 // aura::WindowObserver overrides
120 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
121 window->RemoveObserver(this);
123 // If the widget is being destroyed by the OS then we should not try and
125 if (top_level_widget_ &&
126 window == top_level_widget_->GetNativeView()) {
127 top_level_widget_ = NULL;
131 if (top_level_widget_) {
132 DCHECK(top_level_widget_->GetNativeView());
133 top_level_widget_->GetNativeView()->RemoveObserver(this);
134 // When we receive a notification that the child of the window created
135 // above is being destroyed we go ahead and initiate the destruction of
136 // the corresponding widget.
137 top_level_widget_->Close();
138 top_level_widget_ = NULL;
143 virtual void OnWindowBoundsChanged(aura::Window* window,
144 const gfx::Rect& old_bounds,
145 const gfx::Rect& new_bounds) OVERRIDE {
146 if (top_level_widget_ && window == child_window_)
147 top_level_widget_->SetSize(new_bounds.size());
151 DesktopNativeWidgetTopLevelHandler()
152 : top_level_widget_(NULL),
153 child_window_(NULL) {}
155 virtual ~DesktopNativeWidgetTopLevelHandler() {}
157 Widget* top_level_widget_;
158 aura::Window* child_window_;
160 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetTopLevelHandler);
163 class DesktopNativeWidgetAuraWindowTreeClient :
164 public aura::client::WindowTreeClient {
166 explicit DesktopNativeWidgetAuraWindowTreeClient(
167 aura::Window* root_window)
168 : root_window_(root_window) {
169 aura::client::SetWindowTreeClient(root_window_, this);
171 virtual ~DesktopNativeWidgetAuraWindowTreeClient() {
172 aura::client::SetWindowTreeClient(root_window_, NULL);
175 // Overridden from client::WindowTreeClient:
176 virtual aura::Window* GetDefaultParent(aura::Window* context,
177 aura::Window* window,
178 const gfx::Rect& bounds) OVERRIDE {
179 bool is_fullscreen = window->GetProperty(aura::client::kShowStateKey) ==
180 ui::SHOW_STATE_FULLSCREEN;
181 bool is_menu = window->type() == ui::wm::WINDOW_TYPE_MENU;
183 if (is_fullscreen || is_menu) {
184 bool root_is_always_on_top = false;
185 internal::NativeWidgetPrivate* native_widget =
186 DesktopNativeWidgetAura::ForWindow(root_window_);
188 root_is_always_on_top = native_widget->IsAlwaysOnTop();
190 return DesktopNativeWidgetTopLevelHandler::CreateParentWindow(
191 window, bounds, is_fullscreen, root_is_always_on_top);
197 aura::Window* root_window_;
199 DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetAuraWindowTreeClient);
204 class FocusManagerEventHandler : public ui::EventHandler {
206 FocusManagerEventHandler(DesktopNativeWidgetAura* desktop_native_widget_aura)
207 : desktop_native_widget_aura_(desktop_native_widget_aura) {}
209 // Implementation of ui::EventHandler:
210 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
211 Widget* widget = desktop_native_widget_aura_->GetWidget();
212 if (widget && widget->GetFocusManager()->GetFocusedView() &&
213 !widget->GetFocusManager()->OnKeyEvent(*event)) {
219 DesktopNativeWidgetAura* desktop_native_widget_aura_;
221 DISALLOW_COPY_AND_ASSIGN(FocusManagerEventHandler);
224 class RootWindowDestructionObserver : public aura::WindowObserver {
226 explicit RootWindowDestructionObserver(DesktopNativeWidgetAura* parent)
228 virtual ~RootWindowDestructionObserver() {}
231 // Overridden from aura::WindowObserver:
232 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
233 parent_->RootWindowDestroyed();
234 window->RemoveObserver(this);
238 DesktopNativeWidgetAura* parent_;
240 DISALLOW_COPY_AND_ASSIGN(RootWindowDestructionObserver);
243 ////////////////////////////////////////////////////////////////////////////////
244 // DesktopNativeWidgetAura, public:
246 int DesktopNativeWidgetAura::cursor_reference_count_ = 0;
247 DesktopNativeCursorManager* DesktopNativeWidgetAura::native_cursor_manager_ =
249 wm::CursorManager* DesktopNativeWidgetAura::cursor_manager_ = NULL;
251 DesktopNativeWidgetAura::DesktopNativeWidgetAura(
252 internal::NativeWidgetDelegate* delegate)
253 : desktop_window_tree_host_(NULL),
254 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
255 close_widget_factory_(this),
256 content_window_container_(NULL),
257 content_window_(new aura::Window(this)),
258 native_widget_delegate_(delegate),
259 last_drop_operation_(ui::DragDropTypes::DRAG_NONE),
260 restore_focus_on_activate_(false),
261 restore_focus_on_window_focus_(false),
262 cursor_(gfx::kNullCursor),
263 widget_type_(Widget::InitParams::TYPE_WINDOW) {
264 aura::client::SetFocusChangeObserver(content_window_, this);
265 aura::client::SetActivationChangeObserver(content_window_, this);
268 DesktopNativeWidgetAura::~DesktopNativeWidgetAura() {
269 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
270 delete native_widget_delegate_;
276 DesktopNativeWidgetAura* DesktopNativeWidgetAura::ForWindow(
277 aura::Window* window) {
278 return window->GetProperty(kDesktopNativeWidgetAuraKey);
281 void DesktopNativeWidgetAura::OnHostClosed() {
282 // Don't invoke Widget::OnNativeWidgetDestroying(), its done by
283 // DesktopWindowTreeHost.
285 // The WindowModalityController is at the front of the event pretarget
286 // handler list. We destroy it first to preserve order symantics.
287 if (window_modality_controller_)
288 window_modality_controller_.reset();
290 // Make sure we don't have capture. Otherwise CaptureController and
291 // WindowEventDispatcher are left referencing a deleted Window.
293 aura::Window* capture_window = capture_client_->GetCaptureWindow();
294 if (capture_window && host_->window()->Contains(capture_window))
295 capture_window->ReleaseCapture();
298 // DesktopWindowTreeHost owns the ActivationController which ShadowController
299 // references. Make sure we destroy ShadowController early on.
300 shadow_controller_.reset();
301 tooltip_manager_.reset();
302 if (tooltip_controller_.get()) {
303 host_->window()->RemovePreTargetHandler(tooltip_controller_.get());
304 aura::client::SetTooltipClient(host_->window(), NULL);
305 tooltip_controller_.reset();
308 root_window_event_filter_->RemoveHandler(input_method_event_filter_.get());
310 window_tree_client_.reset(); // Uses host_->dispatcher() at destruction.
312 capture_client_.reset(); // Uses host_->dispatcher() at destruction.
314 // FocusController uses |content_window_|. Destroy it now so that we don't
315 // have to worry about the possibility of FocusController attempting to use
316 // |content_window_| after it's been destroyed but before all child windows
317 // have been destroyed.
318 host_->window()->RemovePreTargetHandler(focus_client_.get());
319 aura::client::SetFocusClient(host_->window(), NULL);
320 aura::client::SetActivationClient(host_->window(), NULL);
321 focus_client_.reset();
323 host_->RemoveObserver(this);
324 host_.reset(); // Uses input_method_event_filter_ at destruction.
325 // WindowEventDispatcher owns |desktop_window_tree_host_|.
326 desktop_window_tree_host_ = NULL;
327 content_window_ = NULL;
329 native_widget_delegate_->OnNativeWidgetDestroyed();
330 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
334 void DesktopNativeWidgetAura::OnDesktopWindowTreeHostDestroyed(
335 aura::WindowTreeHost* host) {
336 // |dispatcher_| is still valid, but DesktopWindowTreeHost is nearly
337 // destroyed. Do cleanup here of members DesktopWindowTreeHost may also use.
338 aura::client::SetDispatcherClient(host->window(), NULL);
339 dispatcher_client_.reset();
341 // We explicitly do NOT clear the cursor client property. Since the cursor
342 // manager is a singleton, it can outlive any window hierarchy, and it's
343 // important that objects attached to this destroying window hierarchy have
344 // an opportunity to deregister their observers from the cursor manager.
345 // They may want to do this when they are notified that they're being
346 // removed from the window hierarchy, which happens soon after this
347 // function when DesktopWindowTreeHost* calls DestroyDispatcher().
348 native_cursor_manager_->RemoveHost(host);
350 aura::client::SetScreenPositionClient(host->window(), NULL);
351 position_client_.reset();
353 aura::client::SetDragDropClient(host->window(), NULL);
354 drag_drop_client_.reset();
356 aura::client::SetEventClient(host->window(), NULL);
357 event_client_.reset();
360 void DesktopNativeWidgetAura::HandleActivationChanged(bool active) {
361 native_widget_delegate_->OnNativeWidgetActivationChanged(active);
362 aura::client::ActivationClient* activation_client =
363 aura::client::GetActivationClient(host_->window());
364 if (!activation_client)
367 if (GetWidget()->HasFocusManager()) {
368 // This function can be called before the focus manager has had a
369 // chance to set the focused view. In which case we should get the
370 // last focused view.
371 View* view_for_activation =
372 GetWidget()->GetFocusManager()->GetFocusedView() ?
373 GetWidget()->GetFocusManager()->GetFocusedView() :
374 GetWidget()->GetFocusManager()->GetStoredFocusView();
375 if (!view_for_activation)
376 view_for_activation = GetWidget()->GetRootView();
377 activation_client->ActivateWindow(
378 view_for_activation->GetWidget()->GetNativeView());
381 // If we're not active we need to deactivate the corresponding
382 // aura::Window. This way if a child widget is active it gets correctly
383 // deactivated (child widgets don't get native desktop activation changes,
384 // only aura activation changes).
385 aura::Window* active_window = activation_client->GetActiveWindow();
387 activation_client->DeactivateWindow(active_window);
391 ////////////////////////////////////////////////////////////////////////////////
392 // DesktopNativeWidgetAura, internal::NativeWidgetPrivate implementation:
394 void DesktopNativeWidgetAura::InitNativeWidget(
395 const Widget::InitParams& params) {
396 ownership_ = params.ownership;
397 widget_type_ = params.type;
399 NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_);
400 // Animations on TYPE_WINDOW are handled by the OS. Additionally if we animate
401 // these windows the size of the window gets augmented, effecting restore
402 // bounds and maximized windows in bad ways.
403 if (params.type == Widget::InitParams::TYPE_WINDOW &&
404 !params.remove_standard_frame) {
405 content_window_->SetProperty(aura::client::kAnimationsDisabledKey, true);
407 content_window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
408 content_window_->Init(params.layer_type);
409 wm::SetShadowType(content_window_, wm::SHADOW_TYPE_NONE);
411 content_window_container_ = new aura::Window(NULL);
412 content_window_container_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
413 content_window_container_->Show();
414 content_window_container_->AddChild(content_window_);
416 desktop_window_tree_host_ = params.desktop_window_tree_host ?
417 params.desktop_window_tree_host :
418 DesktopWindowTreeHost::Create(native_widget_delegate_, this);
419 host_.reset(desktop_window_tree_host_->AsWindowTreeHost());
420 desktop_window_tree_host_->Init(content_window_, params);
422 // Mark this window as Desktop root window.
423 host_->window()->SetProperty(views::kDesktopRootWindow, true);
426 host_->window()->AddChild(content_window_container_);
427 host_->window()->SetProperty(kDesktopNativeWidgetAuraKey, this);
429 host_->window()->AddObserver(new RootWindowDestructionObserver(this));
431 // The WindowsModalityController event filter should be at the head of the
432 // pre target handlers list. This ensures that it handles input events first
433 // when modal windows are at the top of the Zorder.
434 if (widget_type_ == Widget::InitParams::TYPE_WINDOW)
435 window_modality_controller_.reset(
436 new wm::WindowModalityController(host_->window()));
438 // |root_window_event_filter_| must be created before
439 // OnWindowTreeHostCreated() is invoked.
441 // CEF sets focus to the window the user clicks down on.
442 // TODO(beng): see if we can't do this some other way. CEF seems a heavy-
443 // handed way of accomplishing focus.
444 // No event filter for aura::Env. Create CompoundEventFilter per
445 // WindowEventDispatcher.
446 root_window_event_filter_.reset(new wm::CompoundEventFilter);
447 host_->window()->AddPreTargetHandler(root_window_event_filter_.get());
449 // The host's dispatcher must be added to |native_cursor_manager_| before
450 // OnNativeWidgetCreated() is called.
451 cursor_reference_count_++;
452 if (!native_cursor_manager_) {
453 native_cursor_manager_ = new DesktopNativeCursorManager(
454 DesktopCursorLoaderUpdater::Create());
456 if (!cursor_manager_) {
457 cursor_manager_ = new wm::CursorManager(
458 scoped_ptr<wm::NativeCursorManager>(native_cursor_manager_));
460 native_cursor_manager_->AddHost(host());
461 aura::client::SetCursorClient(host_->window(), cursor_manager_);
463 desktop_window_tree_host_->OnNativeWidgetCreated(params);
465 UpdateWindowTransparency();
467 capture_client_.reset(new DesktopCaptureClient(host_->window()));
469 wm::FocusController* focus_controller =
470 new wm::FocusController(new DesktopFocusRules(content_window_));
471 focus_client_.reset(focus_controller);
472 aura::client::SetFocusClient(host_->window(), focus_controller);
473 aura::client::SetActivationClient(host_->window(), focus_controller);
474 host_->window()->AddPreTargetHandler(focus_controller);
476 dispatcher_client_.reset(new DesktopDispatcherClient);
477 aura::client::SetDispatcherClient(host_->window(),
478 dispatcher_client_.get());
480 position_client_.reset(new DesktopScreenPositionClient(host_->window()));
482 InstallInputMethodEventFilter();
484 drag_drop_client_ = desktop_window_tree_host_->CreateDragDropClient(
485 native_cursor_manager_);
486 aura::client::SetDragDropClient(host_->window(),
487 drag_drop_client_.get());
489 static_cast<aura::client::FocusClient*>(focus_client_.get())->
490 FocusWindow(content_window_);
492 OnHostResized(host());
494 host_->AddObserver(this);
496 window_tree_client_.reset(
497 new DesktopNativeWidgetAuraWindowTreeClient(host_->window()));
498 drop_helper_.reset(new DropHelper(GetWidget()->GetRootView()));
499 aura::client::SetDragDropDelegate(content_window_, this);
501 if (params.type != Widget::InitParams::TYPE_TOOLTIP) {
502 tooltip_manager_.reset(new TooltipManagerAura(GetWidget()));
503 tooltip_controller_.reset(
504 new corewm::TooltipController(
505 desktop_window_tree_host_->CreateTooltip()));
506 aura::client::SetTooltipClient(host_->window(),
507 tooltip_controller_.get());
508 host_->window()->AddPreTargetHandler(tooltip_controller_.get());
511 if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) {
512 visibility_controller_.reset(new wm::VisibilityController);
513 aura::client::SetVisibilityClient(host_->window(),
514 visibility_controller_.get());
515 wm::SetChildWindowVisibilityChangesAnimated(host_->window());
516 wm::SetChildWindowVisibilityChangesAnimated(
517 content_window_container_);
520 if (params.type == Widget::InitParams::TYPE_WINDOW) {
521 focus_manager_event_handler_.reset(new FocusManagerEventHandler(this));
522 host_->window()->AddPreTargetHandler(focus_manager_event_handler_.get());
525 event_client_.reset(new DesktopEventClient);
526 aura::client::SetEventClient(host_->window(), event_client_.get());
528 aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_);
530 aura::client::SetActivationDelegate(content_window_, this);
532 shadow_controller_.reset(new wm::ShadowController(
533 aura::client::GetActivationClient(host_->window())));
535 content_window_->SetProperty(aura::client::kCanMaximizeKey,
536 GetWidget()->widget_delegate()->CanMaximize());
537 content_window_->SetProperty(aura::client::kCanResizeKey,
538 GetWidget()->widget_delegate()->CanResize());
540 window_reorderer_.reset(new WindowReorderer(content_window_,
541 GetWidget()->GetRootView()));
544 NonClientFrameView* DesktopNativeWidgetAura::CreateNonClientFrameView() {
545 return ShouldUseNativeFrame() ? new NativeFrameView(GetWidget()) : NULL;
548 bool DesktopNativeWidgetAura::ShouldUseNativeFrame() const {
549 return desktop_window_tree_host_->ShouldUseNativeFrame();
552 bool DesktopNativeWidgetAura::ShouldWindowContentsBeTransparent() const {
553 return desktop_window_tree_host_->ShouldWindowContentsBeTransparent();
556 void DesktopNativeWidgetAura::FrameTypeChanged() {
557 desktop_window_tree_host_->FrameTypeChanged();
558 UpdateWindowTransparency();
561 Widget* DesktopNativeWidgetAura::GetWidget() {
562 return native_widget_delegate_->AsWidget();
565 const Widget* DesktopNativeWidgetAura::GetWidget() const {
566 return native_widget_delegate_->AsWidget();
569 gfx::NativeView DesktopNativeWidgetAura::GetNativeView() const {
570 return content_window_;
573 gfx::NativeWindow DesktopNativeWidgetAura::GetNativeWindow() const {
574 return content_window_;
577 Widget* DesktopNativeWidgetAura::GetTopLevelWidget() {
581 const ui::Compositor* DesktopNativeWidgetAura::GetCompositor() const {
582 return content_window_ ? content_window_->layer()->GetCompositor() : NULL;
585 ui::Compositor* DesktopNativeWidgetAura::GetCompositor() {
586 return const_cast<ui::Compositor*>(
587 const_cast<const DesktopNativeWidgetAura*>(this)->GetCompositor());
590 ui::Layer* DesktopNativeWidgetAura::GetLayer() {
591 return content_window_ ? content_window_->layer() : NULL;
594 void DesktopNativeWidgetAura::ReorderNativeViews() {
595 window_reorderer_->ReorderChildWindows();
598 void DesktopNativeWidgetAura::ViewRemoved(View* view) {
599 DCHECK(drop_helper_.get() != NULL);
600 drop_helper_->ResetTargetViewIfEquals(view);
603 void DesktopNativeWidgetAura::SetNativeWindowProperty(const char* name,
606 content_window_->SetNativeWindowProperty(name, value);
609 void* DesktopNativeWidgetAura::GetNativeWindowProperty(const char* name) const {
610 return content_window_ ?
611 content_window_->GetNativeWindowProperty(name) : NULL;
614 TooltipManager* DesktopNativeWidgetAura::GetTooltipManager() const {
615 return tooltip_manager_.get();
618 void DesktopNativeWidgetAura::SetCapture() {
619 if (!content_window_)
622 content_window_->SetCapture();
625 void DesktopNativeWidgetAura::ReleaseCapture() {
626 if (!content_window_)
629 content_window_->ReleaseCapture();
632 bool DesktopNativeWidgetAura::HasCapture() const {
633 return content_window_ && content_window_->HasCapture() &&
634 desktop_window_tree_host_->HasCapture();
637 InputMethod* DesktopNativeWidgetAura::CreateInputMethod() {
638 if (switches::IsTextInputFocusManagerEnabled())
639 return new NullInputMethod();
641 ui::InputMethod* host = input_method_event_filter_->input_method();
642 return new InputMethodBridge(this, host, false);
645 internal::InputMethodDelegate*
646 DesktopNativeWidgetAura::GetInputMethodDelegate() {
650 ui::InputMethod* DesktopNativeWidgetAura::GetHostInputMethod() {
651 return input_method_event_filter_->input_method();
654 void DesktopNativeWidgetAura::CenterWindow(const gfx::Size& size) {
656 desktop_window_tree_host_->CenterWindow(size);
659 void DesktopNativeWidgetAura::GetWindowPlacement(
661 ui::WindowShowState* maximized) const {
663 desktop_window_tree_host_->GetWindowPlacement(bounds, maximized);
666 bool DesktopNativeWidgetAura::SetWindowTitle(const base::string16& title) {
667 if (!content_window_)
669 content_window_->set_title(title);
670 return desktop_window_tree_host_->SetWindowTitle(title);
673 void DesktopNativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
674 const gfx::ImageSkia& app_icon) {
676 desktop_window_tree_host_->SetWindowIcons(window_icon, app_icon);
679 void DesktopNativeWidgetAura::InitModalType(ui::ModalType modal_type) {
680 // 99% of the time, we should not be asked to create a
681 // DesktopNativeWidgetAura that is modal. We only support window modal
682 // dialogs on the same lines as non AURA.
683 desktop_window_tree_host_->InitModalType(modal_type);
686 gfx::Rect DesktopNativeWidgetAura::GetWindowBoundsInScreen() const {
687 return content_window_ ?
688 desktop_window_tree_host_->GetWindowBoundsInScreen() : gfx::Rect();
691 gfx::Rect DesktopNativeWidgetAura::GetClientAreaBoundsInScreen() const {
692 return content_window_ ?
693 desktop_window_tree_host_->GetClientAreaBoundsInScreen() : gfx::Rect();
696 gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
697 return content_window_ ?
698 desktop_window_tree_host_->GetRestoredBounds() : gfx::Rect();
701 void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
702 if (!content_window_)
705 // This code by default scales the bounds rectangle by 1.
706 // We could probably get rid of this and similar logic from
707 // the DesktopNativeWidgetAura::OnWindowTreeHostResized function.
709 aura::Window* root = host_->window();
711 scale = gfx::Screen::GetScreenFor(root)->
712 GetDisplayNearestWindow(root).device_scale_factor();
714 gfx::Rect bounds_in_pixels(
715 gfx::ToCeiledPoint(gfx::ScalePoint(bounds.origin(), scale)),
716 gfx::ToFlooredSize(gfx::ScaleSize(bounds.size(), scale)));
717 desktop_window_tree_host_->AsWindowTreeHost()->SetBounds(bounds_in_pixels);
720 void DesktopNativeWidgetAura::SetSize(const gfx::Size& size) {
722 desktop_window_tree_host_->SetSize(size);
725 void DesktopNativeWidgetAura::StackAbove(gfx::NativeView native_view) {
728 void DesktopNativeWidgetAura::StackAtTop() {
730 desktop_window_tree_host_->StackAtTop();
733 void DesktopNativeWidgetAura::StackBelow(gfx::NativeView native_view) {
736 void DesktopNativeWidgetAura::SetShape(gfx::NativeRegion shape) {
738 desktop_window_tree_host_->SetShape(shape);
741 void DesktopNativeWidgetAura::Close() {
742 if (!content_window_)
745 content_window_->SuppressPaint();
746 content_window_->Hide();
748 desktop_window_tree_host_->Close();
751 void DesktopNativeWidgetAura::CloseNow() {
753 desktop_window_tree_host_->CloseNow();
756 void DesktopNativeWidgetAura::Show() {
757 if (!content_window_)
759 desktop_window_tree_host_->AsWindowTreeHost()->Show();
760 content_window_->Show();
763 void DesktopNativeWidgetAura::Hide() {
764 if (!content_window_)
766 desktop_window_tree_host_->AsWindowTreeHost()->Hide();
767 content_window_->Hide();
770 void DesktopNativeWidgetAura::ShowMaximizedWithBounds(
771 const gfx::Rect& restored_bounds) {
772 if (!content_window_)
774 desktop_window_tree_host_->ShowMaximizedWithBounds(restored_bounds);
775 content_window_->Show();
778 void DesktopNativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
779 if (!content_window_)
781 desktop_window_tree_host_->ShowWindowWithState(state);
782 content_window_->Show();
785 bool DesktopNativeWidgetAura::IsVisible() const {
786 return content_window_ && desktop_window_tree_host_->IsVisible();
789 void DesktopNativeWidgetAura::Activate() {
791 desktop_window_tree_host_->Activate();
794 void DesktopNativeWidgetAura::Deactivate() {
796 desktop_window_tree_host_->Deactivate();
799 bool DesktopNativeWidgetAura::IsActive() const {
800 return content_window_ && desktop_window_tree_host_->IsActive();
803 void DesktopNativeWidgetAura::SetAlwaysOnTop(bool always_on_top) {
805 desktop_window_tree_host_->SetAlwaysOnTop(always_on_top);
808 bool DesktopNativeWidgetAura::IsAlwaysOnTop() const {
809 return content_window_ && desktop_window_tree_host_->IsAlwaysOnTop();
812 void DesktopNativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) {
814 desktop_window_tree_host_->SetVisibleOnAllWorkspaces(always_visible);
817 void DesktopNativeWidgetAura::Maximize() {
819 desktop_window_tree_host_->Maximize();
822 void DesktopNativeWidgetAura::Minimize() {
824 desktop_window_tree_host_->Minimize();
827 bool DesktopNativeWidgetAura::IsMaximized() const {
828 return content_window_ && desktop_window_tree_host_->IsMaximized();
831 bool DesktopNativeWidgetAura::IsMinimized() const {
832 return content_window_ && desktop_window_tree_host_->IsMinimized();
835 void DesktopNativeWidgetAura::Restore() {
837 desktop_window_tree_host_->Restore();
840 void DesktopNativeWidgetAura::SetFullscreen(bool fullscreen) {
842 desktop_window_tree_host_->SetFullscreen(fullscreen);
845 bool DesktopNativeWidgetAura::IsFullscreen() const {
846 return content_window_ && desktop_window_tree_host_->IsFullscreen();
849 void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity) {
851 desktop_window_tree_host_->SetOpacity(opacity);
854 void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
857 void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
859 desktop_window_tree_host_->FlashFrame(flash_frame);
862 void DesktopNativeWidgetAura::RunShellDrag(
864 const ui::OSExchangeData& data,
865 const gfx::Point& location,
867 ui::DragDropTypes::DragEventSource source) {
868 views::RunShellDrag(content_window_, data, location, operation, source);
871 void DesktopNativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
873 content_window_->SchedulePaintInRect(rect);
876 void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
878 aura::client::CursorClient* cursor_client =
879 aura::client::GetCursorClient(host_->window());
881 cursor_client->SetCursor(cursor);
884 bool DesktopNativeWidgetAura::IsMouseEventsEnabled() const {
885 if (!content_window_)
887 aura::client::CursorClient* cursor_client =
888 aura::client::GetCursorClient(host_->window());
889 return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
892 void DesktopNativeWidgetAura::ClearNativeFocus() {
893 desktop_window_tree_host_->ClearNativeFocus();
895 if (ShouldActivate()) {
896 aura::client::GetFocusClient(content_window_)->
897 ResetFocusWithinActiveWindow(content_window_);
901 gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const {
902 return desktop_window_tree_host_ ?
903 desktop_window_tree_host_->GetWorkAreaBoundsInScreen() : gfx::Rect();
906 Widget::MoveLoopResult DesktopNativeWidgetAura::RunMoveLoop(
907 const gfx::Vector2d& drag_offset,
908 Widget::MoveLoopSource source,
909 Widget::MoveLoopEscapeBehavior escape_behavior) {
910 if (!content_window_)
911 return Widget::MOVE_LOOP_CANCELED;
912 return desktop_window_tree_host_->RunMoveLoop(drag_offset, source,
916 void DesktopNativeWidgetAura::EndMoveLoop() {
918 desktop_window_tree_host_->EndMoveLoop();
921 void DesktopNativeWidgetAura::SetVisibilityChangedAnimationsEnabled(
924 desktop_window_tree_host_->SetVisibilityChangedAnimationsEnabled(value);
927 ui::NativeTheme* DesktopNativeWidgetAura::GetNativeTheme() const {
928 return DesktopWindowTreeHost::GetNativeTheme(content_window_);
931 void DesktopNativeWidgetAura::OnRootViewLayout() const {
933 desktop_window_tree_host_->OnRootViewLayout();
936 void DesktopNativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event) {
937 OnEvent(native_event);
940 ////////////////////////////////////////////////////////////////////////////////
941 // DesktopNativeWidgetAura, aura::WindowDelegate implementation:
943 gfx::Size DesktopNativeWidgetAura::GetMinimumSize() const {
944 return native_widget_delegate_->GetMinimumSize();
947 gfx::Size DesktopNativeWidgetAura::GetMaximumSize() const {
948 return native_widget_delegate_->GetMaximumSize();
951 gfx::NativeCursor DesktopNativeWidgetAura::GetCursor(const gfx::Point& point) {
955 int DesktopNativeWidgetAura::GetNonClientComponent(
956 const gfx::Point& point) const {
957 return native_widget_delegate_->GetNonClientComponent(point);
960 bool DesktopNativeWidgetAura::ShouldDescendIntoChildForEventHandling(
962 const gfx::Point& location) {
963 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
964 return !widget_delegate ||
965 widget_delegate->ShouldDescendIntoChildForEventHandling(child, location);
968 bool DesktopNativeWidgetAura::CanFocus() {
972 void DesktopNativeWidgetAura::OnCaptureLost() {
973 native_widget_delegate_->OnMouseCaptureLost();
976 void DesktopNativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
977 native_widget_delegate_->OnNativeWidgetPaint(canvas);
980 void DesktopNativeWidgetAura::OnDeviceScaleFactorChanged(
981 float device_scale_factor) {
984 void DesktopNativeWidgetAura::OnWindowDestroying(aura::Window* window) {
985 // Cleanup happens in OnHostClosed().
988 void DesktopNativeWidgetAura::OnWindowDestroyed(aura::Window* window) {
989 // Cleanup happens in OnHostClosed(). We own |content_window_| (indirectly by
990 // way of |dispatcher_|) so there should be no need to do any processing
994 void DesktopNativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
997 bool DesktopNativeWidgetAura::HasHitTestMask() const {
998 return native_widget_delegate_->HasHitTestMask();
1001 void DesktopNativeWidgetAura::GetHitTestMask(gfx::Path* mask) const {
1002 native_widget_delegate_->GetHitTestMask(mask);
1005 ////////////////////////////////////////////////////////////////////////////////
1006 // DesktopNativeWidgetAura, ui::EventHandler implementation:
1008 void DesktopNativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
1009 if (event->is_char()) {
1010 // If a ui::InputMethod object is attached to the root window, character
1011 // events are handled inside the object and are not passed to this function.
1012 // If such object is not attached, character events might be sent (e.g. on
1013 // Windows). In this case, we just skip these.
1016 // Renderer may send a key event back to us if the key event wasn't handled,
1017 // and the window may be invisible by that time.
1018 if (!content_window_->IsVisible())
1021 native_widget_delegate_->OnKeyEvent(event);
1022 if (event->handled())
1025 if (GetWidget()->HasFocusManager() &&
1026 !GetWidget()->GetFocusManager()->OnKeyEvent(*event))
1027 event->SetHandled();
1030 void DesktopNativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
1031 DCHECK(content_window_->IsVisible());
1032 if (tooltip_manager_.get())
1033 tooltip_manager_->UpdateTooltip();
1034 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
1035 native_widget_delegate_->OnMouseEvent(event);
1036 // WARNING: we may have been deleted.
1039 void DesktopNativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
1040 if (event->type() == ui::ET_SCROLL) {
1041 native_widget_delegate_->OnScrollEvent(event);
1042 if (event->handled())
1045 // Convert unprocessed scroll events into wheel events.
1046 ui::MouseWheelEvent mwe(*static_cast<ui::ScrollEvent*>(event));
1047 native_widget_delegate_->OnMouseEvent(&mwe);
1049 event->SetHandled();
1051 native_widget_delegate_->OnScrollEvent(event);
1055 void DesktopNativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
1056 native_widget_delegate_->OnGestureEvent(event);
1059 ////////////////////////////////////////////////////////////////////////////////
1060 // DesktopNativeWidgetAura, aura::client::ActivationDelegate implementation:
1062 bool DesktopNativeWidgetAura::ShouldActivate() const {
1063 return native_widget_delegate_->CanActivate();
1066 ////////////////////////////////////////////////////////////////////////////////
1067 // DesktopNativeWidgetAura, aura::client::ActivationChangeObserver
1070 void DesktopNativeWidgetAura::OnWindowActivated(aura::Window* gained_active,
1071 aura::Window* lost_active) {
1072 DCHECK(content_window_ == gained_active || content_window_ == lost_active);
1073 if (gained_active == content_window_ && restore_focus_on_activate_) {
1074 restore_focus_on_activate_ = false;
1075 GetWidget()->GetFocusManager()->RestoreFocusedView();
1076 } else if (lost_active == content_window_ && GetWidget()->HasFocusManager()) {
1077 DCHECK(!restore_focus_on_activate_);
1078 restore_focus_on_activate_ = true;
1079 // Pass in false so that ClearNativeFocus() isn't invoked.
1080 GetWidget()->GetFocusManager()->StoreFocusedView(false);
1084 ////////////////////////////////////////////////////////////////////////////////
1085 // DesktopNativeWidgetAura, aura::client::FocusChangeObserver implementation:
1087 void DesktopNativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
1088 aura::Window* lost_focus) {
1089 if (content_window_ == gained_focus) {
1090 desktop_window_tree_host_->OnNativeWidgetFocus();
1091 native_widget_delegate_->OnNativeFocus(lost_focus);
1093 // If focus is moving from a descendant Window to |content_window_| then
1094 // native activation hasn't changed. Still, the InputMethod and FocusManager
1095 // must be informed of the Window focus change.
1096 InputMethod* input_method = GetWidget()->GetInputMethod();
1098 input_method->OnFocus();
1100 if (restore_focus_on_window_focus_) {
1101 restore_focus_on_window_focus_ = false;
1102 GetWidget()->GetFocusManager()->RestoreFocusedView();
1104 } else if (content_window_ == lost_focus) {
1105 desktop_window_tree_host_->OnNativeWidgetBlur();
1106 native_widget_delegate_->OnNativeBlur(gained_focus);
1108 DCHECK(!restore_focus_on_window_focus_);
1109 restore_focus_on_window_focus_ = true;
1110 GetWidget()->GetFocusManager()->StoreFocusedView(false);
1114 ////////////////////////////////////////////////////////////////////////////////
1115 // DesktopNativeWidgetAura, views::internal::InputMethodDelegate:
1117 void DesktopNativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
1118 FocusManager* focus_manager =
1119 native_widget_delegate_->AsWidget()->GetFocusManager();
1120 native_widget_delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
1121 if (key.handled() || !focus_manager)
1123 focus_manager->OnKeyEvent(key);
1126 ////////////////////////////////////////////////////////////////////////////////
1127 // DesktopNativeWidgetAura, aura::WindowDragDropDelegate implementation:
1129 void DesktopNativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
1130 DCHECK(drop_helper_.get() != NULL);
1131 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
1132 event.location(), event.source_operations());
1135 int DesktopNativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
1136 DCHECK(drop_helper_.get() != NULL);
1137 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
1138 event.location(), event.source_operations());
1139 return last_drop_operation_;
1142 void DesktopNativeWidgetAura::OnDragExited() {
1143 DCHECK(drop_helper_.get() != NULL);
1144 drop_helper_->OnDragExit();
1147 int DesktopNativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) {
1148 DCHECK(drop_helper_.get() != NULL);
1150 return drop_helper_->OnDrop(event.data(), event.location(),
1151 last_drop_operation_);
1154 ////////////////////////////////////////////////////////////////////////////////
1155 // DesktopNativeWidgetAura, aura::WindowTreeHostObserver implementation:
1157 void DesktopNativeWidgetAura::OnHostCloseRequested(
1158 const aura::WindowTreeHost* host) {
1159 GetWidget()->Close();
1162 void DesktopNativeWidgetAura::OnHostResized(const aura::WindowTreeHost* host) {
1163 // Don't update the bounds of the child layers when animating closed. If we
1164 // did it would force a paint, which we don't want. We don't want the paint
1165 // as we can't assume any of the children are valid.
1166 if (desktop_window_tree_host_->IsAnimatingClosed())
1169 gfx::Rect new_bounds = gfx::Rect(host->window()->bounds().size());
1170 content_window_->SetBounds(new_bounds);
1171 // Can be NULL at start.
1172 if (content_window_container_)
1173 content_window_container_->SetBounds(new_bounds);
1174 native_widget_delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
1177 void DesktopNativeWidgetAura::OnHostMoved(const aura::WindowTreeHost* host,
1178 const gfx::Point& new_origin) {
1179 TRACE_EVENT1("views", "DesktopNativeWidgetAura::OnHostMoved",
1180 "new_origin", new_origin.ToString());
1182 native_widget_delegate_->OnNativeWidgetMove();
1185 ////////////////////////////////////////////////////////////////////////////////
1186 // DesktopNativeWidgetAura, private:
1188 void DesktopNativeWidgetAura::InstallInputMethodEventFilter() {
1189 DCHECK(!input_method_event_filter_.get());
1191 input_method_event_filter_.reset(new wm::InputMethodEventFilter(
1192 host_->GetAcceleratedWidget()));
1193 input_method_event_filter_->SetInputMethodPropertyInRootWindow(
1195 root_window_event_filter_->AddHandler(input_method_event_filter_.get());
1198 void DesktopNativeWidgetAura::UpdateWindowTransparency() {
1199 content_window_->SetTransparent(
1200 desktop_window_tree_host_->ShouldWindowContentsBeTransparent());
1201 // Regardless of transparency or not, this root content window will always
1202 // fill its bounds completely, so set this flag to true to avoid an
1203 // unecessary clear before update.
1204 content_window_->SetFillsBoundsCompletely(true);
1207 void DesktopNativeWidgetAura::RootWindowDestroyed() {
1208 cursor_reference_count_--;
1209 if (cursor_reference_count_ == 0) {
1210 // We are the last DesktopNativeWidgetAura instance, and we are responsible
1211 // for cleaning up |cursor_manager_|.
1212 delete cursor_manager_;
1213 native_cursor_manager_ = NULL;
1214 cursor_manager_ = NULL;
1218 } // namespace views