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 "ui/views/widget/native_widget_aura.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "build/build_config.h"
16 #include "ui/aura/client/aura_constants.h"
17 #include "ui/aura/client/capture_client.h"
18 #include "ui/aura/client/cursor_client.h"
19 #include "ui/aura/client/drag_drop_client.h"
20 #include "ui/aura/client/focus_client.h"
21 #include "ui/aura/client/screen_position_client.h"
22 #include "ui/aura/client/window_parenting_client.h"
23 #include "ui/aura/client/window_types.h"
24 #include "ui/aura/env.h"
25 #include "ui/aura/window.h"
26 #include "ui/aura/window_event_dispatcher.h"
27 #include "ui/aura/window_observer.h"
28 #include "ui/aura/window_tree_host.h"
29 #include "ui/base/class_property.h"
30 #include "ui/base/dragdrop/os_exchange_data.h"
31 #include "ui/base/ui_base_types.h"
32 #include "ui/compositor/layer.h"
33 #include "ui/display/display.h"
34 #include "ui/display/screen.h"
35 #include "ui/events/event.h"
36 #include "ui/gfx/canvas.h"
37 #include "ui/native_theme/native_theme_aura.h"
38 #include "ui/views/buildflags.h"
39 #include "ui/views/drag_utils.h"
40 #include "ui/views/views_delegate.h"
41 #include "ui/views/widget/drop_helper.h"
42 #include "ui/views/widget/focus_manager_event_handler.h"
43 #include "ui/views/widget/native_widget_delegate.h"
44 #include "ui/views/widget/root_view.h"
45 #include "ui/views/widget/tooltip_manager_aura.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/wm/core/coordinate_conversion.h"
50 #include "ui/wm/core/shadow_types.h"
51 #include "ui/wm/core/transient_window_manager.h"
52 #include "ui/wm/core/window_animations.h"
53 #include "ui/wm/core/window_properties.h"
54 #include "ui/wm/core/window_util.h"
55 #include "ui/wm/public/activation_client.h"
56 #include "ui/wm/public/window_move_client.h"
57 
58 #if BUILDFLAG(ENABLE_DESKTOP_AURA)
59 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
60 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
61 #endif
62 
63 #if defined(OS_WIN)
64 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
65 #endif
66 
67 #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \
68     (defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD))
69 #include "ui/views/linux_ui/linux_ui.h"
70 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
71 #endif
72 
73 DEFINE_UI_CLASS_PROPERTY_TYPE(views::internal::NativeWidgetPrivate*)
74 
75 namespace views {
76 
77 namespace {
78 
DEFINE_UI_CLASS_PROPERTY_KEY(internal::NativeWidgetPrivate *,kNativeWidgetPrivateKey,nullptr)79 DEFINE_UI_CLASS_PROPERTY_KEY(internal::NativeWidgetPrivate*,
80                              kNativeWidgetPrivateKey,
81                              nullptr)
82 
83 void SetRestoreBounds(aura::Window* window, const gfx::Rect& bounds) {
84   window->SetProperty(aura::client::kRestoreBoundsKey, bounds);
85 }
86 
SetIcon(aura::Window * window,const aura::WindowProperty<gfx::ImageSkia * > * key,const gfx::ImageSkia & value)87 void SetIcon(aura::Window* window,
88              const aura::WindowProperty<gfx::ImageSkia*>* key,
89              const gfx::ImageSkia& value) {
90   if (value.isNull())
91     window->ClearProperty(key);
92   else
93     window->SetProperty(key, value);
94 }
95 
96 }  // namespace
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 // NativeWidgetAura, public:
100 
NativeWidgetAura(internal::NativeWidgetDelegate * delegate)101 NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate)
102     : delegate_(delegate),
103       window_(new aura::Window(this, aura::client::WINDOW_TYPE_UNKNOWN)),
104       ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
105       destroying_(false),
106       cursor_(gfx::kNullCursor) {
107   aura::client::SetFocusChangeObserver(window_, this);
108   wm::SetActivationChangeObserver(window_, this);
109 }
110 
111 // static
RegisterNativeWidgetForWindow(internal::NativeWidgetPrivate * native_widget,aura::Window * window)112 void NativeWidgetAura::RegisterNativeWidgetForWindow(
113     internal::NativeWidgetPrivate* native_widget,
114     aura::Window* window) {
115   window->SetProperty(kNativeWidgetPrivateKey, native_widget);
116 }
117 
118 // static
AssignIconToAuraWindow(aura::Window * window,const gfx::ImageSkia & window_icon,const gfx::ImageSkia & app_icon)119 void NativeWidgetAura::AssignIconToAuraWindow(aura::Window* window,
120                                               const gfx::ImageSkia& window_icon,
121                                               const gfx::ImageSkia& app_icon) {
122   if (window) {
123     SetIcon(window, aura::client::kWindowIconKey, window_icon);
124     SetIcon(window, aura::client::kAppIconKey, app_icon);
125   }
126 }
127 
128 // static
SetShadowElevationFromInitParams(aura::Window * window,const Widget::InitParams & params)129 void NativeWidgetAura::SetShadowElevationFromInitParams(
130     aura::Window* window,
131     const Widget::InitParams& params) {
132   if (params.shadow_type == Widget::InitParams::ShadowType::kNone) {
133     wm::SetShadowElevation(window, wm::kShadowElevationNone);
134   } else if (params.shadow_type == Widget::InitParams::ShadowType::kDrop &&
135              params.shadow_elevation) {
136     wm::SetShadowElevation(window, *params.shadow_elevation);
137   }
138 }
139 
140 // static
SetResizeBehaviorFromDelegate(WidgetDelegate * delegate,aura::Window * window)141 void NativeWidgetAura::SetResizeBehaviorFromDelegate(WidgetDelegate* delegate,
142                                                      aura::Window* window) {
143   int behavior = aura::client::kResizeBehaviorNone;
144   if (delegate) {
145     if (delegate->CanResize())
146       behavior |= aura::client::kResizeBehaviorCanResize;
147     if (delegate->CanMaximize())
148       behavior |= aura::client::kResizeBehaviorCanMaximize;
149     if (delegate->CanMinimize())
150       behavior |= aura::client::kResizeBehaviorCanMinimize;
151   }
152   window->SetProperty(aura::client::kResizeBehaviorKey, behavior);
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 // NativeWidgetAura, internal::NativeWidgetPrivate implementation:
157 
InitNativeWidget(Widget::InitParams params)158 void NativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
159   // See Widget::InitParams::context for details.
160   DCHECK(params.parent || params.context);
161 
162   ownership_ = params.ownership;
163 
164   window_->AcquireAllPropertiesFrom(
165       std::move(params.init_properties_container));
166 
167   RegisterNativeWidgetForWindow(this, window_);
168   window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
169   if (params.corner_radius) {
170     window_->SetProperty(aura::client::kWindowCornerRadiusKey,
171                          *params.corner_radius);
172   }
173   window_->SetProperty(aura::client::kShowStateKey, params.show_state);
174   if (params.type == Widget::InitParams::TYPE_BUBBLE)
175     wm::SetHideOnDeactivate(window_, true);
176   window_->SetTransparent(params.opacity ==
177                           Widget::InitParams::WindowOpacity::kTranslucent);
178 
179   // Check for ShadowType::kNone before aura::Window::Init() to ensure observers
180   // do not add useless shadow layers by deriving one from the window type.
181   SetShadowElevationFromInitParams(window_, params);
182 
183   window_->Init(params.layer_type);
184   // Set name after layer init so it propagates to layer.
185   window_->SetName(params.name.empty() ? "NativeWidgetAura" : params.name);
186   if (params.type == Widget::InitParams::TYPE_CONTROL)
187     window_->Show();
188 
189   delegate_->OnNativeWidgetCreated();
190 
191   gfx::Rect window_bounds = params.bounds;
192   gfx::NativeView parent = params.parent;
193   gfx::NativeView context = params.context;
194   if (!params.child) {
195     // Set up the transient child before the window is added. This way the
196     // LayoutManager knows the window has a transient parent.
197     if (parent && parent->type() != aura::client::WINDOW_TYPE_UNKNOWN) {
198       wm::AddTransientChild(parent, window_);
199       if (!context)
200         context = parent;
201       parent = nullptr;
202 
203       // Generally transient bubbles are showing state associated to the parent
204       // window. Make sure the transient bubble is only visible if the parent is
205       // visible, otherwise the bubble may not make sense by itself.
206       if (params.type == Widget::InitParams::TYPE_BUBBLE) {
207         wm::TransientWindowManager::GetOrCreate(window_)
208             ->set_parent_controls_visibility(true);
209       }
210     }
211     // SetZOrderLevel before SetParent so that always-on-top container is used.
212     SetZOrderLevel(params.EffectiveZOrderLevel());
213 
214     // Make sure we have a real |window_bounds|.
215     aura::Window* parent_or_context = parent ? parent : context;
216     if (parent_or_context && window_bounds == gfx::Rect()) {
217       // If a parent or context is specified but no bounds are given, use the
218       // origin of the display so that the widget will be added to the same
219       // display as the parent or context.
220       gfx::Rect bounds = display::Screen::GetScreen()
221                              ->GetDisplayNearestWindow(parent_or_context)
222                              .bounds();
223       window_bounds.set_origin(bounds.origin());
224     }
225   }
226 
227   // Set properties before adding to the parent so that its layout manager sees
228   // the correct values.
229   OnSizeConstraintsChanged();
230 
231   if (parent) {
232     parent->AddChild(window_);
233   } else {
234     aura::client::ParentWindowWithContext(window_, context->GetRootWindow(),
235                                           window_bounds);
236   }
237 
238   window_->AddObserver(this);
239 
240   // Wait to set the bounds until we have a parent. That way we can know our
241   // true state/bounds (the LayoutManager may enforce a particular
242   // state/bounds).
243   if (IsMaximized())
244     SetRestoreBounds(window_, window_bounds);
245   else
246     SetBounds(window_bounds);
247   window_->SetEventTargetingPolicy(
248       params.accept_events ? aura::EventTargetingPolicy::kTargetAndDescendants
249                            : aura::EventTargetingPolicy::kNone);
250   DCHECK(GetWidget()->GetRootView());
251   if (params.type != Widget::InitParams::TYPE_TOOLTIP)
252     tooltip_manager_ = std::make_unique<views::TooltipManagerAura>(GetWidget());
253 
254   drop_helper_ = std::make_unique<DropHelper>(GetWidget()->GetRootView());
255   if (params.type != Widget::InitParams::TYPE_TOOLTIP &&
256       params.type != Widget::InitParams::TYPE_POPUP) {
257     aura::client::SetDragDropDelegate(window_, this);
258   }
259 
260   if (params.type == Widget::InitParams::TYPE_WINDOW) {
261     focus_manager_event_handler_ =
262         std::make_unique<FocusManagerEventHandler>(GetWidget(), window_);
263   }
264 
265   wm::SetActivationDelegate(window_, this);
266 
267   window_reorderer_ =
268       std::make_unique<WindowReorderer>(window_, GetWidget()->GetRootView());
269 }
270 
OnWidgetInitDone()271 void NativeWidgetAura::OnWidgetInitDone() {}
272 
273 std::unique_ptr<NonClientFrameView>
CreateNonClientFrameView()274 NativeWidgetAura::CreateNonClientFrameView() {
275   return nullptr;
276 }
277 
ShouldUseNativeFrame() const278 bool NativeWidgetAura::ShouldUseNativeFrame() const {
279   // There is only one frame type for aura.
280   return false;
281 }
282 
ShouldWindowContentsBeTransparent() const283 bool NativeWidgetAura::ShouldWindowContentsBeTransparent() const {
284   return false;
285 }
286 
FrameTypeChanged()287 void NativeWidgetAura::FrameTypeChanged() {
288   // This is called when the Theme has changed; forward the event to the root
289   // widget.
290   GetWidget()->ThemeChanged();
291   GetWidget()->GetRootView()->SchedulePaint();
292 }
293 
GetWidget()294 Widget* NativeWidgetAura::GetWidget() {
295   return delegate_->AsWidget();
296 }
297 
GetWidget() const298 const Widget* NativeWidgetAura::GetWidget() const {
299   return delegate_->AsWidget();
300 }
301 
GetNativeView() const302 gfx::NativeView NativeWidgetAura::GetNativeView() const {
303   return window_;
304 }
305 
GetNativeWindow() const306 gfx::NativeWindow NativeWidgetAura::GetNativeWindow() const {
307   return window_;
308 }
309 
GetTopLevelWidget()310 Widget* NativeWidgetAura::GetTopLevelWidget() {
311   NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
312   return native_widget ? native_widget->GetWidget() : nullptr;
313 }
314 
GetCompositor() const315 const ui::Compositor* NativeWidgetAura::GetCompositor() const {
316   return window_ ? window_->layer()->GetCompositor() : nullptr;
317 }
318 
GetLayer() const319 const ui::Layer* NativeWidgetAura::GetLayer() const {
320   return window_ ? window_->layer() : nullptr;
321 }
322 
ReorderNativeViews()323 void NativeWidgetAura::ReorderNativeViews() {
324   window_reorderer_->ReorderChildWindows();
325 }
326 
ViewRemoved(View * view)327 void NativeWidgetAura::ViewRemoved(View* view) {
328   DCHECK(drop_helper_.get() != nullptr);
329   drop_helper_->ResetTargetViewIfEquals(view);
330 }
331 
SetNativeWindowProperty(const char * name,void * value)332 void NativeWidgetAura::SetNativeWindowProperty(const char* name, void* value) {
333   if (window_)
334     window_->SetNativeWindowProperty(name, value);
335 }
336 
GetNativeWindowProperty(const char * name) const337 void* NativeWidgetAura::GetNativeWindowProperty(const char* name) const {
338   return window_ ? window_->GetNativeWindowProperty(name) : nullptr;
339 }
340 
GetTooltipManager() const341 TooltipManager* NativeWidgetAura::GetTooltipManager() const {
342   return tooltip_manager_.get();
343 }
344 
SetCapture()345 void NativeWidgetAura::SetCapture() {
346   if (window_)
347     window_->SetCapture();
348 }
349 
ReleaseCapture()350 void NativeWidgetAura::ReleaseCapture() {
351   if (window_)
352     window_->ReleaseCapture();
353 }
354 
HasCapture() const355 bool NativeWidgetAura::HasCapture() const {
356   return window_ && window_->HasCapture();
357 }
358 
GetInputMethod()359 ui::InputMethod* NativeWidgetAura::GetInputMethod() {
360   if (!window_)
361     return nullptr;
362   aura::Window* root_window = window_->GetRootWindow();
363   return root_window ? root_window->GetHost()->GetInputMethod() : nullptr;
364 }
365 
CenterWindow(const gfx::Size & size)366 void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
367   if (!window_)
368     return;
369 
370   window_->SetProperty(aura::client::kPreferredSize, size);
371 
372   gfx::Rect parent_bounds(window_->parent()->GetBoundsInRootWindow());
373   // When centering window, we take the intersection of the host and
374   // the parent. We assume the root window represents the visible
375   // rect of a single screen.
376   gfx::Rect work_area = display::Screen::GetScreen()
377                             ->GetDisplayNearestWindow(window_)
378                             .work_area();
379 
380   aura::client::ScreenPositionClient* screen_position_client =
381       aura::client::GetScreenPositionClient(window_->GetRootWindow());
382   if (screen_position_client) {
383     gfx::Point origin = work_area.origin();
384     screen_position_client->ConvertPointFromScreen(window_->GetRootWindow(),
385                                                    &origin);
386     work_area.set_origin(origin);
387   }
388 
389   parent_bounds.Intersect(work_area);
390 
391   // If |window_|'s transient parent's bounds are big enough to fit it, then we
392   // center it with respect to the transient parent.
393   if (wm::GetTransientParent(window_)) {
394     gfx::Rect transient_parent_rect =
395         wm::GetTransientParent(window_)->GetBoundsInRootWindow();
396     transient_parent_rect.Intersect(work_area);
397     if (transient_parent_rect.height() >= size.height() &&
398         transient_parent_rect.width() >= size.width())
399       parent_bounds = transient_parent_rect;
400   }
401 
402   gfx::Rect window_bounds(
403       parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
404       parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
405       size.width(), size.height());
406   // Don't size the window bigger than the parent, otherwise the user may not be
407   // able to close or move it.
408   window_bounds.AdjustToFit(parent_bounds);
409 
410   // Convert the bounds back relative to the parent.
411   gfx::Point origin = window_bounds.origin();
412   aura::Window::ConvertPointToTarget(window_->GetRootWindow(),
413                                      window_->parent(), &origin);
414   window_bounds.set_origin(origin);
415   window_->SetBounds(window_bounds);
416 }
417 
GetWindowPlacement(gfx::Rect * bounds,ui::WindowShowState * show_state) const418 void NativeWidgetAura::GetWindowPlacement(
419     gfx::Rect* bounds,
420     ui::WindowShowState* show_state) const {
421   // The interface specifies returning restored bounds, not current bounds.
422   *bounds = GetRestoredBounds();
423   *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey)
424                         : ui::SHOW_STATE_DEFAULT;
425 }
426 
SetWindowTitle(const base::string16 & title)427 bool NativeWidgetAura::SetWindowTitle(const base::string16& title) {
428   if (!window_)
429     return false;
430   if (window_->GetTitle() == title)
431     return false;
432   window_->SetTitle(title);
433   return true;
434 }
435 
SetWindowIcons(const gfx::ImageSkia & window_icon,const gfx::ImageSkia & app_icon)436 void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
437                                       const gfx::ImageSkia& app_icon) {
438   AssignIconToAuraWindow(window_, window_icon, app_icon);
439 }
440 
InitModalType(ui::ModalType modal_type)441 void NativeWidgetAura::InitModalType(ui::ModalType modal_type) {
442   if (modal_type != ui::MODAL_TYPE_NONE)
443     window_->SetProperty(aura::client::kModalKey, modal_type);
444   if (modal_type == ui::MODAL_TYPE_WINDOW) {
445     wm::TransientWindowManager::GetOrCreate(window_)
446         ->set_parent_controls_visibility(true);
447   }
448 }
449 
GetWindowBoundsInScreen() const450 gfx::Rect NativeWidgetAura::GetWindowBoundsInScreen() const {
451   return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
452 }
453 
GetClientAreaBoundsInScreen() const454 gfx::Rect NativeWidgetAura::GetClientAreaBoundsInScreen() const {
455   // View-to-screen coordinate system transformations depend on this returning
456   // the full window bounds, for example View::ConvertPointToScreen().
457   return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
458 }
459 
GetRestoredBounds() const460 gfx::Rect NativeWidgetAura::GetRestoredBounds() const {
461   if (!window_)
462     return gfx::Rect();
463 
464   // Restored bounds should only be relevant if the window is minimized,
465   // maximized, or fullscreen. However, in some places the code expects
466   // GetRestoredBounds() to return the current window bounds if the window is
467   // not in either state.
468   if (IsMinimized() || IsMaximized() || IsFullscreen()) {
469     // Restore bounds are in screen coordinates, no need to convert.
470     gfx::Rect* restore_bounds =
471         window_->GetProperty(aura::client::kRestoreBoundsKey);
472     if (restore_bounds)
473       return *restore_bounds;
474   }
475 
476   // Prefer getting the window bounds and converting them to screen bounds since
477   // Window::GetBoundsInScreen takes into the account the window transform.
478   auto* screen_position_client =
479       aura::client::GetScreenPositionClient(window_->GetRootWindow());
480   if (screen_position_client) {
481     // |window_|'s bounds are in parent's coordinate system so use that when
482     // converting.
483     gfx::Rect bounds = window_->bounds();
484     gfx::Point origin = bounds.origin();
485     screen_position_client->ConvertPointToScreenIgnoringTransforms(
486         window_->parent(), &origin);
487     return gfx::Rect(origin, bounds.size());
488   }
489 
490   return window_->GetBoundsInScreen();
491 }
492 
GetWorkspace() const493 std::string NativeWidgetAura::GetWorkspace() const {
494   return std::string();
495 }
496 
SetBounds(const gfx::Rect & bounds)497 void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
498   if (!window_)
499     return;
500 
501   aura::Window* root = window_->GetRootWindow();
502   if (root) {
503     aura::client::ScreenPositionClient* screen_position_client =
504         aura::client::GetScreenPositionClient(root);
505     if (screen_position_client) {
506       display::Display dst_display =
507           display::Screen::GetScreen()->GetDisplayMatching(bounds);
508       screen_position_client->SetBounds(window_, bounds, dst_display);
509       return;
510     }
511   }
512   window_->SetBounds(bounds);
513 }
514 
SetBoundsConstrained(const gfx::Rect & bounds)515 void NativeWidgetAura::SetBoundsConstrained(const gfx::Rect& bounds) {
516   if (!window_)
517     return;
518 
519   gfx::Rect new_bounds(bounds);
520   if (window_->parent()) {
521     if (window_->parent()->GetProperty(wm::kUsesScreenCoordinatesKey)) {
522       new_bounds =
523           NativeWidgetPrivate::ConstrainBoundsToDisplayWorkArea(new_bounds);
524     } else {
525       new_bounds.AdjustToFit(gfx::Rect(window_->parent()->bounds().size()));
526     }
527   }
528   SetBounds(new_bounds);
529 }
530 
SetSize(const gfx::Size & size)531 void NativeWidgetAura::SetSize(const gfx::Size& size) {
532   if (window_)
533     window_->SetBounds(gfx::Rect(window_->bounds().origin(), size));
534 }
535 
StackAbove(gfx::NativeView native_view)536 void NativeWidgetAura::StackAbove(gfx::NativeView native_view) {
537   if (window_ && window_->parent() &&
538       window_->parent() == native_view->parent())
539     window_->parent()->StackChildAbove(window_, native_view);
540 }
541 
StackAtTop()542 void NativeWidgetAura::StackAtTop() {
543   if (window_)
544     window_->parent()->StackChildAtTop(window_);
545 }
546 
SetShape(std::unique_ptr<Widget::ShapeRects> shape)547 void NativeWidgetAura::SetShape(std::unique_ptr<Widget::ShapeRects> shape) {
548   if (window_)
549     window_->layer()->SetAlphaShape(std::move(shape));
550 }
551 
Close()552 void NativeWidgetAura::Close() {
553   // |window_| may already be deleted by parent window. This can happen
554   // when this widget is child widget or has transient parent
555   // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
556   DCHECK(window_ ||
557          ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
558   if (window_) {
559     Hide();
560     window_->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
561   }
562 
563   if (!close_widget_factory_.HasWeakPtrs()) {
564     base::ThreadTaskRunnerHandle::Get()->PostTask(
565         FROM_HERE, base::BindOnce(&NativeWidgetAura::CloseNow,
566                                   close_widget_factory_.GetWeakPtr()));
567   }
568 }
569 
CloseNow()570 void NativeWidgetAura::CloseNow() {
571   delete window_;
572 }
573 
Show(ui::WindowShowState show_state,const gfx::Rect & restore_bounds)574 void NativeWidgetAura::Show(ui::WindowShowState show_state,
575                             const gfx::Rect& restore_bounds) {
576   if (!window_)
577     return;
578 
579   if (show_state == ui::SHOW_STATE_MAXIMIZED && !restore_bounds.IsEmpty())
580     SetRestoreBounds(window_, restore_bounds);
581   if (show_state == ui::SHOW_STATE_MAXIMIZED ||
582       show_state == ui::SHOW_STATE_FULLSCREEN) {
583     window_->SetProperty(aura::client::kShowStateKey, show_state);
584   }
585   window_->Show();
586   if (delegate_->CanActivate()) {
587     if (show_state != ui::SHOW_STATE_INACTIVE)
588       Activate();
589     // SetInitialFocus() should be always be called, even for
590     // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
591     // do the right thing.
592     // Activate() might fail if the window is non-activatable. In this case, we
593     // should pass SHOW_STATE_INACTIVE to SetInitialFocus() to stop the initial
594     // focused view from getting focused. See crbug.com/515594 for example.
595     SetInitialFocus(IsActive() ? show_state : ui::SHOW_STATE_INACTIVE);
596   }
597 
598   // On desktop aura, a window is activated first even when it is shown as
599   // minimized. Do the same for consistency.
600   if (show_state == ui::SHOW_STATE_MINIMIZED)
601     Minimize();
602 }
603 
Hide()604 void NativeWidgetAura::Hide() {
605   if (window_)
606     window_->Hide();
607 }
608 
IsVisible() const609 bool NativeWidgetAura::IsVisible() const {
610   return window_ && window_->IsVisible();
611 }
612 
Activate()613 void NativeWidgetAura::Activate() {
614   if (!window_)
615     return;
616 
617   // We don't necessarily have a root window yet. This can happen with
618   // constrained windows.
619   if (window_->GetRootWindow())
620     wm::GetActivationClient(window_->GetRootWindow())->ActivateWindow(window_);
621   if (window_->GetProperty(aura::client::kDrawAttentionKey))
622     window_->SetProperty(aura::client::kDrawAttentionKey, false);
623 }
624 
Deactivate()625 void NativeWidgetAura::Deactivate() {
626   if (!window_)
627     return;
628   wm::GetActivationClient(window_->GetRootWindow())->DeactivateWindow(window_);
629 }
630 
IsActive() const631 bool NativeWidgetAura::IsActive() const {
632   return window_ && wm::IsActiveWindow(window_);
633 }
634 
SetZOrderLevel(ui::ZOrderLevel order)635 void NativeWidgetAura::SetZOrderLevel(ui::ZOrderLevel order) {
636   if (window_)
637     window_->SetProperty(aura::client::kZOrderingKey, order);
638 }
639 
GetZOrderLevel() const640 ui::ZOrderLevel NativeWidgetAura::GetZOrderLevel() const {
641   if (window_)
642     return window_->GetProperty(aura::client::kZOrderingKey);
643 
644   return ui::ZOrderLevel::kNormal;
645 }
646 
SetVisibleOnAllWorkspaces(bool always_visible)647 void NativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) {
648   // Not implemented on chromeos or for child widgets.
649 }
650 
IsVisibleOnAllWorkspaces() const651 bool NativeWidgetAura::IsVisibleOnAllWorkspaces() const {
652   return false;
653 }
654 
Maximize()655 void NativeWidgetAura::Maximize() {
656   if (window_)
657     window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
658 }
659 
Minimize()660 void NativeWidgetAura::Minimize() {
661   if (window_)
662     window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
663 }
664 
IsMaximized() const665 bool NativeWidgetAura::IsMaximized() const {
666   return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
667                         ui::SHOW_STATE_MAXIMIZED;
668 }
669 
IsMinimized() const670 bool NativeWidgetAura::IsMinimized() const {
671   return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
672                         ui::SHOW_STATE_MINIMIZED;
673 }
674 
Restore()675 void NativeWidgetAura::Restore() {
676   if (window_)
677     window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
678 }
679 
SetFullscreen(bool fullscreen)680 void NativeWidgetAura::SetFullscreen(bool fullscreen) {
681   if (!window_ || IsFullscreen() == fullscreen)
682     return;  // Nothing to do.
683 
684   wm::SetWindowFullscreen(window_, fullscreen);
685 }
686 
IsFullscreen() const687 bool NativeWidgetAura::IsFullscreen() const {
688   return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
689                         ui::SHOW_STATE_FULLSCREEN;
690 }
691 
SetCanAppearInExistingFullscreenSpaces(bool can_appear_in_existing_fullscreen_spaces)692 void NativeWidgetAura::SetCanAppearInExistingFullscreenSpaces(
693     bool can_appear_in_existing_fullscreen_spaces) {}
694 
SetOpacity(float opacity)695 void NativeWidgetAura::SetOpacity(float opacity) {
696   if (window_)
697     window_->layer()->SetOpacity(opacity);
698 }
699 
SetAspectRatio(const gfx::SizeF & aspect_ratio)700 void NativeWidgetAura::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
701   DCHECK(!aspect_ratio.IsEmpty());
702   if (window_) {
703     // aura::client::kAspectRatio is owned, which allows for passing in this
704     // raw pointer.
705     window_->SetProperty(aura::client::kAspectRatio,
706                          new gfx::SizeF(aspect_ratio));
707   }
708 }
709 
FlashFrame(bool flash)710 void NativeWidgetAura::FlashFrame(bool flash) {
711   if (window_)
712     window_->SetProperty(aura::client::kDrawAttentionKey, flash);
713 }
714 
RunShellDrag(View * view,std::unique_ptr<ui::OSExchangeData> data,const gfx::Point & location,int operation,ui::mojom::DragEventSource source)715 void NativeWidgetAura::RunShellDrag(View* view,
716                                     std::unique_ptr<ui::OSExchangeData> data,
717                                     const gfx::Point& location,
718                                     int operation,
719                                     ui::mojom::DragEventSource source) {
720   if (window_)
721     views::RunShellDrag(window_, std::move(data), location, operation, source);
722 }
723 
SchedulePaintInRect(const gfx::Rect & rect)724 void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
725   if (window_)
726     window_->SchedulePaintInRect(rect);
727 }
728 
ScheduleLayout()729 void NativeWidgetAura::ScheduleLayout() {
730   // ScheduleDraw() triggers a callback to WindowDelegate::UpdateVisualState().
731   if (window_)
732     window_->ScheduleDraw();
733 }
734 
SetCursor(gfx::NativeCursor cursor)735 void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
736   cursor_ = cursor;
737   aura::client::CursorClient* cursor_client =
738       aura::client::GetCursorClient(window_->GetRootWindow());
739   if (cursor_client)
740     cursor_client->SetCursor(cursor);
741 }
742 
IsMouseEventsEnabled() const743 bool NativeWidgetAura::IsMouseEventsEnabled() const {
744   if (!window_)
745     return false;
746   aura::client::CursorClient* cursor_client =
747       aura::client::GetCursorClient(window_->GetRootWindow());
748   return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
749 }
750 
IsMouseButtonDown() const751 bool NativeWidgetAura::IsMouseButtonDown() const {
752   return aura::Env::GetInstance()->IsMouseButtonDown();
753 }
754 
ClearNativeFocus()755 void NativeWidgetAura::ClearNativeFocus() {
756   aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
757   if (window_ && client && window_->Contains(client->GetFocusedWindow()))
758     client->ResetFocusWithinActiveWindow(window_);
759 }
760 
GetWorkAreaBoundsInScreen() const761 gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
762   if (!window_)
763     return gfx::Rect();
764   return display::Screen::GetScreen()
765       ->GetDisplayNearestWindow(window_)
766       .work_area();
767 }
768 
RunMoveLoop(const gfx::Vector2d & drag_offset,Widget::MoveLoopSource source,Widget::MoveLoopEscapeBehavior escape_behavior)769 Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
770     const gfx::Vector2d& drag_offset,
771     Widget::MoveLoopSource source,
772     Widget::MoveLoopEscapeBehavior escape_behavior) {
773   // |escape_behavior| is only needed on windows when running the native message
774   // loop.
775   if (!window_ || !window_->GetRootWindow())
776     return Widget::MOVE_LOOP_CANCELED;
777   wm::WindowMoveClient* move_client =
778       wm::GetWindowMoveClient(window_->GetRootWindow());
779   if (!move_client)
780     return Widget::MOVE_LOOP_CANCELED;
781 
782   SetCapture();
783   wm::WindowMoveSource window_move_source =
784       source == Widget::MoveLoopSource::kMouse ? wm::WINDOW_MOVE_SOURCE_MOUSE
785                                                : wm::WINDOW_MOVE_SOURCE_TOUCH;
786   if (move_client->RunMoveLoop(window_, drag_offset, window_move_source) ==
787       wm::MOVE_SUCCESSFUL) {
788     return Widget::MOVE_LOOP_SUCCESSFUL;
789   }
790   return Widget::MOVE_LOOP_CANCELED;
791 }
792 
EndMoveLoop()793 void NativeWidgetAura::EndMoveLoop() {
794   if (!window_ || !window_->GetRootWindow())
795     return;
796   wm::WindowMoveClient* move_client =
797       wm::GetWindowMoveClient(window_->GetRootWindow());
798   if (move_client)
799     move_client->EndMoveLoop();
800 }
801 
SetVisibilityChangedAnimationsEnabled(bool value)802 void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value) {
803   if (window_)
804     window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
805 }
806 
SetVisibilityAnimationDuration(const base::TimeDelta & duration)807 void NativeWidgetAura::SetVisibilityAnimationDuration(
808     const base::TimeDelta& duration) {
809   wm::SetWindowVisibilityAnimationDuration(window_, duration);
810 }
811 
SetVisibilityAnimationTransition(Widget::VisibilityTransition transition)812 void NativeWidgetAura::SetVisibilityAnimationTransition(
813     Widget::VisibilityTransition transition) {
814   wm::WindowVisibilityAnimationTransition wm_transition = wm::ANIMATE_NONE;
815   switch (transition) {
816     case Widget::ANIMATE_SHOW:
817       wm_transition = wm::ANIMATE_SHOW;
818       break;
819     case Widget::ANIMATE_HIDE:
820       wm_transition = wm::ANIMATE_HIDE;
821       break;
822     case Widget::ANIMATE_BOTH:
823       wm_transition = wm::ANIMATE_BOTH;
824       break;
825     case Widget::ANIMATE_NONE:
826       wm_transition = wm::ANIMATE_NONE;
827       break;
828   }
829   wm::SetWindowVisibilityAnimationTransition(window_, wm_transition);
830 }
831 
IsTranslucentWindowOpacitySupported() const832 bool NativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
833   return true;
834 }
835 
GetGestureRecognizer()836 ui::GestureRecognizer* NativeWidgetAura::GetGestureRecognizer() {
837   return aura::Env::GetInstance()->gesture_recognizer();
838 }
839 
OnSizeConstraintsChanged()840 void NativeWidgetAura::OnSizeConstraintsChanged() {
841   SetResizeBehaviorFromDelegate(GetWidget()->widget_delegate(), window_);
842 }
843 
OnNativeViewHierarchyWillChange()844 void NativeWidgetAura::OnNativeViewHierarchyWillChange() {}
845 
OnNativeViewHierarchyChanged()846 void NativeWidgetAura::OnNativeViewHierarchyChanged() {}
847 
GetName() const848 std::string NativeWidgetAura::GetName() const {
849   return window_ ? window_->GetName() : std::string();
850 }
851 
852 ////////////////////////////////////////////////////////////////////////////////
853 // NativeWidgetAura, aura::WindowDelegate implementation:
854 
GetMinimumSize() const855 gfx::Size NativeWidgetAura::GetMinimumSize() const {
856   return delegate_->GetMinimumSize();
857 }
858 
GetMaximumSize() const859 gfx::Size NativeWidgetAura::GetMaximumSize() const {
860   // Do no check maximizability as EXO clients can have maximum size and be
861   // maximizable at the same time.
862   return delegate_->GetMaximumSize();
863 }
864 
OnBoundsChanged(const gfx::Rect & old_bounds,const gfx::Rect & new_bounds)865 void NativeWidgetAura::OnBoundsChanged(const gfx::Rect& old_bounds,
866                                        const gfx::Rect& new_bounds) {
867   // Assume that if the old bounds was completely empty a move happened. This
868   // handles the case of a maximize animation acquiring the layer (acquiring a
869   // layer results in clearing the bounds).
870   if (old_bounds.origin() != new_bounds.origin() ||
871       (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) {
872     delegate_->OnNativeWidgetMove();
873   }
874   if (old_bounds.size() != new_bounds.size())
875     delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
876 }
877 
GetCursor(const gfx::Point & point)878 gfx::NativeCursor NativeWidgetAura::GetCursor(const gfx::Point& point) {
879   return cursor_;
880 }
881 
GetNonClientComponent(const gfx::Point & point) const882 int NativeWidgetAura::GetNonClientComponent(const gfx::Point& point) const {
883   return delegate_->GetNonClientComponent(point);
884 }
885 
ShouldDescendIntoChildForEventHandling(aura::Window * child,const gfx::Point & location)886 bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
887     aura::Window* child,
888     const gfx::Point& location) {
889   return delegate_->ShouldDescendIntoChildForEventHandling(
890       window_->layer(), child, child->layer(), location);
891 }
892 
CanFocus()893 bool NativeWidgetAura::CanFocus() {
894   return ShouldActivate();
895 }
896 
OnCaptureLost()897 void NativeWidgetAura::OnCaptureLost() {
898   delegate_->OnMouseCaptureLost();
899 }
900 
OnPaint(const ui::PaintContext & context)901 void NativeWidgetAura::OnPaint(const ui::PaintContext& context) {
902   delegate_->OnNativeWidgetPaint(context);
903 }
904 
OnDeviceScaleFactorChanged(float old_device_scale_factor,float new_device_scale_factor)905 void NativeWidgetAura::OnDeviceScaleFactorChanged(
906     float old_device_scale_factor,
907     float new_device_scale_factor) {
908   GetWidget()->DeviceScaleFactorChanged(old_device_scale_factor,
909                                         new_device_scale_factor);
910 }
911 
OnWindowDestroying(aura::Window * window)912 void NativeWidgetAura::OnWindowDestroying(aura::Window* window) {
913   window_->RemoveObserver(this);
914   delegate_->OnNativeWidgetDestroying();
915 
916   // If the aura::Window is destroyed, we can no longer show tooltips.
917   tooltip_manager_.reset();
918 
919   focus_manager_event_handler_.reset();
920 }
921 
OnWindowDestroyed(aura::Window * window)922 void NativeWidgetAura::OnWindowDestroyed(aura::Window* window) {
923   window_ = nullptr;
924   // |OnNativeWidgetDestroyed| may delete |this| if the object does not own
925   // itself.
926   bool should_delete_this =
927       (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET);
928   delegate_->OnNativeWidgetDestroyed();
929   if (should_delete_this)
930     delete this;
931 }
932 
OnWindowTargetVisibilityChanged(bool visible)933 void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
934   delegate_->OnNativeWidgetVisibilityChanged(visible);
935 }
936 
HasHitTestMask() const937 bool NativeWidgetAura::HasHitTestMask() const {
938   return delegate_->HasHitTestMask();
939 }
940 
GetHitTestMask(SkPath * mask) const941 void NativeWidgetAura::GetHitTestMask(SkPath* mask) const {
942   DCHECK(mask);
943   delegate_->GetHitTestMask(mask);
944 }
945 
UpdateVisualState()946 void NativeWidgetAura::UpdateVisualState() {
947   delegate_->LayoutRootViewIfNecessary();
948 }
949 
950 ////////////////////////////////////////////////////////////////////////////////
951 // NativeWidgetAura, aura::WindowObserver implementation:
952 
OnWindowPropertyChanged(aura::Window * window,const void * key,intptr_t old)953 void NativeWidgetAura::OnWindowPropertyChanged(aura::Window* window,
954                                                const void* key,
955                                                intptr_t old) {
956   if (key == aura::client::kShowStateKey)
957     delegate_->OnNativeWidgetWindowShowStateChanged();
958 }
959 
OnResizeLoopStarted(aura::Window * window)960 void NativeWidgetAura::OnResizeLoopStarted(aura::Window* window) {
961   delegate_->OnNativeWidgetBeginUserBoundsChange();
962 }
963 
OnResizeLoopEnded(aura::Window * window)964 void NativeWidgetAura::OnResizeLoopEnded(aura::Window* window) {
965   delegate_->OnNativeWidgetEndUserBoundsChange();
966 }
967 
968 ////////////////////////////////////////////////////////////////////////////////
969 // NativeWidgetAura, ui::EventHandler implementation:
970 
OnKeyEvent(ui::KeyEvent * event)971 void NativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
972   DCHECK(window_);
973   // Renderer may send a key event back to us if the key event wasn't handled,
974   // and the window may be invisible by that time.
975   if (!window_->IsVisible())
976     return;
977 
978   delegate_->OnKeyEvent(event);
979 }
980 
OnMouseEvent(ui::MouseEvent * event)981 void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
982   DCHECK(window_);
983   DCHECK(window_->IsVisible());
984   if (event->type() == ui::ET_MOUSEWHEEL) {
985     delegate_->OnMouseEvent(event);
986     return;
987   }
988 
989   if (tooltip_manager_.get())
990     tooltip_manager_->UpdateTooltip();
991   TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
992   delegate_->OnMouseEvent(event);
993 }
994 
OnScrollEvent(ui::ScrollEvent * event)995 void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
996   delegate_->OnScrollEvent(event);
997 }
998 
OnGestureEvent(ui::GestureEvent * event)999 void NativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
1000   DCHECK(window_);
1001   DCHECK(window_->IsVisible() || event->IsEndingEvent());
1002   delegate_->OnGestureEvent(event);
1003 }
1004 
1005 ////////////////////////////////////////////////////////////////////////////////
1006 // NativeWidgetAura, wm::ActivationDelegate implementation:
1007 
ShouldActivate() const1008 bool NativeWidgetAura::ShouldActivate() const {
1009   return delegate_->CanActivate();
1010 }
1011 
1012 ////////////////////////////////////////////////////////////////////////////////
1013 // NativeWidgetAura, wm::ActivationChangeObserver implementation:
1014 
OnWindowActivated(wm::ActivationChangeObserver::ActivationReason,aura::Window * gained_active,aura::Window * lost_active)1015 void NativeWidgetAura::OnWindowActivated(
1016     wm::ActivationChangeObserver::ActivationReason,
1017     aura::Window* gained_active,
1018     aura::Window* lost_active) {
1019   DCHECK(window_ == gained_active || window_ == lost_active);
1020   if (GetWidget()->GetFocusManager()) {
1021     if (window_ == gained_active)
1022       GetWidget()->GetFocusManager()->RestoreFocusedView();
1023     else if (window_ == lost_active)
1024       GetWidget()->GetFocusManager()->StoreFocusedView(true);
1025   }
1026   delegate_->OnNativeWidgetActivationChanged(window_ == gained_active);
1027 }
1028 
1029 ////////////////////////////////////////////////////////////////////////////////
1030 // NativeWidgetAura, aura::client::FocusChangeObserver:
1031 
OnWindowFocused(aura::Window * gained_focus,aura::Window * lost_focus)1032 void NativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
1033                                        aura::Window* lost_focus) {
1034   if (window_ == gained_focus)
1035     delegate_->OnNativeFocus();
1036   else if (window_ == lost_focus)
1037     delegate_->OnNativeBlur();
1038 }
1039 
1040 ////////////////////////////////////////////////////////////////////////////////
1041 // NativeWidgetAura, aura::WindowDragDropDelegate implementation:
1042 
OnDragEntered(const ui::DropTargetEvent & event)1043 void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
1044   DCHECK(drop_helper_.get() != nullptr);
1045   last_drop_operation_ = drop_helper_->OnDragOver(
1046       event.data(), event.location(), event.source_operations());
1047 }
1048 
OnDragUpdated(const ui::DropTargetEvent & event)1049 int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
1050   DCHECK(drop_helper_.get() != nullptr);
1051   last_drop_operation_ = drop_helper_->OnDragOver(
1052       event.data(), event.location(), event.source_operations());
1053   return last_drop_operation_;
1054 }
1055 
OnDragExited()1056 void NativeWidgetAura::OnDragExited() {
1057   DCHECK(drop_helper_.get() != nullptr);
1058   drop_helper_->OnDragExit();
1059 }
1060 
OnPerformDrop(const ui::DropTargetEvent & event,std::unique_ptr<ui::OSExchangeData> data)1061 int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event,
1062                                     std::unique_ptr<ui::OSExchangeData> data) {
1063   DCHECK(drop_helper_.get() != nullptr);
1064   return drop_helper_->OnDrop(event.data(), event.location(),
1065                               last_drop_operation_);
1066 }
1067 
1068 ////////////////////////////////////////////////////////////////////////////////
1069 // NativeWidgetAura, protected:
1070 
~NativeWidgetAura()1071 NativeWidgetAura::~NativeWidgetAura() {
1072   destroying_ = true;
1073   if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
1074     delete delegate_;
1075   else
1076     CloseNow();
1077 }
1078 
1079 ////////////////////////////////////////////////////////////////////////////////
1080 // NativeWidgetAura, private:
1081 
SetInitialFocus(ui::WindowShowState show_state)1082 void NativeWidgetAura::SetInitialFocus(ui::WindowShowState show_state) {
1083   // The window does not get keyboard messages unless we focus it.
1084   if (!GetWidget()->SetInitialFocus(show_state))
1085     window_->Focus();
1086 }
1087 
1088 ////////////////////////////////////////////////////////////////////////////////
1089 // Widget, public:
1090 
1091 namespace {
1092 #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \
1093     (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD))
CloseWindow(aura::Window * window)1094 void CloseWindow(aura::Window* window) {
1095   if (window) {
1096     Widget* widget = Widget::GetWidgetForNativeView(window);
1097     if (widget && widget->is_secondary_widget())
1098       // To avoid the delay in shutdown caused by using Close which may wait
1099       // for animations, use CloseNow. Because this is only used on secondary
1100       // widgets it seems relatively safe to skip the extra processing of
1101       // Close.
1102       widget->CloseNow();
1103   }
1104 }
1105 #endif
1106 
1107 #if defined(OS_WIN)
WindowCallbackProc(HWND hwnd,LPARAM lParam)1108 BOOL CALLBACK WindowCallbackProc(HWND hwnd, LPARAM lParam) {
1109   aura::Window* root_window =
1110       DesktopWindowTreeHostWin::GetContentWindowForHWND(hwnd);
1111   CloseWindow(root_window);
1112   return TRUE;
1113 }
1114 #endif
1115 }  // namespace
1116 
1117 // static
CloseAllSecondaryWidgets()1118 void Widget::CloseAllSecondaryWidgets() {
1119 #if defined(OS_WIN)
1120   EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0);
1121 #endif
1122 
1123 #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \
1124     (defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD))
1125   DesktopWindowTreeHostLinux::CleanUpWindowList(CloseWindow);
1126 #endif
1127 }
1128 
GetNativeTheme() const1129 const ui::NativeTheme* Widget::GetNativeTheme() const {
1130 #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \
1131     (defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD))
1132   const LinuxUI* linux_ui = LinuxUI::instance();
1133   if (linux_ui) {
1134     ui::NativeTheme* native_theme =
1135         linux_ui->GetNativeTheme(native_widget_->GetNativeWindow());
1136     if (native_theme)
1137       return native_theme;
1138   }
1139 #endif
1140 
1141   return ui::NativeTheme::GetInstanceForNativeUi();
1142 }
1143 
1144 namespace internal {
1145 
1146 ////////////////////////////////////////////////////////////////////////////////
1147 // internal::NativeWidgetPrivate, public:
1148 
1149 // static
CreateNativeWidget(internal::NativeWidgetDelegate * delegate)1150 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
1151     internal::NativeWidgetDelegate* delegate) {
1152   return new NativeWidgetAura(delegate);
1153 }
1154 
1155 // static
GetNativeWidgetForNativeView(gfx::NativeView native_view)1156 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1157     gfx::NativeView native_view) {
1158   return native_view->GetProperty(kNativeWidgetPrivateKey);
1159 }
1160 
1161 // static
GetNativeWidgetForNativeWindow(gfx::NativeWindow native_window)1162 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1163     gfx::NativeWindow native_window) {
1164   return native_window->GetProperty(kNativeWidgetPrivateKey);
1165 }
1166 
1167 // static
GetTopLevelNativeWidget(gfx::NativeView native_view)1168 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
1169     gfx::NativeView native_view) {
1170   aura::Window* window = native_view;
1171   NativeWidgetPrivate* top_level_native_widget = nullptr;
1172   while (window) {
1173     NativeWidgetPrivate* native_widget = GetNativeWidgetForNativeView(window);
1174     if (native_widget)
1175       top_level_native_widget = native_widget;
1176     window = window->parent();
1177   }
1178   return top_level_native_widget;
1179 }
1180 
1181 // static
GetAllChildWidgets(gfx::NativeView native_view,Widget::Widgets * children)1182 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
1183                                              Widget::Widgets* children) {
1184   {
1185     // Code expects widget for |native_view| to be added to |children|.
1186     NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1187         GetNativeWidgetForNativeView(native_view));
1188     if (native_widget && native_widget->GetWidget())
1189       children->insert(native_widget->GetWidget());
1190   }
1191 
1192   for (auto* child_window : native_view->children())
1193     GetAllChildWidgets(child_window, children);
1194 }
1195 
1196 // static
GetAllOwnedWidgets(gfx::NativeView native_view,Widget::Widgets * owned)1197 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
1198                                              Widget::Widgets* owned) {
1199   // Add all owned widgets.
1200   for (aura::Window* transient_child : wm::GetTransientChildren(native_view)) {
1201     NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1202         GetNativeWidgetForNativeView(transient_child));
1203     if (native_widget && native_widget->GetWidget())
1204       owned->insert(native_widget->GetWidget());
1205     GetAllOwnedWidgets(transient_child, owned);
1206   }
1207 
1208   // Add all child windows.
1209   for (aura::Window* child : native_view->children())
1210     GetAllChildWidgets(child, owned);
1211 }
1212 
1213 // static
ReparentNativeView(gfx::NativeView native_view,gfx::NativeView new_parent)1214 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
1215                                              gfx::NativeView new_parent) {
1216   DCHECK(native_view != new_parent);
1217 
1218   gfx::NativeView previous_parent = native_view->parent();
1219   if (previous_parent == new_parent)
1220     return;
1221 
1222   Widget::Widgets widgets;
1223   GetAllChildWidgets(native_view, &widgets);
1224 
1225   // First notify all the widgets that they are being disassociated
1226   // from their previous parent.
1227   for (auto* widget : widgets)
1228     widget->NotifyNativeViewHierarchyWillChange();
1229 
1230   if (new_parent) {
1231     new_parent->AddChild(native_view);
1232   } else {
1233     // The following looks weird, but it's the equivalent of what aura has
1234     // always done. (The previous behaviour of aura::Window::SetParent() used
1235     // NULL as a special value that meant ask the WindowParentingClient where
1236     // things should go.)
1237     //
1238     // This probably isn't strictly correct, but its an invariant that a Window
1239     // in use will be attached to a RootWindow, so we can't just call
1240     // RemoveChild here. The only possible thing that could assign a RootWindow
1241     // in this case is the stacking client of the current RootWindow. This
1242     // matches our previous behaviour; the global stacking client would almost
1243     // always reattach the window to the same RootWindow.
1244     aura::Window* root_window = native_view->GetRootWindow();
1245     aura::client::ParentWindowWithContext(native_view, root_window,
1246                                           root_window->GetBoundsInScreen());
1247   }
1248 
1249   // And now, notify them that they have a brand new parent.
1250   for (auto* widget : widgets)
1251     widget->NotifyNativeViewHierarchyChanged();
1252 }
1253 
1254 // static
GetGlobalCapture(gfx::NativeView native_view)1255 gfx::NativeView NativeWidgetPrivate::GetGlobalCapture(
1256     gfx::NativeView native_view) {
1257   aura::client::CaptureClient* capture_client =
1258       aura::client::GetCaptureClient(native_view->GetRootWindow());
1259   if (!capture_client)
1260     return nullptr;
1261   return capture_client->GetGlobalCaptureWindow();
1262 }
1263 
1264 }  // namespace internal
1265 }  // namespace views
1266