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