Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Side by Side Diff: ui/views/widget/native_widget_aura.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/widget/native_widget_aura.h ('k') | ui/views/widget/native_widget_aura_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "base/bind.h"
8 #include "base/strings/string_util.h"
9 #include "third_party/skia/include/core/SkRegion.h"
10 #include "ui/aura/client/aura_constants.h"
11 #include "ui/aura/client/cursor_client.h"
12 #include "ui/aura/client/focus_client.h"
13 #include "ui/aura/client/screen_position_client.h"
14 #include "ui/aura/client/window_tree_client.h"
15 #include "ui/aura/env.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/aura/window_observer.h"
19 #include "ui/base/dragdrop/os_exchange_data.h"
20 #include "ui/base/ui_base_switches_util.h"
21 #include "ui/base/ui_base_types.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/events/event.h"
24 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/font_list.h"
26 #include "ui/gfx/screen.h"
27 #include "ui/native_theme/native_theme_aura.h"
28 #include "ui/views/drag_utils.h"
29 #include "ui/views/ime/input_method_bridge.h"
30 #include "ui/views/ime/null_input_method.h"
31 #include "ui/views/views_delegate.h"
32 #include "ui/views/widget/drop_helper.h"
33 #include "ui/views/widget/native_widget_delegate.h"
34 #include "ui/views/widget/root_view.h"
35 #include "ui/views/widget/tooltip_manager_aura.h"
36 #include "ui/views/widget/widget_aura_utils.h"
37 #include "ui/views/widget/widget_delegate.h"
38 #include "ui/views/widget/window_reorderer.h"
39 #include "ui/wm/core/shadow_types.h"
40 #include "ui/wm/core/window_util.h"
41 #include "ui/wm/public/activation_client.h"
42 #include "ui/wm/public/drag_drop_client.h"
43 #include "ui/wm/public/window_move_client.h"
44 #include "ui/wm/public/window_types.h"
45
46 #if defined(OS_WIN)
47 #include "base/win/scoped_gdi_object.h"
48 #include "base/win/win_util.h"
49 #include "ui/base/l10n/l10n_util_win.h"
50 #endif
51
52 namespace views {
53
54 namespace {
55
56 void SetRestoreBounds(aura::Window* window, const gfx::Rect& bounds) {
57 window->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds));
58 }
59
60 } // namespace
61
62 ////////////////////////////////////////////////////////////////////////////////
63 // NativeWidgetAura, public:
64
65 NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate)
66 : delegate_(delegate),
67 window_(new aura::Window(this)),
68 ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
69 destroying_(false),
70 cursor_(gfx::kNullCursor),
71 saved_window_state_(ui::SHOW_STATE_DEFAULT),
72 close_widget_factory_(this) {
73 aura::client::SetFocusChangeObserver(window_, this);
74 aura::client::SetActivationChangeObserver(window_, this);
75 }
76
77 // static
78 void NativeWidgetAura::RegisterNativeWidgetForWindow(
79 internal::NativeWidgetPrivate* native_widget,
80 aura::Window* window) {
81 window->set_user_data(native_widget);
82 }
83
84 ////////////////////////////////////////////////////////////////////////////////
85 // NativeWidgetAura, internal::NativeWidgetPrivate implementation:
86
87 void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
88 // Aura needs to know which desktop (Ash or regular) will manage this widget.
89 // See Widget::InitParams::context for details.
90 DCHECK(params.parent || params.context);
91
92 ownership_ = params.ownership;
93
94 RegisterNativeWidgetForWindow(this, window_);
95 window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
96 window_->SetProperty(aura::client::kShowStateKey, params.show_state);
97 if (params.type == Widget::InitParams::TYPE_BUBBLE)
98 aura::client::SetHideOnDeactivate(window_, true);
99 window_->SetTransparent(
100 params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW);
101 window_->Init(params.layer_type);
102 if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_NONE)
103 SetShadowType(window_, wm::SHADOW_TYPE_NONE);
104 else if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP)
105 SetShadowType(window_, wm::SHADOW_TYPE_RECTANGULAR);
106 if (params.type == Widget::InitParams::TYPE_CONTROL)
107 window_->Show();
108
109 delegate_->OnNativeWidgetCreated(false);
110
111 gfx::Rect window_bounds = params.bounds;
112 gfx::NativeView parent = params.parent;
113 gfx::NativeView context = params.context;
114 if (!params.child) {
115 // Set up the transient child before the window is added. This way the
116 // LayoutManager knows the window has a transient parent.
117 if (parent && parent->type() != ui::wm::WINDOW_TYPE_UNKNOWN) {
118 wm::AddTransientChild(parent, window_);
119 if (!context)
120 context = parent;
121 parent = NULL;
122 }
123 // SetAlwaysOnTop before SetParent so that always-on-top container is used.
124 SetAlwaysOnTop(params.keep_on_top);
125 // Make sure we have a real |window_bounds|.
126 if (parent && window_bounds == gfx::Rect()) {
127 // If a parent is specified but no bounds are given,
128 // use the origin of the parent's display so that the widget
129 // will be added to the same display as the parent.
130 gfx::Rect bounds = gfx::Screen::GetScreenFor(parent)->
131 GetDisplayNearestWindow(parent).bounds();
132 window_bounds.set_origin(bounds.origin());
133 }
134 }
135
136 // Set properties before adding to the parent so that its layout manager sees
137 // the correct values.
138 OnSizeConstraintsChanged();
139
140 if (parent) {
141 parent->AddChild(window_);
142 } else {
143 aura::client::ParentWindowWithContext(
144 window_, context->GetRootWindow(), window_bounds);
145 }
146
147 // Start observing property changes.
148 window_->AddObserver(this);
149
150 // Wait to set the bounds until we have a parent. That way we can know our
151 // true state/bounds (the LayoutManager may enforce a particular
152 // state/bounds).
153 if (IsMaximized())
154 SetRestoreBounds(window_, window_bounds);
155 else
156 SetBounds(window_bounds);
157 window_->set_ignore_events(!params.accept_events);
158 DCHECK(GetWidget()->GetRootView());
159 if (params.type != Widget::InitParams::TYPE_TOOLTIP)
160 tooltip_manager_.reset(new views::TooltipManagerAura(GetWidget()));
161
162 drop_helper_.reset(new DropHelper(GetWidget()->GetRootView()));
163 if (params.type != Widget::InitParams::TYPE_TOOLTIP &&
164 params.type != Widget::InitParams::TYPE_POPUP) {
165 aura::client::SetDragDropDelegate(window_, this);
166 }
167
168 aura::client::SetActivationDelegate(window_, this);
169
170 window_reorderer_.reset(new WindowReorderer(window_,
171 GetWidget()->GetRootView()));
172 }
173
174 NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() {
175 return NULL;
176 }
177
178 bool NativeWidgetAura::ShouldUseNativeFrame() const {
179 // There is only one frame type for aura.
180 return false;
181 }
182
183 bool NativeWidgetAura::ShouldWindowContentsBeTransparent() const {
184 return false;
185 }
186
187 void NativeWidgetAura::FrameTypeChanged() {
188 // This is called when the Theme has changed; forward the event to the root
189 // widget.
190 GetWidget()->ThemeChanged();
191 GetWidget()->GetRootView()->SchedulePaint();
192 }
193
194 Widget* NativeWidgetAura::GetWidget() {
195 return delegate_->AsWidget();
196 }
197
198 const Widget* NativeWidgetAura::GetWidget() const {
199 return delegate_->AsWidget();
200 }
201
202 gfx::NativeView NativeWidgetAura::GetNativeView() const {
203 return window_;
204 }
205
206 gfx::NativeWindow NativeWidgetAura::GetNativeWindow() const {
207 return window_;
208 }
209
210 Widget* NativeWidgetAura::GetTopLevelWidget() {
211 NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView());
212 return native_widget ? native_widget->GetWidget() : NULL;
213 }
214
215 const ui::Compositor* NativeWidgetAura::GetCompositor() const {
216 return window_ ? window_->layer()->GetCompositor() : NULL;
217 }
218
219 ui::Compositor* NativeWidgetAura::GetCompositor() {
220 return window_ ? window_->layer()->GetCompositor() : NULL;
221 }
222
223 ui::Layer* NativeWidgetAura::GetLayer() {
224 return window_ ? window_->layer() : NULL;
225 }
226
227 void NativeWidgetAura::ReorderNativeViews() {
228 window_reorderer_->ReorderChildWindows();
229 }
230
231 void NativeWidgetAura::ViewRemoved(View* view) {
232 DCHECK(drop_helper_.get() != NULL);
233 drop_helper_->ResetTargetViewIfEquals(view);
234 }
235
236 void NativeWidgetAura::SetNativeWindowProperty(const char* name, void* value) {
237 if (window_)
238 window_->SetNativeWindowProperty(name, value);
239 }
240
241 void* NativeWidgetAura::GetNativeWindowProperty(const char* name) const {
242 return window_ ? window_->GetNativeWindowProperty(name) : NULL;
243 }
244
245 TooltipManager* NativeWidgetAura::GetTooltipManager() const {
246 return tooltip_manager_.get();
247 }
248
249 void NativeWidgetAura::SetCapture() {
250 if (window_)
251 window_->SetCapture();
252 }
253
254 void NativeWidgetAura::ReleaseCapture() {
255 if (window_)
256 window_->ReleaseCapture();
257 }
258
259 bool NativeWidgetAura::HasCapture() const {
260 return window_ && window_->HasCapture();
261 }
262
263 InputMethod* NativeWidgetAura::CreateInputMethod() {
264 if (!window_)
265 return NULL;
266
267 if (switches::IsTextInputFocusManagerEnabled())
268 return new NullInputMethod();
269
270 aura::Window* root_window = window_->GetRootWindow();
271 ui::InputMethod* host =
272 root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
273 return new InputMethodBridge(this, host, true);
274 }
275
276 internal::InputMethodDelegate* NativeWidgetAura::GetInputMethodDelegate() {
277 return this;
278 }
279
280 ui::InputMethod* NativeWidgetAura::GetHostInputMethod() {
281 aura::Window* root_window = window_->GetRootWindow();
282 return root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
283 }
284
285 void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
286 if (!window_)
287 return;
288
289 gfx::Rect parent_bounds(window_->parent()->GetBoundsInRootWindow());
290 // When centering window, we take the intersection of the host and
291 // the parent. We assume the root window represents the visible
292 // rect of a single screen.
293 gfx::Rect work_area = gfx::Screen::GetScreenFor(window_)->
294 GetDisplayNearestWindow(window_).work_area();
295
296 aura::client::ScreenPositionClient* screen_position_client =
297 aura::client::GetScreenPositionClient(window_->GetRootWindow());
298 if (screen_position_client) {
299 gfx::Point origin = work_area.origin();
300 screen_position_client->ConvertPointFromScreen(window_->GetRootWindow(),
301 &origin);
302 work_area.set_origin(origin);
303 }
304
305 parent_bounds.Intersect(work_area);
306
307 // If |window_|'s transient parent's bounds are big enough to fit it, then we
308 // center it with respect to the transient parent.
309 if (wm::GetTransientParent(window_)) {
310 gfx::Rect transient_parent_rect =
311 wm::GetTransientParent(window_)->GetBoundsInRootWindow();
312 transient_parent_rect.Intersect(work_area);
313 if (transient_parent_rect.height() >= size.height() &&
314 transient_parent_rect.width() >= size.width())
315 parent_bounds = transient_parent_rect;
316 }
317
318 gfx::Rect window_bounds(
319 parent_bounds.x() + (parent_bounds.width() - size.width()) / 2,
320 parent_bounds.y() + (parent_bounds.height() - size.height()) / 2,
321 size.width(),
322 size.height());
323 // Don't size the window bigger than the parent, otherwise the user may not be
324 // able to close or move it.
325 window_bounds.AdjustToFit(parent_bounds);
326
327 // Convert the bounds back relative to the parent.
328 gfx::Point origin = window_bounds.origin();
329 aura::Window::ConvertPointToTarget(window_->GetRootWindow(),
330 window_->parent(), &origin);
331 window_bounds.set_origin(origin);
332 window_->SetBounds(window_bounds);
333 }
334
335 void NativeWidgetAura::GetWindowPlacement(
336 gfx::Rect* bounds,
337 ui::WindowShowState* show_state) const {
338 // The interface specifies returning restored bounds, not current bounds.
339 *bounds = GetRestoredBounds();
340 *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey) :
341 ui::SHOW_STATE_DEFAULT;
342 }
343
344 bool NativeWidgetAura::SetWindowTitle(const base::string16& title) {
345 if (!window_)
346 return false;
347 if (window_->title() == title)
348 return false;
349 window_->SetTitle(title);
350 return true;
351 }
352
353 void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon,
354 const gfx::ImageSkia& app_icon) {
355 // Aura doesn't have window icons.
356 }
357
358 void NativeWidgetAura::InitModalType(ui::ModalType modal_type) {
359 if (modal_type != ui::MODAL_TYPE_NONE)
360 window_->SetProperty(aura::client::kModalKey, modal_type);
361 }
362
363 gfx::Rect NativeWidgetAura::GetWindowBoundsInScreen() const {
364 return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
365 }
366
367 gfx::Rect NativeWidgetAura::GetClientAreaBoundsInScreen() const {
368 // View-to-screen coordinate system transformations depend on this returning
369 // the full window bounds, for example View::ConvertPointToScreen().
370 return window_ ? window_->GetBoundsInScreen() : gfx::Rect();
371 }
372
373 gfx::Rect NativeWidgetAura::GetRestoredBounds() const {
374 if (!window_)
375 return gfx::Rect();
376
377 // Restored bounds should only be relevant if the window is minimized or
378 // maximized. However, in some places the code expects GetRestoredBounds()
379 // to return the current window bounds if the window is not in either state.
380 if (IsMinimized() || IsMaximized() || IsFullscreen()) {
381 // Restore bounds are in screen coordinates, no need to convert.
382 gfx::Rect* restore_bounds =
383 window_->GetProperty(aura::client::kRestoreBoundsKey);
384 if (restore_bounds)
385 return *restore_bounds;
386 }
387 return window_->GetBoundsInScreen();
388 }
389
390 void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
391 if (!window_)
392 return;
393
394 aura::Window* root = window_->GetRootWindow();
395 if (root) {
396 aura::client::ScreenPositionClient* screen_position_client =
397 aura::client::GetScreenPositionClient(root);
398 if (screen_position_client) {
399 gfx::Display dst_display =
400 gfx::Screen::GetScreenFor(window_)->GetDisplayMatching(bounds);
401 screen_position_client->SetBounds(window_, bounds, dst_display);
402 return;
403 }
404 }
405 window_->SetBounds(bounds);
406 }
407
408 void NativeWidgetAura::SetSize(const gfx::Size& size) {
409 if (window_)
410 window_->SetBounds(gfx::Rect(window_->bounds().origin(), size));
411 }
412
413 void NativeWidgetAura::StackAbove(gfx::NativeView native_view) {
414 if (window_ && window_->parent() &&
415 window_->parent() == native_view->parent())
416 window_->parent()->StackChildAbove(window_, native_view);
417 }
418
419 void NativeWidgetAura::StackAtTop() {
420 if (window_)
421 window_->parent()->StackChildAtTop(window_);
422 }
423
424 void NativeWidgetAura::StackBelow(gfx::NativeView native_view) {
425 if (window_ && window_->parent() &&
426 window_->parent() == native_view->parent())
427 window_->parent()->StackChildBelow(window_, native_view);
428 }
429
430 void NativeWidgetAura::SetShape(gfx::NativeRegion region) {
431 if (window_)
432 window_->layer()->SetAlphaShape(make_scoped_ptr(region));
433 else
434 delete region;
435 }
436
437 void NativeWidgetAura::Close() {
438 // |window_| may already be deleted by parent window. This can happen
439 // when this widget is child widget or has transient parent
440 // and ownership is WIDGET_OWNS_NATIVE_WIDGET.
441 DCHECK(window_ ||
442 ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
443 if (window_) {
444 window_->SuppressPaint();
445 Hide();
446 window_->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
447 }
448
449 if (!close_widget_factory_.HasWeakPtrs()) {
450 base::MessageLoop::current()->PostTask(
451 FROM_HERE,
452 base::Bind(&NativeWidgetAura::CloseNow,
453 close_widget_factory_.GetWeakPtr()));
454 }
455 }
456
457 void NativeWidgetAura::CloseNow() {
458 delete window_;
459 }
460
461 void NativeWidgetAura::Show() {
462 ShowWithWindowState(ui::SHOW_STATE_NORMAL);
463 }
464
465 void NativeWidgetAura::Hide() {
466 if (window_)
467 window_->Hide();
468 }
469
470 void NativeWidgetAura::ShowMaximizedWithBounds(
471 const gfx::Rect& restored_bounds) {
472 SetRestoreBounds(window_, restored_bounds);
473 ShowWithWindowState(ui::SHOW_STATE_MAXIMIZED);
474 }
475
476 void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
477 if (!window_)
478 return;
479
480 if (state == ui::SHOW_STATE_MAXIMIZED || state == ui::SHOW_STATE_FULLSCREEN)
481 window_->SetProperty(aura::client::kShowStateKey, state);
482 window_->Show();
483 if (delegate_->CanActivate()) {
484 if (state != ui::SHOW_STATE_INACTIVE)
485 Activate();
486 // SetInitialFocus() should be always be called, even for
487 // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
488 // do the right thing.
489 SetInitialFocus(state);
490 }
491 }
492
493 bool NativeWidgetAura::IsVisible() const {
494 return window_ && window_->IsVisible();
495 }
496
497 void NativeWidgetAura::Activate() {
498 if (!window_)
499 return;
500
501 // We don't necessarily have a root window yet. This can happen with
502 // constrained windows.
503 if (window_->GetRootWindow()) {
504 aura::client::GetActivationClient(window_->GetRootWindow())->ActivateWindow(
505 window_);
506 }
507 if (window_->GetProperty(aura::client::kDrawAttentionKey))
508 window_->SetProperty(aura::client::kDrawAttentionKey, false);
509 }
510
511 void NativeWidgetAura::Deactivate() {
512 if (!window_)
513 return;
514 aura::client::GetActivationClient(window_->GetRootWindow())->DeactivateWindow(
515 window_);
516 }
517
518 bool NativeWidgetAura::IsActive() const {
519 return window_ && wm::IsActiveWindow(window_);
520 }
521
522 void NativeWidgetAura::SetAlwaysOnTop(bool on_top) {
523 if (window_)
524 window_->SetProperty(aura::client::kAlwaysOnTopKey, on_top);
525 }
526
527 bool NativeWidgetAura::IsAlwaysOnTop() const {
528 return window_ && window_->GetProperty(aura::client::kAlwaysOnTopKey);
529 }
530
531 void NativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) {
532 // Not implemented on chromeos or for child widgets.
533 }
534
535 void NativeWidgetAura::Maximize() {
536 if (window_)
537 window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
538 }
539
540 void NativeWidgetAura::Minimize() {
541 if (window_)
542 window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
543 }
544
545 bool NativeWidgetAura::IsMaximized() const {
546 return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
547 ui::SHOW_STATE_MAXIMIZED;
548 }
549
550 bool NativeWidgetAura::IsMinimized() const {
551 return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
552 ui::SHOW_STATE_MINIMIZED;
553 }
554
555 void NativeWidgetAura::Restore() {
556 if (window_)
557 window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
558 }
559
560 void NativeWidgetAura::SetFullscreen(bool fullscreen) {
561 if (!window_ || IsFullscreen() == fullscreen)
562 return; // Nothing to do.
563
564 // Save window state before entering full screen so that it could restored
565 // when exiting full screen.
566 if (fullscreen)
567 saved_window_state_ = window_->GetProperty(aura::client::kShowStateKey);
568
569 window_->SetProperty(
570 aura::client::kShowStateKey,
571 fullscreen ? ui::SHOW_STATE_FULLSCREEN : saved_window_state_);
572 }
573
574 bool NativeWidgetAura::IsFullscreen() const {
575 return window_ && window_->GetProperty(aura::client::kShowStateKey) ==
576 ui::SHOW_STATE_FULLSCREEN;
577 }
578
579 void NativeWidgetAura::SetOpacity(unsigned char opacity) {
580 if (window_)
581 window_->layer()->SetOpacity(opacity / 255.0);
582 }
583
584 void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
585 NOTIMPLEMENTED();
586 }
587
588 void NativeWidgetAura::FlashFrame(bool flash) {
589 if (window_)
590 window_->SetProperty(aura::client::kDrawAttentionKey, flash);
591 }
592
593 void NativeWidgetAura::RunShellDrag(View* view,
594 const ui::OSExchangeData& data,
595 const gfx::Point& location,
596 int operation,
597 ui::DragDropTypes::DragEventSource source) {
598 if (window_)
599 views::RunShellDrag(window_, data, location, operation, source);
600 }
601
602 void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) {
603 if (window_)
604 window_->SchedulePaintInRect(rect);
605 }
606
607 void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor) {
608 cursor_ = cursor;
609 aura::client::CursorClient* cursor_client =
610 aura::client::GetCursorClient(window_->GetRootWindow());
611 if (cursor_client)
612 cursor_client->SetCursor(cursor);
613 }
614
615 bool NativeWidgetAura::IsMouseEventsEnabled() const {
616 if (!window_)
617 return false;
618 aura::client::CursorClient* cursor_client =
619 aura::client::GetCursorClient(window_->GetRootWindow());
620 return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
621 }
622
623 void NativeWidgetAura::ClearNativeFocus() {
624 aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
625 if (window_ && client && window_->Contains(client->GetFocusedWindow()))
626 client->ResetFocusWithinActiveWindow(window_);
627 }
628
629 gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
630 if (!window_)
631 return gfx::Rect();
632 return gfx::Screen::GetScreenFor(window_)->
633 GetDisplayNearestWindow(window_).work_area();
634 }
635
636 Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
637 const gfx::Vector2d& drag_offset,
638 Widget::MoveLoopSource source,
639 Widget::MoveLoopEscapeBehavior escape_behavior) {
640 // |escape_behavior| is only needed on windows when running the native message
641 // loop.
642 if (!window_ || !window_->GetRootWindow())
643 return Widget::MOVE_LOOP_CANCELED;
644 aura::client::WindowMoveClient* move_client =
645 aura::client::GetWindowMoveClient(window_->GetRootWindow());
646 if (!move_client)
647 return Widget::MOVE_LOOP_CANCELED;
648
649 SetCapture();
650 aura::client::WindowMoveSource window_move_source =
651 source == Widget::MOVE_LOOP_SOURCE_MOUSE ?
652 aura::client::WINDOW_MOVE_SOURCE_MOUSE :
653 aura::client::WINDOW_MOVE_SOURCE_TOUCH;
654 if (move_client->RunMoveLoop(window_, drag_offset, window_move_source) ==
655 aura::client::MOVE_SUCCESSFUL) {
656 return Widget::MOVE_LOOP_SUCCESSFUL;
657 }
658 return Widget::MOVE_LOOP_CANCELED;
659 }
660
661 void NativeWidgetAura::EndMoveLoop() {
662 if (!window_ || !window_->GetRootWindow())
663 return;
664 aura::client::WindowMoveClient* move_client =
665 aura::client::GetWindowMoveClient(window_->GetRootWindow());
666 if (move_client)
667 move_client->EndMoveLoop();
668 }
669
670 void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value) {
671 if (window_)
672 window_->SetProperty(aura::client::kAnimationsDisabledKey, !value);
673 }
674
675 ui::NativeTheme* NativeWidgetAura::GetNativeTheme() const {
676 return ui::NativeThemeAura::instance();
677 }
678
679 void NativeWidgetAura::OnRootViewLayout() {
680 }
681
682 bool NativeWidgetAura::IsTranslucentWindowOpacitySupported() const {
683 return true;
684 }
685
686 void NativeWidgetAura::OnSizeConstraintsChanged() {
687 window_->SetProperty(aura::client::kCanMaximizeKey,
688 GetWidget()->widget_delegate()->CanMaximize());
689 window_->SetProperty(aura::client::kCanMinimizeKey,
690 GetWidget()->widget_delegate()->CanMinimize());
691 window_->SetProperty(aura::client::kCanResizeKey,
692 GetWidget()->widget_delegate()->CanResize());
693 }
694
695 void NativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event) {
696 OnEvent(native_event);
697 }
698
699 ////////////////////////////////////////////////////////////////////////////////
700 // NativeWidgetAura, views::InputMethodDelegate implementation:
701
702 void NativeWidgetAura::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
703 FocusManager* focus_manager = GetWidget()->GetFocusManager();
704 delegate_->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
705 if (key.handled() || !focus_manager)
706 return;
707 focus_manager->OnKeyEvent(key);
708 }
709
710 ////////////////////////////////////////////////////////////////////////////////
711 // NativeWidgetAura, aura::WindowDelegate implementation:
712
713 gfx::Size NativeWidgetAura::GetMinimumSize() const {
714 return delegate_->GetMinimumSize();
715 }
716
717 gfx::Size NativeWidgetAura::GetMaximumSize() const {
718 // If a window have a maximum size, the window should not be
719 // maximizable.
720 DCHECK(delegate_->GetMaximumSize().IsEmpty() ||
721 !window_->GetProperty(aura::client::kCanMaximizeKey));
722 return delegate_->GetMaximumSize();
723 }
724
725 void NativeWidgetAura::OnBoundsChanged(const gfx::Rect& old_bounds,
726 const gfx::Rect& new_bounds) {
727 // Assume that if the old bounds was completely empty a move happened. This
728 // handles the case of a maximize animation acquiring the layer (acquiring a
729 // layer results in clearing the bounds).
730 if (old_bounds.origin() != new_bounds.origin() ||
731 (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) {
732 delegate_->OnNativeWidgetMove();
733 }
734 if (old_bounds.size() != new_bounds.size())
735 delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
736 }
737
738 gfx::NativeCursor NativeWidgetAura::GetCursor(const gfx::Point& point) {
739 return cursor_;
740 }
741
742 int NativeWidgetAura::GetNonClientComponent(const gfx::Point& point) const {
743 return delegate_->GetNonClientComponent(point);
744 }
745
746 bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling(
747 aura::Window* child,
748 const gfx::Point& location) {
749 views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
750 if (widget_delegate &&
751 !widget_delegate->ShouldDescendIntoChildForEventHandling(child, location))
752 return false;
753
754 // Don't descend into |child| if there is a view with a Layer that contains
755 // the point and is stacked above |child|s layer.
756 typedef std::vector<ui::Layer*> Layers;
757 const Layers& root_layers(delegate_->GetRootLayers());
758 if (root_layers.empty())
759 return true;
760
761 Layers::const_iterator child_layer_iter(
762 std::find(window_->layer()->children().begin(),
763 window_->layer()->children().end(), child->layer()));
764 if (child_layer_iter == window_->layer()->children().end())
765 return true;
766
767 for (std::vector<ui::Layer*>::const_reverse_iterator i = root_layers.rbegin();
768 i != root_layers.rend(); ++i) {
769 ui::Layer* layer = *i;
770 if (layer->visible() && layer->bounds().Contains(location)) {
771 Layers::const_iterator root_layer_iter(
772 std::find(window_->layer()->children().begin(),
773 window_->layer()->children().end(), layer));
774 if (root_layer_iter > child_layer_iter)
775 return false;
776 }
777 }
778 return true;
779 }
780
781 bool NativeWidgetAura::CanFocus() {
782 return ShouldActivate();
783 }
784
785 void NativeWidgetAura::OnCaptureLost() {
786 delegate_->OnMouseCaptureLost();
787 }
788
789 void NativeWidgetAura::OnPaint(gfx::Canvas* canvas) {
790 delegate_->OnNativeWidgetPaint(canvas);
791 }
792
793 void NativeWidgetAura::OnDeviceScaleFactorChanged(float device_scale_factor) {
794 // Repainting with new scale factor will paint the content at the right scale.
795 }
796
797 void NativeWidgetAura::OnWindowDestroying(aura::Window* window) {
798 window_->RemoveObserver(this);
799 delegate_->OnNativeWidgetDestroying();
800
801 // If the aura::Window is destroyed, we can no longer show tooltips.
802 tooltip_manager_.reset();
803 }
804
805 void NativeWidgetAura::OnWindowDestroyed(aura::Window* window) {
806 window_ = NULL;
807 delegate_->OnNativeWidgetDestroyed();
808 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
809 delete this;
810 }
811
812 void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) {
813 delegate_->OnNativeWidgetVisibilityChanged(visible);
814 }
815
816 bool NativeWidgetAura::HasHitTestMask() const {
817 return delegate_->HasHitTestMask();
818 }
819
820 void NativeWidgetAura::GetHitTestMask(gfx::Path* mask) const {
821 DCHECK(mask);
822 delegate_->GetHitTestMask(mask);
823 }
824
825 ////////////////////////////////////////////////////////////////////////////////
826 // NativeWidgetAura, aura::WindowObserver implementation:
827
828 void NativeWidgetAura::OnWindowPropertyChanged(aura::Window* window,
829 const void* key,
830 intptr_t old) {
831 if (key == aura::client::kShowStateKey)
832 delegate_->OnNativeWidgetWindowShowStateChanged();
833 }
834
835 ////////////////////////////////////////////////////////////////////////////////
836 // NativeWidgetAura, ui::EventHandler implementation:
837
838 void NativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
839 DCHECK(window_);
840 if (event->is_char()) {
841 // If a ui::InputMethod object is attached to the root window, character
842 // events are handled inside the object and are not passed to this function.
843 // If such object is not attached, character events might be sent (e.g. on
844 // Windows). In this case, we just skip these.
845 return;
846 }
847 // Renderer may send a key event back to us if the key event wasn't handled,
848 // and the window may be invisible by that time.
849 if (!window_->IsVisible())
850 return;
851 InputMethod* input_method = GetWidget()->GetInputMethod();
852 if (!input_method)
853 return;
854 input_method->DispatchKeyEvent(*event);
855 if (switches::IsTextInputFocusManagerEnabled()) {
856 FocusManager* focus_manager = GetWidget()->GetFocusManager();
857 delegate_->OnKeyEvent(event);
858 if (!event->handled() && focus_manager)
859 focus_manager->OnKeyEvent(*event);
860 }
861 event->SetHandled();
862 }
863
864 void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
865 DCHECK(window_);
866 DCHECK(window_->IsVisible());
867 if (event->type() == ui::ET_MOUSEWHEEL) {
868 delegate_->OnMouseEvent(event);
869 if (event->handled())
870 return;
871 }
872
873 if (tooltip_manager_.get())
874 tooltip_manager_->UpdateTooltip();
875 TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
876 delegate_->OnMouseEvent(event);
877 }
878
879 void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
880 delegate_->OnScrollEvent(event);
881 }
882
883 void NativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) {
884 DCHECK(window_);
885 DCHECK(window_->IsVisible() || event->IsEndingEvent());
886 delegate_->OnGestureEvent(event);
887 }
888
889 ////////////////////////////////////////////////////////////////////////////////
890 // NativeWidgetAura, aura::client::ActivationDelegate implementation:
891
892 bool NativeWidgetAura::ShouldActivate() const {
893 return delegate_->CanActivate();
894 }
895
896 ////////////////////////////////////////////////////////////////////////////////
897 // NativeWidgetAura, aura::client::ActivationChangeObserver implementation:
898
899 void NativeWidgetAura::OnWindowActivated(aura::Window* gained_active,
900 aura::Window* lost_active) {
901 DCHECK(window_ == gained_active || window_ == lost_active);
902 if (GetWidget()->GetFocusManager()) {
903 if (window_ == gained_active)
904 GetWidget()->GetFocusManager()->RestoreFocusedView();
905 else if (window_ == lost_active)
906 GetWidget()->GetFocusManager()->StoreFocusedView(true);
907 }
908 delegate_->OnNativeWidgetActivationChanged(window_ == gained_active);
909 }
910
911 ////////////////////////////////////////////////////////////////////////////////
912 // NativeWidgetAura, aura::client::FocusChangeObserver:
913
914 void NativeWidgetAura::OnWindowFocused(aura::Window* gained_focus,
915 aura::Window* lost_focus) {
916 if (window_ == gained_focus) {
917 // In aura, it is possible for child native widgets to take input and focus,
918 // this differs from the behavior on windows.
919 if (GetWidget()->GetInputMethod()) // Null in tests.
920 GetWidget()->GetInputMethod()->OnFocus();
921 delegate_->OnNativeFocus(lost_focus);
922 } else if (window_ == lost_focus) {
923 // GetInputMethod() recreates the input method if it's previously been
924 // destroyed. If we get called during destruction, the input method will be
925 // gone, and creating a new one and telling it that we lost the focus will
926 // trigger a DCHECK (the new input method doesn't think that we have the
927 // focus and doesn't expect a blur). OnBlur() shouldn't be called during
928 // destruction unless WIDGET_OWNS_NATIVE_WIDGET is set (which is just the
929 // case in tests).
930 if (!destroying_) {
931 if (GetWidget()->GetInputMethod())
932 GetWidget()->GetInputMethod()->OnBlur();
933 } else {
934 DCHECK_EQ(ownership_, Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
935 }
936
937 delegate_->OnNativeBlur(gained_focus);
938 }
939 }
940
941 ////////////////////////////////////////////////////////////////////////////////
942 // NativeWidgetAura, aura::WindowDragDropDelegate implementation:
943
944 void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) {
945 DCHECK(drop_helper_.get() != NULL);
946 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
947 event.location(), event.source_operations());
948 }
949
950 int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) {
951 DCHECK(drop_helper_.get() != NULL);
952 last_drop_operation_ = drop_helper_->OnDragOver(event.data(),
953 event.location(), event.source_operations());
954 return last_drop_operation_;
955 }
956
957 void NativeWidgetAura::OnDragExited() {
958 DCHECK(drop_helper_.get() != NULL);
959 drop_helper_->OnDragExit();
960 }
961
962 int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event) {
963 DCHECK(drop_helper_.get() != NULL);
964 return drop_helper_->OnDrop(event.data(), event.location(),
965 last_drop_operation_);
966 }
967
968 ////////////////////////////////////////////////////////////////////////////////
969 // NativeWidgetAura, protected:
970
971 NativeWidgetAura::~NativeWidgetAura() {
972 destroying_ = true;
973 if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
974 delete delegate_;
975 else
976 CloseNow();
977 }
978
979 ////////////////////////////////////////////////////////////////////////////////
980 // NativeWidgetAura, private:
981
982 void NativeWidgetAura::SetInitialFocus(ui::WindowShowState show_state) {
983 // The window does not get keyboard messages unless we focus it.
984 if (!GetWidget()->SetInitialFocus(show_state))
985 window_->Focus();
986 }
987
988 ////////////////////////////////////////////////////////////////////////////////
989 // Widget, public:
990
991 // static
992 void Widget::CloseAllSecondaryWidgets() {
993 }
994
995 bool Widget::ConvertRect(const Widget* source,
996 const Widget* target,
997 gfx::Rect* rect) {
998 return false;
999 }
1000
1001 namespace internal {
1002
1003 ////////////////////////////////////////////////////////////////////////////////
1004 // internal::NativeWidgetPrivate, public:
1005
1006 // static
1007 NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget(
1008 internal::NativeWidgetDelegate* delegate) {
1009 return new NativeWidgetAura(delegate);
1010 }
1011
1012 // static
1013 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView(
1014 gfx::NativeView native_view) {
1015 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1016 return reinterpret_cast<NativeWidgetPrivate*>(native_view->user_data());
1017 }
1018
1019 // static
1020 NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow(
1021 gfx::NativeWindow native_window) {
1022 // Cast must match type supplied to RegisterNativeWidgetForWindow().
1023 return reinterpret_cast<NativeWidgetPrivate*>(native_window->user_data());
1024 }
1025
1026 // static
1027 NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget(
1028 gfx::NativeView native_view) {
1029 aura::Window* window = native_view;
1030 NativeWidgetPrivate* top_level_native_widget = NULL;
1031 while (window) {
1032 NativeWidgetPrivate* native_widget = GetNativeWidgetForNativeView(window);
1033 if (native_widget)
1034 top_level_native_widget = native_widget;
1035 window = window->parent();
1036 }
1037 return top_level_native_widget;
1038 }
1039
1040 // static
1041 void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view,
1042 Widget::Widgets* children) {
1043 {
1044 // Code expects widget for |native_view| to be added to |children|.
1045 NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1046 GetNativeWidgetForNativeView(native_view));
1047 if (native_widget && native_widget->GetWidget())
1048 children->insert(native_widget->GetWidget());
1049 }
1050
1051 const aura::Window::Windows& child_windows = native_view->children();
1052 for (aura::Window::Windows::const_iterator i = child_windows.begin();
1053 i != child_windows.end(); ++i) {
1054 GetAllChildWidgets((*i), children);
1055 }
1056 }
1057
1058 // static
1059 void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view,
1060 Widget::Widgets* owned) {
1061 const aura::Window::Windows& transient_children =
1062 wm::GetTransientChildren(native_view);
1063 for (aura::Window::Windows::const_iterator i = transient_children.begin();
1064 i != transient_children.end(); ++i) {
1065 NativeWidgetPrivate* native_widget = static_cast<NativeWidgetPrivate*>(
1066 GetNativeWidgetForNativeView(*i));
1067 if (native_widget && native_widget->GetWidget())
1068 owned->insert(native_widget->GetWidget());
1069 GetAllOwnedWidgets((*i), owned);
1070 }
1071 }
1072
1073 // static
1074 void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view,
1075 gfx::NativeView new_parent) {
1076 DCHECK(native_view != new_parent);
1077
1078 gfx::NativeView previous_parent = native_view->parent();
1079 if (previous_parent == new_parent)
1080 return;
1081
1082 Widget::Widgets widgets;
1083 GetAllChildWidgets(native_view, &widgets);
1084
1085 // First notify all the widgets that they are being disassociated
1086 // from their previous parent.
1087 for (Widget::Widgets::iterator it = widgets.begin();
1088 it != widgets.end(); ++it) {
1089 (*it)->NotifyNativeViewHierarchyWillChange();
1090 }
1091
1092 if (new_parent) {
1093 new_parent->AddChild(native_view);
1094 } else {
1095 // The following looks weird, but it's the equivalent of what aura has
1096 // always done. (The previous behaviour of aura::Window::SetParent() used
1097 // NULL as a special value that meant ask the WindowTreeClient where things
1098 // should go.)
1099 //
1100 // This probably isn't strictly correct, but its an invariant that a Window
1101 // in use will be attached to a RootWindow, so we can't just call
1102 // RemoveChild here. The only possible thing that could assign a RootWindow
1103 // in this case is the stacking client of the current RootWindow. This
1104 // matches our previous behaviour; the global stacking client would almost
1105 // always reattach the window to the same RootWindow.
1106 aura::Window* root_window = native_view->GetRootWindow();
1107 aura::client::ParentWindowWithContext(
1108 native_view, root_window, root_window->GetBoundsInScreen());
1109 }
1110
1111 // And now, notify them that they have a brand new parent.
1112 for (Widget::Widgets::iterator it = widgets.begin();
1113 it != widgets.end(); ++it) {
1114 (*it)->NotifyNativeViewHierarchyChanged();
1115 }
1116 }
1117
1118 // static
1119 bool NativeWidgetPrivate::IsMouseButtonDown() {
1120 return aura::Env::GetInstance()->IsMouseButtonDown();
1121 }
1122
1123 // static
1124 gfx::FontList NativeWidgetPrivate::GetWindowTitleFontList() {
1125 #if defined(OS_WIN)
1126 NONCLIENTMETRICS_XP ncm;
1127 base::win::GetNonClientMetrics(&ncm);
1128 l10n_util::AdjustUIFont(&(ncm.lfCaptionFont));
1129 base::win::ScopedHFONT caption_font(CreateFontIndirect(&(ncm.lfCaptionFont)));
1130 return gfx::FontList(gfx::Font(caption_font));
1131 #else
1132 return gfx::FontList();
1133 #endif
1134 }
1135
1136 } // namespace internal
1137 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/native_widget_aura.h ('k') | ui/views/widget/native_widget_aura_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698