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