summaryrefslogtreecommitdiff
path: root/chromium/ui/views/widget
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/widget')
-rw-r--r--chromium/ui/views/widget/android/android_focus_rules.cc19
-rw-r--r--chromium/ui/views/widget/android/android_focus_rules.h28
-rw-r--r--chromium/ui/views/widget/android/native_widget_android.cc841
-rw-r--r--chromium/ui/views/widget/android/native_widget_android.h249
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.cc34
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.h32
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc29
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h3
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc49
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_win.h6
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc25
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc10
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc36
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h16
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc14
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h1
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc10
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc13
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc3
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc3
-rw-r--r--chromium/ui/views/widget/desktop_widget_unittest.cc7
-rw-r--r--chromium/ui/views/widget/native_widget_aura.cc23
-rw-r--r--chromium/ui/views/widget/native_widget_aura.h5
-rw-r--r--chromium/ui/views/widget/native_widget_aura_unittest.cc51
-rw-r--r--chromium/ui/views/widget/native_widget_delegate.h12
-rw-r--r--chromium/ui/views/widget/native_widget_mac.h1
-rw-r--r--chromium/ui/views/widget/native_widget_mac.mm26
-rw-r--r--chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm81
-rw-r--r--chromium/ui/views/widget/native_widget_mac_unittest.mm424
-rw-r--r--chromium/ui/views/widget/native_widget_private.h1
-rw-r--r--chromium/ui/views/widget/tooltip_manager.h7
-rw-r--r--chromium/ui/views/widget/tooltip_manager_aura.cc10
-rw-r--r--chromium/ui/views/widget/tooltip_manager_aura.h3
-rw-r--r--chromium/ui/views/widget/widget.cc115
-rw-r--r--chromium/ui/views/widget/widget.h70
-rw-r--r--chromium/ui/views/widget/widget_delegate.cc14
-rw-r--r--chromium/ui/views/widget/widget_delegate.h2
-rw-r--r--chromium/ui/views/widget/widget_interactive_uitest.cc139
-rw-r--r--chromium/ui/views/widget/widget_removals_observer.h6
-rw-r--r--chromium/ui/views/widget/widget_unittest.cc421
43 files changed, 1171 insertions, 1678 deletions
diff --git a/chromium/ui/views/widget/android/android_focus_rules.cc b/chromium/ui/views/widget/android/android_focus_rules.cc
deleted file mode 100644
index c01ace9ca58..00000000000
--- a/chromium/ui/views/widget/android/android_focus_rules.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/widget/android/android_focus_rules.h"
-
-#include "ui/aura/window.h"
-
-namespace views {
-
-AndroidFocusRules::AndroidFocusRules() {}
-
-AndroidFocusRules::~AndroidFocusRules() {}
-
-bool AndroidFocusRules::SupportsChildActivation(aura::Window* window) const {
- return window->IsRootWindow();
-}
-
-} // namespace views
diff --git a/chromium/ui/views/widget/android/android_focus_rules.h b/chromium/ui/views/widget/android/android_focus_rules.h
deleted file mode 100644
index 867d53d4812..00000000000
--- a/chromium/ui/views/widget/android/android_focus_rules.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_ANDROID_ANDROID_FOCUS_RULES_H_
-#define UI_VIEWS_WIDGET_ANDROID_ANDROID_FOCUS_RULES_H_
-
-#include "base/macros.h"
-#include "ui/wm/core/base_focus_rules.h"
-
-namespace views {
-
-// A set of focus rules for Android using aura.
-class AndroidFocusRules : public wm::BaseFocusRules {
- public:
- AndroidFocusRules();
- ~AndroidFocusRules() override;
-
- private:
- // wm::BaseFocusRules:
- bool SupportsChildActivation(aura::Window* window) const override;
-
- DISALLOW_COPY_AND_ASSIGN(AndroidFocusRules);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_ANDROID_ANDROID_FOCUS_RULES_H_
diff --git a/chromium/ui/views/widget/android/native_widget_android.cc b/chromium/ui/views/widget/android/native_widget_android.cc
deleted file mode 100644
index 2aed158559a..00000000000
--- a/chromium/ui/views/widget/android/native_widget_android.cc
+++ /dev/null
@@ -1,841 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/widget/android/native_widget_android.h"
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/strings/string_util.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/aura/client/aura_constants.h"
-#include "ui/aura/client/cursor_client.h"
-#include "ui/aura/client/default_capture_client.h"
-#include "ui/aura/client/focus_client.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/client/window_tree_client.h"
-#include "ui/aura/env.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/aura/window_observer.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/base/ui_base_types.h"
-#include "ui/compositor/layer.h"
-#include "ui/events/event.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/font_list.h"
-#include "ui/gfx/screen.h"
-#include "ui/native_theme/native_theme_aura.h"
-#include "ui/views/drag_utils.h"
-#include "ui/views/views_delegate.h"
-#include "ui/views/widget/android/android_focus_rules.h"
-#include "ui/views/widget/native_widget_aura.h"
-#include "ui/views/widget/native_widget_delegate.h"
-#include "ui/views/widget/root_view.h"
-#include "ui/views/widget/tooltip_manager_aura.h"
-#include "ui/views/widget/widget_aura_utils.h"
-#include "ui/views/widget/widget_delegate.h"
-#include "ui/views/widget/window_reorderer.h"
-#include "ui/wm/core/default_activation_client.h"
-#include "ui/wm/core/default_screen_position_client.h"
-#include "ui/wm/core/focus_controller.h"
-#include "ui/wm/core/shadow_types.h"
-#include "ui/wm/core/window_animations.h"
-#include "ui/wm/core/window_util.h"
-#include "ui/wm/public/activation_client.h"
-#include "ui/wm/public/dispatcher_client.h"
-#include "ui/wm/public/drag_drop_client.h"
-#include "ui/wm/public/window_move_client.h"
-#include "ui/wm/public/window_types.h"
-
-// TODO(bshe): Most of the code is copied from NativeWidgetAura or
-// DesktopNativeWidgetAura. Share more code instead of duplicate code when
-// possible. crbug.com/554961.
-namespace {
-
-class WindowTreeClientImpl : public aura::client::WindowTreeClient {
- public:
- explicit WindowTreeClientImpl(aura::Window* root_window)
- : root_window_(root_window) {
- aura::client::SetWindowTreeClient(root_window_, this);
- }
- ~WindowTreeClientImpl() override {
- aura::client::SetWindowTreeClient(root_window_, nullptr);
- }
-
- // Overridden from client::WindowTreeClient:
- aura::Window* GetDefaultParent(aura::Window* context,
- aura::Window* window,
- const gfx::Rect& bounds) override {
- return root_window_;
- }
-
- private:
- aura::Window* root_window_;
-
- DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl);
-};
-
-// TODO(bshe|jonross): Get rid of nested message loop once crbug.com/523680 is
-// fixed.
-class AndroidDispatcherClient : public aura::client::DispatcherClient {
- public:
- AndroidDispatcherClient() {}
- ~AndroidDispatcherClient() override {}
-
- // aura::client::DispatcherClient:
- void PrepareNestedLoopClosures(base::MessagePumpDispatcher* dispatcher,
- base::Closure* run_closure,
- base::Closure* quit_closure) override {
- scoped_ptr<base::RunLoop> run_loop(new base::RunLoop());
- *quit_closure = run_loop->QuitClosure();
- *run_closure =
- base::Bind(&AndroidDispatcherClient::RunNestedDispatcher,
- base::Unretained(this), base::Passed(&run_loop), dispatcher);
- }
-
- private:
- void RunNestedDispatcher(scoped_ptr<base::RunLoop> run_loop,
- base::MessagePumpDispatcher* dispatcher) {
- base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
- base::MessageLoop::ScopedNestableTaskAllower allow(loop);
- run_loop->Run();
- }
-
- DISALLOW_COPY_AND_ASSIGN(AndroidDispatcherClient);
-};
-
-} // namespace
-
-namespace views {
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, public
-
-NativeWidgetAndroid::NativeWidgetAndroid(
- internal::NativeWidgetDelegate* delegate)
- : delegate_(delegate),
- window_(new aura::Window(this)),
- ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
- destroying_(false),
- cursor_(gfx::kNullCursor),
- saved_window_state_(ui::SHOW_STATE_DEFAULT),
- close_widget_factory_(this) {
- aura::client::SetFocusChangeObserver(window_, this);
- aura::client::SetActivationChangeObserver(window_, this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, internal::NativeWidgetPrivate implementation:
-
-void NativeWidgetAndroid::InitNativeWidget(const Widget::InitParams& params) {
- ownership_ = params.ownership;
- NativeWidgetAura::RegisterNativeWidgetForWindow(this, window_);
-
- window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
- window_->Init(params.layer_type);
- wm::SetShadowType(window_, wm::SHADOW_TYPE_NONE);
- window_->Show();
-
- // TODO(bshe): Get rid of the hard coded size. Tracked in crbug.com/551923.
- host_.reset(aura::WindowTreeHost::Create(gfx::Rect(0, 0, 800, 600)));
- host_->InitHost();
- host_->AddObserver(this);
-
- window_tree_client_.reset(new WindowTreeClientImpl(host_->window()));
-
- focus_client_.reset(new wm::FocusController(new AndroidFocusRules));
- aura::client::SetFocusClient(host_->window(), focus_client_.get());
- host_->window()->AddPreTargetHandler(focus_client_.get());
-
- new wm::DefaultActivationClient(host_->window());
-
- capture_client_.reset(
- new aura::client::DefaultCaptureClient(host_->window()));
-
- screen_position_client_.reset(new wm::DefaultScreenPositionClient);
- aura::client::SetScreenPositionClient(host_->window(),
- screen_position_client_.get());
- dispatcher_client_.reset(new AndroidDispatcherClient);
- aura::client::SetDispatcherClient(host_->window(), dispatcher_client_.get());
-
- delegate_->OnNativeWidgetCreated(false);
-
- DCHECK(GetWidget()->GetRootView());
- if (params.type != Widget::InitParams::TYPE_TOOLTIP)
- tooltip_manager_.reset(new views::TooltipManagerAura(GetWidget()));
-
- if (params.type != Widget::InitParams::TYPE_TOOLTIP &&
- params.type != Widget::InitParams::TYPE_POPUP) {
- aura::client::SetDragDropDelegate(window_, this);
- }
-
- aura::client::SetActivationDelegate(window_, this);
-
- host_->window()->AddChild(window_);
- window_reorderer_.reset(
- new WindowReorderer(window_, GetWidget()->GetRootView()));
-
- // TODO(bshe): figure out how to add cursor manager, drag drop client and all
- // the necessary parts that exists in desktop_native_widget_aura.
-}
-
-void NativeWidgetAndroid::OnWidgetInitDone() {}
-
-NonClientFrameView* NativeWidgetAndroid::CreateNonClientFrameView() {
- NOTIMPLEMENTED();
- return nullptr;
-}
-
-bool NativeWidgetAndroid::ShouldUseNativeFrame() const {
- // There is only one frame type for aura.
- return false;
-}
-
-bool NativeWidgetAndroid::ShouldWindowContentsBeTransparent() const {
- NOTIMPLEMENTED();
- return false;
-}
-
-void NativeWidgetAndroid::FrameTypeChanged() {
- NOTIMPLEMENTED();
-}
-
-Widget* NativeWidgetAndroid::GetWidget() {
- return delegate_->AsWidget();
-}
-
-const Widget* NativeWidgetAndroid::GetWidget() const {
- return delegate_->AsWidget();
-}
-
-gfx::NativeView NativeWidgetAndroid::GetNativeView() const {
- return window_;
-}
-
-gfx::NativeWindow NativeWidgetAndroid::GetNativeWindow() const {
- return window_;
-}
-
-Widget* NativeWidgetAndroid::GetTopLevelWidget() {
- return GetWidget();
-}
-
-const ui::Compositor* NativeWidgetAndroid::GetCompositor() const {
- return host_->compositor();
-}
-
-const ui::Layer* NativeWidgetAndroid::GetLayer() const {
- return GetNativeWindow()->layer();
-}
-
-void NativeWidgetAndroid::ReorderNativeViews() {
- window_reorderer_->ReorderChildWindows();
-}
-
-void NativeWidgetAndroid::ViewRemoved(View* view) {
- // TODO(bshe): Implement drag and drop. crbug.com/554029.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::SetNativeWindowProperty(const char* name,
- void* value) {
- GetNativeWindow()->SetNativeWindowProperty(name, value);
-}
-
-void* NativeWidgetAndroid::GetNativeWindowProperty(const char* name) const {
- return GetNativeWindow()->GetNativeWindowProperty(name);
-}
-
-TooltipManager* NativeWidgetAndroid::GetTooltipManager() const {
- return tooltip_manager_.get();
-}
-
-void NativeWidgetAndroid::SetCapture() {
- GetNativeWindow()->SetCapture();
-}
-
-void NativeWidgetAndroid::ReleaseCapture() {
- GetNativeWindow()->ReleaseCapture();
-}
-
-bool NativeWidgetAndroid::HasCapture() const {
- return GetNativeWindow()->HasCapture();
-}
-
-ui::InputMethod* NativeWidgetAndroid::GetInputMethod() {
- return host_->GetInputMethod();
-}
-
-void NativeWidgetAndroid::CenterWindow(const gfx::Size& size) {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::GetWindowPlacement(
- gfx::Rect* bounds,
- ui::WindowShowState* show_state) const {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-bool NativeWidgetAndroid::SetWindowTitle(const base::string16& title) {
- if (GetNativeWindow()->title() == title)
- return false;
- GetNativeWindow()->SetTitle(title);
- return true;
-}
-
-void NativeWidgetAndroid::SetWindowIcons(const gfx::ImageSkia& window_icon,
- const gfx::ImageSkia& app_icon) {
- // TODO(bshe): Implement this. See crbug.com/554953.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::InitModalType(ui::ModalType modal_type) {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-gfx::Rect NativeWidgetAndroid::GetWindowBoundsInScreen() const {
- return GetNativeWindow()->GetBoundsInScreen();
-}
-
-gfx::Rect NativeWidgetAndroid::GetClientAreaBoundsInScreen() const {
- // View-to-screen coordinate system transformations depend on this returning
- // the full window bounds, for example View::ConvertPointToScreen().
- return GetNativeWindow()->GetBoundsInScreen();
-}
-
-gfx::Rect NativeWidgetAndroid::GetRestoredBounds() const {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
- return gfx::Rect();
-}
-
-void NativeWidgetAndroid::SetBounds(const gfx::Rect& bounds) {
- // TODO(bshe): This may not work. We may need to resize SurfaceView too. See
- // crbug.com/554952.
- host_->SetBounds(bounds);
-}
-
-void NativeWidgetAndroid::SetSize(const gfx::Size& size) {
- gfx::Rect bounds = host_->GetBounds();
- SetBounds(gfx::Rect(bounds.origin(), size));
-}
-
-void NativeWidgetAndroid::StackAbove(gfx::NativeView native_view) {
- // TODO(bshe): Implements window stacking logic. See crbug.com/554047
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::StackAtTop() {
- // TODO(bshe): Implements window stacking logic. See crbug.com/554047
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::StackBelow(gfx::NativeView native_view) {
- // TODO(bshe): Implements window stacking logic. See crbug.com/554047
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::SetShape(SkRegion* region) {
- GetNativeWindow()->layer()->SetAlphaShape(make_scoped_ptr(region));
-}
-
-void NativeWidgetAndroid::Close() {
- // TODO(bshe): This might not be right. See crbug.com/554259.
- DCHECK(ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET);
- GetNativeWindow()->SuppressPaint();
- Hide();
- GetNativeWindow()->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE);
-
- if (!close_widget_factory_.HasWeakPtrs()) {
- base::MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&NativeWidgetAndroid::CloseNow,
- close_widget_factory_.GetWeakPtr()));
- }
-}
-
-void NativeWidgetAndroid::CloseNow() {
- // TODO(bshe): This might not be right. See crbug.com/554259.
- host_->RemoveObserver(this);
- host_.reset();
- delete window_;
-}
-
-void NativeWidgetAndroid::Show() {
- host_->Show();
- GetNativeWindow()->Show();
-}
-
-void NativeWidgetAndroid::Hide() {
- host_->Hide();
- GetNativeWindow()->Hide();
-}
-
-void NativeWidgetAndroid::ShowMaximizedWithBounds(
- const gfx::Rect& restored_bounds) {
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::ShowWithWindowState(ui::WindowShowState state) {
- NOTIMPLEMENTED();
-}
-
-bool NativeWidgetAndroid::IsVisible() const {
- return GetNativeWindow()->IsVisible();
-}
-
-void NativeWidgetAndroid::Activate() {
- aura::client::GetActivationClient(host_->window())
- ->ActivateWindow(GetNativeWindow());
-}
-
-void NativeWidgetAndroid::Deactivate() {
- aura::client::GetActivationClient(host_->window())
- ->DeactivateWindow(GetNativeWindow());
-}
-
-bool NativeWidgetAndroid::IsActive() const {
- return wm::IsActiveWindow(GetNativeWindow());
-}
-
-void NativeWidgetAndroid::SetAlwaysOnTop(bool on_top) {
- GetNativeWindow()->SetProperty(aura::client::kAlwaysOnTopKey, on_top);
-}
-
-bool NativeWidgetAndroid::IsAlwaysOnTop() const {
- return GetNativeWindow()->GetProperty(aura::client::kAlwaysOnTopKey);
-}
-
-void NativeWidgetAndroid::SetVisibleOnAllWorkspaces(bool always_visible) {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::Maximize() {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::Minimize() {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-bool NativeWidgetAndroid::IsMaximized() const {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
- return false;
-}
-
-bool NativeWidgetAndroid::IsMinimized() const {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
- return false;
-}
-
-void NativeWidgetAndroid::Restore() {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::SetFullscreen(bool fullscreen) {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-bool NativeWidgetAndroid::IsFullscreen() const {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
- return false;
-}
-
-void NativeWidgetAndroid::SetOpacity(unsigned char opacity) {
- GetNativeWindow()->layer()->SetOpacity(opacity / 255.0);
-}
-
-void NativeWidgetAndroid::SetUseDragFrame(bool use_drag_frame) {
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::FlashFrame(bool flash) {
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::RunShellDrag(
- View* view,
- const ui::OSExchangeData& data,
- const gfx::Point& location,
- int operation,
- ui::DragDropTypes::DragEventSource source) {
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::SchedulePaintInRect(const gfx::Rect& rect) {
- GetNativeWindow()->SchedulePaintInRect(rect);
-}
-
-void NativeWidgetAndroid::SetCursor(gfx::NativeCursor cursor) {
- cursor_ = cursor;
- aura::client::CursorClient* cursor_client =
- aura::client::GetCursorClient(host_->window());
- if (cursor_client)
- cursor_client->SetCursor(cursor);
-}
-
-bool NativeWidgetAndroid::IsMouseEventsEnabled() const {
- aura::client::CursorClient* cursor_client =
- aura::client::GetCursorClient(host_->window());
- return cursor_client ? cursor_client->IsMouseEventsEnabled() : true;
-}
-
-void NativeWidgetAndroid::ClearNativeFocus() {
- aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
- if (client && window_->Contains(client->GetFocusedWindow()))
- client->ResetFocusWithinActiveWindow(window_);
-}
-
-gfx::Rect NativeWidgetAndroid::GetWorkAreaBoundsInScreen() const {
- return gfx::Screen::GetScreenFor(window_)
- ->GetDisplayNearestWindow(window_)
- .work_area();
-}
-
-Widget::MoveLoopResult NativeWidgetAndroid::RunMoveLoop(
- const gfx::Vector2d& drag_offset,
- Widget::MoveLoopSource source,
- Widget::MoveLoopEscapeBehavior escape_behavior) {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
- return Widget::MOVE_LOOP_SUCCESSFUL;
-}
-
-void NativeWidgetAndroid::EndMoveLoop() {
- // TODO(bshe): Implement this. See crbug.com/554208.
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetAndroid::SetVisibilityChangedAnimationsEnabled(bool value) {
- GetNativeWindow()->SetProperty(aura::client::kAnimationsDisabledKey, !value);
-}
-
-void NativeWidgetAndroid::SetVisibilityAnimationDuration(
- const base::TimeDelta& duration) {
- wm::SetWindowVisibilityAnimationDuration(GetNativeWindow(), duration);
-}
-
-void NativeWidgetAndroid::SetVisibilityAnimationTransition(
- Widget::VisibilityTransition transition) {
- wm::WindowVisibilityAnimationTransition wm_transition = wm::ANIMATE_NONE;
- switch (transition) {
- case Widget::ANIMATE_SHOW:
- wm_transition = wm::ANIMATE_SHOW;
- break;
- case Widget::ANIMATE_HIDE:
- wm_transition = wm::ANIMATE_HIDE;
- break;
- case Widget::ANIMATE_BOTH:
- wm_transition = wm::ANIMATE_BOTH;
- break;
- case Widget::ANIMATE_NONE:
- wm_transition = wm::ANIMATE_NONE;
- break;
- }
- wm::SetWindowVisibilityAnimationTransition(GetNativeWindow(), wm_transition);
-}
-
-ui::NativeTheme* NativeWidgetAndroid::GetNativeTheme() const {
- return ui::NativeThemeAura::instance();
-}
-
-void NativeWidgetAndroid::OnRootViewLayout() {
- NOTIMPLEMENTED();
-}
-
-bool NativeWidgetAndroid::IsTranslucentWindowOpacitySupported() const {
- return true;
-}
-
-void NativeWidgetAndroid::OnSizeConstraintsChanged() {
- window_->SetProperty(aura::client::kCanMaximizeKey,
- GetWidget()->widget_delegate()->CanMaximize());
- window_->SetProperty(aura::client::kCanMinimizeKey,
- GetWidget()->widget_delegate()->CanMinimize());
- window_->SetProperty(aura::client::kCanResizeKey,
- GetWidget()->widget_delegate()->CanResize());
-}
-
-void NativeWidgetAndroid::RepostNativeEvent(gfx::NativeEvent native_event) {
- OnEvent(native_event);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::WindowDelegate implementation:
-
-gfx::Size NativeWidgetAndroid::GetMinimumSize() const {
- return delegate_->GetMinimumSize();
-}
-
-gfx::Size NativeWidgetAndroid::GetMaximumSize() const {
- // If a window have a maximum size, the window should not be
- // maximizable.
- DCHECK(delegate_->GetMaximumSize().IsEmpty() ||
- !window_->GetProperty(aura::client::kCanMaximizeKey));
- return delegate_->GetMaximumSize();
-}
-
-void NativeWidgetAndroid::OnBoundsChanged(const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
- // Assume that if the old bounds was completely empty a move happened. This
- // handles the case of a maximize animation acquiring the layer (acquiring a
- // layer results in clearing the bounds).
- if (old_bounds.origin() != new_bounds.origin() ||
- (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) {
- delegate_->OnNativeWidgetMove();
- }
- if (old_bounds.size() != new_bounds.size())
- delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
-}
-
-gfx::NativeCursor NativeWidgetAndroid::GetCursor(const gfx::Point& point) {
- return cursor_;
-}
-
-int NativeWidgetAndroid::GetNonClientComponent(const gfx::Point& point) const {
- return delegate_->GetNonClientComponent(point);
-}
-
-bool NativeWidgetAndroid::ShouldDescendIntoChildForEventHandling(
- aura::Window* child,
- const gfx::Point& location) {
- views::WidgetDelegate* widget_delegate = GetWidget()->widget_delegate();
- if (widget_delegate &&
- !widget_delegate->ShouldDescendIntoChildForEventHandling(child, location))
- return false;
-
- // Don't descend into |child| if there is a view with a Layer that contains
- // the point and is stacked above |child|s layer.
- typedef std::vector<ui::Layer*> Layers;
- const Layers& root_layers(delegate_->GetRootLayers());
- if (root_layers.empty())
- return true;
-
- Layers::const_iterator child_layer_iter(
- std::find(window_->layer()->children().begin(),
- window_->layer()->children().end(), child->layer()));
- if (child_layer_iter == window_->layer()->children().end())
- return true;
-
- for (std::vector<ui::Layer*>::const_reverse_iterator i = root_layers.rbegin();
- i != root_layers.rend(); ++i) {
- ui::Layer* layer = *i;
- if (layer->visible() && layer->bounds().Contains(location)) {
- Layers::const_iterator root_layer_iter(
- std::find(window_->layer()->children().begin(),
- window_->layer()->children().end(), layer));
- if (root_layer_iter > child_layer_iter)
- return false;
- }
- }
- return true;
-}
-
-bool NativeWidgetAndroid::CanFocus() {
- return ShouldActivate();
-}
-
-void NativeWidgetAndroid::OnCaptureLost() {
- delegate_->OnMouseCaptureLost();
-}
-
-void NativeWidgetAndroid::OnPaint(const ui::PaintContext& context) {
- delegate_->OnNativeWidgetPaint(context);
-}
-
-void NativeWidgetAndroid::OnDeviceScaleFactorChanged(
- float device_scale_factor) {
- GetWidget()->DeviceScaleFactorChanged(device_scale_factor);
-}
-
-void NativeWidgetAndroid::OnWindowDestroying(aura::Window* window) {
- delegate_->OnNativeWidgetDestroying();
-
- // If the aura::Window is destroyed, we can no longer show tooltips.
- tooltip_manager_.reset();
-}
-
-void NativeWidgetAndroid::OnWindowDestroyed(aura::Window* window) {
- window_ = nullptr;
- delegate_->OnNativeWidgetDestroyed();
- if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
- delete this;
-}
-
-void NativeWidgetAndroid::OnWindowTargetVisibilityChanged(bool visible) {
- delegate_->OnNativeWidgetVisibilityChanged(visible);
-}
-
-bool NativeWidgetAndroid::HasHitTestMask() const {
- return delegate_->HasHitTestMask();
-}
-
-void NativeWidgetAndroid::GetHitTestMask(gfx::Path* mask) const {
- DCHECK(mask);
- delegate_->GetHitTestMask(mask);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, ui::EventHandler implementation:
-
-void NativeWidgetAndroid::OnKeyEvent(ui::KeyEvent* event) {
- DCHECK(window_);
- // Renderer may send a key event back to us if the key event wasn't handled,
- // and the window may be invisible by that time.
- if (!window_->IsVisible())
- return;
-
- FocusManager* focus_manager = GetWidget()->GetFocusManager();
- delegate_->OnKeyEvent(event);
- if (!event->handled() && focus_manager)
- focus_manager->OnKeyEvent(*event);
- event->SetHandled();
-}
-
-void NativeWidgetAndroid::OnMouseEvent(ui::MouseEvent* event) {
- DCHECK(window_);
- DCHECK(window_->IsVisible());
- if (event->type() == ui::ET_MOUSEWHEEL) {
- delegate_->OnMouseEvent(event);
- if (event->handled())
- return;
- }
-
- if (tooltip_manager_.get())
- tooltip_manager_->UpdateTooltip();
- TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget());
- delegate_->OnMouseEvent(event);
-}
-
-void NativeWidgetAndroid::OnScrollEvent(ui::ScrollEvent* event) {
- delegate_->OnScrollEvent(event);
-}
-
-void NativeWidgetAndroid::OnGestureEvent(ui::GestureEvent* event) {
- DCHECK(window_);
- DCHECK(window_->IsVisible() || event->IsEndingEvent());
- delegate_->OnGestureEvent(event);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::client::ActivationDelegate implementation:
-
-bool NativeWidgetAndroid::ShouldActivate() const {
- return delegate_->CanActivate();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::client::ActivationChangeObserver
-// implementation:
-
-void NativeWidgetAndroid::OnWindowActivated(
- aura::client::ActivationChangeObserver::ActivationReason,
- aura::Window* gained_active,
- aura::Window* lost_active) {
- DCHECK(window_ == gained_active || window_ == lost_active);
- if (GetWidget()->GetFocusManager()) {
- if (window_ == gained_active)
- GetWidget()->GetFocusManager()->RestoreFocusedView();
- else if (window_ == lost_active)
- GetWidget()->GetFocusManager()->StoreFocusedView(true);
- }
- delegate_->OnNativeWidgetActivationChanged(window_ == gained_active);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::client::FocusChangeObserver:
-
-void NativeWidgetAndroid::OnWindowFocused(aura::Window* gained_focus,
- aura::Window* lost_focus) {
- if (window_ == gained_focus)
- delegate_->OnNativeFocus();
- else if (window_ == lost_focus)
- delegate_->OnNativeBlur();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::WindowDragDropDelegate implementation:
-
-void NativeWidgetAndroid::OnDragEntered(const ui::DropTargetEvent& event) {
- // TODO: Implement drag and drop. crbug.com/554029.
- NOTIMPLEMENTED();
-}
-
-int NativeWidgetAndroid::OnDragUpdated(const ui::DropTargetEvent& event) {
- // TODO: Implement drag and drop. crbug.com/554029.
- NOTIMPLEMENTED();
- return 0;
-}
-
-void NativeWidgetAndroid::OnDragExited() {
- // TODO: Implement drag and drop. crbug.com/554029.
- NOTIMPLEMENTED();
-}
-
-int NativeWidgetAndroid::OnPerformDrop(const ui::DropTargetEvent& event) {
- // TODO: Implement drag and drop. crbug.com/554029.
- NOTIMPLEMENTED();
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, aura::WindowTreeHostObserver implementation:
-
-void NativeWidgetAndroid::OnHostCloseRequested(
- const aura::WindowTreeHost* host) {
- GetWidget()->Close();
-}
-
-void NativeWidgetAndroid::OnHostResized(const aura::WindowTreeHost* host) {
- gfx::Rect new_bounds = gfx::Rect(host_->window()->bounds().size());
- GetNativeWindow()->SetBounds(new_bounds);
- delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
-}
-
-void NativeWidgetAndroid::OnHostMoved(const aura::WindowTreeHost* host,
- const gfx::Point& new_origin) {
- TRACE_EVENT1("views", "NativeWidgetAndroid::OnHostMoved", "new_origin",
- new_origin.ToString());
-
- delegate_->OnNativeWidgetMove();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, protected:
-
-NativeWidgetAndroid::~NativeWidgetAndroid() {
- destroying_ = true;
- if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
- delete delegate_;
- else
- CloseNow();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeWidgetAndroid, private:
-
-bool NativeWidgetAndroid::IsDocked() const {
- NOTIMPLEMENTED();
- return false;
-}
-
-void NativeWidgetAndroid::SetInitialFocus(ui::WindowShowState show_state) {
- // The window does not get keyboard messages unless we focus it.
- if (!GetWidget()->SetInitialFocus(show_state))
- window_->Focus();
-}
-
-} // namespace views
diff --git a/chromium/ui/views/widget/android/native_widget_android.h b/chromium/ui/views/widget/android/native_widget_android.h
deleted file mode 100644
index 8aaa3c470bd..00000000000
--- a/chromium/ui/views/widget/android/native_widget_android.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_ANDROID_NATIVE_WIDGET_ANDROID_H_
-#define UI_VIEWS_WIDGET_ANDROID_NATIVE_WIDGET_ANDROID_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "ui/aura/client/focus_change_observer.h"
-#include "ui/aura/window_delegate.h"
-#include "ui/aura/window_observer.h"
-#include "ui/aura/window_tree_host_observer.h"
-#include "ui/base/cursor/cursor.h"
-#include "ui/events/event_constants.h"
-#include "ui/views/views_export.h"
-#include "ui/views/widget/native_widget_private.h"
-#include "ui/wm/public/activation_change_observer.h"
-#include "ui/wm/public/activation_delegate.h"
-#include "ui/wm/public/drag_drop_delegate.h"
-
-namespace aura {
-class Window;
-class WindowTreeHost;
-namespace client {
-class DefaultCaptureClient;
-class DispatcherClient;
-class ScreenPositionClient;
-class WindowTreeClient;
-}
-}
-namespace gfx {
-class FontList;
-}
-namespace wm {
-class FocusController;
-}
-
-namespace views {
-
-class TooltipManagerAura;
-class WindowReorderer;
-
-// NativeWidgetAndroid creates and hosts the Widget in an Android native window.
-// It is used to create a top level window on Android platform.
-class VIEWS_EXPORT NativeWidgetAndroid
- : public internal::NativeWidgetPrivate,
- public aura::WindowDelegate,
- public aura::client::ActivationDelegate,
- public aura::client::ActivationChangeObserver,
- public aura::client::FocusChangeObserver,
- public aura::client::DragDropDelegate,
- public aura::WindowTreeHostObserver {
- public:
- explicit NativeWidgetAndroid(internal::NativeWidgetDelegate* delegate);
-
- aura::WindowTreeHost* host() { return host_.get(); }
-
- // Overridden from internal::NativeWidgetPrivate:
- void InitNativeWidget(const Widget::InitParams& params) override;
- void OnWidgetInitDone() override;
- NonClientFrameView* CreateNonClientFrameView() override;
- bool ShouldUseNativeFrame() const override;
- bool ShouldWindowContentsBeTransparent() const override;
- void FrameTypeChanged() override;
- Widget* GetWidget() override;
- const Widget* GetWidget() const override;
- gfx::NativeView GetNativeView() const override;
- gfx::NativeWindow GetNativeWindow() const override;
- Widget* GetTopLevelWidget() override;
- const ui::Compositor* GetCompositor() const override;
- const ui::Layer* GetLayer() const override;
- void ReorderNativeViews() override;
- void ViewRemoved(View* view) override;
- void SetNativeWindowProperty(const char* name, void* value) override;
- void* GetNativeWindowProperty(const char* name) const override;
- TooltipManager* GetTooltipManager() const override;
- void SetCapture() override;
- void ReleaseCapture() override;
- bool HasCapture() const override;
- ui::InputMethod* GetInputMethod() override;
- void CenterWindow(const gfx::Size& size) override;
- void GetWindowPlacement(gfx::Rect* bounds,
- ui::WindowShowState* maximized) const override;
- bool SetWindowTitle(const base::string16& title) override;
- void SetWindowIcons(const gfx::ImageSkia& window_icon,
- const gfx::ImageSkia& app_icon) override;
- void InitModalType(ui::ModalType modal_type) override;
- gfx::Rect GetWindowBoundsInScreen() const override;
- gfx::Rect GetClientAreaBoundsInScreen() const override;
- gfx::Rect GetRestoredBounds() const override;
- void SetBounds(const gfx::Rect& bounds) override;
- void SetSize(const gfx::Size& size) override;
- void StackAbove(gfx::NativeView native_view) override;
- void StackAtTop() override;
- void StackBelow(gfx::NativeView native_view) override;
- void SetShape(SkRegion* shape) override;
- void Close() override;
- void CloseNow() override;
- void Show() override;
- void Hide() override;
- void ShowMaximizedWithBounds(const gfx::Rect& restored_bounds) override;
- void ShowWithWindowState(ui::WindowShowState state) override;
- bool IsVisible() const override;
- void Activate() override;
- void Deactivate() override;
- bool IsActive() const override;
- void SetAlwaysOnTop(bool always_on_top) override;
- bool IsAlwaysOnTop() const override;
- void SetVisibleOnAllWorkspaces(bool always_visible) override;
- void Maximize() override;
- void Minimize() override;
- bool IsMaximized() const override;
- bool IsMinimized() const override;
- void Restore() override;
- void SetFullscreen(bool fullscreen) override;
- bool IsFullscreen() const override;
- void SetOpacity(unsigned char opacity) override;
- void SetUseDragFrame(bool use_drag_frame) override;
- void FlashFrame(bool flash_frame) override;
- void RunShellDrag(View* view,
- const ui::OSExchangeData& data,
- const gfx::Point& location,
- int operation,
- ui::DragDropTypes::DragEventSource source) override;
- void SchedulePaintInRect(const gfx::Rect& rect) override;
- void SetCursor(gfx::NativeCursor cursor) override;
- bool IsMouseEventsEnabled() const override;
- void ClearNativeFocus() override;
- gfx::Rect GetWorkAreaBoundsInScreen() const override;
- Widget::MoveLoopResult RunMoveLoop(
- const gfx::Vector2d& drag_offset,
- Widget::MoveLoopSource source,
- Widget::MoveLoopEscapeBehavior escape_behavior) override;
- void EndMoveLoop() override;
- void SetVisibilityChangedAnimationsEnabled(bool value) override;
- void SetVisibilityAnimationDuration(const base::TimeDelta& duration) override;
- void SetVisibilityAnimationTransition(
- Widget::VisibilityTransition transition) override;
- ui::NativeTheme* GetNativeTheme() const override;
- void OnRootViewLayout() override;
- bool IsTranslucentWindowOpacitySupported() const override;
- void OnSizeConstraintsChanged() override;
- void RepostNativeEvent(gfx::NativeEvent native_event) override;
-
- // Overridden from aura::WindowDelegate:
- gfx::Size GetMinimumSize() const override;
- gfx::Size GetMaximumSize() const override;
- void OnBoundsChanged(const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override;
- gfx::NativeCursor GetCursor(const gfx::Point& point) override;
- int GetNonClientComponent(const gfx::Point& point) const override;
- bool ShouldDescendIntoChildForEventHandling(
- aura::Window* child,
- const gfx::Point& location) override;
- bool CanFocus() override;
- void OnCaptureLost() override;
- void OnPaint(const ui::PaintContext& context) override;
- void OnDeviceScaleFactorChanged(float device_scale_factor) override;
- void OnWindowDestroying(aura::Window* window) override;
- void OnWindowDestroyed(aura::Window* window) override;
- void OnWindowTargetVisibilityChanged(bool visible) override;
- bool HasHitTestMask() const override;
- void GetHitTestMask(gfx::Path* mask) const override;
-
- // Overridden from ui::EventHandler:
- void OnKeyEvent(ui::KeyEvent* event) override;
- void OnMouseEvent(ui::MouseEvent* event) override;
- void OnScrollEvent(ui::ScrollEvent* event) override;
- void OnGestureEvent(ui::GestureEvent* event) override;
-
- // Overridden from aura::client::ActivationDelegate:
- bool ShouldActivate() const override;
-
- // Overridden from aura::client::ActivationChangeObserver:
- void OnWindowActivated(
- aura::client::ActivationChangeObserver::ActivationReason reason,
- aura::Window* gained_active,
- aura::Window* lost_active) override;
-
- // Overridden from aura::client::FocusChangeObserver:
- void OnWindowFocused(aura::Window* gained_focus,
- aura::Window* lost_focus) override;
-
- // Overridden from aura::client::DragDropDelegate:
- void OnDragEntered(const ui::DropTargetEvent& event) override;
- int OnDragUpdated(const ui::DropTargetEvent& event) override;
- void OnDragExited() override;
- int OnPerformDrop(const ui::DropTargetEvent& event) override;
-
- // Overridden from aura::WindowTreeHostObserver:
- void OnHostCloseRequested(const aura::WindowTreeHost* host) override;
- void OnHostResized(const aura::WindowTreeHost* host) override;
- void OnHostMoved(const aura::WindowTreeHost* host,
- const gfx::Point& new_origin) override;
-
- protected:
- ~NativeWidgetAndroid() override;
-
- internal::NativeWidgetDelegate* delegate() { return delegate_; }
-
- private:
- class ActiveWindowObserver;
-
- bool IsDocked() const;
- void SetInitialFocus(ui::WindowShowState show_state);
-
- internal::NativeWidgetDelegate* delegate_;
-
- // WARNING: set to NULL when destroyed. As the Widget is not necessarily
- // destroyed along with |window_| all usage of |window_| should first verify
- // non-NULL.
- aura::Window* window_;
-
- // See class documentation for Widget in widget.h for a note about ownership.
- Widget::InitParams::Ownership ownership_;
-
- // Are we in the destructor?
- bool destroying_;
-
- gfx::NativeCursor cursor_;
-
- // The saved window state for exiting full screen state.
- ui::WindowShowState saved_window_state_;
-
- scoped_ptr<TooltipManagerAura> tooltip_manager_;
-
- // Reorders child windows of |window_| associated with a view based on the
- // order of the associated views in the widget's view hierarchy.
- scoped_ptr<WindowReorderer> window_reorderer_;
-
- scoped_ptr<aura::WindowTreeHost> host_;
- scoped_ptr<wm::FocusController> focus_client_;
- scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
- scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
- scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
- scoped_ptr<aura::client::DispatcherClient> dispatcher_client_;
-
- // The following factory is used for calls to close the
- // NativeWidgetAndroid instance.
- base::WeakPtrFactory<NativeWidgetAndroid> close_widget_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(NativeWidgetAndroid);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_ANDROID_NATIVE_WIDGET_ANDROID_H_
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.cc b/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.cc
deleted file mode 100644
index 409057da5f0..00000000000
--- a/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
-
-#include "base/auto_reset.h"
-#include "base/bind.h"
-#include "base/run_loop.h"
-#include "build/build_config.h"
-
-namespace views {
-
-DesktopDispatcherClient::DesktopDispatcherClient() {
-}
-
-DesktopDispatcherClient::~DesktopDispatcherClient() {
-}
-
-void DesktopDispatcherClient::PrepareNestedLoopClosures(
- base::MessagePumpDispatcher* dispatcher,
- base::Closure* run_closure,
- base::Closure* quit_closure) {
-#if defined(OS_WIN)
- scoped_ptr<base::RunLoop> run_loop(new base::RunLoop(dispatcher));
-#else
- scoped_ptr<base::RunLoop> run_loop(new base::RunLoop());
-#endif
- *quit_closure = run_loop->QuitClosure();
- *run_closure =
- base::Bind(&base::RunLoop::Run, base::Owned(run_loop.release()));
-}
-
-} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.h b/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.h
deleted file mode 100644
index 3d7f6f42caa..00000000000
--- a/chromium/ui/views/widget/desktop_aura/desktop_dispatcher_client.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DISPATCHER_CLIENT_H_
-#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DISPATCHER_CLIENT_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "ui/views/views_export.h"
-#include "ui/wm/public/dispatcher_client.h"
-
-namespace views {
-
-// TODO(erg): I won't lie to you; I have no idea what this is or what it does.
-class VIEWS_EXPORT DesktopDispatcherClient
- : public aura::client::DispatcherClient {
- public:
- DesktopDispatcherClient();
- ~DesktopDispatcherClient() override;
-
- void PrepareNestedLoopClosures(base::MessagePumpDispatcher* dispatcher,
- base::Closure* run_closure,
- base::Closure* quit_closure) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DesktopDispatcherClient);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DISPATCHER_CLIENT_H_
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index 3ef11e83603..e9907e2a275 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -1186,8 +1186,8 @@ void DesktopDragDropClientAuraX11::CreateDragWidget(
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.accept_events = false;
- gfx::Point location = gfx::Screen::GetNativeScreen()->GetCursorScreenPoint() -
- drag_widget_offset_;
+ gfx::Point location =
+ gfx::Screen::GetScreen()->GetCursorScreenPoint() - drag_widget_offset_;
params.bounds = gfx::Rect(location, image.size());
widget->set_focus_on_creation(false);
widget->set_frame_type(Widget::FRAME_TYPE_FORCE_NATIVE);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 01c1d875c29..f69b839d73a 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -32,7 +32,6 @@
#include "ui/views/view_constants_aura.h"
#include "ui/views/widget/desktop_aura/desktop_capture_client.h"
#include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h"
-#include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
#include "ui/views/widget/desktop_aura/desktop_event_client.h"
#include "ui/views/widget/desktop_aura/desktop_focus_rules.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
@@ -61,7 +60,6 @@
#if defined(OS_WIN)
#include "ui/base/win/shell.h"
-#include "ui/gfx/win/dpi.h"
#endif
DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(VIEWS_EXPORT,
@@ -341,11 +339,6 @@ void DesktopNativeWidgetAura::OnHostClosed() {
void DesktopNativeWidgetAura::OnDesktopWindowTreeHostDestroyed(
aura::WindowTreeHost* host) {
- // |dispatcher_| is still valid, but DesktopWindowTreeHost is nearly
- // destroyed. Do cleanup here of members DesktopWindowTreeHost may also use.
- aura::client::SetDispatcherClient(host->window(), NULL);
- dispatcher_client_.reset();
-
// We explicitly do NOT clear the cursor client property. Since the cursor
// manager is a singleton, it can outlive any window hierarchy, and it's
// important that objects attached to this destroying window hierarchy have
@@ -483,10 +476,6 @@ void DesktopNativeWidgetAura::InitNativeWidget(
aura::client::SetActivationClient(host_->window(), focus_controller);
host_->window()->AddPreTargetHandler(focus_controller);
- dispatcher_client_.reset(new DesktopDispatcherClient);
- aura::client::SetDispatcherClient(host_->window(),
- dispatcher_client_.get());
-
position_client_.reset(new DesktopScreenPositionClient(host_->window()));
drag_drop_client_ = desktop_window_tree_host_->CreateDragDropClient(
@@ -689,18 +678,9 @@ gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
if (!content_window_)
return;
- // TODO(ananta)
- // This code by default scales the bounds rectangle by 1.
- // We could probably get rid of this and similar logic from
- // the DesktopNativeWidgetAura::OnWindowTreeHostResized function.
- float scale = 1;
aura::Window* root = host_->window();
- if (root) {
- scale = gfx::Screen::GetScreenFor(root)->
- GetDisplayNearestWindow(root).device_scale_factor();
- }
- gfx::Rect bounds_in_pixels =
- gfx::ScaleToEnclosingRect(bounds, scale, scale);
+ gfx::Screen* screen = gfx::Screen::GetScreen();
+ gfx::Rect bounds_in_pixels = screen->DIPToScreenRectInWindow(root, bounds);
desktop_window_tree_host_->AsWindowTreeHost()->SetBounds(bounds_in_pixels);
}
@@ -840,9 +820,6 @@ void DesktopNativeWidgetAura::SetOpacity(unsigned char opacity) {
desktop_window_tree_host_->SetOpacity(opacity);
}
-void DesktopNativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
-}
-
void DesktopNativeWidgetAura::FlashFrame(bool flash_frame) {
if (content_window_)
desktop_window_tree_host_->FlashFrame(flash_frame);
@@ -1069,7 +1046,7 @@ void DesktopNativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) {
return;
// Convert unprocessed scroll events into wheel events.
- ui::MouseWheelEvent mwe(*static_cast<ui::ScrollEvent*>(event));
+ ui::MouseWheelEvent mwe(*event->AsScrollEvent());
native_widget_delegate_->OnMouseEvent(&mwe);
if (mwe.handled())
event->SetHandled();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index 2a756d9fd72..47f514924bf 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -42,7 +42,6 @@ namespace corewm {
class TooltipController;
}
class DesktopCaptureClient;
-class DesktopDispatcherClient;
class DesktopEventClient;
class DesktopNativeCursorManager;
class DesktopWindowTreeHost;
@@ -149,7 +148,6 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
void SetFullscreen(bool fullscreen) override;
bool IsFullscreen() const override;
void SetOpacity(unsigned char opacity) override;
- void SetUseDragFrame(bool use_drag_frame) override;
void FlashFrame(bool flash_frame) override;
void RunShellDrag(View* view,
const ui::OSExchangeData& data,
@@ -256,7 +254,6 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
internal::NativeWidgetDelegate* native_widget_delegate_;
scoped_ptr<wm::FocusController> focus_client_;
- scoped_ptr<DesktopDispatcherClient> dispatcher_client_;
scoped_ptr<aura::client::ScreenPositionClient> position_client_;
scoped_ptr<aura::client::DragDropClient> drag_drop_client_;
scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index 9578951b137..86e60d31fc8 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/run_loop.h"
#include "build/build_config.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/cursor_client.h"
@@ -17,15 +18,17 @@
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/screen.h"
+#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
-#include "ui/wm/public/dispatcher_client.h"
#if defined(OS_WIN)
+#include "ui/base/view_prop.h"
+#include "ui/base/win/window_event_target.h"
#include "ui/views/win/hwnd_util.h"
#endif
@@ -231,15 +234,10 @@ TEST_F(DesktopNativeWidgetAuraTest, WidgetCanBeDestroyedFromNestedLoop) {
widget->Init(params);
widget->Show();
- aura::Window* window = widget->GetNativeView();
- aura::Window* root = window->GetRootWindow();
- aura::client::DispatcherClient* client =
- aura::client::GetDispatcherClient(root);
-
// Post a task that terminates the nested loop and destroyes the widget. This
// task will be executed from the nested loop initiated with the call to
// |RunWithDispatcher()| below.
- aura::client::DispatcherRunLoop run_loop(client, NULL);
+ base::RunLoop run_loop;
base::Closure quit_runloop = run_loop.QuitClosure();
message_loop()->PostTask(FROM_HERE,
base::Bind(&QuitNestedLoopAndCloseWidget,
@@ -434,9 +432,7 @@ TEST_F(DesktopAuraWidgetTest, TopLevelOwnedPopupRepositionTest) {
gfx::Rect new_pos(10, 10, 400, 400);
popup_window.owned_window()->SetBoundsInScreen(
- new_pos,
- gfx::Screen::GetScreenFor(
- popup_window.owned_window())->GetDisplayNearestPoint(gfx::Point()));
+ new_pos, gfx::Screen::GetScreen()->GetDisplayNearestPoint(gfx::Point()));
EXPECT_EQ(new_pos,
popup_window.top_level_widget()->GetWindowBoundsInScreen());
@@ -493,7 +489,8 @@ void RunCloseWidgetDuringDispatchTest(WidgetTest* test,
Widget* widget = new Widget;
Widget::InitParams params =
test->CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget = new PlatformDesktopNativeWidget(widget);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, widget, nullptr);
params.bounds = gfx::Rect(0, 0, 50, 100);
widget->Init(params);
widget->SetContentsView(new CloseWidgetView(last_event_type));
@@ -535,8 +532,8 @@ TEST_F(WidgetTest, WindowMouseModalityTest) {
gfx::Rect initial_bounds(0, 0, 500, 500);
init_params.bounds = initial_bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget =
- new PlatformDesktopNativeWidget(&top_level_widget);
+ init_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ init_params, &top_level_widget, nullptr);
top_level_widget.Init(init_params);
top_level_widget.Show();
EXPECT_TRUE(top_level_widget.IsVisible());
@@ -632,6 +629,32 @@ TEST_F(WidgetTest, WindowModalityActivationTest) {
modal_dialog_widget->CloseNow();
}
+
+// This test validates that sending WM_CHAR/WM_SYSCHAR/WM_SYSDEADCHAR
+// messages via the WindowEventTarget interface implemented by the
+// HWNDMessageHandler class does not cause a crash due to an unprocessed
+// event
+TEST_F(WidgetTest, CharMessagesAsKeyboardMessagesDoesNotCrash) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, &widget, nullptr);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+ widget.Show();
+
+ ui::WindowEventTarget* target =
+ reinterpret_cast<ui::WindowEventTarget*>(ui::ViewProp::GetValue(
+ widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(),
+ ui::WindowEventTarget::kWin32InputEventTarget));
+ ASSERT_NE(nullptr, target);
+ bool handled = false;
+ target->HandleKeyboardMessage(WM_CHAR, 0, 0, &handled);
+ target->HandleKeyboardMessage(WM_SYSCHAR, 0, 0, &handled);
+ target->HandleKeyboardMessage(WM_SYSDEADCHAR, 0, 0, &handled);
+ widget.CloseNow();
+}
+
#endif // defined(OS_WIN)
} // namespace test
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
index a8e088c92c6..4df7b7ffae5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
@@ -24,7 +24,7 @@ DesktopScreenWin::~DesktopScreenWin() {
}
////////////////////////////////////////////////////////////////////////////////
-// DesktopScreenWin, gfx::ScreenWin implementation:
+// DesktopScreenWin, display::win::ScreenWin implementation:
gfx::Display DesktopScreenWin::GetDisplayMatching(
const gfx::Rect& match_rect) const {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
index 8add5bdb3f2..085ba321da1 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -6,18 +6,18 @@
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_H_
#include "base/macros.h"
-#include "ui/gfx/screen_win.h"
+#include "ui/display/win/screen_win.h"
#include "ui/views/views_export.h"
namespace views {
-class VIEWS_EXPORT DesktopScreenWin : public gfx::ScreenWin {
+class VIEWS_EXPORT DesktopScreenWin : public display::win::ScreenWin {
public:
DesktopScreenWin();
~DesktopScreenWin() override;
private:
- // Overridden from gfx::ScreenWin:
+ // Overridden from display::win::ScreenWin:
gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
HWND GetHWNDFromNativeView(gfx::NativeView window) const override;
gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 07bcfca6189..6ffd94a3c89 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -20,6 +20,7 @@
#include "ui/display/util/x11/edid_parser_x11.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/display.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/native_widget_types.h"
@@ -38,9 +39,12 @@ const int64_t kConfigureDelayMs = 500;
double GetDeviceScaleFactor() {
float device_scale_factor = 1.0f;
- if (views::LinuxUI::instance())
+ if (views::LinuxUI::instance()) {
device_scale_factor =
views::LinuxUI::instance()->GetDeviceScaleFactor();
+ } else if (gfx::Display::HasForceDeviceScaleFactor()) {
+ device_scale_factor = gfx::Display::GetForcedDeviceScaleFactor();
+ }
return device_scale_factor;
}
@@ -104,9 +108,9 @@ DesktopScreenX11::DesktopScreenX11()
RROutputChangeNotifyMask |
RRCrtcChangeNotifyMask);
- displays_ = BuildDisplaysFromXRandRInfo();
+ SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
} else {
- displays_ = GetFallbackDisplayList();
+ SetDisplaysInternal(GetFallbackDisplayList());
}
}
@@ -255,7 +259,7 @@ uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
// static
void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
DesktopScreenX11* screen =
- static_cast<DesktopScreenX11*>(gfx::Screen::GetNativeScreen());
+ static_cast<DesktopScreenX11*>(gfx::Screen::GetScreen());
screen->ConfigureTimerFired();
}
@@ -310,7 +314,8 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
crtc(XRRGetCrtcInfo(xdisplay_, resources.get(), output_info->crtc));
int64_t display_id = -1;
- if (!ui::GetDisplayId(output_id, static_cast<uint8_t>(i), &display_id)) {
+ if (!ui::EDIDParserX11(output_id).GetDisplayId(static_cast<uint8_t>(i),
+ &display_id)) {
// It isn't ideal, but if we can't parse the EDID data, fallback on the
// display number.
display_id = i;
@@ -362,11 +367,17 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
void DesktopScreenX11::ConfigureTimerFired() {
std::vector<gfx::Display> old_displays = displays_;
- displays_ = BuildDisplaysFromXRandRInfo();
-
+ SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
}
+void DesktopScreenX11::SetDisplaysInternal(
+ const std::vector<gfx::Display>& displays) {
+ displays_ = displays;
+ gfx::SetFontRenderParamsDeviceScaleFactor(
+ GetPrimaryDisplay().device_scale_factor());
+}
+
////////////////////////////////////////////////////////////////////////////////
gfx::Screen* CreateDesktopScreen() {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
index c49d4daf28b..e96d983ccb2 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gfx/display_change_notifier.h"
@@ -70,6 +71,9 @@ class VIEWS_EXPORT DesktopScreenX11 : public gfx::Screen,
// We delay updating the display so we can coalesce events.
void ConfigureTimerFired();
+ // Updates |displays_| and sets FontRenderParams's scale factor.
+ void SetDisplaysInternal(const std::vector<gfx::Display>& displays);
+
Display* xdisplay_;
::Window x_root_window_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
index c527545c4b0..a2e2d2aed7e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
@@ -16,6 +16,7 @@
#include "ui/base/x/x11_util.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/display_observer.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -83,9 +84,10 @@ class DesktopScreenX11Test : public views::ViewsTestBase,
DesktopScreenX11* screen() { return screen_.get(); }
void NotifyDisplaysChanged(const std::vector<gfx::Display>& displays) {
- DesktopScreenX11* screen = screen_.get();
- screen->change_notifier_.NotifyDisplaysChanged(screen->displays_, displays);
- screen->displays_ = displays;
+ std::vector<gfx::Display> old_displays = screen_->displays_;
+ screen_->SetDisplaysInternal(displays);
+ screen_->change_notifier_.NotifyDisplaysChanged(old_displays,
+ screen_->displays_);
}
void ResetDisplayChanges() {
@@ -439,6 +441,7 @@ TEST_F(DesktopScreenX11Test, DeviceScaleFactorChange) {
displays[0].set_device_scale_factor(2.5f);
NotifyDisplaysChanged(displays);
EXPECT_EQ(1u, changed_display_.size());
+ EXPECT_EQ(2.5f, gfx::GetFontRenderParamsDeviceScaleFactor());
displays[1].set_device_scale_factor(2.5f);
NotifyDisplaysChanged(displays);
@@ -456,6 +459,7 @@ TEST_F(DesktopScreenX11Test, DeviceScaleFactorChange) {
displays[1].set_device_scale_factor(1.f);
NotifyDisplaysChanged(displays);
EXPECT_EQ(4u, changed_display_.size());
+ EXPECT_EQ(1.f, gfx::GetFontRenderParamsDeviceScaleFactor());
}
} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index c354154a542..fa9ea48b500 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -125,6 +125,7 @@ void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
const Widget::InitParams& params) {
// TODO(beng): SetInitParams().
content_window_ = content_window;
+ wants_mouse_events_when_inactive_ = params.wants_mouse_events_when_inactive;
aura::client::SetAnimationHost(content_window_, this);
@@ -136,8 +137,7 @@ void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
if (params.parent && params.parent->GetHost())
parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
- message_handler_->set_remove_standard_frame(params.remove_standard_frame);
-
+ remove_standard_frame_ = params.remove_standard_frame;
has_non_client_view_ = Widget::RequiresNonClientView(params.type);
gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
@@ -587,24 +587,30 @@ void DesktopWindowTreeHostWin::OnWindowHidingAnimationCompleted() {
////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHostWin, HWNDMessageHandlerDelegate implementation:
-bool DesktopWindowTreeHostWin::IsWidgetWindow() const {
+bool DesktopWindowTreeHostWin::HasNonClientView() const {
return has_non_client_view_;
}
-bool DesktopWindowTreeHostWin::IsUsingCustomFrame() const {
- return !GetWidget()->ShouldUseNativeFrame();
+FrameMode DesktopWindowTreeHostWin::GetFrameMode() const {
+ return GetWidget()->ShouldUseNativeFrame() ? FrameMode::SYSTEM_DRAWN
+ : FrameMode::CUSTOM_DRAWN;
+}
+
+bool DesktopWindowTreeHostWin::HasFrame() const {
+ return !remove_standard_frame_;
}
void DesktopWindowTreeHostWin::SchedulePaint() {
GetWidget()->GetRootView()->SchedulePaint();
}
-void DesktopWindowTreeHostWin::EnableInactiveRendering() {
- native_widget_delegate_->EnableInactiveRendering();
+void DesktopWindowTreeHostWin::SetAlwaysRenderAsActive(
+ bool always_render_as_active) {
+ native_widget_delegate_->SetAlwaysRenderAsActive(always_render_as_active);
}
-bool DesktopWindowTreeHostWin::IsInactiveRenderingDisabled() {
- return native_widget_delegate_->IsInactiveRenderingDisabled();
+bool DesktopWindowTreeHostWin::IsAlwaysRenderAsActive() {
+ return native_widget_delegate_->IsAlwaysRenderAsActive();
}
bool DesktopWindowTreeHostWin::CanResize() const {
@@ -626,7 +632,7 @@ bool DesktopWindowTreeHostWin::CanActivate() const {
}
bool DesktopWindowTreeHostWin::WantsMouseEventsWhenInactive() const {
- return false;
+ return wants_mouse_events_when_inactive_;
}
bool DesktopWindowTreeHostWin::WidgetSizeIsClientSize() const {
@@ -692,7 +698,7 @@ bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
}
void DesktopWindowTreeHostWin::HandleAppDeactivated() {
- native_widget_delegate_->EnableInactiveRendering();
+ native_widget_delegate_->SetAlwaysRenderAsActive(false);
}
void DesktopWindowTreeHostWin::HandleActivationChanged(bool active) {
@@ -911,9 +917,11 @@ void DesktopWindowTreeHostWin::HandleWindowSizeChanged() {
// changed (can occur on Windows 10 when snapping a window to the side of
// the screen). In that case do a resize to the current size to reenable
// swaps.
- if (compositor())
- compositor()->SetScaleAndSize(compositor()->device_scale_factor(),
- compositor()->size());
+ if (compositor()) {
+ compositor()->SetScaleAndSize(
+ compositor()->device_scale_factor(),
+ message_handler_->GetClientAreaBounds().size());
+ }
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index ad82485eb0c..3465112eac0 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -126,11 +126,12 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void OnWindowHidingAnimationCompleted() override;
// Overridden from HWNDMessageHandlerDelegate:
- bool IsWidgetWindow() const override;
- bool IsUsingCustomFrame() const override;
+ bool HasNonClientView() const override;
+ FrameMode GetFrameMode() const override;
+ bool HasFrame() const override;
void SchedulePaint() override;
- void EnableInactiveRendering() override;
- bool IsInactiveRenderingDisabled() override;
+ void SetAlwaysRenderAsActive(bool always_render_as_active) override;
+ bool IsAlwaysRenderAsActive() override;
bool CanResize() const override;
bool CanMaximize() const override;
bool CanMinimize() const override;
@@ -244,6 +245,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
// Init time, before the Widget has created the NonClientView.
bool has_non_client_view_;
+ // True if the window should have the frame removed.
+ bool remove_standard_frame_;
+
// Owned by TooltipController, but we need to forward events to it so we keep
// a reference.
corewm::TooltipWin* tooltip_;
@@ -256,6 +260,10 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
scoped_ptr<aura::client::ScopedTooltipDisabler> tooltip_disabler_;
+ // Indicates if current window will receive mouse events when should not
+ // become activated.
+ bool wants_mouse_events_when_inactive_ = false;
+
DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostWin);
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index e2fb724b914..cecae1ee81d 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -109,7 +109,7 @@ const char* kAtomsToCache[] = {
"_NET_WM_WINDOW_TYPE_NOTIFICATION",
"_NET_WM_WINDOW_TYPE_TOOLTIP",
"XdndActionAsk",
- "XdndActionCopy"
+ "XdndActionCopy",
"XdndActionLink",
"XdndActionList",
"XdndActionMove",
@@ -820,7 +820,7 @@ void DesktopWindowTreeHostX11::SetFullscreen(bool fullscreen) {
if (fullscreen) {
restored_bounds_in_pixels_ = bounds_in_pixels_;
const gfx::Display display =
- gfx::Screen::GetScreenFor(NULL)->GetDisplayNearestWindow(window());
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(window());
bounds_in_pixels_ = ToPixelRect(display.bounds());
} else {
bounds_in_pixels_ = restored_bounds_in_pixels_;
@@ -938,10 +938,10 @@ void DesktopWindowTreeHostX11::SizeConstraintsChanged() {
// DesktopWindowTreeHostX11, aura::WindowTreeHost implementation:
gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const {
- gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
+ gfx::Display display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
if (window_mapped_) {
aura::Window* win = const_cast<aura::Window*>(window());
- display = gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(win);
+ display = gfx::Screen::GetScreen()->GetDisplayNearestWindow(win);
}
float scale = display.device_scale_factor();
@@ -1287,7 +1287,7 @@ void DesktopWindowTreeHostX11::InitX11Window(
gfx::Size DesktopWindowTreeHostX11::AdjustSize(
const gfx::Size& requested_size_in_pixels) {
std::vector<gfx::Display> displays =
- gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE)->GetAllDisplays();
+ gfx::Screen::GetScreen()->GetAllDisplays();
// Compare against all monitor sizes. The window manager can move the window
// to whichever monitor it wants.
for (size_t i = 0; i < displays.size(); ++i) {
@@ -1533,9 +1533,9 @@ void DesktopWindowTreeHostX11::ConvertEventToDifferentHost(
DesktopWindowTreeHostX11* host) {
DCHECK_NE(this, host);
const gfx::Display display_src =
- gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(window());
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(window());
const gfx::Display display_dest =
- gfx::Screen::GetNativeScreen()->GetDisplayNearestWindow(host->window());
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(host->window());
DCHECK_EQ(display_src.device_scale_factor(),
display_dest.device_scale_factor());
gfx::Vector2d offset = GetLocationOnNativeScreen() -
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 759194f6b52..7e842fed086 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -36,7 +36,6 @@ class EventHandler;
namespace views {
class DesktopDragDropClientAuraX11;
-class DesktopDispatcherClient;
class DesktopWindowTreeHostObserverX11;
class X11DesktopWindowMoveClient;
class X11WindowEventFilter;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index 162cf3c49a3..7c2253493ac 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -24,7 +24,7 @@
#include "ui/base/hit_test.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
-#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/events/platform/x11/x11_event_source_glib.h"
#include "ui/events/test/platform_event_source_test_api.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
@@ -68,11 +68,9 @@ class WMStateWaiter : public X11PropertyChangeWaiter {
bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
std::vector<Atom> hints;
if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) {
- std::vector<Atom>::iterator it = std::find(
- hints.begin(),
- hints.end(),
- atom_cache_->GetAtom(hint_));
- bool hint_set = (it != hints.end());
+ auto it = std::find(hints.cbegin(), hints.cend(),
+ atom_cache_->GetAtom(hint_));
+ bool hint_set = (it != hints.cend());
return hint_set != wait_till_set_;
}
return true;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
index f5343ad5a2b..46357f60f00 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -55,11 +55,9 @@ class MinimizeWaiter : public X11PropertyChangeWaiter {
bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
std::vector<Atom> wm_states;
if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &wm_states)) {
- std::vector<Atom>::iterator it = std::find(
- wm_states.begin(),
- wm_states.end(),
- atom_cache_->GetAtom("_NET_WM_STATE_HIDDEN"));
- return it == wm_states.end();
+ auto it = std::find(wm_states.cbegin(), wm_states.cend(),
+ atom_cache_->GetAtom("_NET_WM_STATE_HIDDEN"));
+ return it == wm_states.cend();
}
return true;
}
@@ -97,9 +95,8 @@ class StackingClientListWaiter : public X11PropertyChangeWaiter {
std::vector<XID> stack;
ui::GetXWindowStack(ui::GetX11RootWindow(), &stack);
for (size_t i = 0; i < expected_windows_.size(); ++i) {
- std::vector<XID>::iterator it = std::find(
- stack.begin(), stack.end(), expected_windows_[i]);
- if (it == stack.end())
+ auto it = std::find(stack.cbegin(), stack.cend(), expected_windows_[i]);
+ if (it == stack.cend())
return true;
}
return false;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index a33f12ff76e..eca9951d2da 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -22,6 +22,7 @@
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
+#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/scoped_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/views/widget/desktop_aura/x11_pointer_grab.h"
@@ -81,7 +82,7 @@ uint32_t X11WholeScreenMoveLoop::DispatchEvent(const ui::PlatformEvent& event) {
case ui::ET_MOUSE_DRAGGED: {
bool dispatch_mouse_event = !last_motion_in_screen_.get();
last_motion_in_screen_.reset(
- static_cast<ui::MouseEvent*>(ui::EventFromNative(xev).release()));
+ ui::EventFromNative(xev).release()->AsMouseEvent());
last_motion_in_screen_->set_location(
ui::EventSystemLocationFromNative(xev));
if (dispatch_mouse_event) {
diff --git a/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc b/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
index c8f1065d31e..c0ead5563fd 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
@@ -151,9 +151,8 @@ void X11WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) {
if (!widget)
return;
- gfx::Screen* screen = gfx::Screen::GetNativeScreen();
gfx::Rect display_work_area =
- screen->GetDisplayNearestWindow(target).work_area();
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area();
gfx::Rect bounds = widget->GetWindowBoundsInScreen();
if (event->IsMiddleMouseButton()) {
bounds.set_y(display_work_area.y());
diff --git a/chromium/ui/views/widget/desktop_widget_unittest.cc b/chromium/ui/views/widget/desktop_widget_unittest.cc
index 6bd67c6ee4a..0004ccab265 100644
--- a/chromium/ui/views/widget/desktop_widget_unittest.cc
+++ b/chromium/ui/views/widget/desktop_widget_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/widget.h"
@@ -18,7 +19,8 @@ TEST_F(DesktopScreenPositionClientTest, PositionDialog) {
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.bounds = gfx::Rect(10, 11, 200, 200);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.native_widget = new PlatformDesktopNativeWidget(&parent_widget);
+ params.native_widget = test::CreatePlatformDesktopNativeWidgetImpl(
+ params, &parent_widget, nullptr);
parent_widget.Init(params);
// Owned by |dialog|.
@@ -52,7 +54,8 @@ TEST_F(DesktopScreenPositionClientTest, PositionControlWithNonRootParent) {
CreateParams(Widget::InitParams::TYPE_WINDOW);
params1.bounds = gfx::Rect(origin, gfx::Size(700, 600));
params1.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params1.native_widget = new PlatformDesktopNativeWidget(&widget1);
+ params1.native_widget =
+ test::CreatePlatformDesktopNativeWidgetImpl(params1, &widget1, nullptr);
widget1.Init(params1);
Widget::InitParams params2 =
diff --git a/chromium/ui/views/widget/native_widget_aura.cc b/chromium/ui/views/widget/native_widget_aura.cc
index fb2396c8399..4f24e5caced 100644
--- a/chromium/ui/views/widget/native_widget_aura.cc
+++ b/chromium/ui/views/widget/native_widget_aura.cc
@@ -137,8 +137,8 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
// If a parent is specified but no bounds are given,
// use the origin of the parent's display so that the widget
// will be added to the same display as the parent.
- gfx::Rect bounds = gfx::Screen::GetScreenFor(parent)->
- GetDisplayNearestWindow(parent).bounds();
+ gfx::Rect bounds =
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(parent).bounds();
window_bounds.set_origin(bounds.origin());
}
}
@@ -283,8 +283,8 @@ void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
// When centering window, we take the intersection of the host and
// the parent. We assume the root window represents the visible
// rect of a single screen.
- gfx::Rect work_area = gfx::Screen::GetScreenFor(window_)->
- GetDisplayNearestWindow(window_).work_area();
+ gfx::Rect work_area =
+ gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_).work_area();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(window_->GetRootWindow());
@@ -404,7 +404,7 @@ void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
aura::client::GetScreenPositionClient(root);
if (screen_position_client) {
gfx::Display dst_display =
- gfx::Screen::GetScreenFor(window_)->GetDisplayMatching(bounds);
+ gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
screen_position_client->SetBounds(window_, bounds, dst_display);
return;
}
@@ -495,7 +495,10 @@ void NativeWidgetAura::ShowWithWindowState(ui::WindowShowState state) {
// SetInitialFocus() should be always be called, even for
// SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will
// do the right thing.
- SetInitialFocus(state);
+ // Activate() might fail if the window is non-activatable. In this case, we
+ // should pass SHOW_STATE_INACTIVE to SetInitialFocus() to stop the initial
+ // focused view from getting focused. See crbug.com/515594 for example.
+ SetInitialFocus(IsActive() ? state : ui::SHOW_STATE_INACTIVE);
}
// On desktop aura, a window is activated first even when it is shown as
@@ -595,10 +598,6 @@ void NativeWidgetAura::SetOpacity(unsigned char opacity) {
window_->layer()->SetOpacity(opacity / 255.0);
}
-void NativeWidgetAura::SetUseDragFrame(bool use_drag_frame) {
- NOTIMPLEMENTED();
-}
-
void NativeWidgetAura::FlashFrame(bool flash) {
if (window_)
window_->SetProperty(aura::client::kDrawAttentionKey, flash);
@@ -643,8 +642,7 @@ void NativeWidgetAura::ClearNativeFocus() {
gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
if (!window_)
return gfx::Rect();
- return gfx::Screen::GetScreenFor(window_)->
- GetDisplayNearestWindow(window_).work_area();
+ return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_).work_area();
}
Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
@@ -875,7 +873,6 @@ void NativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) {
return;
delegate_->OnKeyEvent(event);
- event->SetHandled();
}
void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) {
diff --git a/chromium/ui/views/widget/native_widget_aura.h b/chromium/ui/views/widget/native_widget_aura.h
index 30bf169c784..9e27cca806b 100644
--- a/chromium/ui/views/widget/native_widget_aura.h
+++ b/chromium/ui/views/widget/native_widget_aura.h
@@ -42,8 +42,8 @@ class VIEWS_EXPORT NativeWidgetAura
public:
explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate);
- // Called internally by NativeWidget implementations to associate
- // |native_widget| with |window|.
+ // Called internally by NativeWidgetAura and DesktopNativeWidgetAura to
+ // associate |native_widget| with |window|.
static void RegisterNativeWidgetForWindow(
internal::NativeWidgetPrivate* native_widget,
aura::Window* window);
@@ -108,7 +108,6 @@ class VIEWS_EXPORT NativeWidgetAura
void SetFullscreen(bool fullscreen) override;
bool IsFullscreen() const override;
void SetOpacity(unsigned char opacity) override;
- void SetUseDragFrame(bool use_drag_frame) override;
void FlashFrame(bool flash_frame) override;
void RunShellDrag(View* view,
const ui::OSExchangeData& data,
diff --git a/chromium/ui/views/widget/native_widget_aura_unittest.cc b/chromium/ui/views/widget/native_widget_aura_unittest.cc
index f10981f2327..0a626ae45a1 100644
--- a/chromium/ui/views/widget/native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/native_widget_aura_unittest.cc
@@ -19,9 +19,12 @@
#include "ui/events/event_utils.h"
#include "ui/gfx/screen.h"
#include "ui/views/layout/fill_layout.h"
+#include "ui/views/test/widget_test.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget_delegate.h"
+#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/default_activation_client.h"
+#include "ui/wm/core/focus_controller.h"
namespace views {
namespace {
@@ -34,19 +37,50 @@ NativeWidgetAura* Init(aura::Window* parent, Widget* widget) {
return static_cast<NativeWidgetAura*>(widget->native_widget());
}
+// TestFocusRules is intended to provide a way to manually set a window's
+// activatability so that the focus rules can be tested.
+class TestFocusRules : public wm::BaseFocusRules {
+ public:
+ TestFocusRules() {}
+ ~TestFocusRules() override {}
+
+ void set_can_activate(bool can_activate) { can_activate_ = can_activate; }
+
+ // wm::BaseFocusRules overrides:
+ bool SupportsChildActivation(aura::Window* window) const override {
+ return true;
+ }
+
+ bool CanActivateWindow(aura::Window* window) const override {
+ return can_activate_;
+ }
+
+ private:
+ bool can_activate_ = true;
+
+ DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
+};
+
class NativeWidgetAuraTest : public aura::test::AuraTestBase {
public:
NativeWidgetAuraTest() {}
~NativeWidgetAuraTest() override {}
+ TestFocusRules* test_focus_rules() { return test_focus_rules_; }
+
// testing::Test overrides:
void SetUp() override {
AuraTestBase::SetUp();
- new wm::DefaultActivationClient(root_window());
+ test_focus_rules_ = new TestFocusRules;
+ focus_controller_.reset(new wm::FocusController(test_focus_rules_));
+ aura::client::SetActivationClient(root_window(), focus_controller_.get());
host()->SetBounds(gfx::Rect(640, 480));
}
private:
+ scoped_ptr<wm::FocusController> focus_controller_;
+ TestFocusRules* test_focus_rules_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetAuraTest);
};
@@ -485,5 +519,20 @@ TEST_F(NativeWidgetAuraTest, OnWidgetMovedInvokedAfterAcquireLayer) {
widget->CloseNow();
}
+// Tests that if a widget has a view which should be initially focused when the
+// widget is shown, this view should not get focused if the associated window
+// can not be activated.
+TEST_F(NativeWidgetAuraTest, PreventFocusOnNonActivableWindow) {
+ test_focus_rules()->set_can_activate(false);
+ views::test::TestInitialFocusWidgetDelegate delegate(root_window());
+ delegate.GetWidget()->Show();
+ EXPECT_FALSE(delegate.view()->HasFocus());
+
+ test_focus_rules()->set_can_activate(true);
+ views::test::TestInitialFocusWidgetDelegate delegate2(root_window());
+ delegate2.GetWidget()->Show();
+ EXPECT_TRUE(delegate2.view()->HasFocus());
+}
+
} // namespace
} // namespace views
diff --git a/chromium/ui/views/widget/native_widget_delegate.h b/chromium/ui/views/widget/native_widget_delegate.h
index 224972c2d12..033db2bf107 100644
--- a/chromium/ui/views/widget/native_widget_delegate.h
+++ b/chromium/ui/views/widget/native_widget_delegate.h
@@ -51,8 +51,12 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// Returns true if the window can be activated.
virtual bool CanActivate() const = 0;
- virtual bool IsInactiveRenderingDisabled() const = 0;
- virtual void EnableInactiveRendering() = 0;
+ // Prevents the window from being rendered as deactivated. This state is
+ // reset automatically as soon as the window becomes activated again. There is
+ // no ability to control the state through this API as this leads to sync
+ // problems.
+ virtual void SetAlwaysRenderAsActive(bool always_render_as_active) = 0;
+ virtual bool IsAlwaysRenderAsActive() const = 0;
// Called when the activation state of a window has changed.
virtual void OnNativeWidgetActivationChanged(bool active) = 0;
@@ -113,11 +117,10 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// |point|, in client coordinates.
virtual int GetNonClientComponent(const gfx::Point& point) = 0;
- // Mouse and key event handlers.
+ // Event handlers.
virtual void OnKeyEvent(ui::KeyEvent* event) = 0;
virtual void OnMouseEvent(ui::MouseEvent* event) = 0;
virtual void OnMouseCaptureLost() = 0;
-
virtual void OnScrollEvent(ui::ScrollEvent* event) = 0;
virtual void OnGestureEvent(ui::GestureEvent* event) = 0;
@@ -133,7 +136,6 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// Provides the hit-test mask if HasHitTestMask above returns true.
virtual void GetHitTestMask(gfx::Path* mask) const = 0;
- //
virtual Widget* AsWidget() = 0;
virtual const Widget* AsWidget() const = 0;
diff --git a/chromium/ui/views/widget/native_widget_mac.h b/chromium/ui/views/widget/native_widget_mac.h
index f2f79181a05..1b7deb2c801 100644
--- a/chromium/ui/views/widget/native_widget_mac.h
+++ b/chromium/ui/views/widget/native_widget_mac.h
@@ -107,7 +107,6 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
void SetFullscreen(bool fullscreen) override;
bool IsFullscreen() const override;
void SetOpacity(unsigned char opacity) override;
- void SetUseDragFrame(bool use_drag_frame) override;
void FlashFrame(bool flash_frame) override;
void RunShellDrag(View* view,
const ui::OSExchangeData& data,
diff --git a/chromium/ui/views/widget/native_widget_mac.mm b/chromium/ui/views/widget/native_widget_mac.mm
index f61ff8171a5..126623ff0e7 100644
--- a/chromium/ui/views/widget/native_widget_mac.mm
+++ b/chromium/ui/views/widget/native_widget_mac.mm
@@ -193,8 +193,10 @@ const ui::Layer* NativeWidgetMac::GetLayer() const {
}
void NativeWidgetMac::ReorderNativeViews() {
- if (bridge_)
+ if (bridge_) {
bridge_->SetRootView(GetWidget()->GetRootView());
+ bridge_->ReorderChildViews();
+ }
}
void NativeWidgetMac::ViewRemoved(View* view) {
@@ -410,6 +412,10 @@ void NativeWidgetMac::ShowWithWindowState(ui::WindowShowState state) {
bridge_->SetVisibilityState(state == ui::SHOW_STATE_INACTIVE
? BridgedNativeWidget::SHOW_INACTIVE
: BridgedNativeWidget::SHOW_AND_ACTIVATE_WINDOW);
+
+ // Ignore the SetInitialFocus() result. BridgedContentView should get
+ // firstResponder status regardless.
+ delegate_->SetInitialFocus(state);
}
bool NativeWidgetMac::IsVisible() const {
@@ -484,11 +490,7 @@ bool NativeWidgetMac::IsFullscreen() const {
}
void NativeWidgetMac::SetOpacity(unsigned char opacity) {
- NOTIMPLEMENTED();
-}
-
-void NativeWidgetMac::SetUseDragFrame(bool use_drag_frame) {
- NOTIMPLEMENTED();
+ [GetNativeWindow() setAlphaValue:opacity / 255.0];
}
void NativeWidgetMac::FlashFrame(bool flash_frame) {
@@ -504,9 +506,15 @@ void NativeWidgetMac::RunShellDrag(View* view,
}
void NativeWidgetMac::SchedulePaintInRect(const gfx::Rect& rect) {
- // TODO(tapted): This should use setNeedsDisplayInRect:, once the coordinate
- // system of |rect| has been converted.
- [GetNativeView() setNeedsDisplay:YES];
+ // |rect| is relative to client area of the window.
+ NSWindow* window = GetNativeWindow();
+ NSRect client_rect = [window contentRectForFrameRect:[window frame]];
+ NSRect target_rect = rect.ToCGRect();
+
+ // Convert to Appkit coordinate system (origin at bottom left).
+ target_rect.origin.y =
+ NSHeight(client_rect) - target_rect.origin.y - NSHeight(target_rect);
+ [GetNativeView() setNeedsDisplayInRect:target_rect];
if (bridge_ && bridge_->layer())
bridge_->layer()->SchedulePaint(rect);
}
diff --git a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
index 8f192662b24..528f67d42a7 100644
--- a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
@@ -6,8 +6,10 @@
#import <Cocoa/Cocoa.h>
+#import "base/mac/mac_util.h"
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
+#include "ui/base/test/ui_controls.h"
#import "ui/base/test/windowed_nsnotification_observer.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/widget_test.h"
@@ -24,7 +26,11 @@ class NativeWidgetMacInteractiveUITest
class Observer;
NativeWidgetMacInteractiveUITest()
- : activationCount_(0), deactivationCount_(0) {}
+ : activationCount_(0), deactivationCount_(0) {
+ // TODO(tapted): Remove this when these are absorbed into Chrome's
+ // interactive_ui_tests target. See http://crbug.com/403679.
+ ui_controls::EnableUIControls();
+ }
Widget* MakeWidget() {
return GetParam() ? CreateTopLevelFramelessPlatformWidget()
@@ -133,6 +139,79 @@ TEST_P(NativeWidgetMacInteractiveUITest, ShowInactiveIgnoresKeyStatus) {
widget->CloseNow();
}
+namespace {
+
+// Show |widget| and wait for it to become the key window.
+void ShowKeyWindow(Widget* widget) {
+ base::scoped_nsobject<WindowedNSNotificationObserver> waiter(
+ [[WindowedNSNotificationObserver alloc]
+ initForNotification:NSWindowDidBecomeKeyNotification
+ object:widget->GetNativeWindow()]);
+ widget->Show();
+ EXPECT_TRUE([waiter wait]);
+ EXPECT_TRUE([widget->GetNativeWindow() isKeyWindow]);
+}
+
+NSData* ViewAsTIFF(NSView* view) {
+ NSBitmapImageRep* bitmap =
+ [view bitmapImageRepForCachingDisplayInRect:[view bounds]];
+ [view cacheDisplayInRect:[view bounds] toBitmapImageRep:bitmap];
+ return [bitmap TIFFRepresentation];
+}
+
+} // namespace
+
+// Test that parent windows keep their traffic lights enabled when showing
+// dialogs.
+TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
+ Widget* parent_widget = CreateTopLevelPlatformWidget();
+ parent_widget->SetBounds(gfx::Rect(100, 100, 100, 100));
+ ShowKeyWindow(parent_widget);
+
+ NSWindow* parent = parent_widget->GetNativeWindow();
+ EXPECT_TRUE([parent isMainWindow]);
+
+ NSButton* button = [parent standardWindowButton:NSWindowCloseButton];
+ EXPECT_TRUE(button);
+ NSData* active_button_image = ViewAsTIFF(button);
+ EXPECT_TRUE(active_button_image);
+
+ // Create an activatable frameless child. Frameless so that it doesn't have
+ // traffic lights of its own, and activatable so that it can take key status.
+ Widget* child_widget = new Widget;
+ Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.native_widget = new NativeWidgetMac(child_widget);
+ params.bounds = gfx::Rect(130, 130, 100, 100);
+ params.parent = parent_widget->GetNativeView();
+ child_widget->Init(params);
+ ShowKeyWindow(child_widget);
+
+ // Ensure the button instance is still valid.
+ EXPECT_EQ(button, [parent standardWindowButton:NSWindowCloseButton]);
+
+ // Parent window should still be main, and have its traffic lights active.
+ EXPECT_TRUE([parent isMainWindow]);
+ EXPECT_FALSE([parent isKeyWindow]);
+
+ // Enabled status doesn't actually change, but check anyway.
+ EXPECT_TRUE([button isEnabled]);
+ NSData* button_image_with_child = ViewAsTIFF(button);
+ EXPECT_TRUE([active_button_image isEqualToData:button_image_with_child]);
+
+ // Verify that activating some other random window does change the button.
+ Widget* other_widget = CreateTopLevelPlatformWidget();
+ other_widget->SetBounds(gfx::Rect(200, 200, 100, 100));
+ ShowKeyWindow(other_widget);
+ EXPECT_FALSE([parent isMainWindow]);
+ EXPECT_FALSE([parent isKeyWindow]);
+ EXPECT_TRUE([button isEnabled]);
+ NSData* inactive_button_image = ViewAsTIFF(button);
+ EXPECT_FALSE([active_button_image isEqualToData:inactive_button_image]);
+
+ other_widget->CloseNow();
+ parent_widget->CloseNow();
+}
+
INSTANTIATE_TEST_CASE_P(NativeWidgetMacInteractiveUITestInstance,
NativeWidgetMacInteractiveUITest,
::testing::Bool());
diff --git a/chromium/ui/views/widget/native_widget_mac_unittest.mm b/chromium/ui/views/widget/native_widget_mac_unittest.mm
index 5a48f025722..ba095dfbeeb 100644
--- a/chromium/ui/views/widget/native_widget_mac_unittest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_unittest.mm
@@ -22,13 +22,17 @@
#import "ui/events/test/cocoa_test_event_utils.h"
#include "ui/events/test/event_generator.h"
#import "ui/gfx/mac/coordinate_conversion.h"
+#include "ui/views/bubble/bubble_delegate.h"
#import "ui/views/cocoa/bridged_native_widget.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/label.h"
+#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/native_cursor.h"
+#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/widget_test.h"
+#include "ui/views/widget/native_widget_mac.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/window/dialog_delegate.h"
@@ -53,6 +57,24 @@
@property(readonly, nonatomic) int invalidateShadowCount;
@end
+// Used to mock BridgedContentView so that calls to drawRect: can be
+// intercepted.
+@interface MockBridgedView : NSView {
+ @private
+ // Number of times -[NSView drawRect:] has been called.
+ NSUInteger drawRectCount_;
+
+ // The dirtyRect parameter passed to last invocation of drawRect:.
+ NSRect lastDirtyRect_;
+}
+
+@property(assign, nonatomic) NSUInteger drawRectCount;
+@property(assign, nonatomic) NSRect lastDirtyRect;
+@end
+
+@interface FocusableTestNSView : NSView
+@end
+
namespace views {
namespace test {
@@ -190,6 +212,30 @@ class WidgetChangeObserver : public TestWidgetObserver {
DISALLOW_COPY_AND_ASSIGN(WidgetChangeObserver);
};
+class NativeHostHolder {
+ public:
+ NativeHostHolder()
+ : view_([[NSView alloc] init]), host_(new NativeViewHost()) {
+ host_->set_owned_by_client();
+ }
+
+ void AttachNativeView() {
+ DCHECK(!host_->native_view());
+ host_->Attach(view_.get());
+ }
+
+ void Detach() { host_->Detach(); }
+
+ gfx::NativeView view() const { return view_.get(); }
+ NativeViewHost* host() const { return host_.get(); }
+
+ private:
+ base::scoped_nsobject<NSView> view_;
+ scoped_ptr<NativeViewHost> host_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeHostHolder);
+};
+
// Test visibility states triggered externally.
TEST_F(NativeWidgetMacTest, HideAndShowExternally) {
Widget* widget = CreateTopLevelPlatformWidget();
@@ -468,8 +514,9 @@ TEST_F(NativeWidgetMacTest, SetCursor) {
EXPECT_NE(arrow, hand);
EXPECT_NE(arrow, ibeam);
- // At the start of the test, the cursor stack should be empty.
- EXPECT_FALSE([NSCursor currentCursor]);
+ // Make arrow the current cursor.
+ [arrow set];
+ EXPECT_EQ(arrow, [NSCursor currentCursor]);
// Use an event generator to ask views code to set the cursor. However, note
// that this does not cause Cocoa to generate tracking rectangle updates.
@@ -477,7 +524,7 @@ TEST_F(NativeWidgetMacTest, SetCursor) {
widget->GetNativeWindow());
// Move the mouse over the first view, then simulate a tracking rectangle
- // update.
+ // update. Verify that the cursor changed from arrow to hand type.
event_generator.MoveMouseTo(gfx::Point(50, 50));
[widget->GetNativeWindow() cursorUpdate:event_in_content];
EXPECT_EQ(hand, [NSCursor currentCursor]);
@@ -534,12 +581,12 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
[[native_parent contentView] addSubview:anchor_view];
// Note: Don't use WidgetTest::CreateChildPlatformWidget because that makes
- // windows of TYPE_CONTROL which are automatically made visible. But still
- // mark it as a child to test window positioning.
+ // windows of TYPE_CONTROL which need a parent Widget to obtain the focus
+ // manager.
Widget* child = new Widget;
Widget::InitParams init_params;
init_params.parent = anchor_view;
- init_params.child = true;
+ init_params.type = Widget::InitParams::TYPE_POPUP;
child->Init(init_params);
TestWidgetObserver child_observer(child);
@@ -556,7 +603,8 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
NativeWidgetMac::GetBridgeForNativeWindow(child->GetNativeWindow());
EXPECT_EQ(native_parent, bridged_native_widget->parent()->GetNSWindow());
- child->SetBounds(gfx::Rect(50, 50, 200, 100));
+ const gfx::Rect child_bounds(50, 50, 200, 100);
+ child->SetBounds(child_bounds);
EXPECT_FALSE(child->IsVisible());
EXPECT_EQ(0u, [[native_parent childWindows] count]);
@@ -567,11 +615,9 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
[[native_parent childWindows] objectAtIndex:0]);
EXPECT_EQ(native_parent, [child->GetNativeWindow() parentWindow]);
- // Child should be positioned on screen relative to the parent, but note we
- // positioned the parent in Cocoa coordinates, so we need to convert.
- gfx::Point parent_origin = gfx::ScreenRectFromNSRect(ParentRect()).origin();
- EXPECT_EQ(gfx::Rect(150, parent_origin.y() + 50, 200, 100),
- child->GetWindowBoundsInScreen());
+ // Only non-toplevel Widgets are positioned relative to the parent, so the
+ // bounds set above should be in screen coordinates.
+ EXPECT_EQ(child_bounds, child->GetWindowBoundsInScreen());
// Removing the anchor_view from its view hierarchy is permitted. This should
// not break the relationship between the two windows.
@@ -918,6 +964,96 @@ TEST_F(NativeWidgetMacTest, NoopReparentNativeView) {
parent_widget->CloseNow();
}
+// Attaches a child window to |parent| that checks its parent's delegate is
+// cleared when the child is destroyed. This assumes the child is destroyed via
+// destruction of its parent.
+class ParentCloseMonitor : public WidgetObserver {
+ public:
+ explicit ParentCloseMonitor(Widget* parent) {
+ Widget* child = new Widget();
+ child->AddObserver(this);
+ Widget::InitParams init_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ init_params.parent = parent->GetNativeView();
+ init_params.bounds = gfx::Rect(100, 100, 100, 100);
+ init_params.native_widget =
+ CreatePlatformNativeWidgetImpl(init_params, child, kStubCapture,
+ nullptr);
+ child->Init(init_params);
+ child->Show();
+
+ // NSWindow parent/child relationship should be established on Show() and
+ // the parent should have a delegate. Retain the parent since it can't be
+ // retrieved from the child while it is being destroyed.
+ parent_nswindow_.reset([[child->GetNativeWindow() parentWindow] retain]);
+ EXPECT_TRUE(parent_nswindow_);
+ EXPECT_TRUE([parent_nswindow_ delegate]);
+ }
+
+ ~ParentCloseMonitor() override {
+ EXPECT_TRUE(child_closed_); // Otherwise the observer wasn't removed.
+ }
+
+ void OnWidgetDestroying(Widget* child) override {
+ // Upon a parent-triggered close, the NSWindow relationship will already be
+ // removed. The parent should still be open (children are always closed
+ // first), but not have a delegate (since it is being torn down).
+ EXPECT_FALSE([child->GetNativeWindow() parentWindow]);
+ EXPECT_TRUE([parent_nswindow_ isVisible]);
+ EXPECT_FALSE([parent_nswindow_ delegate]);
+
+ EXPECT_FALSE(child_closed_);
+ child->RemoveObserver(this);
+ child_closed_ = true;
+ }
+
+ bool child_closed() const { return child_closed_; }
+
+ private:
+ base::scoped_nsobject<NSWindow> parent_nswindow_;
+ bool child_closed_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(ParentCloseMonitor);
+};
+
+// Ensures when a parent window is destroyed, and triggers its child windows to
+// be closed, that the child windows (via AppKit) do not attempt to call back
+// into the parent, whilst it's in the process of being destroyed.
+TEST_F(NativeWidgetMacTest, NoParentDelegateDuringTeardown) {
+ // First test "normal" windows and AppKit close.
+ {
+ Widget* parent = CreateTopLevelPlatformWidget();
+ parent->SetBounds(gfx::Rect(100, 100, 300, 200));
+ parent->Show();
+ ParentCloseMonitor monitor(parent);
+ [parent->GetNativeWindow() close];
+ EXPECT_TRUE(monitor.child_closed());
+ }
+
+ // Test the Widget::CloseNow() flow.
+ {
+ Widget* parent = CreateTopLevelPlatformWidget();
+ parent->SetBounds(gfx::Rect(100, 100, 300, 200));
+ parent->Show();
+ ParentCloseMonitor monitor(parent);
+ parent->CloseNow();
+ EXPECT_TRUE(monitor.child_closed());
+ }
+
+ // Test the WIDGET_OWNS_NATIVE_WIDGET flow.
+ {
+ scoped_ptr<Widget> parent(new Widget);
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.bounds = gfx::Rect(100, 100, 300, 200);
+ parent->Init(params);
+ parent->Show();
+
+ ParentCloseMonitor monitor(parent.get());
+ parent.reset();
+ EXPECT_TRUE(monitor.child_closed());
+ }
+}
+
// Tests Cocoa properties that should be given to particular widget types.
TEST_F(NativeWidgetMacTest, NativeProperties) {
// Create a regular widget (TYPE_WINDOW).
@@ -938,6 +1074,20 @@ TEST_F(NativeWidgetMacTest, NativeProperties) {
// Dialogs shouldn't take main status away from their parent.
EXPECT_FALSE([dialog_widget->GetNativeWindow() canBecomeMainWindow]);
+ // Create a bubble widget with a parent: also shouldn't get main.
+ BubbleDelegateView* bubble_view = new BubbleDelegateView();
+ bubble_view->set_parent_window(regular_widget->GetNativeView());
+ Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_view);
+ EXPECT_TRUE([bubble_widget->GetNativeWindow() canBecomeKeyWindow]);
+ EXPECT_FALSE([bubble_widget->GetNativeWindow() canBecomeMainWindow]);
+
+ // But a bubble without a parent should still be able to become main.
+ Widget* toplevel_bubble_widget =
+ BubbleDelegateView::CreateBubble(new BubbleDelegateView());
+ EXPECT_TRUE([toplevel_bubble_widget->GetNativeWindow() canBecomeKeyWindow]);
+ EXPECT_TRUE([toplevel_bubble_widget->GetNativeWindow() canBecomeMainWindow]);
+
+ toplevel_bubble_widget->CloseNow();
regular_widget->CloseNow();
}
@@ -991,7 +1141,8 @@ TEST_F(NativeWidgetMacTest, DoesHideTitle) {
// Same as CreateTopLevelPlatformWidget but with a custom delegate.
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
Widget* widget = new Widget;
- params.native_widget = new NativeWidgetCapture(widget);
+ params.native_widget =
+ CreatePlatformNativeWidgetImpl(params, widget, kStubCapture, nullptr);
CustomTitleWidgetDelegate delegate(widget);
params.delegate = &delegate;
params.bounds = gfx::Rect(0, 0, 800, 600);
@@ -1089,6 +1240,235 @@ TEST_F(NativeWidgetMacTest, GetWorkAreaBoundsInScreen) {
EXPECT_TRUE(NSIsEmptyRect(actual));
}
+// Test that Widget opacity can be changed.
+TEST_F(NativeWidgetMacTest, ChangeOpacity) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+ NSWindow* ns_window = widget->GetNativeWindow();
+
+ CGFloat old_opacity = [ns_window alphaValue];
+ widget->SetOpacity(0xAA);
+ EXPECT_NE(old_opacity, [ns_window alphaValue]);
+ EXPECT_DOUBLE_EQ(0xAA / 255.0, [ns_window alphaValue]);
+
+ widget->CloseNow();
+}
+
+// Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect
+// parameter to BridgedContentView::drawRect, for a titled window (window with a
+// toolbar).
+TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Titled) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+
+ gfx::Rect screen_rect(50, 50, 100, 100);
+ widget->SetBounds(screen_rect);
+
+ // Setup the mock content view for the NSWindow, so that we can intercept
+ // drawRect.
+ NSWindow* window = widget->GetNativeWindow();
+ base::scoped_nsobject<MockBridgedView> mock_bridged_view(
+ [[MockBridgedView alloc] init]);
+ [window setContentView:mock_bridged_view];
+
+ // Ensure the initial draw of the window is done.
+ base::RunLoop().RunUntilIdle();
+
+ // Add a dummy view to the widget. This will cause SchedulePaint to be called
+ // on the dummy view.
+ View* dummy_view = new View();
+ gfx::Rect dummy_bounds(25, 30, 10, 15);
+ dummy_view->SetBoundsRect(dummy_bounds);
+ // Reset drawRect count.
+ [mock_bridged_view setDrawRectCount:0];
+ widget->GetContentsView()->AddChildView(dummy_view);
+
+ // SchedulePaint is asyncronous. Wait for drawRect: to be called.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1u, [mock_bridged_view drawRectCount]);
+ int client_area_height = widget->GetClientAreaBoundsInScreen().height();
+ // These are expected dummy_view bounds in AppKit coordinate system. The y
+ // coordinate of rect origin is calculated as:
+ // client_area_height - 30 (dummy_view's y coordinate) - 15 (dummy view's
+ // height).
+ gfx::Rect expected_appkit_bounds(25, client_area_height - 45, 10, 15);
+ EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(),
+ [mock_bridged_view lastDirtyRect]);
+ widget->CloseNow();
+}
+
+// Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect
+// parameter to BridgedContentView::drawRect, for a borderless window.
+TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Borderless) {
+ Widget* widget = CreateTopLevelFramelessPlatformWidget();
+
+ gfx::Rect screen_rect(50, 50, 100, 100);
+ widget->SetBounds(screen_rect);
+
+ // Setup the mock content view for the NSWindow, so that we can intercept
+ // drawRect.
+ NSWindow* window = widget->GetNativeWindow();
+ base::scoped_nsobject<MockBridgedView> mock_bridged_view(
+ [[MockBridgedView alloc] init]);
+ [window setContentView:mock_bridged_view];
+
+ // Ensure the initial draw of the window is done.
+ base::RunLoop().RunUntilIdle();
+
+ // Add a dummy view to the widget. This will cause SchedulePaint to be called
+ // on the dummy view.
+ View* dummy_view = new View();
+ gfx::Rect dummy_bounds(25, 30, 10, 15);
+ dummy_view->SetBoundsRect(dummy_bounds);
+ // Reset drawRect count.
+ [mock_bridged_view setDrawRectCount:0];
+ widget->GetRootView()->AddChildView(dummy_view);
+
+ // SchedulePaint is asyncronous. Wait for drawRect: to be called.
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(1u, [mock_bridged_view drawRectCount]);
+ // These are expected dummy_view bounds in AppKit coordinate system. The y
+ // coordinate of rect origin is calculated as:
+ // 100(client area height) - 30 (dummy_view's y coordinate) - 15 (dummy view's
+ // height).
+ gfx::Rect expected_appkit_bounds(25, 55, 10, 15);
+ EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(),
+ [mock_bridged_view lastDirtyRect]);
+ widget->CloseNow();
+}
+
+// Ensure traversing NSView focus correctly updates the views::FocusManager.
+TEST_F(NativeWidgetMacTest, ChangeFocusOnChangeFirstResponder) {
+ Widget* widget = CreateTopLevelPlatformWidget();
+ widget->GetRootView()->SetFocusable(true);
+ widget->Show();
+
+ base::scoped_nsobject<NSView> child_view([[FocusableTestNSView alloc]
+ initWithFrame:[widget->GetNativeView() bounds]]);
+ [widget->GetNativeView() addSubview:child_view];
+ EXPECT_TRUE([child_view acceptsFirstResponder]);
+ EXPECT_TRUE(widget->GetRootView()->IsFocusable());
+
+ FocusManager* manager = widget->GetFocusManager();
+ manager->SetFocusedView(widget->GetRootView());
+ EXPECT_EQ(manager->GetFocusedView(), widget->GetRootView());
+
+ [widget->GetNativeWindow() makeFirstResponder:child_view];
+ EXPECT_FALSE(manager->GetFocusedView());
+
+ [widget->GetNativeWindow() makeFirstResponder:widget->GetNativeView()];
+ EXPECT_EQ(manager->GetFocusedView(), widget->GetRootView());
+
+ widget->CloseNow();
+}
+
+class NativeWidgetMacViewsOrderTest : public WidgetTest {
+ public:
+ NativeWidgetMacViewsOrderTest() {}
+
+ protected:
+ // testing::Test:
+ void SetUp() override {
+ WidgetTest::SetUp();
+
+ widget_ = CreateTopLevelPlatformWidget();
+
+ ASSERT_EQ(1u, [[widget_->GetNativeView() subviews] count]);
+ compositor_view_ = [[widget_->GetNativeView() subviews] firstObject];
+
+ native_host_parent_ = new View();
+ widget_->GetContentsView()->AddChildView(native_host_parent_);
+
+ const int kNativeViewCount = 3;
+ for (int i = 0; i < kNativeViewCount; ++i) {
+ scoped_ptr<NativeHostHolder> holder(new NativeHostHolder());
+ native_host_parent_->AddChildView(holder->host());
+ holder->AttachNativeView();
+ hosts_.push_back(std::move(holder));
+ }
+ EXPECT_EQ(kNativeViewCount, native_host_parent_->child_count());
+ EXPECT_TRUE(([[widget_->GetNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[1]->view(), hosts_[2]->view()
+ ]]));
+ }
+
+ void TearDown() override {
+ widget_->CloseNow();
+ WidgetTest::TearDown();
+ }
+
+ NSView* GetContentNativeView() { return widget_->GetNativeView(); }
+
+ Widget* widget_ = nullptr;
+ View* native_host_parent_ = nullptr;
+ NSView* compositor_view_ = nil;
+ std::vector<scoped_ptr<NativeHostHolder>> hosts_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NativeWidgetMacViewsOrderTest);
+};
+
+// Test that NativeViewHost::Attach()/Detach() method saves the NativeView
+// z-order.
+TEST_F(NativeWidgetMacViewsOrderTest, NativeViewAttached) {
+ hosts_[1]->Detach();
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[2]->view()
+ ]]));
+
+ hosts_[1]->AttachNativeView();
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
+ hosts_[2]->view()
+ ]]));
+}
+
+// Tests that NativeViews order changes according to views::View hierarchy.
+TEST_F(NativeWidgetMacViewsOrderTest, ReorderViews) {
+ native_host_parent_->ReorderChildView(hosts_[2]->host(), 1);
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[2]->view(),
+ hosts_[1]->view()
+ ]]));
+
+ native_host_parent_->RemoveChildView(hosts_[2]->host());
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[1]->view()
+ ]]));
+
+ View* new_parent = new View();
+ native_host_parent_->RemoveChildView(hosts_[1]->host());
+ native_host_parent_->AddChildView(new_parent);
+ new_parent->AddChildView(hosts_[1]->host());
+ new_parent->AddChildView(hosts_[2]->host());
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
+ hosts_[2]->view()
+ ]]));
+
+ native_host_parent_->ReorderChildView(new_parent, 0);
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[1]->view(), hosts_[2]->view(),
+ hosts_[0]->view()
+ ]]));
+}
+
+// Test that unassociated native views stay on top after reordering.
+TEST_F(NativeWidgetMacViewsOrderTest, UnassociatedViewsIsAbove) {
+ base::scoped_nsobject<NSView> child_view([[NSView alloc] init]);
+ [GetContentNativeView() addSubview:child_view];
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[1]->view(),
+ hosts_[2]->view(), child_view
+ ]]));
+
+ native_host_parent_->ReorderChildView(hosts_[2]->host(), 1);
+ EXPECT_TRUE(([[GetContentNativeView() subviews] isEqualToArray:@[
+ compositor_view_, hosts_[0]->view(), hosts_[2]->view(),
+ hosts_[1]->view(), child_view
+ ]]));
+}
+
} // namespace test
} // namespace views
@@ -1108,3 +1488,21 @@ TEST_F(NativeWidgetMacTest, GetWorkAreaBoundsInScreen) {
}
@end
+
+@implementation MockBridgedView
+
+@synthesize drawRectCount = drawRectCount_;
+@synthesize lastDirtyRect = lastDirtyRect_;
+
+- (void)drawRect:(NSRect)dirtyRect {
+ ++drawRectCount_;
+ lastDirtyRect_ = dirtyRect;
+}
+
+@end
+
+@implementation FocusableTestNSView
+- (BOOL)acceptsFirstResponder {
+ return YES;
+}
+@end
diff --git a/chromium/ui/views/widget/native_widget_private.h b/chromium/ui/views/widget/native_widget_private.h
index 6e52bf66749..777eaa226a4 100644
--- a/chromium/ui/views/widget/native_widget_private.h
+++ b/chromium/ui/views/widget/native_widget_private.h
@@ -194,7 +194,6 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
virtual void SetFullscreen(bool fullscreen) = 0;
virtual bool IsFullscreen() const = 0;
virtual void SetOpacity(unsigned char opacity) = 0;
- virtual void SetUseDragFrame(bool use_drag_frame) = 0;
virtual void FlashFrame(bool flash) = 0;
virtual void RunShellDrag(View* view,
const ui::OSExchangeData& data,
diff --git a/chromium/ui/views/widget/tooltip_manager.h b/chromium/ui/views/widget/tooltip_manager.h
index 4287fc53d6a..e8074047340 100644
--- a/chromium/ui/views/widget/tooltip_manager.h
+++ b/chromium/ui/views/widget/tooltip_manager.h
@@ -8,7 +8,6 @@
#include <string>
#include "base/strings/string16.h"
-#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
namespace gfx {
@@ -39,10 +38,8 @@ class VIEWS_EXPORT TooltipManager {
virtual ~TooltipManager() {}
// Returns the maximum width of the tooltip. |point| gives the location
- // the tooltip is to be displayed on in screen coordinates. |context| is
- // used to determine which gfx::Screen should be used.
- virtual int GetMaxWidth(const gfx::Point& location,
- gfx::NativeView context) const = 0;
+ // the tooltip is to be displayed on in screen coordinates.
+ virtual int GetMaxWidth(const gfx::Point& location) const = 0;
// Returns the font list used for tooltips.
virtual const gfx::FontList& GetFontList() const = 0;
diff --git a/chromium/ui/views/widget/tooltip_manager_aura.cc b/chromium/ui/views/widget/tooltip_manager_aura.cc
index 1c5bd26c32e..c4bf40ea856 100644
--- a/chromium/ui/views/widget/tooltip_manager_aura.cc
+++ b/chromium/ui/views/widget/tooltip_manager_aura.cc
@@ -49,7 +49,7 @@ void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) {
if (!screen_position_client)
return;
screen_position_client->ConvertPointToScreen(root_window, &screen_loc);
- gfx::Screen* screen = gfx::Screen::GetScreenFor(root_window);
+ gfx::Screen* screen = gfx::Screen::GetScreen();
aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
if (!target)
return;
@@ -81,10 +81,10 @@ const gfx::FontList& TooltipManagerAura::GetFontList() const {
return GetDefaultFontList();
}
-int TooltipManagerAura::GetMaxWidth(const gfx::Point& point,
- aura::Window* context) const {
- return aura::client::GetTooltipClient(context->GetRootWindow())->
- GetMaxWidth(point, context);
+int TooltipManagerAura::GetMaxWidth(const gfx::Point& point) const {
+ return aura::client::GetTooltipClient(
+ widget_->GetNativeView()->GetRootWindow())
+ ->GetMaxWidth(point);
}
void TooltipManagerAura::UpdateTooltip() {
diff --git a/chromium/ui/views/widget/tooltip_manager_aura.h b/chromium/ui/views/widget/tooltip_manager_aura.h
index 8d6bd9aff84..f429385525a 100644
--- a/chromium/ui/views/widget/tooltip_manager_aura.h
+++ b/chromium/ui/views/widget/tooltip_manager_aura.h
@@ -39,8 +39,7 @@ class TooltipManagerAura : public TooltipManager {
static const gfx::FontList& GetDefaultFontList();
// TooltipManager:
- int GetMaxWidth(const gfx::Point& location,
- aura::Window* context) const override;
+ int GetMaxWidth(const gfx::Point& location) const override;
const gfx::FontList& GetFontList() const override;
void UpdateTooltip() override;
void TooltipTextChanged(View* view) override;
diff --git a/chromium/ui/views/widget/widget.cc b/chromium/ui/views/widget/widget.cc
index 02a570db6da..ffafd0d2bbb 100644
--- a/chromium/ui/views/widget/widget.cc
+++ b/chromium/ui/views/widget/widget.cc
@@ -10,6 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "ui/base/cursor/cursor.h"
+#include "ui/base/default_style.h"
#include "ui/base/default_theme_provider.h"
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
@@ -110,30 +111,7 @@ class DefaultWidgetDelegate : public WidgetDelegate {
////////////////////////////////////////////////////////////////////////////////
// Widget, InitParams:
-Widget::InitParams::InitParams()
- : type(TYPE_WINDOW),
- delegate(nullptr),
- child(false),
- opacity(INFER_OPACITY),
- accept_events(true),
- activatable(ACTIVATABLE_DEFAULT),
- keep_on_top(false),
- visible_on_all_workspaces(false),
- ownership(NATIVE_WIDGET_OWNS_WIDGET),
- mirror_origin_in_rtl(false),
- shadow_type(SHADOW_TYPE_DEFAULT),
- remove_standard_frame(false),
- use_system_default_icon(false),
- show_state(ui::SHOW_STATE_DEFAULT),
- parent(nullptr),
- native_widget(nullptr),
- native_theme(nullptr),
- desktop_window_tree_host(nullptr),
- layer_type(ui::LAYER_TEXTURED),
- context(nullptr),
- force_show_in_taskbar(false),
- force_software_compositing(false) {
-}
+Widget::InitParams::InitParams() : InitParams(TYPE_WINDOW) {}
Widget::InitParams::InitParams(Type type)
: type(type),
@@ -152,7 +130,6 @@ Widget::InitParams::InitParams(Type type)
show_state(ui::SHOW_STATE_DEFAULT),
parent(nullptr),
native_widget(nullptr),
- native_theme(nullptr),
desktop_window_tree_host(nullptr),
layer_type(ui::LAYER_TEXTURED),
context(nullptr),
@@ -160,6 +137,8 @@ Widget::InitParams::InitParams(Type type)
force_software_compositing(false) {
}
+Widget::InitParams::InitParams(const InitParams& other) = default;
+
Widget::InitParams::~InitParams() {
}
@@ -168,14 +147,13 @@ Widget::InitParams::~InitParams() {
Widget::Widget()
: native_widget_(nullptr),
- native_theme_(nullptr),
widget_delegate_(nullptr),
non_client_view_(nullptr),
dragged_view_(nullptr),
ownership_(InitParams::NATIVE_WIDGET_OWNS_WIDGET),
is_secondary_widget_(true),
frame_type_(FRAME_TYPE_DEFAULT),
- disable_inactive_rendering_(false),
+ always_render_as_active_(false),
widget_closed_(false),
saved_show_state_(ui::SHOW_STATE_DEFAULT),
focus_on_creation_(true),
@@ -203,22 +181,6 @@ Widget::~Widget() {
}
// static
-Widget* Widget::CreateWindow(WidgetDelegate* delegate) {
- return CreateWindowWithBounds(delegate, gfx::Rect());
-}
-
-// static
-Widget* Widget::CreateWindowWithBounds(WidgetDelegate* delegate,
- const gfx::Rect& bounds) {
- Widget* widget = new Widget;
- Widget::InitParams params;
- params.bounds = bounds;
- params.delegate = delegate;
- widget->Init(params);
- return widget;
-}
-
-// static
Widget* Widget::CreateWindowWithParent(WidgetDelegate* delegate,
gfx::NativeView parent) {
return CreateWindowWithParentAndBounds(delegate, parent, gfx::Rect());
@@ -278,7 +240,6 @@ Widget* Widget::GetTopLevelWidgetForNativeView(gfx::NativeView native_view) {
return native_widget ? native_widget->GetWidget() : NULL;
}
-
// static
void Widget::GetAllChildWidgets(gfx::NativeView native_view,
Widgets* children) {
@@ -299,14 +260,16 @@ void Widget::ReparentNativeView(gfx::NativeView native_view,
// static
int Widget::GetLocalizedContentsWidth(int col_resource_id) {
- return ui::GetLocalizedContentsWidthForFont(col_resource_id,
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
+ return ui::GetLocalizedContentsWidthForFont(
+ col_resource_id, ResourceBundle::GetSharedInstance().GetFontWithDelta(
+ ui::kMessageFontSizeDelta));
}
// static
int Widget::GetLocalizedContentsHeight(int row_resource_id) {
- return ui::GetLocalizedContentsHeightForFont(row_resource_id,
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
+ return ui::GetLocalizedContentsHeightForFont(
+ row_resource_id, ResourceBundle::GetSharedInstance().GetFontWithDelta(
+ ui::kMessageFontSizeDelta));
}
// static
@@ -369,7 +332,6 @@ void Widget::Init(const InitParams& in_params) {
internal::NativeWidgetPrivate::IsMouseButtonDown();
}
native_widget_->InitNativeWidget(params);
- native_theme_ = params.native_theme;
if (RequiresNonClientView(params.type)) {
non_client_view_ = new NonClientView;
non_client_view_->SetFrameView(CreateNonClientFrameView());
@@ -532,9 +494,9 @@ void Widget::CenterWindow(const gfx::Size& size) {
}
void Widget::SetBoundsConstrained(const gfx::Rect& bounds) {
- gfx::Rect work_area =
- gfx::Screen::GetScreenFor(GetNativeView())->GetDisplayNearestPoint(
- bounds.origin()).work_area();
+ gfx::Rect work_area = gfx::Screen::GetScreen()
+ ->GetDisplayNearestPoint(bounds.origin())
+ .work_area();
if (work_area.IsEmpty()) {
SetBounds(bounds);
} else {
@@ -683,10 +645,6 @@ bool Widget::IsActive() const {
return native_widget_->IsActive();
}
-void Widget::DisableInactiveRendering() {
- SetInactiveRenderingDisabled(true);
-}
-
void Widget::SetAlwaysOnTop(bool on_top) {
native_widget_->SetAlwaysOnTop(on_top);
}
@@ -737,10 +695,6 @@ void Widget::SetOpacity(unsigned char opacity) {
native_widget_->SetOpacity(opacity);
}
-void Widget::SetUseDragFrame(bool use_drag_frame) {
- native_widget_->SetUseDragFrame(use_drag_frame);
-}
-
void Widget::FlashFrame(bool flash) {
native_widget_->FlashFrame(flash);
}
@@ -774,7 +728,7 @@ const ui::ThemeProvider* Widget::GetThemeProvider() const {
}
const ui::NativeTheme* Widget::GetNativeTheme() const {
- return native_theme_? native_theme_ : native_widget_->GetNativeTheme();
+ return native_widget_->GetNativeTheme();
}
FocusManager* Widget::GetFocusManager() {
@@ -1007,7 +961,7 @@ void Widget::SynthesizeMouseMoveEvent() {
// In screen coordinate.
gfx::Point mouse_location = EventMonitor::GetLastMouseLocation();
if (!GetWindowBoundsInScreen().Contains(mouse_location))
- return;
+ return;
// Convert: screen coordinate -> widget coordinate.
View::ConvertPointFromScreen(root_view_.get(), &mouse_location);
@@ -1031,8 +985,7 @@ void Widget::OnSizeConstraintsChanged() {
non_client_view_->SizeConstraintsChanged();
}
-void Widget::OnOwnerClosing() {
-}
+void Widget::OnOwnerClosing() {}
////////////////////////////////////////////////////////////////////////////////
// Widget, NativeWidgetDelegate implementation:
@@ -1049,12 +1002,8 @@ bool Widget::CanActivate() const {
return widget_delegate_->CanActivate();
}
-bool Widget::IsInactiveRenderingDisabled() const {
- return disable_inactive_rendering_;
-}
-
-void Widget::EnableInactiveRendering() {
- SetInactiveRenderingDisabled(false);
+bool Widget::IsAlwaysRenderAsActive() const {
+ return always_render_as_active_;
}
void Widget::OnNativeWidgetActivationChanged(bool active) {
@@ -1067,8 +1016,8 @@ void Widget::OnNativeWidgetActivationChanged(bool active) {
FOR_EACH_OBSERVER(WidgetObserver, observers_,
OnWidgetActivationChanged(this, active));
- if (IsVisible() && non_client_view())
- non_client_view()->frame_view()->SchedulePaint();
+ if (non_client_view())
+ non_client_view()->frame_view()->ActivationChanged(active);
}
void Widget::OnNativeFocus() {
@@ -1338,7 +1287,7 @@ bool Widget::SetInitialFocus(ui::WindowShowState show_state) {
show_state == ui::SHOW_STATE_MINIMIZED) {
// If not focusing the window now, tell the focus manager which view to
// focus when the window is restored.
- if (v)
+ if (v && focus_manager_.get())
focus_manager_->SetStoredFocusView(v);
return true;
}
@@ -1401,22 +1350,24 @@ void Widget::DestroyRootView() {
root_view_.reset();
}
-void Widget::OnDragWillStart() {
-}
+void Widget::OnDragWillStart() {}
-void Widget::OnDragComplete() {
-}
+void Widget::OnDragComplete() {}
////////////////////////////////////////////////////////////////////////////////
// Widget, private:
-void Widget::SetInactiveRenderingDisabled(bool value) {
- if (value == disable_inactive_rendering_)
+void Widget::SetAlwaysRenderAsActive(bool always_render_as_active) {
+ if (always_render_as_active_ == always_render_as_active)
return;
- disable_inactive_rendering_ = value;
- if (non_client_view_)
- non_client_view_->SetInactiveRenderingDisabled(value);
+ always_render_as_active_ = always_render_as_active;
+
+ // If active, the frame should already be painted. Otherwise,
+ // |always_render_as_active_| just changed, and the widget is inactive, so
+ // schedule a repaint.
+ if (non_client_view_ && !IsActive())
+ non_client_view_->frame_view()->SchedulePaint();
}
void Widget::SaveWindowPlacement() {
diff --git a/chromium/ui/views/widget/widget.h b/chromium/ui/views/widget/widget.h
index 80aaddee1a6..0ceaf825ffb 100644
--- a/chromium/ui/views/widget/widget.h
+++ b/chromium/ui/views/widget/widget.h
@@ -97,8 +97,8 @@ class RootView;
// The Widget instance owns its NativeWidget. This state implies someone
// else wants to control the lifetime of this object. When they destroy
// the Widget it is responsible for destroying the NativeWidget (from its
-// destructor).
-//
+// destructor). This is often used to place a Widget in a scoped_ptr<> or
+// on the stack in a test.
class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
public ui::EventSource,
public FocusTraversable,
@@ -202,25 +202,27 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
InitParams();
explicit InitParams(Type type);
+ InitParams(const InitParams& other);
~InitParams();
Type type;
- // If NULL, a default implementation will be constructed.
+ // If null, a default implementation will be constructed. The default
+ // implementation deletes itself when the Widget closes.
WidgetDelegate* delegate;
bool child;
// If TRANSLUCENT_WINDOW, the widget may be fully or partially transparent.
- // Translucent windows may not always be supported. Use
- // IsTranslucentWindowOpacitySupported to determine if translucent windows
- // are supported.
// If OPAQUE_WINDOW, we can perform optimizations based on the widget being
- // fully opaque. Defaults to TRANSLUCENT_WINDOW if
- // ViewsDelegate::UseTransparentWindows(). Defaults to OPAQUE_WINDOW for
- // non-window widgets.
+ // fully opaque.
+ // Default is based on ViewsDelegate::GetOpacityForInitParams(). Defaults
+ // to OPAQUE_WINDOW for non-window widgets.
+ // Translucent windows may not always be supported. Use
+ // IsTranslucentWindowOpacitySupported to determine whether they are.
WindowOpacity opacity;
bool accept_events;
Activatable activatable;
bool keep_on_top;
bool visible_on_all_workspaces;
+ // See Widget class comment above.
Ownership ownership;
bool mirror_origin_in_rtl;
ShadowType shadow_type;
@@ -242,8 +244,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// When set, this value is used as the Widget's NativeWidget implementation.
// The Widget will not construct a default one. Default is NULL.
NativeWidget* native_widget;
- // If provided, sets the native theme for this widget.
- ui::NativeTheme* native_theme;
// Aura-only. Provides a DesktopWindowTreeHost implementation to use instead
// of the default one.
// TODO(beng): Figure out if there's a better way to expose this, e.g. get
@@ -273,23 +273,18 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// If true then the widget uses software compositing. Defaults to false.
// Only used on Windows.
bool force_software_compositing;
+
+ // Used if widget is not activatable to do determine if mouse events should
+ // be sent to the widget.
+ bool wants_mouse_events_when_inactive = false;
};
Widget();
~Widget() override;
- // Creates a toplevel window with no context. These methods should only be
- // used in cases where there is no contextual information because we're
- // creating a toplevel window connected to no other event.
- //
- // If you have any parenting or context information, or can pass that
- // information, prefer the WithParent or WithContext versions of these
- // methods.
- static Widget* CreateWindow(WidgetDelegate* delegate);
- static Widget* CreateWindowWithBounds(WidgetDelegate* delegate,
- const gfx::Rect& bounds);
-
- // Creates a decorated window Widget with the specified properties.
+ // Creates a decorated window Widget with the specified properties. The
+ // returned Widget is owned by its NativeWidget; see Widget class comment for
+ // details.
static Widget* CreateWindowWithParent(WidgetDelegate* delegate,
gfx::NativeView parent);
static Widget* CreateWindowWithParentAndBounds(WidgetDelegate* delegate,
@@ -297,6 +292,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
const gfx::Rect& bounds);
// Creates a decorated window Widget in the same desktop context as |context|.
+ // The returned Widget is owned by its NativeWidget; see Widget class comment
+ // for details.
static Widget* CreateWindowWithContext(WidgetDelegate* delegate,
gfx::NativeWindow context);
static Widget* CreateWindowWithContextAndBounds(WidgetDelegate* delegate,
@@ -498,12 +495,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Returns whether the Widget is the currently active window.
virtual bool IsActive() const;
- // Prevents the window from being rendered as deactivated. This state is
- // reset automatically as soon as the window becomes activated again. There is
- // no ability to control the state through this API as this leads to sync
- // problems.
- void DisableInactiveRendering();
-
// Sets the widget to be on top of all other widgets in the windowing system.
void SetAlwaysOnTop(bool on_top);
@@ -532,10 +523,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// underlying windowing system.
void SetOpacity(unsigned char opacity);
- // Sets whether or not the window should show its frame as a "transient drag
- // frame" - slightly transparent and without the standard window controls.
- void SetUseDragFrame(bool use_drag_frame);
-
// Flashes the frame of the window to draw attention to it. Currently only
// implemented on Windows for non-Aura.
void FlashFrame(bool flash);
@@ -565,7 +552,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
return const_cast<ui::NativeTheme*>(
const_cast<const Widget*>(this)->GetNativeTheme());
}
- const ui::NativeTheme* GetNativeTheme() const;
+ virtual const ui::NativeTheme* GetNativeTheme() const;
// Returns the FocusManager for this widget.
// Note that all widgets in a widget hierarchy share the same focus manager.
@@ -775,8 +762,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
bool IsModal() const override;
bool IsDialogBox() const override;
bool CanActivate() const override;
- bool IsInactiveRenderingDisabled() const override;
- void EnableInactiveRendering() override;
+ bool IsAlwaysRenderAsActive() const override;
+ void SetAlwaysRenderAsActive(bool always_render_as_active) override;
void OnNativeWidgetActivationChanged(bool active) override;
void OnNativeFocus() override;
void OnNativeBlur() override;
@@ -838,12 +825,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
private:
friend class ComboboxTest;
+ friend class CustomButtonTest;
friend class TextfieldTest;
- // Sets the value of |disable_inactive_rendering_|. If the value changes,
- // both the NonClientView and WidgetDelegate are notified.
- void SetInactiveRenderingDisabled(bool value);
-
// Persists the window's restored position and "show" state using the
// window delegate.
void SaveWindowPlacement();
@@ -866,10 +850,6 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
internal::NativeWidgetPrivate* native_widget_;
- // If non-null, the native theme for this widget. Otherwise the native theme
- // comes from |native_widget_|.
- ui::NativeTheme* native_theme_;
-
base::ObserverList<WidgetObserver> observers_;
base::ObserverList<WidgetRemovalsObserver> removals_observers_;
@@ -914,7 +894,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// True when the window should be rendered as active, regardless of whether
// or not it actually is.
- bool disable_inactive_rendering_;
+ bool always_render_as_active_;
// Set to true if the widget is in the process of closing.
bool widget_closed_;
diff --git a/chromium/ui/views/widget/widget_delegate.cc b/chromium/ui/views/widget/widget_delegate.cc
index e62aa92847e..ced90b6f392 100644
--- a/chromium/ui/views/widget/widget_delegate.cc
+++ b/chromium/ui/views/widget/widget_delegate.cc
@@ -32,15 +32,19 @@ void WidgetDelegate::OnWorkAreaChanged() {
}
View* WidgetDelegate::GetInitiallyFocusedView() {
- return NULL;
+ return nullptr;
}
BubbleDelegateView* WidgetDelegate::AsBubbleDelegate() {
- return NULL;
+ return nullptr;
+}
+
+BubbleDialogDelegateView* WidgetDelegate::AsBubbleDialogDelegate() {
+ return nullptr;
}
DialogDelegate* WidgetDelegate::AsDialogDelegate() {
- return NULL;
+ return nullptr;
}
bool WidgetDelegate::CanResize() const {
@@ -80,7 +84,11 @@ bool WidgetDelegate::ShouldShowWindowTitle() const {
}
bool WidgetDelegate::ShouldShowCloseButton() const {
+#if defined(OS_MACOSX)
+ return false;
+#else
return true;
+#endif
}
bool WidgetDelegate::ShouldHandleSystemCommands() const {
diff --git a/chromium/ui/views/widget/widget_delegate.h b/chromium/ui/views/widget/widget_delegate.h
index 660313d1648..0ec021505b6 100644
--- a/chromium/ui/views/widget/widget_delegate.h
+++ b/chromium/ui/views/widget/widget_delegate.h
@@ -19,6 +19,7 @@ class Rect;
}
namespace views {
+class BubbleDialogDelegateView;
class BubbleDelegateView;
class ClientView;
class DialogDelegate;
@@ -51,6 +52,7 @@ class VIEWS_EXPORT WidgetDelegate {
virtual View* GetInitiallyFocusedView();
virtual BubbleDelegateView* AsBubbleDelegate();
+ virtual BubbleDialogDelegateView* AsBubbleDialogDelegate();
virtual DialogDelegate* AsDialogDelegate();
// Returns true if the window can be resized.
diff --git a/chromium/ui/views/widget/widget_interactive_uitest.cc b/chromium/ui/views/widget/widget_interactive_uitest.cc
index fa5fb3954fc..e9f9397c01b 100644
--- a/chromium/ui/views/widget/widget_interactive_uitest.cc
+++ b/chromium/ui/views/widget/widget_interactive_uitest.cc
@@ -26,6 +26,7 @@
#include "ui/views/controls/textfield/textfield_test_api.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/test/focus_manager_test.h"
+#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/touchui/touch_selection_controller_impl.h"
#include "ui/views/widget/widget.h"
@@ -52,7 +53,7 @@ class ExitLoopOnRelease : public View {
~ExitLoopOnRelease() override {}
private:
- // Overridden from View:
+ // View:
void OnMouseReleased(const ui::MouseEvent& event) override {
GetWidget()->Close();
base::MessageLoop::current()->QuitNow();
@@ -68,7 +69,7 @@ class GestureCaptureView : public View {
~GestureCaptureView() override {}
private:
- // Overridden from View:
+ // View:
void OnGestureEvent(ui::GestureEvent* event) override {
if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
GetWidget()->SetCapture(this);
@@ -132,7 +133,7 @@ class NestedLoopCaptureView : public View {
~NestedLoopCaptureView() override {}
private:
- // Overridden from View:
+ // View:
bool OnMousePressed(const ui::MouseEvent& event) override {
// Start a nested loop.
widget_->Show();
@@ -654,6 +655,7 @@ TEST_F(WidgetTestInteractive, ViewFocusOnHWNDEnabledChanges) {
}
widget->Show();
+ widget->GetNativeWindow()->GetHost()->Show();
const HWND hwnd = HWNDForWidget(widget);
EXPECT_TRUE(::IsWindow(hwnd));
EXPECT_TRUE(::IsWindowEnabled(hwnd));
@@ -740,6 +742,69 @@ TEST_F(WidgetTestInteractive, WidgetNotActivatedOnFakeActivationMessages) {
EXPECT_EQ(true, widget1.active());
EXPECT_EQ(false, widget2.active());
}
+
+// On Windows if we create a fullscreen window on a thread, then it affects the
+// way other windows on the thread interact with the taskbar. To workaround
+// this we reduce the bounds of a fullscreen window by 1px when it loses
+// activation. This test verifies the same.
+TEST_F(WidgetTestInteractive, FullscreenBoundsReducedOnActivationLoss) {
+ Widget widget1;
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget = new DesktopNativeWidgetAura(&widget1);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget1.Init(params);
+ widget1.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget1.Show();
+
+ widget1.Activate();
+ RunPendingMessages();
+ EXPECT_EQ(::GetActiveWindow(),
+ widget1.GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+
+ widget1.SetFullscreen(true);
+ EXPECT_TRUE(widget1.IsFullscreen());
+ // Ensure that the StopIgnoringPosChanges task in HWNDMessageHandler runs.
+ // This task is queued when a widget becomes fullscreen.
+ RunPendingMessages();
+ EXPECT_EQ(::GetActiveWindow(),
+ widget1.GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+ gfx::Rect fullscreen_bounds = widget1.GetWindowBoundsInScreen();
+
+ Widget widget2;
+ params.native_widget = new DesktopNativeWidgetAura(&widget2);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget2.Init(params);
+ widget2.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget2.Show();
+
+ widget2.Activate();
+ RunPendingMessages();
+ EXPECT_EQ(::GetActiveWindow(),
+ widget2.GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+
+ gfx::Rect fullscreen_bounds_after_activation_loss =
+ widget1.GetWindowBoundsInScreen();
+
+ // After deactivation loss the bounds of the fullscreen widget should be
+ // reduced by 1px.
+ EXPECT_EQ(fullscreen_bounds.height() -
+ fullscreen_bounds_after_activation_loss.height(), 1);
+
+ widget1.Activate();
+ RunPendingMessages();
+ EXPECT_EQ(::GetActiveWindow(),
+ widget1.GetNativeWindow()->GetHost()->GetAcceleratedWidget());
+
+ gfx::Rect fullscreen_bounds_after_activate =
+ widget1.GetWindowBoundsInScreen();
+
+ // After activation the bounds of the fullscreen widget should be restored.
+ EXPECT_EQ(fullscreen_bounds, fullscreen_bounds_after_activate);
+
+ widget1.CloseNow();
+ widget2.CloseNow();
+}
#endif // defined(OS_WIN)
#if !defined(OS_CHROMEOS)
@@ -774,8 +839,8 @@ TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
gfx::Rect initial_bounds(0, 0, 500, 500);
init_params.bounds = initial_bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget =
- new PlatformDesktopNativeWidget(&top_level_widget);
+ init_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ init_params, &top_level_widget, nullptr);
top_level_widget.Init(init_params);
ShowSync(&top_level_widget);
@@ -843,8 +908,8 @@ TEST_F(WidgetTestInteractive, MAYBE_SystemModalWindowReleasesCapture) {
gfx::Rect initial_bounds(0, 0, 500, 500);
init_params.bounds = initial_bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget =
- new PlatformDesktopNativeWidget(&top_level_widget);
+ init_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ init_params, &top_level_widget, nullptr);
top_level_widget.Init(init_params);
ShowSync(&top_level_widget);
@@ -881,9 +946,8 @@ TEST_F(WidgetTestInteractive, CanActivateFlagIsHonored) {
init_params.bounds = gfx::Rect(0, 0, 200, 200);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
init_params.activatable = Widget::InitParams::ACTIVATABLE_NO;
-#if !defined(OS_CHROMEOS)
- init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
-#endif // !defined(OS_CHROMEOS)
+ init_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(init_params, &widget, nullptr);
widget.Init(init_params);
widget.Show();
@@ -1048,7 +1112,8 @@ TEST_F(WidgetTestInteractive, InactiveWidgetDoesNotGrabActivation) {
Widget widget2;
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget = new PlatformDesktopNativeWidget(&widget2);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, &widget2, nullptr);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget2.Init(params);
widget2.Show();
@@ -1107,9 +1172,35 @@ TEST_F(WidgetTestInteractive, MAYBE_ExitFullscreenRestoreState) {
RunPendingMessages();
}
+// Testing initial focus is assigned properly for normal top-level widgets,
+// and subclasses that specify a initially focused child view.
+TEST_F(WidgetTestInteractive, InitialFocus) {
+ // By default, there is no initially focused view (even if there is a
+ // focusable subview).
+ Widget* toplevel(CreateTopLevelPlatformWidget());
+ View* view = new View;
+ view->SetFocusable(true);
+ toplevel->GetContentsView()->AddChildView(view);
+
+ ShowSync(toplevel);
+ toplevel->Show();
+ EXPECT_FALSE(view->HasFocus());
+ EXPECT_FALSE(toplevel->GetFocusManager()->GetStoredFocusView());
+ toplevel->CloseNow();
+
+ // Testing a widget which specifies a initially focused view.
+ TestInitialFocusWidgetDelegate delegate(GetContext());
+
+ Widget* widget = delegate.GetWidget();
+ ShowSync(widget);
+ widget->Show();
+ EXPECT_TRUE(delegate.view()->HasFocus());
+ EXPECT_EQ(delegate.view(), widget->GetFocusManager()->GetStoredFocusView());
+}
+
namespace {
-// Used to veirfy OnMouseCaptureLost() has been invoked.
+// Used to verify OnMouseCaptureLost() has been invoked.
class CaptureLostTrackingWidget : public Widget {
public:
CaptureLostTrackingWidget() : got_capture_lost_(false) {}
@@ -1157,8 +1248,8 @@ class WidgetCaptureTest : public ViewsTestBase {
CaptureLostTrackingWidget widget1;
Widget::InitParams params1 =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
- params1.native_widget = CreateNativeWidget(use_desktop_native_widget,
- &widget1);
+ params1.native_widget =
+ CreateNativeWidget(params1, use_desktop_native_widget, &widget1);
params1.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget1.Init(params1);
widget1.Show();
@@ -1167,8 +1258,8 @@ class WidgetCaptureTest : public ViewsTestBase {
Widget::InitParams params2 =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
params2.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params2.native_widget = CreateNativeWidget(use_desktop_native_widget,
- &widget2);
+ params2.native_widget =
+ CreateNativeWidget(params2, use_desktop_native_widget, &widget2);
widget2.Init(params2);
widget2.Show();
@@ -1194,13 +1285,12 @@ class WidgetCaptureTest : public ViewsTestBase {
EXPECT_FALSE(widget2.GetAndClearGotCaptureLost());
}
- NativeWidget* CreateNativeWidget(bool create_desktop_native_widget,
+ NativeWidget* CreateNativeWidget(const Widget::InitParams& params,
+ bool create_desktop_native_widget,
Widget* widget) {
-#if !defined(OS_CHROMEOS)
if (create_desktop_native_widget)
- return new PlatformDesktopNativeWidget(widget);
-#endif
- return NULL;
+ return CreatePlatformDesktopNativeWidgetImpl(params, widget, nullptr);
+ return CreatePlatformNativeWidgetImpl(params, widget, kDefault, nullptr);
}
private:
@@ -1266,7 +1356,7 @@ TEST_F(WidgetCaptureTest, MAYBE_MouseExitOnCaptureGrab) {
Widget widget1;
Widget::InitParams params1 =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- params1.native_widget = CreateNativeWidget(true, &widget1);
+ params1.native_widget = CreateNativeWidget(params1, true, &widget1);
params1.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget1.Init(params1);
MouseView* mouse_view1 = new MouseView;
@@ -1277,7 +1367,7 @@ TEST_F(WidgetCaptureTest, MAYBE_MouseExitOnCaptureGrab) {
Widget widget2;
Widget::InitParams params2 =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- params2.native_widget = CreateNativeWidget(true, &widget2);
+ params2.native_widget = CreateNativeWidget(params2, true, &widget2);
params2.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget2.Init(params2);
widget2.Show();
@@ -1329,7 +1419,8 @@ TEST_F(WidgetCaptureTest, SetCaptureToNonToplevel) {
Widget toplevel;
Widget::InitParams toplevel_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- toplevel_params.native_widget = CreateNativeWidget(true, &toplevel);
+ toplevel_params.native_widget = CreateNativeWidget(toplevel_params, true,
+ &toplevel);
toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
toplevel.Init(toplevel_params);
toplevel.Show();
diff --git a/chromium/ui/views/widget/widget_removals_observer.h b/chromium/ui/views/widget/widget_removals_observer.h
index e62acab36a4..d7046073c4d 100644
--- a/chromium/ui/views/widget/widget_removals_observer.h
+++ b/chromium/ui/views/widget/widget_removals_observer.h
@@ -18,7 +18,11 @@ class View;
// from |View|.
class VIEWS_EXPORT WidgetRemovalsObserver {
public:
- // Called immediately before a descendant view of |widget| is removed.
+ // Called immediately before a descendant view of |widget| is removed
+ // from this widget. Won't be called if the view is moved within the
+ // same widget, but will be called if it's moved to a different widget.
+ // Only called on the root of a view tree; it implies that all of the
+ // descendants of |view| will be removed.
virtual void OnWillRemoveView(Widget* widget, View* view) {}
protected:
diff --git a/chromium/ui/views/widget/widget_unittest.cc b/chromium/ui/views/widget/widget_unittest.cc
index 41bbe8198d7..0b8c645a5ea 100644
--- a/chromium/ui/views/widget/widget_unittest.cc
+++ b/chromium/ui/views/widget/widget_unittest.cc
@@ -23,12 +23,15 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/native_widget_delegate.h"
+#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget_deletion_observer.h"
+#include "ui/views/widget/widget_removals_observer.h"
#include "ui/views/window/dialog_delegate.h"
#include "ui/views/window/native_frame_view.h"
@@ -42,7 +45,6 @@
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
-#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
#endif
namespace views {
@@ -59,15 +61,6 @@ gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {
return tmp;
}
-// Helper function for Snow Leopard special cases to avoid #ifdef litter.
-bool IsTestingSnowLeopard() {
-#if defined(OS_MACOSX)
- return base::mac::IsOSSnowLeopard();
-#else
- return false;
-#endif
-}
-
// This class can be used as a deleter for scoped_ptr<Widget>
// to call function Widget::CloseNow automatically.
struct WidgetCloser {
@@ -367,44 +360,6 @@ struct OwnershipTestState {
bool native_widget_deleted;
};
-// A platform NativeWidget subclass that updates a bag of state when it is
-// destroyed.
-class OwnershipTestNativeWidget : public PlatformNativeWidget {
- public:
- OwnershipTestNativeWidget(internal::NativeWidgetDelegate* delegate,
- OwnershipTestState* state)
- : PlatformNativeWidget(delegate),
- state_(state) {
- }
- ~OwnershipTestNativeWidget() override {
- state_->native_widget_deleted = true;
- }
-
- private:
- OwnershipTestState* state_;
-
- DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidget);
-};
-
-// A views NativeWidget subclass that updates a bag of state when it is
-// destroyed.
-class OwnershipTestNativeWidgetAura : public NativeWidgetCapture {
- public:
- OwnershipTestNativeWidgetAura(internal::NativeWidgetDelegate* delegate,
- OwnershipTestState* state)
- : NativeWidgetCapture(delegate),
- state_(state) {
- }
- ~OwnershipTestNativeWidgetAura() override {
- state_->native_widget_deleted = true;
- }
-
- private:
- OwnershipTestState* state_;
-
- DISALLOW_COPY_AND_ASSIGN(OwnershipTestNativeWidgetAura);
-};
-
// A Widget subclass that updates a bag of state when it is destroyed.
class OwnershipTestWidget : public Widget {
public:
@@ -417,6 +372,8 @@ class OwnershipTestWidget : public Widget {
DISALLOW_COPY_AND_ASSIGN(OwnershipTestWidget);
};
+// TODO(sky): add coverage of ownership for the desktop variants.
+
// Widget owns its NativeWidget, part 1: NativeWidget is a platform-native
// widget.
TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
@@ -424,8 +381,8 @@ TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget.get(), &state);
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget.get(), kStubCapture, &state.native_widget_deleted);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
@@ -445,8 +402,8 @@ TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget.get(), &state);
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget.get(), kStubCapture, &state.native_widget_deleted);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
@@ -470,9 +427,9 @@ TEST_F(WidgetOwnershipTest,
scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget.get(), &state);
params.parent = toplevel->GetNativeView();
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget.get(), kStubCapture, &state.native_widget_deleted);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
@@ -500,8 +457,8 @@ TEST_F(WidgetOwnershipTest, Ownership_PlatformNativeWidgetOwnsWidget) {
Widget* widget = new OwnershipTestWidget(&state);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget, &state);
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget, kStubCapture, &state.native_widget_deleted);
widget->Init(params);
// Now destroy the native widget.
@@ -519,9 +476,9 @@ TEST_F(WidgetOwnershipTest, Ownership_ViewsNativeWidgetOwnsWidget) {
Widget* widget = new OwnershipTestWidget(&state);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget, &state);
params.parent = toplevel->GetNativeView();
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget, kStubCapture, &state.native_widget_deleted);
widget->Init(params);
// Now destroy the native widget. This is achieved by closing the toplevel.
@@ -543,8 +500,8 @@ TEST_F(WidgetOwnershipTest,
Widget* widget = new OwnershipTestWidget(&state);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget, &state);
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget, kStubCapture, &state.native_widget_deleted);
widget->Init(params);
// Now simulate a destroy of the platform native widget from the OS:
@@ -564,9 +521,9 @@ TEST_F(WidgetOwnershipTest,
Widget* widget = new OwnershipTestWidget(&state);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget, &state);
params.parent = toplevel->GetNativeView();
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget, kStubCapture, &state.native_widget_deleted);
widget->Init(params);
// Destroy the widget (achieved by closing the toplevel).
@@ -590,9 +547,9 @@ TEST_F(WidgetOwnershipTest,
Widget* widget = new OwnershipTestWidget(&state);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget, &state);
params.parent = toplevel->GetNativeView();
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget, kStubCapture, &state.native_widget_deleted);
widget->Init(params);
// Destroy the widget.
@@ -616,8 +573,8 @@ TEST_F(WidgetOwnershipTest,
scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget =
- new OwnershipTestNativeWidgetAura(widget.get(), &state);
+ params.native_widget = CreatePlatformNativeWidgetImpl(
+ params, widget.get(), kStubCapture, &state.native_widget_deleted);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.delegate = delegate_view;
widget->Init(params);
@@ -658,7 +615,6 @@ class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
widget->Activate();
widget->Deactivate();
widget->IsActive();
- widget->DisableInactiveRendering();
widget->SetAlwaysOnTop(true);
widget->IsAlwaysOnTop();
widget->Maximize();
@@ -667,7 +623,6 @@ class WidgetWithDestroyedNativeViewTest : public ViewsTestBase {
widget->IsMaximized();
widget->IsFullscreen();
widget->SetOpacity(0);
- widget->SetUseDragFrame(true);
widget->FlashFrame(true);
widget->IsVisible();
widget->GetThemeProvider();
@@ -706,7 +661,8 @@ TEST_F(WidgetWithDestroyedNativeViewTest, Test) {
{
Widget widget;
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- params.native_widget = new PlatformDesktopNativeWidget(&widget);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, &widget, nullptr);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget.Init(params);
widget.Show();
@@ -971,6 +927,11 @@ TEST_F(WidgetObserverTest, ClosingOnHiddenParent) {
// Test behavior of NativeWidget*::GetWindowPlacement on the native desktop.
TEST_F(WidgetTest, GetWindowPlacement) {
+ if (IsMus()) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
WidgetAutoclosePtr widget;
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// On desktop-Linux cheat and use non-desktop widgets. On X11, minimize is
@@ -1081,10 +1042,12 @@ TEST_F(WidgetTest, MinimumSizeConstraints) {
widget->SetSize(smaller_size);
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// TODO(tapted): Desktop Linux ignores size constraints for SetSize. Fix it.
- EXPECT_EQ(smaller_size, widget->GetClientAreaBoundsInScreen().size());
+ const bool use_small_size = IsMus() ? false : true;
#else
- EXPECT_EQ(minimum_size, widget->GetClientAreaBoundsInScreen().size());
+ const bool use_small_size = false;
#endif
+ EXPECT_EQ(use_small_size ? smaller_size : minimum_size,
+ widget->GetClientAreaBoundsInScreen().size());
}
// Tests that SetBounds() and GetWindowBoundsInScreen() is symmetric when the
@@ -1155,10 +1118,10 @@ TEST_F(WidgetTest, GetWindowBoundsInScreen) {
// Test that GetRestoredBounds() returns the original bounds of the window.
TEST_F(WidgetTest, MAYBE_GetRestoredBounds) {
-#if defined(OS_MACOSX)
- // Fullscreen on Mac requires an interactive UI test, fake them here.
- ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
-#endif
+ if (IsMus()) {
+ NOTIMPLEMENTED();
+ return;
+ }
WidgetAutoclosePtr toplevel(CreateNativeDesktopWidget());
toplevel->Show();
@@ -1188,14 +1151,8 @@ TEST_F(WidgetTest, MAYBE_GetRestoredBounds) {
toplevel->SetFullscreen(true);
RunPendingMessages();
- if (IsTestingSnowLeopard()) {
- // Fullscreen not implemented for Snow Leopard.
- EXPECT_EQ(toplevel->GetWindowBoundsInScreen(),
- toplevel->GetRestoredBounds());
- } else {
- EXPECT_NE(toplevel->GetWindowBoundsInScreen(),
- toplevel->GetRestoredBounds());
- }
+ EXPECT_NE(toplevel->GetWindowBoundsInScreen(),
+ toplevel->GetRestoredBounds());
EXPECT_EQ(bounds, toplevel->GetRestoredBounds());
toplevel->SetFullscreen(false);
@@ -1239,7 +1196,8 @@ TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
init_params.bounds = gfx::Rect(0, 0, 200, 200);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
#if !defined(OS_CHROMEOS)
- init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
+ init_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(init_params, &widget, nullptr);
#endif
widget.Init(init_params);
widget.SetContentsView(contents_view);
@@ -1301,6 +1259,10 @@ TEST_F(WidgetTest, BubbleControlsResetOnInit) {
// the case for desktop widgets on Windows. Other platforms retain the window
// size while minimized.
TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
+ if (IsMus()) {
+ // This test is testing behavior specific to DesktopWindowTreeHostWin.
+ return;
+ }
// Create a widget.
Widget widget;
Widget::InitParams init_params =
@@ -1309,7 +1271,8 @@ TEST_F(WidgetTest, TestViewWidthAfterMinimizingWidget) {
gfx::Rect initial_bounds(0, 0, 300, 400);
init_params.bounds = initial_bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
+ init_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(init_params, &widget, nullptr);
widget.Init(init_params);
NonClientView* non_client_view = widget.non_client_view();
NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
@@ -1383,7 +1346,8 @@ class DesktopAuraTestValidPaintWidget : public views::Widget {
void DesktopAuraTestValidPaintWidget::InitForTest(InitParams init_params) {
init_params.bounds = gfx::Rect(0, 0, 200, 200);
init_params.ownership = InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget = new PlatformDesktopNativeWidget(this);
+ init_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(init_params, this, nullptr);
Init(init_params);
View* contents_view = new View;
@@ -1394,7 +1358,14 @@ void DesktopAuraTestValidPaintWidget::InitForTest(InitParams init_params) {
Activate();
}
-TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {
+#if defined(OS_LINUX)
+// Flaky on Linux rel ng: https://crbug.com/596039.
+#define MAYBE_DesktopNativeWidgetNoPaintAfterCloseTest DISABLED_DesktopNativeWidgetNoPaintAfterCloseTest
+#else
+#define MAYBE_DesktopNativeWidgetNoPaintAfterCloseTest DesktopNativeWidgetNoPaintAfterCloseTest
+#endif
+
+TEST_F(WidgetTest, MAYBE_DesktopNativeWidgetNoPaintAfterCloseTest) {
DesktopAuraTestValidPaintWidget widget;
widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
RunPendingMessages();
@@ -1406,7 +1377,12 @@ TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterCloseTest) {
EXPECT_FALSE(widget.received_paint_while_hidden());
}
-TEST_F(WidgetTest, DesktopNativeWidgetNoPaintAfterHideTest) {
+#if defined(OS_LINUX)
+#define MAYBE_DesktopNativeWidgetNoPaintAfterHideTest DISABLED_DesktopNativeWidgetNoPaintAfterHideTest
+#else
+#define MAYBE_DesktopNativeWidgetNoPaintAfterHideTest DesktopNativeWidgetNoPaintAfterHideTest
+#endif
+TEST_F(WidgetTest, MAYBE_DesktopNativeWidgetNoPaintAfterHideTest) {
DesktopAuraTestValidPaintWidget widget;
widget.InitForTest(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
RunPendingMessages();
@@ -1430,7 +1406,8 @@ TEST_F(WidgetTest, TestWindowVisibilityAfterHide) {
gfx::Rect initial_bounds(0, 0, 300, 400);
init_params.bounds = initial_bounds;
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- init_params.native_widget = new PlatformDesktopNativeWidget(&widget);
+ init_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(init_params, &widget, nullptr);
widget.Init(init_params);
NonClientView* non_client_view = widget.non_client_view();
NonClientFrameView* frame_view = new MinimumSizeFrameView(&widget);
@@ -1690,7 +1667,9 @@ TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
EXPECT_EQ(0, v2->GetEventCount(ui::ET_MOUSE_MOVED));
gfx::Point cursor_location(5, 5);
- ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
+ ui::test::EventGenerator generator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow());
generator.MoveMouseTo(cursor_location);
EXPECT_EQ(1, v1->GetEventCount(ui::ET_MOUSE_MOVED));
@@ -1734,7 +1713,7 @@ class MousePressEventConsumer : public ui::EventHandler {
// Test that mouse presses and mouse releases are dispatched normally when a
// touch is down.
TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
- WidgetAutoclosePtr widget(CreateTopLevelNativeWidget());
+ Widget* widget = CreateTopLevelNativeWidget();
widget->Show();
widget->SetSize(gfx::Size(300, 300));
@@ -1745,12 +1724,17 @@ TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
MousePressEventConsumer consumer;
event_count_view->AddPostTargetHandler(&consumer);
- ui::test::EventGenerator generator(GetContext(), widget->GetNativeWindow());
- generator.PressTouch();
- generator.ClickLeftButton();
+ scoped_ptr<ui::test::EventGenerator> generator(new ui::test::EventGenerator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow()));
+ generator->PressTouch();
+ generator->ClickLeftButton();
EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_RELEASED));
+
+ // For mus it's important we destroy the widget before the EventGenerator.
+ widget->CloseNow();
}
#endif // !defined(OS_MACOSX) || defined(USE_AURA)
@@ -1771,15 +1755,16 @@ class WidgetWindowTitleTest : public WidgetTest {
WidgetAutoclosePtr widget(new Widget()); // Destroyed by CloseNow().
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
- widget->Init(init_params);
#if !defined(OS_CHROMEOS)
if (desktop_native_widget)
- init_params.native_widget = new PlatformDesktopNativeWidget(widget.get());
+ init_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ init_params, widget.get(), nullptr);
#else
DCHECK(!desktop_native_widget)
<< "DesktopNativeWidget does not exist on non-Aura or on ChromeOS.";
#endif
+ widget->Init(init_params);
internal::NativeWidgetPrivate* native_widget =
widget->native_widget_private();
@@ -1821,6 +1806,14 @@ TEST_F(WidgetWindowTitleTest, SetWindowTitleChanged_DesktopNativeWidget) {
#endif // !OS_CHROMEOS
TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) {
+ // This test doesn't work in mus as it assumes widget and GetContext()
+ // share an aura hierarchy. Test coverage of deletion from mouse pressed is
+ // important though and should be added, hence the NOTIMPLEMENTED().
+ // http://crbug.com/594260.
+ if (IsMus()) {
+ NOTIMPLEMENTED();
+ return;
+ }
Widget* widget = new Widget;
Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_POPUP);
@@ -1844,6 +1837,9 @@ TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) {
#if !defined(OS_MACOSX) || defined(USE_AURA)
TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) {
+ // This test doesn't make sense for mus. Force NativeWidgetAura to be used.
+ DisableNativeWidgetMus();
+
Widget* widget = new Widget;
Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_POPUP);
@@ -1895,7 +1891,8 @@ bool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
params.delegate = new GetNativeThemeFromDestructorView;
#if !defined(OS_CHROMEOS)
if (is_first_run) {
- params.native_widget = new PlatformDesktopNativeWidget(widget.get());
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, widget.get(), nullptr);
needs_second_run = true;
}
#endif
@@ -1979,7 +1976,8 @@ TEST_F(WidgetTest, CloseDestroys) {
CreateParams(views::Widget::InitParams::TYPE_MENU);
params.opacity = Widget::InitParams::OPAQUE_WINDOW;
#if !defined(OS_CHROMEOS)
- params.native_widget = new PlatformDesktopNativeWidget(widget);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, widget, nullptr);
#endif
widget->Init(params);
widget->Show();
@@ -2906,8 +2904,10 @@ class WidgetChildDestructionTest : public WidgetTest {
Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
#if !defined(OS_CHROMEOS)
- if (top_level_has_desktop_native_widget_aura)
- params.native_widget = new PlatformDesktopNativeWidget(top_level);
+ if (top_level_has_desktop_native_widget_aura) {
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, top_level, nullptr);
+ }
#endif
top_level->Init(params);
top_level->GetRootView()->AddChildView(
@@ -2919,8 +2919,10 @@ class WidgetChildDestructionTest : public WidgetTest {
CreateParams(views::Widget::InitParams::TYPE_POPUP);
child_params.parent = top_level->GetNativeView();
#if !defined(OS_CHROMEOS)
- if (child_has_desktop_native_widget_aura)
- child_params.native_widget = new PlatformDesktopNativeWidget(child);
+ if (child_has_desktop_native_widget_aura) {
+ child_params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(child_params, child, nullptr);
+ }
#endif
child->Init(child_params);
child->GetRootView()->AddChildView(
@@ -2970,27 +2972,34 @@ TEST_F(WidgetTest, FullscreenStatePropagated) {
init_params.bounds = gfx::Rect(0, 0, 500, 500);
init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- {
- Widget top_level_widget;
- top_level_widget.Init(init_params);
- top_level_widget.SetFullscreen(true);
- EXPECT_EQ(top_level_widget.IsVisible(),
- IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
- top_level_widget.CloseNow();
- }
+ Widget top_level_widget;
+ top_level_widget.Init(init_params);
+ top_level_widget.SetFullscreen(true);
+ EXPECT_EQ(top_level_widget.IsVisible(),
+ IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
+ top_level_widget.CloseNow();
+}
+
+// Verifies nativeview visbility matches that of Widget visibility when
+// SetFullscreen is invoked, for a widget provided with a desktop widget.
#if !defined(OS_CHROMEOS)
- {
- Widget top_level_widget;
- init_params.native_widget =
- new PlatformDesktopNativeWidget(&top_level_widget);
- top_level_widget.Init(init_params);
- top_level_widget.SetFullscreen(true);
- EXPECT_EQ(top_level_widget.IsVisible(),
- IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
- top_level_widget.CloseNow();
- }
-#endif
+TEST_F(WidgetTest, FullscreenStatePropagated_DesktopWidget) {
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ init_params.show_state = ui::SHOW_STATE_NORMAL;
+ init_params.bounds = gfx::Rect(0, 0, 500, 500);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ Widget top_level_widget;
+ init_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ init_params, &top_level_widget, nullptr);
+
+ top_level_widget.Init(init_params);
+ top_level_widget.SetFullscreen(true);
+ EXPECT_EQ(top_level_widget.IsVisible(),
+ IsNativeWindowVisible(top_level_widget.GetNativeWindow()));
+ top_level_widget.CloseNow();
}
+#endif
namespace {
@@ -3045,12 +3054,7 @@ TEST_F(WidgetTest, FullscreenFrameLayout) {
widget->Show();
RunPendingMessages();
- if (IsTestingSnowLeopard()) {
- // Fullscreen is currently ignored on Snow Leopard.
- EXPECT_FALSE(frame->fullscreen_layout_called());
- } else {
- EXPECT_TRUE(frame->fullscreen_layout_called());
- }
+ EXPECT_TRUE(frame->fullscreen_layout_called());
}
#if !defined(OS_CHROMEOS)
@@ -3078,7 +3082,8 @@ TEST_F(WidgetTest, IsActiveFromDestroy) {
Widget parent_widget;
Widget::InitParams parent_params =
CreateParams(Widget::InitParams::TYPE_POPUP);
- parent_params.native_widget = new PlatformDesktopNativeWidget(&parent_widget);
+ parent_params.native_widget = CreatePlatformDesktopNativeWidgetImpl(
+ parent_params, &parent_widget, nullptr);
parent_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
parent_widget.Init(parent_params);
parent_widget.Show();
@@ -3183,37 +3188,13 @@ TEST_F(WidgetTest, NonClientWindowValidAfterInit) {
}
#if defined(OS_WIN)
-// This test validates that sending WM_CHAR/WM_SYSCHAR/WM_SYSDEADCHAR
-// messages via the WindowEventTarget interface implemented by the
-// HWNDMessageHandler class does not cause a crash due to an unprocessed
-// event
-TEST_F(WidgetTest, CharMessagesAsKeyboardMessagesDoesNotCrash) {
- Widget widget;
- Widget::InitParams params =
- CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.native_widget = new PlatformDesktopNativeWidget(&widget);
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget.Init(params);
- widget.Show();
-
- ui::WindowEventTarget* target =
- reinterpret_cast<ui::WindowEventTarget*>(ui::ViewProp::GetValue(
- widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget(),
- ui::WindowEventTarget::kWin32InputEventTarget));
- EXPECT_NE(nullptr, target);
- bool handled = false;
- target->HandleKeyboardMessage(WM_CHAR, 0, 0, &handled);
- target->HandleKeyboardMessage(WM_SYSCHAR, 0, 0, &handled);
- target->HandleKeyboardMessage(WM_SYSDEADCHAR, 0, 0, &handled);
- widget.CloseNow();
-}
-
// Provides functionality to subclass a window and keep track of messages
// received.
class SubclassWindowHelper {
public:
explicit SubclassWindowHelper(HWND window)
- : window_(window) {
+ : window_(window),
+ message_to_destroy_on_(0) {
EXPECT_EQ(instance_, nullptr);
instance_ = this;
EXPECT_TRUE(Subclass());
@@ -3233,6 +3214,10 @@ class SubclassWindowHelper {
messages_.clear();
}
+ void set_message_to_destroy_on(unsigned int message) {
+ message_to_destroy_on_ = message;
+ }
+
private:
bool Subclass() {
old_proc_ = reinterpret_cast<WNDPROC>(
@@ -3258,14 +3243,20 @@ class SubclassWindowHelper {
// Keep track of messags received for this window.
instance_->messages_.insert(message);
- return ::CallWindowProc(instance_->old_proc_, window, message, w_param,
- l_param);
+ LRESULT ret = ::CallWindowProc(instance_->old_proc_, window, message,
+ w_param, l_param);
+ if (message == instance_->message_to_destroy_on_) {
+ instance_->Unsubclass();
+ ::DestroyWindow(window);
+ }
+ return ret;
}
WNDPROC old_proc_;
HWND window_;
static SubclassWindowHelper* instance_;
std::set<unsigned int> messages_;
+ unsigned int message_to_destroy_on_;
DISALLOW_COPY_AND_ASSIGN(SubclassWindowHelper);
};
@@ -3278,11 +3269,13 @@ SubclassWindowHelper* SubclassWindowHelper::instance_ = nullptr;
// 1. Posting a WM_NCMOUSEMOVE message for a different location.
// 2. Posting a WM_NCMOUSEMOVE message with a different hittest code.
// 3. Posting a WM_MOUSEMOVE message.
-TEST_F(WidgetTest, SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
+// Disabled because of flaky timeouts: http://crbug.com/592742
+TEST_F(WidgetTest, DISABLED_SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
Widget widget;
Widget::InitParams params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.native_widget = new PlatformDesktopNativeWidget(&widget);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, &widget, nullptr);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget.Init(params);
widget.SetBounds(gfx::Rect(0, 0, 200, 200));
@@ -3347,10 +3340,49 @@ TEST_F(WidgetTest, SysCommandMoveOnNCLButtonDownOnCaptionAndMoveTest) {
widget.CloseNow();
}
+
+// This test validates that destroying the window in the context of the
+// WM_SYSCOMMAND message with SC_MOVE does not crash.
+// Disabled because of flaky timeouts: http://crbug.com/592742
+TEST_F(WidgetTest, DISABLED_DestroyInSysCommandNCLButtonDownOnCaption) {
+ Widget widget;
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget =
+ CreatePlatformDesktopNativeWidgetImpl(params, &widget, nullptr);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+ widget.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget.Show();
+ ::SetCursorPos(500, 500);
+
+ HWND window = widget.GetNativeWindow()->GetHost()->GetAcceleratedWidget();
+
+ SubclassWindowHelper subclass_helper(window);
+
+ // Destroying the window in the context of the WM_SYSCOMMAND message
+ // should not crash.
+ subclass_helper.set_message_to_destroy_on(WM_SYSCOMMAND);
+
+ ::PostMessage(window, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(100, 100));
+ ::PostMessage(window, WM_NCMOUSEMOVE, HTCAPTION, MAKELPARAM(110, 110));
+ RunPendingMessages();
+
+ EXPECT_TRUE(subclass_helper.received_message(WM_NCLBUTTONDOWN));
+ EXPECT_TRUE(subclass_helper.received_message(WM_SYSCOMMAND));
+
+ widget.CloseNow();
+}
+
#endif
// Test that SetAlwaysOnTop and IsAlwaysOnTop are consistent.
TEST_F(WidgetTest, AlwaysOnTop) {
+ if (IsMus()) {
+ NOTIMPLEMENTED();
+ return;
+ }
+
WidgetAutoclosePtr widget(CreateTopLevelNativeWidget());
EXPECT_FALSE(widget->IsAlwaysOnTop());
widget->SetAlwaysOnTop(true);
@@ -3401,5 +3433,78 @@ TEST_F(WidgetTest, OnDeviceScaleFactorChanged) {
EXPECT_EQ(scale_factor, view->last_scale_factor());
}
+namespace {
+
+class TestWidgetRemovalsObserver : public WidgetRemovalsObserver {
+ public:
+ TestWidgetRemovalsObserver() {}
+ ~TestWidgetRemovalsObserver() override {}
+
+ void OnWillRemoveView(Widget* widget, View* view) override {
+ removed_views_.insert(view);
+ }
+
+ bool DidRemoveView(View* view) {
+ return removed_views_.find(view) != removed_views_.end();
+ }
+
+ private:
+ std::set<View*> removed_views_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestWidgetRemovalsObserver);
+};
+
+}
+
+// Test that WidgetRemovalsObserver::OnWillRemoveView is called when deleting
+// a view.
+TEST_F(WidgetTest, WidgetRemovalsObserverCalled) {
+ WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget());
+ TestWidgetRemovalsObserver removals_observer;
+ widget->AddRemovalsObserver(&removals_observer);
+
+ View* parent = new View();
+ widget->client_view()->AddChildView(parent);
+
+ View* child = new View();
+ parent->AddChildView(child);
+
+ widget->client_view()->RemoveChildView(parent);
+ EXPECT_TRUE(removals_observer.DidRemoveView(parent));
+ EXPECT_FALSE(removals_observer.DidRemoveView(child));
+
+ // Calling RemoveChildView() doesn't delete the view, but deleting
+ // |parent| will automatically delete |child|.
+ delete parent;
+
+ widget->RemoveRemovalsObserver(&removals_observer);
+}
+
+// Test that WidgetRemovalsObserver::OnWillRemoveView is called when moving
+// a view from one widget to another, but not when moving a view within
+// the same widget.
+TEST_F(WidgetTest, WidgetRemovalsObserverCalledWhenMovingBetweenWidgets) {
+ WidgetAutoclosePtr widget(CreateTopLevelPlatformWidget());
+ TestWidgetRemovalsObserver removals_observer;
+ widget->AddRemovalsObserver(&removals_observer);
+
+ View* parent = new View();
+ widget->client_view()->AddChildView(parent);
+
+ View* child = new View();
+ widget->client_view()->AddChildView(child);
+
+ // Reparenting the child shouldn't call the removals observer.
+ parent->AddChildView(child);
+ EXPECT_FALSE(removals_observer.DidRemoveView(child));
+
+ // Moving the child to a different widget should call the removals observer.
+ WidgetAutoclosePtr widget2(CreateTopLevelPlatformWidget());
+ widget2->client_view()->AddChildView(child);
+ EXPECT_TRUE(removals_observer.DidRemoveView(child));
+
+ widget->RemoveRemovalsObserver(&removals_observer);
+}
+
} // namespace test
} // namespace views