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