diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 22:40:52 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-23 22:40:52 +0000 |
commit | 2f74428eee5f226ccdba805b91bd7e45a0f7a4e4 (patch) | |
tree | 7bba8d381a8f4f46f487f92cd5ce81e978d0114a /ash | |
parent | eb929d6e96d746d808f1083dd54d7514e4c45e85 (diff) | |
download | chromium_src-2f74428eee5f226ccdba805b91bd7e45a0f7a4e4.zip chromium_src-2f74428eee5f226ccdba805b91bd7e45a0f7a4e4.tar.gz chromium_src-2f74428eee5f226ccdba805b91bd7e45a0f7a4e4.tar.bz2 |
More stuff -> ash
http://crbug.com/108457
TEST=none
TBR=sky
Review URL: http://codereview.chromium.org/9033006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115741 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
34 files changed, 2609 insertions, 8 deletions
diff --git a/ash/OWNERS b/ash/OWNERS new file mode 100644 index 0000000..ec790c4 --- /dev/null +++ b/ash/OWNERS @@ -0,0 +1,3 @@ +set noparent +ben@chromium.org +sky@chromium.org diff --git a/ash/PRESUBMIT.py b/ash/PRESUBMIT.py new file mode 100644 index 0000000..12f1918 --- /dev/null +++ b/ash/PRESUBMIT.py @@ -0,0 +1,12 @@ +# Copyright (c) 2011 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. + +"""Chromium presubmit script for src/ash + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details on the presubmit API built into gcl. +""" + +def GetPreferredTrySlaves(): + return ['linux_aura:compile'] diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc new file mode 100644 index 0000000..e2aaeda --- /dev/null +++ b/ash/accelerators/accelerator_controller.cc @@ -0,0 +1,206 @@ +// Copyright (c) 2011 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 "ash/accelerators/accelerator_controller.h" + +#include "ash/launcher/launcher.h" +#include "ash/launcher/launcher_model.h" +#include "ash/wm/window_util.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura_shell/screenshot_delegate.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_window_ids.h" +#include "ui/base/accelerators/accelerator.h" +#include "ui/base/accelerators/accelerator_manager.h" +#include "ui/gfx/compositor/debug_utils.h" +#include "ui/gfx/compositor/layer_animation_sequence.h" +#include "ui/gfx/compositor/layer_animator.h" +#include "ui/gfx/compositor/screen_rotation.h" + +namespace { + +enum AcceleratorAction { + CYCLE_BACKWARD, + CYCLE_FORWARD, + TAKE_SCREENSHOT, +#if !defined(NDEBUG) + ROTATE_SCREEN, + PRINT_LAYER_HIERARCHY, + TOGGLE_ROOT_WINDOW_FULL_SCREEN, +#endif +}; + +// Accelerators handled by AcceleratorController. +struct AcceleratorData { + ui::KeyboardCode keycode; + bool shift; + bool ctrl; + bool alt; + AcceleratorAction action; +} kAcceleratorData[] = { + { ui::VKEY_TAB, true, false, true, CYCLE_BACKWARD }, + { ui::VKEY_TAB, false, false, true, CYCLE_FORWARD }, + { ui::VKEY_F5, false, false, false, CYCLE_FORWARD }, + { ui::VKEY_F5, false, true, false, TAKE_SCREENSHOT }, + { ui::VKEY_PRINT, false, false, false, TAKE_SCREENSHOT }, +#if !defined(NDEBUG) + { ui::VKEY_HOME, false, true, false, ROTATE_SCREEN }, + { ui::VKEY_F11, false, true, false, TOGGLE_ROOT_WINDOW_FULL_SCREEN }, + { ui::VKEY_L, false, false, true, PRINT_LAYER_HIERARCHY }, +#endif +}; + +bool HandleCycleWindow(bool forward) { + if (aura_shell::Shell::GetInstance()->IsScreenLocked()) + return false; + + // Use the same order of the windows in LauncherModel to cycle windows. + aura_shell::LauncherModel* model = + aura_shell::Shell::GetInstance()->launcher()->model(); + aura::Window* active_window = aura_shell::GetActiveWindow(); + if (!active_window) { + LOG(ERROR) << "No active window"; + return false; + } + int active_index = model->ItemIndexByWindow(active_window); + if (active_index < 0) { + VLOG(2) << "Active window not found in the launcher model"; + return false; + } + int next_index = (active_index + (forward ? 1 : -1) + model->item_count()) % + model->item_count(); + aura_shell::ActivateWindow(model->items()[next_index].window); + return true; +} + +#if !defined(NDEBUG) +// Rotates the screen. +bool HandleRotateScreen() { + static int i = 0; + int delta = 0; + switch (i) { + case 0: delta = 90; break; + case 1: delta = 90; break; + case 2: delta = 90; break; + case 3: delta = 90; break; + case 4: delta = -90; break; + case 5: delta = -90; break; + case 6: delta = -90; break; + case 7: delta = -90; break; + case 8: delta = -90; break; + case 9: delta = 180; break; + case 10: delta = 180; break; + case 11: delta = 90; break; + case 12: delta = 180; break; + case 13: delta = 180; break; + } + i = (i + 1) % 14; + aura::RootWindow::GetInstance()->layer()->GetAnimator()-> + set_preemption_strategy(ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); + scoped_ptr<ui::LayerAnimationSequence> screen_rotation( + new ui::LayerAnimationSequence(new ui::ScreenRotation(delta))); + screen_rotation->AddObserver(aura::RootWindow::GetInstance()); + aura::RootWindow::GetInstance()->layer()->GetAnimator()->StartAnimation( + screen_rotation.release()); + return true; +} + +bool HandleToggleRootWindowFullScreen() { + aura::RootWindow::GetInstance()->ToggleFullScreen(); + return true; +} + +bool HandlePrintLayerHierarchy() { + ui::PrintLayerHierarchy(aura::RootWindow::GetInstance()->layer()); + return true; +} +#endif + +} // namespace + +namespace aura_shell { + +//////////////////////////////////////////////////////////////////////////////// +// AcceleratorController, public: + +AcceleratorController::AcceleratorController() + : accelerator_manager_(new ui::AcceleratorManager) { + Init(); +} + +AcceleratorController::~AcceleratorController() { +} + +void AcceleratorController::Init() { + for (size_t i = 0; i < arraysize(kAcceleratorData); ++i) { + ui::Accelerator accelerator(kAcceleratorData[i].keycode, + kAcceleratorData[i].shift, + kAcceleratorData[i].ctrl, + kAcceleratorData[i].alt); + Register(accelerator, this); + accelerators_.insert(std::make_pair(accelerator, + kAcceleratorData[i].action)); + } +} + +void AcceleratorController::Register( + const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target) { + accelerator_manager_->Register(accelerator, target); +} + +void AcceleratorController::Unregister( + const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target) { + accelerator_manager_->Unregister(accelerator, target); +} + +void AcceleratorController::UnregisterAll( + ui::AcceleratorTarget* target) { + accelerator_manager_->UnregisterAll(target); +} + +bool AcceleratorController::Process(const ui::Accelerator& accelerator) { + return accelerator_manager_->Process(accelerator); +} + +void AcceleratorController::SetScreenshotDelegate( + ScreenshotDelegate* screenshot_delegate) { + screenshot_delegate_.reset(screenshot_delegate); +} + +//////////////////////////////////////////////////////////////////////////////// +// AcceleratorController, ui::AcceleratorTarget implementation: + +bool AcceleratorController::AcceleratorPressed( + const ui::Accelerator& accelerator) { + std::map<ui::Accelerator, int>::const_iterator it = + accelerators_.find(accelerator); + DCHECK(it != accelerators_.end()); + switch (static_cast<AcceleratorAction>(it->second)) { + case CYCLE_BACKWARD: + return HandleCycleWindow(false); + case CYCLE_FORWARD: + return HandleCycleWindow(true); + case TAKE_SCREENSHOT: + if (screenshot_delegate_.get()) + screenshot_delegate_->HandleTakeScreenshot(); + // Return true to prevent propagation of the key event. + return true; +#if !defined(NDEBUG) + case ROTATE_SCREEN: + return HandleRotateScreen(); + case TOGGLE_ROOT_WINDOW_FULL_SCREEN: + return HandleToggleRootWindowFullScreen(); + case PRINT_LAYER_HIERARCHY: + return HandlePrintLayerHierarchy(); +#endif + default: + NOTREACHED() << "Unhandled action " << it->second;; + } + return false; +} + +} // namespace aura_shell diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h new file mode 100644 index 0000000..e6a0946 --- /dev/null +++ b/ash/accelerators/accelerator_controller.h @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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 ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_H_ +#define ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_H_ +#pragma once + +#include <map> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/base/accelerators/accelerator.h" + +namespace ui { +class AcceleratorManager; +} + +namespace aura_shell { + +class ScreenshotDelegate; + +// AcceleratorController provides functions for registering or unregistering +// global keyboard accelerators, which are handled earlier than any windows. It +// also implements several handlers as an accelerator target. +class AURA_SHELL_EXPORT AcceleratorController : public ui::AcceleratorTarget { + public: + AcceleratorController(); + virtual ~AcceleratorController(); + + // Register a global keyboard accelerator for the specified target. If + // multiple targets are registered for an accelerator, a target registered + // later has higher priority. + void Register(const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target); + + // Unregister the specified keyboard accelerator for the specified target. + void Unregister(const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target); + + // Unregister all keyboard accelerators for the specified target. + void UnregisterAll(ui::AcceleratorTarget* target); + + // Activate the target associated with the specified accelerator. + // First, AcceleratorPressed handler of the most recently registered target + // is called, and if that handler processes the event (i.e. returns true), + // this method immediately returns. If not, we do the same thing on the next + // target, and so on. + // Returns true if an accelerator was activated. + bool Process(const ui::Accelerator& accelerator); + + // Overridden from ui::AcceleratorTarget: + virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; + + void SetScreenshotDelegate(ScreenshotDelegate* screenshot_delegate); + + private: + // Initialize the accelerators this class handles as a target. + void Init(); + + scoped_ptr<ui::AcceleratorManager> accelerator_manager_; + + scoped_ptr<ScreenshotDelegate> screenshot_delegate_; + + // A map from accelerators to the AcceleratorAction values, which are used in + // the implementation. + std::map<ui::Accelerator, int> accelerators_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratorController); +}; + +} // namespace aura_shell + +#endif // ASH_ACCELERATORS_ACCELERATOR_CONTROLLER_H_ diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc new file mode 100644 index 0000000..f4de2e2 --- /dev/null +++ b/ash/accelerators/accelerator_controller_unittest.cc @@ -0,0 +1,333 @@ +// Copyright (c) 2011 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 "ash/accelerators/accelerator_controller.h" +#include "ash/test/aura_shell_test_base.h" +#include "ash/wm/window_util.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura/test/test_window_delegate.h" +#include "ui/aura/test/test_windows.h" +#include "ui/aura/window.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_window_ids.h" + +#if defined(USE_X11) +#include <X11/Xlib.h> +#include "ui/base/x/x11_util.h" +#endif + +namespace aura_shell { +namespace test { + +namespace { +class TestTarget : public ui::AcceleratorTarget { + public: + TestTarget() : accelerator_pressed_count_(0) {}; + virtual ~TestTarget() {}; + + int accelerator_pressed_count() const { + return accelerator_pressed_count_; + } + + void set_accelerator_pressed_count(int accelerator_pressed_count) { + accelerator_pressed_count_ = accelerator_pressed_count; + } + + // Overridden from ui::AcceleratorTarget: + virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; + + private: + int accelerator_pressed_count_; +}; + +bool TestTarget::AcceleratorPressed(const ui::Accelerator& accelerator) { + ++accelerator_pressed_count_; + return true; +} + +} // namespace + +class AcceleratorControllerTest : public AuraShellTestBase { + public: + AcceleratorControllerTest() {}; + virtual ~AcceleratorControllerTest() {}; + + static AcceleratorController* GetController(); +}; + +AcceleratorController* AcceleratorControllerTest::GetController() { + return Shell::GetInstance()->accelerator_controller(); +} + +TEST_F(AcceleratorControllerTest, Register) { + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target; + GetController()->Register(accelerator_a, &target); + + // The registered accelerator is processed. + EXPECT_TRUE(GetController()->Process(accelerator_a)); + EXPECT_EQ(1, target.accelerator_pressed_count()); +} + +TEST_F(AcceleratorControllerTest, RegisterMultipleTarget) { + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target1; + GetController()->Register(accelerator_a, &target1); + TestTarget target2; + GetController()->Register(accelerator_a, &target2); + + // If multiple targets are registered with the same accelerator, the target + // registered later processes the accelerator. + EXPECT_TRUE(GetController()->Process(accelerator_a)); + EXPECT_EQ(0, target1.accelerator_pressed_count()); + EXPECT_EQ(1, target2.accelerator_pressed_count()); +} + +TEST_F(AcceleratorControllerTest, Unregister) { + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target; + GetController()->Register(accelerator_a, &target); + const ui::Accelerator accelerator_b(ui::VKEY_B, false, false, false); + GetController()->Register(accelerator_b, &target); + + // Unregistering a different accelerator does not affect the other + // accelerator. + GetController()->Unregister(accelerator_b, &target); + EXPECT_TRUE(GetController()->Process(accelerator_a)); + EXPECT_EQ(1, target.accelerator_pressed_count()); + + // The unregistered accelerator is no longer processed. + target.set_accelerator_pressed_count(0); + GetController()->Unregister(accelerator_a, &target); + EXPECT_FALSE(GetController()->Process(accelerator_a)); + EXPECT_EQ(0, target.accelerator_pressed_count()); +} + +TEST_F(AcceleratorControllerTest, UnregisterAll) { + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target1; + GetController()->Register(accelerator_a, &target1); + const ui::Accelerator accelerator_b(ui::VKEY_B, false, false, false); + GetController()->Register(accelerator_b, &target1); + const ui::Accelerator accelerator_c(ui::VKEY_C, false, false, false); + TestTarget target2; + GetController()->Register(accelerator_c, &target2); + GetController()->UnregisterAll(&target1); + + // All the accelerators registered for |target1| are no longer processed. + EXPECT_FALSE(GetController()->Process(accelerator_a)); + EXPECT_FALSE(GetController()->Process(accelerator_b)); + EXPECT_EQ(0, target1.accelerator_pressed_count()); + + // UnregisterAll with a different target does not affect the other target. + EXPECT_TRUE(GetController()->Process(accelerator_c)); + EXPECT_EQ(1, target2.accelerator_pressed_count()); +} + +TEST_F(AcceleratorControllerTest, Process) { + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target1; + GetController()->Register(accelerator_a, &target1); + + // The registered accelerator is processed. + EXPECT_TRUE(GetController()->Process(accelerator_a)); + EXPECT_EQ(1, target1.accelerator_pressed_count()); + + // The non-registered accelerator is not processed. + const ui::Accelerator accelerator_b(ui::VKEY_B, false, false, false); + EXPECT_FALSE(GetController()->Process(accelerator_b)); +} + +#if defined(OS_WIN) || defined(USE_X11) +TEST_F(AcceleratorControllerTest, ProcessOnce) { + // A focused window must exist for accelerators to be processed. + aura::Window* default_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_DefaultContainer); + aura::Window* window = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + default_container); + ActivateWindow(window); + + const ui::Accelerator accelerator_a(ui::VKEY_A, false, false, false); + TestTarget target; + GetController()->Register(accelerator_a, &target); + + // The accelerator is processed only once. +#if defined(OS_WIN) + MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 }; + aura::KeyEvent key_event1(msg1, false); + EXPECT_TRUE(aura::RootWindow::GetInstance()->DispatchKeyEvent(&key_event1)); + + MSG msg2 = { NULL, WM_CHAR, L'A', 0 }; + aura::KeyEvent key_event2(msg2, true); + EXPECT_FALSE(aura::RootWindow::GetInstance()->DispatchKeyEvent(&key_event2)); + + MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 }; + aura::KeyEvent key_event3(msg3, false); + EXPECT_FALSE(aura::RootWindow::GetInstance()->DispatchKeyEvent(&key_event3)); +#elif defined(USE_X11) + XEvent key_event; + ui::InitXKeyEventForTesting(ui::ET_KEY_PRESSED, + ui::VKEY_A, + 0, + &key_event); + EXPECT_TRUE(aura::RootWindow::GetInstance()->GetDispatcher()->Dispatch( + &key_event)); +#endif + EXPECT_EQ(1, target.accelerator_pressed_count()); +} +#endif + +TEST_F(AcceleratorControllerTest, GlobalAccelerators) { + // A focused window must exist for accelerators to be processed. + aura::Window* default_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_DefaultContainer); + aura::Window* window = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + default_container); + ActivateWindow(window); + + // CycleBackward + EXPECT_TRUE(GetController()->Process( + ui::Accelerator(ui::VKEY_TAB, true, false, true))); + // CycleForwrard + EXPECT_TRUE(GetController()->Process( + ui::Accelerator(ui::VKEY_F5, false, false, false))); + EXPECT_TRUE(GetController()->Process( + ui::Accelerator(ui::VKEY_TAB, false, false, true))); + // TakeScreenshot + // EXPECT_TRUE(GetController()->Process( + // ui::Accelerator(ui::VKEY_F5, false, true, false))); + // EXPECT_TRUE(GetController()->Process( + // ui::Accelerator(ui::VKEY_PRINT, false, false, false))); +#if !defined(NDEBUG) + // RotateScreen + EXPECT_TRUE(GetController()->Process( + ui::Accelerator(ui::VKEY_HOME, false, true, false))); +#if !defined(OS_LINUX) + // ToggleDesktopFullScreen (not implemented yet on Linux) + EXPECT_TRUE(GetController()->Process( + ui::Accelerator(ui::VKEY_F11, false, true, false))); +#endif +#endif +} + +TEST_F(AcceleratorControllerTest, HandleCycleWindow) { + aura::Window* default_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_DefaultContainer); + aura::Window* window0 = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + default_container); + aura::Window* window1 = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + default_container); + aura::Window* window2 = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + default_container); + ActivateWindow(window0); + EXPECT_TRUE(IsActiveWindow(window0)); + + ui::Accelerator cycle_forward(ui::VKEY_TAB, false, false, true); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_TRUE(IsActiveWindow(window1)); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_TRUE(IsActiveWindow(window2)); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_TRUE(IsActiveWindow(window0)); + + ui::Accelerator cycle_backward(ui::VKEY_TAB, true, false, true); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_TRUE(IsActiveWindow(window2)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_TRUE(IsActiveWindow(window1)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_TRUE(IsActiveWindow(window0)); + + aura::Window* modal_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_AlwaysOnTopContainer); + aura::Window* modal_window = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + modal_container); + + // When the modal window is active, cycling window does not take effect. + ActivateWindow(modal_window); + EXPECT_TRUE(IsActiveWindow(modal_window)); + EXPECT_FALSE(GetController()->Process(cycle_forward)); + EXPECT_TRUE(IsActiveWindow(modal_window)); + EXPECT_FALSE(IsActiveWindow(window0)); + EXPECT_FALSE(IsActiveWindow(window1)); + EXPECT_FALSE(IsActiveWindow(window2)); + EXPECT_FALSE(GetController()->Process(cycle_backward)); + EXPECT_TRUE(IsActiveWindow(modal_window)); + EXPECT_FALSE(IsActiveWindow(window0)); + EXPECT_FALSE(IsActiveWindow(window1)); + EXPECT_FALSE(IsActiveWindow(window2)); + + // The modal window is not activated by cycling window. + ActivateWindow(window0); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); + EXPECT_FALSE(IsActiveWindow(modal_window)); + + // When a screen lock window is visible, cycling window does not take effect. + aura::Window* lock_screen_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_LockScreenContainer); + aura::Window* lock_screen_window = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + lock_screen_container); + + lock_screen_window->Show(); + EXPECT_FALSE(GetController()->Process(cycle_forward)); + EXPECT_FALSE(GetController()->Process(cycle_backward)); + + // When a screen lock window is visible, cycling window does not take effect. + // But otherwise, cycling window does take effect. + aura::Window* lock_modal_container = + aura_shell::Shell::GetInstance()->GetContainer( + internal::kShellWindowId_LockModalContainer); + aura::Window* lock_modal_window = aura::test::CreateTestWindowWithDelegate( + new aura::test::TestWindowDelegate, + -1, + gfx::Rect(), + lock_modal_container); + + lock_modal_window->Show(); + EXPECT_FALSE(GetController()->Process(cycle_forward)); + EXPECT_FALSE(GetController()->Process(cycle_backward)); + lock_screen_window->Hide(); + EXPECT_TRUE(GetController()->Process(cycle_forward)); + EXPECT_TRUE(GetController()->Process(cycle_backward)); +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/accelerators/accelerator_filter.cc b/ash/accelerators/accelerator_filter.cc new file mode 100644 index 0000000..fbeaaa0 --- /dev/null +++ b/ash/accelerators/accelerator_filter.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2011 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 "ash/accelerators/accelerator_filter.h" + +#include "ash/accelerators/accelerator_controller.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura_shell/shell.h" +#include "ui/base/accelerators/accelerator.h" +#include "ui/base/accelerators/accelerator_manager.h" + +namespace { +const int kModifierFlagMask = (ui::EF_SHIFT_DOWN | + ui::EF_CONTROL_DOWN | + ui::EF_ALT_DOWN); +} // namespace + +namespace aura_shell { +namespace internal { + +//////////////////////////////////////////////////////////////////////////////// +// AcceleratorFilter, public: + +AcceleratorFilter::AcceleratorFilter() + : EventFilter(aura::RootWindow::GetInstance()) { +} + +AcceleratorFilter::~AcceleratorFilter() { +} + +//////////////////////////////////////////////////////////////////////////////// +// AcceleratorFilter, EventFilter implementation: + +bool AcceleratorFilter::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + if (event->type() == ui::ET_KEY_PRESSED && !event->is_char()) { + return Shell::GetInstance()->accelerator_controller()->Process( + ui::Accelerator(event->key_code(), + event->flags() & kModifierFlagMask)); + } + return false; +} + +bool AcceleratorFilter::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + return false; +} + +ui::TouchStatus AcceleratorFilter::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/accelerators/accelerator_filter.h b/ash/accelerators/accelerator_filter.h new file mode 100644 index 0000000..11c2fdd --- /dev/null +++ b/ash/accelerators/accelerator_filter.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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 ASH_ACCELERATORS_ACCELERATOR_FILTER_H_ +#define ASH_ACCELERATORS_ACCELERATOR_FILTER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/aura/event_filter.h" +#include "ui/aura_shell/aura_shell_export.h" + +namespace aura_shell { +namespace internal { + +// AcceleratorFilter filters key events for AcceleratorControler handling global +// keyboard accelerators. +class AURA_SHELL_EXPORT AcceleratorFilter : public aura::EventFilter { + public: + AcceleratorFilter(); + virtual ~AcceleratorFilter(); + + // Overridden from aura::EventFilter: + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(AcceleratorFilter); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_ACCELERATORS_ACCELERATOR_FILTER_H_ diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc new file mode 100644 index 0000000..e046a8b --- /dev/null +++ b/ash/desktop_background/desktop_background_view.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2011 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 "ash/desktop_background/desktop_background_view.h" + +#include "base/utf_string_conversions.h" +#include "grit/ui_resources.h" +#include "ui/aura/root_window.h" +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_window_ids.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace internal { + +//////////////////////////////////////////////////////////////////////////////// +// DesktopBackgroundView, public: + +DesktopBackgroundView::DesktopBackgroundView() { + wallpaper_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_AURA_WALLPAPER); + wallpaper_.buildMipMap(false); +} + +DesktopBackgroundView::~DesktopBackgroundView() { +} + +//////////////////////////////////////////////////////////////////////////////// +// DesktopBackgroundView, views::View overrides: + +void DesktopBackgroundView::OnPaint(gfx::Canvas* canvas) { + canvas->DrawBitmapInt(wallpaper_, + 0, 0, wallpaper_.width(), wallpaper_.height(), + 0, 0, width(), height(), + true); +} + +bool DesktopBackgroundView::OnMousePressed(const views::MouseEvent& event) { + return true; +} + +void DesktopBackgroundView::OnMouseReleased(const views::MouseEvent& event) { + Shell::GetInstance()->ToggleOverview(); +} + +views::Widget* CreateDesktopBackground() { + views::Widget* desktop_widget = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + DesktopBackgroundView* view = new DesktopBackgroundView; + params.delegate = view; + desktop_widget->Init(params); + Shell::GetInstance()->GetContainer( + aura_shell::internal::kShellWindowId_DesktopBackgroundContainer)-> + AddChild(desktop_widget->GetNativeView()); + desktop_widget->SetContentsView(view); + desktop_widget->Show(); + desktop_widget->GetNativeView()->SetName("DesktopBackgroundView"); + return desktop_widget; +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/desktop_background/desktop_background_view.h b/ash/desktop_background/desktop_background_view.h new file mode 100644 index 0000000..8f8912b --- /dev/null +++ b/ash/desktop_background/desktop_background_view.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011 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 ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_VIEW_H_ +#define ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_VIEW_H_ +#pragma once + +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget_delegate.h" + +namespace aura_shell { +namespace internal { + +class DesktopBackgroundView : public views::WidgetDelegateView { + public: + DesktopBackgroundView(); + virtual ~DesktopBackgroundView(); + + private: + // Overridden from views::View: + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE; + virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE; + + SkBitmap wallpaper_; + + DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundView); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_VIEW_H_ diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc new file mode 100644 index 0000000..b316d14 --- /dev/null +++ b/ash/drag_drop/drag_drop_controller.cc @@ -0,0 +1,176 @@ +// Copyright (c) 2011 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 "ash/drag_drop/drag_drop_controller.h" + +#include "ash/drag_drop/drag_image_view.h" +#include "base/message_loop.h" +#include "ui/aura/client/drag_drop_delegate.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/aura_shell/shell.h" +#include "ui/base/dragdrop/drag_drop_types.h" +#include "ui/base/dragdrop/os_exchange_data_provider_aura.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" +#include "ui/views/widget/native_widget_aura.h" + +namespace aura_shell { +namespace internal { + +using aura::RootWindow; + +namespace { +const gfx::Point kDragDropWidgetOffset(0, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +// DragDropController, public: + +DragDropController::DragDropController() + : aura::EventFilter(RootWindow::GetInstance()), + drag_image_(NULL), + drag_data_(NULL), + drag_operation_(0), + dragged_window_(NULL), + drag_drop_in_progress_(false), + should_block_during_drag_drop_(true) { + Shell::GetInstance()->AddRootWindowEventFilter(this); + aura::client::SetDragDropClient(this); +} + +DragDropController::~DragDropController() { + Shell::GetInstance()->RemoveRootWindowEventFilter(this); + Cleanup(); +} + +int DragDropController::StartDragAndDrop(const ui::OSExchangeData& data, + int operation) { + DCHECK(!drag_drop_in_progress_); + aura::Window* capture_window = RootWindow::GetInstance()->capture_window(); + if (capture_window) + RootWindow::GetInstance()->ReleaseCapture(capture_window); + drag_drop_in_progress_ = true; + + drag_data_ = &data; + drag_operation_ = operation; + gfx::Point location = RootWindow::GetInstance()->last_mouse_location(); + const ui::OSExchangeDataProviderAura& provider = + static_cast<const ui::OSExchangeDataProviderAura&>(data.provider()); + + drag_image_.reset(new DragImageView); + drag_image_->SetImage(provider.drag_image()); + drag_image_->SetScreenBounds(gfx::Rect(location.Add(kDragDropWidgetOffset), + drag_image_->GetPreferredSize())); + drag_image_->SetWidgetVisible(true); + + dragged_window_ = NULL; + + if (should_block_during_drag_drop_) { + MessageLoopForUI::current()->RunWithDispatcher( + RootWindow::GetInstance()->GetDispatcher()); + } + return drag_operation_; +} + +void DragDropController::DragUpdate(aura::Window* target, + const aura::MouseEvent& event) { + aura::client::DragDropDelegate* delegate = NULL; + if (target != dragged_window_) { + if (dragged_window_ && + (delegate = aura::client::GetDragDropDelegate(dragged_window_))) { + delegate->OnDragExited(); + } + dragged_window_ = target; + if ((delegate = aura::client::GetDragDropDelegate(dragged_window_))) { + aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_); + delegate->OnDragEntered(e); + } + } else { + if ((delegate = aura::client::GetDragDropDelegate(dragged_window_))) { + aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_); + int op = delegate->OnDragUpdated(e); + gfx::NativeCursor cursor = (op == ui::DragDropTypes::DRAG_NONE)? + aura::kCursorMove : aura::kCursorHand; + RootWindow::GetInstance()->SetCursor(cursor); + } + } + + DCHECK(drag_image_.get()); + if (drag_image_->visible()) { + drag_image_->SetScreenPosition(RootWindow::GetInstance()-> + last_mouse_location().Add(kDragDropWidgetOffset)); + } +} + +void DragDropController::Drop(aura::Window* target, + const aura::MouseEvent& event) { + aura::client::DragDropDelegate* delegate = NULL; + DCHECK(target == dragged_window_); + if ((delegate = aura::client::GetDragDropDelegate(dragged_window_))) { + aura::DropTargetEvent e(*drag_data_, event.location(), drag_operation_); + drag_operation_ = delegate->OnPerformDrop(e); + // TODO(varunjain): if drag_op is 0, do drag widget flying back animation + } + + Cleanup(); + if (should_block_during_drag_drop_) + MessageLoop::current()->Quit(); +} + +void DragDropController::DragCancel() { + // TODO(varunjain): Do drag widget flying back animation + Cleanup(); + drag_operation_ = 0; + if (should_block_during_drag_drop_) + MessageLoop::current()->Quit(); +} + +bool DragDropController::IsDragDropInProgress() { + return drag_drop_in_progress_; +} + +bool DragDropController::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + return false; +} + +bool DragDropController::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + if (!drag_drop_in_progress_) + return false; + switch (event->type()) { + case ui::ET_MOUSE_DRAGGED: + DragUpdate(target, *event); + break; + case ui::ET_MOUSE_RELEASED: + Drop(target, *event); + break; + case ui::ET_MOUSE_EXITED: + DragCancel(); + break; + default: + NOTREACHED(); + break; + } + return true; +} + +ui::TouchStatus DragDropController::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +//////////////////////////////////////////////////////////////////////////////// +// DragDropController, private: + +void DragDropController::Cleanup() { + drag_image_.reset(); + drag_data_ = NULL; + drag_drop_in_progress_ = false; +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h new file mode 100644 index 0000000..b1aabf8 --- /dev/null +++ b/ash/drag_drop/drag_drop_controller.h @@ -0,0 +1,83 @@ +// Copyright (c) 2011 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 ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_ +#define ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_ +#pragma once + +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/aura/client/drag_drop_client.h" +#include "ui/aura/event.h" +#include "ui/aura/event_filter.h" +#include "ui/base/dragdrop/os_exchange_data.h" +#include "ui/base/events.h" +#include "ui/gfx/point.h" + +namespace aura { +class Window; +} + +namespace aura_shell { + +namespace test { +class DragDropControllerTest; +} + +namespace internal { + +class DragImageView; + +class AURA_SHELL_EXPORT DragDropController + : public aura::client::DragDropClient, + public aura::EventFilter { + public: + DragDropController(); + virtual ~DragDropController(); + + void set_should_block_during_drag_drop(bool should_block_during_drag_drop) { + should_block_during_drag_drop_ = should_block_during_drag_drop; + } + + // Overridden from aura::client::DragDropClient: + virtual int StartDragAndDrop(const ui::OSExchangeData& data, + int operation) OVERRIDE; + virtual void DragUpdate(aura::Window* target, + const aura::MouseEvent& event) OVERRIDE; + virtual void Drop(aura::Window* target, + const aura::MouseEvent& event) OVERRIDE; + virtual void DragCancel() OVERRIDE; + virtual bool IsDragDropInProgress() OVERRIDE; + + // Overridden from aura::EventFilter: + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + + private: + friend class aura_shell::test::DragDropControllerTest; + + // Helper method to reset everything. + void Cleanup(); + + scoped_ptr<DragImageView> drag_image_; + const ui::OSExchangeData* drag_data_; + int drag_operation_; + aura::Window* dragged_window_; + + bool drag_drop_in_progress_; + + // Indicates whether the caller should be blocked on a drag/drop session. + // Only be used for tests. + bool should_block_during_drag_drop_; + + DISALLOW_COPY_AND_ASSIGN(DragDropController); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_ diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc new file mode 100644 index 0000000..db4ae5e --- /dev/null +++ b/ash/drag_drop/drag_drop_controller_unittest.cc @@ -0,0 +1,432 @@ +// Copyright (c) 2011 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 "ash/drag_drop/drag_drop_controller.h" + +#include "ash/test/aura_shell_test_base.h" +#include "ash/wm/root_window_event_filter.h" +#include "base/location.h" +#include "base/utf_string_conversions.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/base/dragdrop/drag_drop_types.h" +#include "ui/base/dragdrop/os_exchange_data.h" +#include "ui/views/events/event.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace test { + +namespace { + +// A simple view that makes sure RunShellDrag is invoked on mouse drag. +class DragTestView : public views::View { + public: + DragTestView() : views::View() { + Reset(); + } + + void Reset() { + num_drag_enters_ = 0; + num_drag_exits_ = 0; + num_drag_updates_ = 0; + num_drops_ = 0; + drag_done_received_ = false; + } + + int VerticalDragThreshold() { + return views::View::GetVerticalDragThreshold(); + } + + int HorizontalDragThreshold() { + return views::View::GetHorizontalDragThreshold(); + } + + int num_drag_enters_; + int num_drag_exits_; + int num_drag_updates_; + int num_drops_; + bool drag_done_received_; + + private: + // View overrides: + int GetDragOperations(const gfx::Point& press_pt) OVERRIDE { + return ui::DragDropTypes::DRAG_COPY; + } + + void WriteDragData(const gfx::Point& p, OSExchangeData* data) OVERRIDE { + data->SetString(UTF8ToUTF16("I am being dragged")); + } + + bool OnMousePressed(const views::MouseEvent& event) OVERRIDE { + return true; + } + + bool GetDropFormats(int* formats, + std::set<OSExchangeData::CustomFormat>* custom_formats) { + *formats = ui::OSExchangeData::STRING; + return true; + } + + bool CanDrop(const OSExchangeData& data) OVERRIDE { + return true; + } + + void OnDragEntered(const views::DropTargetEvent& event) OVERRIDE { + num_drag_enters_++; + } + + int OnDragUpdated(const views::DropTargetEvent& event) OVERRIDE { + num_drag_updates_++; + return ui::DragDropTypes::DRAG_COPY; + } + + void OnDragExited() OVERRIDE { + num_drag_exits_++; + } + + int OnPerformDrop(const views::DropTargetEvent& event) OVERRIDE { + num_drops_++; + return ui::DragDropTypes::DRAG_COPY; + } + + void OnDragDone() OVERRIDE { + drag_done_received_ = true; + } + + DISALLOW_COPY_AND_ASSIGN(DragTestView); +}; + +class TestDragDropController : public internal::DragDropController { + public: + TestDragDropController() : internal::DragDropController() { + Reset(); + } + + void Reset() { + drag_start_received_ = false; + num_drag_updates_ = 0; + drop_received_ = false; + drag_string_.clear(); + } + + bool drag_start_received_; + int num_drag_updates_; + bool drop_received_; + string16 drag_string_; + + private: + int StartDragAndDrop(const ui::OSExchangeData& data, + int operation) OVERRIDE { + drag_start_received_ = true; + data.GetString(&drag_string_); + return DragDropController::StartDragAndDrop(data, operation); + } + + void DragUpdate(aura::Window* target, + const aura::MouseEvent& event) OVERRIDE { + DragDropController::DragUpdate(target, event); + num_drag_updates_++; + } + + void Drop(aura::Window* target, const aura::MouseEvent& event) OVERRIDE { + DragDropController::Drop(target, event); + drop_received_ = true; + } + + DISALLOW_COPY_AND_ASSIGN(TestDragDropController); +}; + +views::Widget* CreateNewWidget() { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; + params.accept_events = true; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.parent = aura::RootWindow::GetInstance(); + params.child = true; + widget->Init(params); + widget->Show(); + return widget; +} + +void AddViewToWidgetAndResize(views::Widget* widget, views::View* view) { + if (!widget->GetContentsView()) { + views::View* contents_view = new views::View; + widget->SetContentsView(contents_view); + } + + views::View* contents_view = widget->GetContentsView(); + contents_view->AddChildView(view); + view->SetBounds(contents_view->width(), 0, 100, 100); + gfx::Rect contents_view_bounds = contents_view->bounds(); + contents_view_bounds = contents_view_bounds.Union(view->bounds()); + contents_view->SetBoundsRect(contents_view_bounds); + widget->SetBounds(contents_view_bounds); +} + +} // namespace + +class DragDropControllerTest : public AuraShellTestBase { + public: + DragDropControllerTest() : AuraShellTestBase() {} + virtual ~DragDropControllerTest() {} + + void SetUp() OVERRIDE { + AuraShellTestBase::SetUp(); + drag_drop_controller_.reset(new TestDragDropController); + drag_drop_controller_->set_should_block_during_drag_drop(false); + aura::client::SetDragDropClient(drag_drop_controller_.get()); + } + + void TearDown() OVERRIDE { + aura::client::SetDragDropClient(NULL); + drag_drop_controller_.reset(); + AuraShellTestBase::TearDown(); + } + + void UpdateDragData(ui::OSExchangeData* data) { + drag_drop_controller_->drag_data_ = data; + } + + protected: + scoped_ptr<TestDragDropController> drag_drop_controller_; + + private: + DISALLOW_COPY_AND_ASSIGN(DragDropControllerTest); +}; + +TEST_F(DragDropControllerTest, DragDropInSingleViewTest) { + views::Widget* widget = CreateNewWidget(); + DragTestView* drag_view = new DragTestView; + AddViewToWidgetAndResize(widget, drag_view); + gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint(); + ui::OSExchangeData data; + data.SetString(UTF8ToUTF16("I am being dragged")); + + aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event1); + + int num_drags = 17; + for (int i = 0; i < num_drags; ++i) { + // Because we are not doing a blocking drag and drop, the original + // OSDragExchangeData object is lost as soon as we return from the drag + // initiation in DragDropController::StartDragAndDrop(). Hence we set the + // drag_data_ to a fake drag data object that we created. + if (i > 0) + UpdateDragData(&data); + point.Offset(0, 1); + aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&drag_event); + } + + aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event2); + + EXPECT_TRUE(drag_drop_controller_->drag_start_received_); + EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(), + drag_drop_controller_->num_drag_updates_); + EXPECT_TRUE(drag_drop_controller_->drop_received_); + EXPECT_EQ(UTF8ToUTF16("I am being dragged"), + drag_drop_controller_->drag_string_); + + EXPECT_EQ(1, drag_view->num_drag_enters_); + EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(), + drag_view->num_drag_updates_); + EXPECT_EQ(1, drag_view->num_drops_); + EXPECT_EQ(0, drag_view->num_drag_exits_); + EXPECT_TRUE(drag_view->drag_done_received_); + delete widget; +} + +TEST_F(DragDropControllerTest, DragDropInMultipleViewsSingleWidgetTest) { + views::Widget* widget = CreateNewWidget(); + DragTestView* drag_view1 = new DragTestView; + AddViewToWidgetAndResize(widget, drag_view1); + gfx::Point point = drag_view1->bounds().CenterPoint(); + DragTestView* drag_view2 = new DragTestView; + AddViewToWidgetAndResize(widget, drag_view2); + + ui::OSExchangeData data; + data.SetString(UTF8ToUTF16("I am being dragged")); + + aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event1); + + int num_drags = drag_view1->width(); + for (int i = 0; i < num_drags; ++i) { + // Because we are not doing a blocking drag and drop, the original + // OSDragExchangeData object is lost as soon as we return from the drag + // initiation in DragDropController::StartDragAndDrop(). Hence we set the + // drag_data_ to a fake drag data object that we created. + if (i > 0) + UpdateDragData(&data); + point.Offset(1, 0); + aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&drag_event); + } + + aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event2); + + EXPECT_TRUE(drag_drop_controller_->drag_start_received_); + EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(), + drag_drop_controller_->num_drag_updates_); + EXPECT_TRUE(drag_drop_controller_->drop_received_); + EXPECT_EQ(UTF8ToUTF16("I am being dragged"), + drag_drop_controller_->drag_string_); + + EXPECT_EQ(1, drag_view1->num_drag_enters_); + int num_expected_updates = drag_view1->bounds().width() - + drag_view1->bounds().CenterPoint().x() - 2; + EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(), + drag_view1->num_drag_updates_); + EXPECT_EQ(0, drag_view1->num_drops_); + EXPECT_EQ(1, drag_view1->num_drag_exits_); + EXPECT_TRUE(drag_view1->drag_done_received_); + + EXPECT_EQ(1, drag_view2->num_drag_enters_); + num_expected_updates = num_drags - num_expected_updates - 1; + EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_); + EXPECT_EQ(1, drag_view2->num_drops_); + EXPECT_EQ(0, drag_view2->num_drag_exits_); + EXPECT_FALSE(drag_view2->drag_done_received_); + delete widget; +} + +TEST_F(DragDropControllerTest, DragDropInMultipleViewsMultipleWidgetsTest) { + views::Widget* widget1 = CreateNewWidget(); + DragTestView* drag_view1 = new DragTestView; + AddViewToWidgetAndResize(widget1, drag_view1); + gfx::Point point = drag_view1->bounds().CenterPoint(); + views::Widget* widget2 = CreateNewWidget(); + DragTestView* drag_view2 = new DragTestView; + AddViewToWidgetAndResize(widget2, drag_view2); + gfx::Rect widget1_bounds = widget1->GetClientAreaScreenBounds(); + gfx::Rect widget2_bounds = widget2->GetClientAreaScreenBounds(); + widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0, + widget2_bounds.width(), widget2_bounds.height())); + + ui::OSExchangeData data; + data.SetString(UTF8ToUTF16("I am being dragged")); + + aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event1); + + int num_drags = drag_view1->width(); + for (int i = 0; i < num_drags; ++i) { + // Because we are not doing a blocking drag and drop, the original + // OSDragExchangeData object is lost as soon as we return from the drag + // initiation in DragDropController::StartDragAndDrop(). Hence we set the + // drag_data_ to a fake drag data object that we created. + if (i > 0) + UpdateDragData(&data); + point.Offset(1, 0); + aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&drag_event); + } + + aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event2); + + EXPECT_TRUE(drag_drop_controller_->drag_start_received_); + EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(), + drag_drop_controller_->num_drag_updates_); + EXPECT_TRUE(drag_drop_controller_->drop_received_); + EXPECT_EQ(UTF8ToUTF16("I am being dragged"), + drag_drop_controller_->drag_string_); + + EXPECT_EQ(1, drag_view1->num_drag_enters_); + int num_expected_updates = drag_view1->bounds().width() - + drag_view1->bounds().CenterPoint().x() - 2; + EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(), + drag_view1->num_drag_updates_); + EXPECT_EQ(0, drag_view1->num_drops_); + EXPECT_EQ(1, drag_view1->num_drag_exits_); + EXPECT_TRUE(drag_view1->drag_done_received_); + + EXPECT_EQ(1, drag_view2->num_drag_enters_); + num_expected_updates = num_drags - num_expected_updates - 1; + EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_); + EXPECT_EQ(1, drag_view2->num_drops_); + EXPECT_EQ(0, drag_view2->num_drag_exits_); + EXPECT_FALSE(drag_view2->drag_done_received_); + delete widget1; + delete widget2; +} + +TEST_F(DragDropControllerTest, ViewRemovedWhileInDragDropTest) { + views::Widget* widget = CreateNewWidget(); + DragTestView* drag_view = new DragTestView; + AddViewToWidgetAndResize(widget, drag_view); + gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint(); + ui::OSExchangeData data; + data.SetString(UTF8ToUTF16("I am being dragged")); + + aura::MouseEvent event1(ui::ET_MOUSE_PRESSED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event1); + + int num_drags_1 = 17; + for (int i = 0; i < num_drags_1; ++i) { + // Because we are not doing a blocking drag and drop, the original + // OSDragExchangeData object is lost as soon as we return from the drag + // initiation in DragDropController::StartDragAndDrop(). Hence we set the + // drag_data_ to a fake drag data object that we created. + if (i > 0) + UpdateDragData(&data); + point.Offset(0, 1); + aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&drag_event); + } + + drag_view->parent()->RemoveChildView(drag_view); + // View has been removed. We will not get any of the following drag updates. + int num_drags_2 = 23; + for (int i = 0; i < num_drags_2; ++i) { + UpdateDragData(&data); + point.Offset(0, 1); + aura::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, + point, + ui::EF_LEFT_MOUSE_BUTTON); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&drag_event); + } + + aura::MouseEvent event2(ui::ET_MOUSE_RELEASED, point, 0); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event2); + + EXPECT_TRUE(drag_drop_controller_->drag_start_received_); + EXPECT_EQ(num_drags_1 + num_drags_2 - 1 - drag_view->VerticalDragThreshold(), + drag_drop_controller_->num_drag_updates_); + EXPECT_TRUE(drag_drop_controller_->drop_received_); + EXPECT_EQ(UTF8ToUTF16("I am being dragged"), + drag_drop_controller_->drag_string_); + + EXPECT_EQ(1, drag_view->num_drag_enters_); + EXPECT_EQ(num_drags_1 - 1 - drag_view->VerticalDragThreshold(), + drag_view->num_drag_updates_); + EXPECT_EQ(0, drag_view->num_drops_); + EXPECT_EQ(0, drag_view->num_drag_exits_); + EXPECT_TRUE(drag_view->drag_done_received_); + delete widget; +} + +} // namespace test +} // namespace aura diff --git a/ash/drag_drop/drag_image_view.cc b/ash/drag_drop/drag_image_view.cc new file mode 100644 index 0000000..13e4193 --- /dev/null +++ b/ash/drag_drop/drag_image_view.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2011 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 "ash/drag_drop/drag_image_view.h" + +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace internal { + +namespace { +using views::Widget; + +Widget* CreateDragWidget() { + Widget* drag_widget = new Widget; + Widget::InitParams params; + params.type = Widget::InitParams::TYPE_TOOLTIP; + params.keep_on_top = true; + params.accept_events = false; + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.transparent = true; + drag_widget->Init(params); + drag_widget->SetOpacity(0xFF); + return drag_widget; +} +} + +DragImageView::DragImageView() : views::ImageView() { + widget_.reset(CreateDragWidget()); + widget_->SetContentsView(this); + widget_->SetAlwaysOnTop(true); + + // We are owned by the DragDropController. + set_parent_owned(false); +} + +DragImageView::~DragImageView() { + widget_->Hide(); +} + +void DragImageView::SetScreenBounds(const gfx::Rect& bounds) { + widget_->SetBounds(bounds); +} + +void DragImageView::SetScreenPosition(const gfx::Point& position) { + widget_->SetBounds(gfx::Rect(position, GetPreferredSize())); +} + +void DragImageView::SetWidgetVisible(bool visible) { + if (visible != widget_->IsVisible()) { + if (visible) + widget_->Show(); + else + widget_->Hide(); + } +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/drag_drop/drag_image_view.h b/ash/drag_drop/drag_image_view.h new file mode 100644 index 0000000..2e75034 --- /dev/null +++ b/ash/drag_drop/drag_image_view.h @@ -0,0 +1,41 @@ +// Copyright (c) 2011 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 ASH_DRAG_DROP_DRAG_IMAGE_VIEW_H_ +#define ASH_DRAG_DROP_DRAG_IMAGE_VIEW_H_ +#pragma once + +#include "ui/views/controls/image_view.h" + +namespace views { +class Widget; +} + +namespace aura_shell { +namespace internal { + +class DragImageView : public views::ImageView { + public: + DragImageView(); + virtual ~DragImageView(); + + // Sets the bounds of the native widget. + void SetScreenBounds(const gfx::Rect& bounds); + + // Sets the position of the native widget. + void SetScreenPosition(const gfx::Point& position); + + // Sets the visibility of the native widget. + void SetWidgetVisible(bool visible); + + private: + scoped_ptr<views::Widget> widget_; + + DISALLOW_COPY_AND_ASSIGN(DragImageView); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_DRAG_DROP_DRAG_IMAGE_VIEW_H_ diff --git a/ash/launcher/launcher_unittest.cc b/ash/launcher/launcher_unittest.cc index de65658..69ac021 100644 --- a/ash/launcher/launcher_unittest.cc +++ b/ash/launcher/launcher_unittest.cc @@ -4,8 +4,8 @@ #include "ash/launcher/launcher.h" +#include "ash/test/aura_shell_test_base.h" #include "ui/aura_shell/shell.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" diff --git a/ash/status_area/status_area_view.cc b/ash/status_area/status_area_view.cc new file mode 100644 index 0000000..5f9fb01 --- /dev/null +++ b/ash/status_area/status_area_view.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2011 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 "ash/status_area/status_area_view.h" + +#include "base/utf_string_conversions.h" +#include "grit/ui_resources.h" +#include "ui/aura/root_window.h" +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_window_ids.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace internal { + +StatusAreaView::StatusAreaView() + : status_mock_(*ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_AURA_STATUS_MOCK)) { +} +StatusAreaView::~StatusAreaView() { +} + +gfx::Size StatusAreaView::GetPreferredSize() { + return gfx::Size(status_mock_.width(), status_mock_.height()); +} + +void StatusAreaView::OnPaint(gfx::Canvas* canvas) { + canvas->DrawBitmapInt(status_mock_, 0, 0); +} + +AURA_SHELL_EXPORT views::Widget* CreateStatusArea() { + StatusAreaView* status_area_view = new StatusAreaView; + views::Widget* widget = new views::Widget; + views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); + gfx::Size ps = status_area_view->GetPreferredSize(); + params.bounds = gfx::Rect(0, 0, ps.width(), ps.height()); + params.parent = Shell::GetInstance()->GetContainer( + aura_shell::internal::kShellWindowId_StatusContainer); + params.delegate = status_area_view; + params.transparent = true; + widget->Init(params); + widget->SetContentsView(status_area_view); + widget->Show(); + widget->GetNativeView()->SetName("StatusAreaView"); + return widget; +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/status_area/status_area_view.h b/ash/status_area/status_area_view.h new file mode 100644 index 0000000..7e7f8dc --- /dev/null +++ b/ash/status_area/status_area_view.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 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 ASH_STATUS_AREA_STATUS_AREA_VIEW_H_ +#define ASH_STATUS_AREA_STATUS_AREA_VIEW_H_ +#pragma once + +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/views/widget/widget_delegate.h" + +namespace aura_shell { +namespace internal { + +class StatusAreaView : public views::WidgetDelegateView { + public: + StatusAreaView(); + virtual ~StatusAreaView(); + + // Overridden from views::View: + virtual gfx::Size GetPreferredSize() OVERRIDE; + + private: + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + + SkBitmap status_mock_; + + DISALLOW_COPY_AND_ASSIGN(StatusAreaView); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_STATUS_AREA_STATUS_AREA_VIEW_H_ diff --git a/ash/test/aura_shell_test_base.cc b/ash/test/aura_shell_test_base.cc new file mode 100644 index 0000000..608f76a --- /dev/null +++ b/ash/test/aura_shell_test_base.cc @@ -0,0 +1,37 @@ +// Copyright (c) 2011 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 "ash/test/aura_shell_test_base.h" + +#include "ash/test/test_shell_delegate.h" +#include "ui/aura_shell/shell.h" + +namespace aura_shell { +namespace test { + +AuraShellTestBase::AuraShellTestBase() { +} + +AuraShellTestBase::~AuraShellTestBase() { +} + +void AuraShellTestBase::SetUp() { + aura::test::AuraTestBase::SetUp(); + + // Creates Shell and hook with Desktop. + aura_shell::Shell::CreateInstance(new TestShellDelegate); +} + +void AuraShellTestBase::TearDown() { + // Flush the message loop to finish pending release tasks. + RunAllPendingInMessageLoop(); + + // Tear down the shell. + aura_shell::Shell::DeleteInstance(); + + aura::test::AuraTestBase::TearDown(); +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/test/aura_shell_test_base.h b/ash/test/aura_shell_test_base.h new file mode 100644 index 0000000..92cb9ca --- /dev/null +++ b/ash/test/aura_shell_test_base.h @@ -0,0 +1,31 @@ +// Copyright (c) 2011 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 ASH_TEST_AURA_SHELL_TEST_BASE_H_ +#define ASH_TEST_AURA_SHELL_TEST_BASE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "ui/aura/test/aura_test_base.h" + +namespace aura_shell { +namespace test { + +class AuraShellTestBase : public aura::test::AuraTestBase { + public: + AuraShellTestBase(); + virtual ~AuraShellTestBase(); + + // testing::Test: + virtual void SetUp() OVERRIDE; + virtual void TearDown() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(AuraShellTestBase); +}; + +} // namespace test +} // namespace aura_shell + +#endif // ASH_TEST_AURA_SHELL_TEST_BASE_H_ diff --git a/ash/test/test_activation_delegate.cc b/ash/test/test_activation_delegate.cc new file mode 100644 index 0000000..e92223a --- /dev/null +++ b/ash/test/test_activation_delegate.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2011 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 "ash/test/test_activation_delegate.h" + +#include "ash/wm/window_util.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/window.h" + +namespace aura_shell { +namespace test { + +//////////////////////////////////////////////////////////////////////////////// +// TestActivationDelegate + +TestActivationDelegate::TestActivationDelegate() + : window_(NULL), + window_was_active_(false), + activate_(true), + activated_count_(0), + lost_active_count_(0), + should_activate_count_(0) { +} + +TestActivationDelegate::TestActivationDelegate(bool activate) + : window_(NULL), + window_was_active_(false), + activate_(activate), + activated_count_(0), + lost_active_count_(0), + should_activate_count_(0) { +} + +void TestActivationDelegate::SetWindow(aura::Window* window) { + window_ = window; + aura::client::SetActivationDelegate(window, this); +} + +bool TestActivationDelegate::ShouldActivate(aura::Event* event) { + should_activate_count_++; + return activate_; +} +void TestActivationDelegate::OnActivated() { + activated_count_++; +} +void TestActivationDelegate::OnLostActive() { + if (lost_active_count_++ == 0) + window_was_active_ = IsActiveWindow(window_); +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/test/test_activation_delegate.h b/ash/test/test_activation_delegate.h new file mode 100644 index 0000000..d799745 --- /dev/null +++ b/ash/test/test_activation_delegate.h @@ -0,0 +1,59 @@ +// Copyright (c) 2011 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 ASH_TEST_TEST_ACTIVATION_DELEGATE_H_ +#define ASH_TEST_TEST_ACTIVATION_DELEGATE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "ui/aura/client/activation_delegate.h" + +namespace aura { +class Window; +} + +namespace aura_shell { +namespace test { + +// A test ActivationDelegate that can be used to track activation changes for +// an aura::Window. +class TestActivationDelegate : public aura::client::ActivationDelegate { + public: + TestActivationDelegate(); + explicit TestActivationDelegate(bool activate); + + // Associates this delegate with a Window. + void SetWindow(aura::Window* window); + + bool window_was_active() const { return window_was_active_; } + void set_activate(bool v) { activate_ = v; } + int activated_count() const { return activated_count_; } + int lost_active_count() const { return lost_active_count_; } + int should_activate_count() const { return should_activate_count_; } + void Clear() { + activated_count_ = lost_active_count_ = should_activate_count_ = 0; + window_was_active_ = false; + } + + // Overridden from client::ActivationDelegate: + virtual bool ShouldActivate(aura::Event* event) OVERRIDE; + virtual void OnActivated() OVERRIDE; + virtual void OnLostActive() OVERRIDE; + + private: + aura::Window* window_; + bool window_was_active_; + bool activate_; + int activated_count_; + int lost_active_count_; + int should_activate_count_; + + DISALLOW_COPY_AND_ASSIGN(TestActivationDelegate); +}; + +} // namespace test +} // namespace aura_shell + +#endif // ASH_TEST_TEST_ACTIVATION_DELEGATE_H_ diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc new file mode 100644 index 0000000..eb289f4 --- /dev/null +++ b/ash/test/test_shell_delegate.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2011 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 "ash/test/test_shell_delegate.h" + +namespace aura_shell { +namespace test { + +TestShellDelegate::TestShellDelegate() { +} + +TestShellDelegate::~TestShellDelegate() { +} + +void TestShellDelegate::CreateNewWindow() { +} + +views::Widget* TestShellDelegate::CreateStatusArea() { + return NULL; +} + +void TestShellDelegate::RequestAppListWidget( + const gfx::Rect& bounds, + const SetWidgetCallback& callback) { +} + +void TestShellDelegate::BuildAppListModel(AppListModel* model) { +} + +AppListViewDelegate* TestShellDelegate::CreateAppListViewDelegate() { + return NULL; +} + +void TestShellDelegate::LauncherItemClicked(const LauncherItem& item) { +} + +bool TestShellDelegate::ConfigureLauncherItem(LauncherItem* item) { + return true; +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h new file mode 100644 index 0000000..6d922ca --- /dev/null +++ b/ash/test/test_shell_delegate.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011 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 ASH_TEST_TEST_SHELL_DELEGATE_H_ +#define ASH_TEST_TEST_SHELL_DELEGATE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "ui/aura_shell/shell_delegate.h" + +namespace aura_shell { +namespace test { + +class TestShellDelegate : public ShellDelegate { + public: + TestShellDelegate(); + virtual ~TestShellDelegate(); + + // Overridden from ShellDelegate: + virtual void CreateNewWindow() OVERRIDE; + virtual views::Widget* CreateStatusArea() OVERRIDE; + virtual void RequestAppListWidget( + const gfx::Rect& bounds, + const SetWidgetCallback& callback) OVERRIDE; + virtual void BuildAppListModel(AppListModel* model) OVERRIDE; + virtual AppListViewDelegate* CreateAppListViewDelegate() OVERRIDE; + virtual void LauncherItemClicked(const LauncherItem& item) OVERRIDE; + virtual bool ConfigureLauncherItem(LauncherItem* item) OVERRIDE; +}; + +} // namespace test +} // namespace aura_shell + +#endif // ASH_TEST_TEST_SHELL_DELEGATE_H_ diff --git a/ash/test/test_suite.cc b/ash/test/test_suite.cc new file mode 100644 index 0000000..eb22a6b --- /dev/null +++ b/ash/test/test_suite.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2011 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 "ash/test/test_suite.h" + +#include "base/file_path.h" +#include "base/path_service.h" +#include "build/build_config.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_paths.h" +#include "ui/gfx/compositor/test/compositor_test_support.h" +#include "ui/gfx/gfx_paths.h" + +#if defined(USE_WEBKIT_COMPOSITOR) +#include "ui/gfx/compositor/compositor_setup.h" +#else +#include "ui/gfx/test/gfx_test_utils.h" +#endif + +namespace aura_shell { +namespace test { + +AuraShellTestSuite::AuraShellTestSuite(int argc, char** argv) + : TestSuite(argc, argv) {} + +void AuraShellTestSuite::Initialize() { + base::TestSuite::Initialize(); + + gfx::RegisterPathProvider(); + ui::RegisterPathProvider(); + + // Force unittests to run using en-US so if we test against string + // output, it'll pass regardless of the system language. + ui::ResourceBundle::InitSharedInstance("en-US"); + ui::CompositorTestSupport::Initialize(); +#if defined(USE_WEBKIT_COMPOSITOR) + ui::SetupTestCompositor(); +#else + ui::gfx_test_utils::SetupTestCompositor(); +#endif +} + +void AuraShellTestSuite::Shutdown() { + ui::CompositorTestSupport::Terminate(); + ui::ResourceBundle::CleanupSharedInstance(); + + base::TestSuite::Shutdown(); +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/test/test_suite.h b/ash/test/test_suite.h new file mode 100644 index 0000000..5a32b69 --- /dev/null +++ b/ash/test/test_suite.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 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 ASH_TEST_TEST_SUITE_H_ +#define ASH_TEST_TEST_SUITE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/test/test_suite.h" + +namespace aura_shell { +namespace test { + +class AuraShellTestSuite : public base::TestSuite { + public: + AuraShellTestSuite(int argc, char** argv); + + protected: + // base::TestSuite: + virtual void Initialize() OVERRIDE; + virtual void Shutdown() OVERRIDE; +}; + +} // namespace test +} // namespace aura_shell + +#endif // ASH_TEST_TEST_SUITE_H_ diff --git a/ash/tooltips/tooltip_controller.cc b/ash/tooltips/tooltip_controller.cc new file mode 100644 index 0000000..20e1097 --- /dev/null +++ b/ash/tooltips/tooltip_controller.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2011 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 "ash/tooltips/tooltip_controller.h" + +#include <vector> + +#include "base/command_line.h" +#include "base/location.h" +#include "base/string_split.h" +#include "base/time.h" +#include "ui/aura_shell/aura_shell_switches.h" +#include "ui/aura/event.h" +#include "ui/aura/window.h" +#include "ui/aura_shell/shell.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/text/text_elider.h" +#include "ui/gfx/font.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/screen.h" +#include "ui/views/background.h" +#include "ui/views/border.h" +#include "ui/views/controls/label.h" +#include "ui/views/widget/widget.h" + +namespace { + +const SkColor kTooltipBackground = 0xFFFFFFCC; +const SkColor kTooltipBorder = 0xFF646450; +const int kTooltipBorderWidth = 1; +const int kTooltipHorizontalPadding = 3; +// TODO(derat): This padding is needed on Chrome OS devices but seems excessive +// when running the same binary on a Linux workstation; presumably there's a +// difference in font metrics. Rationalize this. +const int kTooltipVerticalPadding = 2; +const int kTooltipTimeoutMs = 500; + +// FIXME: get cursor offset from actual cursor size. +const int kCursorOffsetX = 10; +const int kCursorOffsetY = 15; + +// Maximum number of characters we allow in a tooltip. +const size_t kMaxTooltipLength = 1024; + +// Maximum number of lines we allow in the tooltip. +const size_t kMaxLines = 6; + +gfx::Font GetDefaultFont() { + // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure + // out a way to merge. + return ui::ResourceBundle::GetSharedInstance().GetFont( + ui::ResourceBundle::BaseFont); +} + +int GetMaxWidth(int x, int y) { + // TODO(varunjain): implementation duplicated in tooltip_manager_aura. Figure + // out a way to merge. + gfx::Rect monitor_bounds = + gfx::Screen::GetMonitorAreaNearestPoint(gfx::Point(x, y)); + return (monitor_bounds.width() + 1) / 2; +} + +// Trims the tooltip to fit, setting |text| to the clipped result, +// |max_width| to the width (in pixels) of the clipped text and |line_count| +// to the number of lines of text in the tooltip. |x| and |y| give the +// location of the tooltip in screen coordinates. +void TrimTooltipToFit(string16* text, + int* max_width, + int* line_count, + int x, + int y) { + *max_width = 0; + *line_count = 0; + + // Clamp the tooltip length to kMaxTooltipLength so that we don't + // accidentally DOS the user with a mega tooltip. + if (text->length() > kMaxTooltipLength) + *text = text->substr(0, kMaxTooltipLength); + + // Determine the available width for the tooltip. + int available_width = GetMaxWidth(x, y); + + // Split the string into at most kMaxLines lines. + std::vector<string16> lines; + base::SplitString(*text, '\n', &lines); + if (lines.size() > kMaxLines) + lines.resize(kMaxLines); + *line_count = static_cast<int>(lines.size()); + + // Format each line to fit. + gfx::Font font = GetDefaultFont(); + string16 result; + for (std::vector<string16>::iterator i = lines.begin(); i != lines.end(); + ++i) { + string16 elided_text = + ui::ElideText(*i, font, available_width, ui::ELIDE_AT_END); + *max_width = std::max(*max_width, font.GetStringWidth(elided_text)); + if (!result.empty()) + result.push_back('\n'); + result.append(elided_text); + } + *text = result; +} + +// Creates a widget of type TYPE_TOOLTIP +views::Widget* CreateTooltip() { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + // For aura, since we set the type to TOOLTIP_TYPE, the widget will get + // auto-parented to the MenuAndTooltipsContainer. + params.type = views::Widget::InitParams::TYPE_TOOLTIP; + params.keep_on_top = true; + params.accept_events = false; + params.transparent = true; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + widget->Init(params); + return widget; +} + +} // namespace + +namespace aura_shell { +namespace internal { + +// Displays a widget with tooltip using a views::Label. +class TooltipController::Tooltip { + public: + Tooltip() { + label_.set_background( + views::Background::CreateSolidBackground(kTooltipBackground)); + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAuraNoShadows)) { + label_.set_border( + views::Border::CreateSolidBorder(kTooltipBorderWidth, + kTooltipBorder)); + } + label_.set_parent_owned(false); + widget_.reset(CreateTooltip()); + widget_->SetContentsView(&label_); + widget_->Activate(); + } + + ~Tooltip() { + widget_->Close(); + } + + // Updates the text on the tooltip and resizes to fit. + void SetText(string16 tooltip_text, gfx::Point location) { + int max_width, line_count; + TrimTooltipToFit(&tooltip_text, &max_width, &line_count, + location.x(), location.y()); + label_.SetText(tooltip_text); + + int width = max_width + 2 * kTooltipHorizontalPadding; + int height = label_.GetPreferredSize().height() + + 2 * kTooltipVerticalPadding; + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAuraNoShadows)) { + width += 2 * kTooltipBorderWidth; + height += 2 * kTooltipBorderWidth; + } + SetTooltipBounds(location, width, height); + } + + // Shows the tooltip. + void Show() { + widget_->Show(); + } + + // Hides the tooltip. + void Hide() { + widget_->Hide(); + } + + bool IsVisible() { + return widget_->IsVisible(); + } + + private: + views::Label label_; + scoped_ptr<views::Widget> widget_; + + // Adjusts the bounds given by the arguments to fit inside the desktop + // and applies the adjusted bounds to the label_. + void SetTooltipBounds(gfx::Point mouse_pos, + int tooltip_width, + int tooltip_height) { + gfx::Rect tooltip_rect(mouse_pos.x(), mouse_pos.y(), tooltip_width, + tooltip_height); + + tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY); + gfx::Rect monitor_bounds = + gfx::Screen::GetMonitorAreaNearestPoint(tooltip_rect.origin()); + widget_->SetBounds(tooltip_rect.AdjustToFit(monitor_bounds)); + } + +}; + +//////////////////////////////////////////////////////////////////////////////// +// TooltipController public: + +TooltipController::TooltipController() + : aura::EventFilter(NULL), + tooltip_window_(NULL), + tooltip_(new Tooltip) { + tooltip_timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs), + this, &TooltipController::TooltipTimerFired); +} + +TooltipController::~TooltipController() { + if (tooltip_window_) + tooltip_window_->RemoveObserver(this); +} + +void TooltipController::UpdateTooltip(aura::Window* target) { + // If tooltip is visible, we may want to hide it. If it is not, we are ok. + if (tooltip_window_ == target && tooltip_->IsVisible()) + UpdateIfRequired(); +} + +bool TooltipController::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + return false; +} + +bool TooltipController::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + switch (event->type()) { + case ui::ET_MOUSE_MOVED: + if (tooltip_window_ != target) { + if (tooltip_window_) + tooltip_window_->RemoveObserver(this); + tooltip_window_ = target; + tooltip_window_->AddObserver(this); + } + curr_mouse_loc_ = event->location(); + if (tooltip_timer_.IsRunning()) + tooltip_timer_.Reset(); + + if (tooltip_->IsVisible()) + UpdateIfRequired(); + break; + case ui::ET_MOUSE_PRESSED: + case ui::ET_MOUSE_RELEASED: + case ui::ET_MOUSE_DRAGGED: + case ui::ET_MOUSEWHEEL: + // Hide the tooltip for click, release, drag, wheel events. + if (tooltip_->IsVisible()) + tooltip_->Hide(); + break; + default: + break; + } + return false; +} + +ui::TouchStatus TooltipController::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +void TooltipController::OnWindowDestroyed(aura::Window* window) { + if (tooltip_window_ == window) { + tooltip_window_->RemoveObserver(this); + tooltip_window_ = NULL; + } +} + +void TooltipController::TooltipTimerFired() { + UpdateIfRequired(); +} + +void TooltipController::UpdateIfRequired() { + string16 tooltip_text; + if (tooltip_window_) + tooltip_text = *aura::client::GetTooltipText(tooltip_window_); + + if (tooltip_text_ != tooltip_text) { + tooltip_text_ = tooltip_text; + if (tooltip_text_.empty()) { + tooltip_->Hide(); + } else { + string16 tooltip_text(tooltip_text_); + gfx::Point widget_loc = curr_mouse_loc_; + widget_loc = widget_loc.Add(tooltip_window_->GetScreenBounds().origin()); + tooltip_->SetText(tooltip_text, widget_loc); + tooltip_->Show(); + } + } +} + +} // namespace internal +} // namespace aura_shell diff --git a/ash/tooltips/tooltip_controller.h b/ash/tooltips/tooltip_controller.h new file mode 100644 index 0000000..41daaa22 --- /dev/null +++ b/ash/tooltips/tooltip_controller.h @@ -0,0 +1,80 @@ +// Copyright (c) 2011 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 ASH_TOOLTIPS_TOOLTIP_CONTROLLER_H_ +#define ASH_TOOLTIPS_TOOLTIP_CONTROLLER_H_ +#pragma once + +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "base/timer.h" +#include "ui/aura/client/tooltip_client.h" +#include "ui/aura/event_filter.h" +#include "ui/aura/window_observer.h" +#include "ui/aura_shell/aura_shell_export.h" +#include "ui/gfx/point.h" + +namespace aura { +class KeyEvent; +class MouseEvent; +class TouchEvent; +class Window; +} + +namespace aura_shell { + +namespace test { +class TooltipControllerTest; +} // namespace test + +namespace internal { + +// TooltipController provides tooltip functionality for aura shell. +class AURA_SHELL_EXPORT TooltipController : public aura::client::TooltipClient, + public aura::EventFilter, + public aura::WindowObserver { + public: + TooltipController(); + virtual ~TooltipController(); + + // Overridden from aura::client::TooltipClient. + void UpdateTooltip(aura::Window* target); + + // Overridden from aura::EventFilter. + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + + // Overridden from aura::WindowObserver. + virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; + + private: + friend class aura_shell::test::TooltipControllerTest; + + class Tooltip; + + void TooltipTimerFired(); + + // Updates the tooltip if required (if there is any change in the tooltip + // text or the aura::Window. + void UpdateIfRequired(); + + aura::Window* tooltip_window_; + string16 tooltip_text_; + scoped_ptr<Tooltip> tooltip_; + + base::RepeatingTimer<TooltipController> tooltip_timer_; + + gfx::Point curr_mouse_loc_; + + DISALLOW_COPY_AND_ASSIGN(TooltipController); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // ASH_TOOLTIPS_TOOLTIP_CONTROLLER_H_ diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc new file mode 100644 index 0000000..8ac5937 --- /dev/null +++ b/ash/tooltips/tooltip_controller_unittest.cc @@ -0,0 +1,179 @@ +// Copyright (c) 2011 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 "ash/test/aura_shell_test_base.h" +#include "ash/tooltips/tooltip_controller.h" +#include "base/utf_string_conversions.h" +#include "ui/aura/client/tooltip_client.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/gfx/point.h" +#include "ui/views/view.h" +#include "ui/views/widget/widget.h" + +namespace aura_shell { +namespace test { + +namespace { + +class TooltipTestView : public views::View { + public: + TooltipTestView() : views::View() { + } + + void set_tooltip_text(string16 tooltip_text) { tooltip_text_ = tooltip_text; } + + // Overridden from views::View + bool GetTooltipText(const gfx::Point& p, string16* tooltip) const { + *tooltip = tooltip_text_; + return true; + } + + private: + string16 tooltip_text_; + + DISALLOW_COPY_AND_ASSIGN(TooltipTestView); +}; + +views::Widget* CreateNewWidget() { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; + params.accept_events = true; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.parent = aura::RootWindow::GetInstance(); + params.child = true; + widget->Init(params); + widget->Show(); + return widget; +} + +void AddViewToWidgetAndResize(views::Widget* widget, views::View* view) { + if (!widget->GetContentsView()) { + views::View* contents_view = new views::View; + widget->SetContentsView(contents_view); + } + + views::View* contents_view = widget->GetContentsView(); + contents_view->AddChildView(view); + view->SetBounds(contents_view->width(), 0, 100, 100); + gfx::Rect contents_view_bounds = contents_view->bounds(); + contents_view_bounds = contents_view_bounds.Union(view->bounds()); + contents_view->SetBoundsRect(contents_view_bounds); + widget->SetBounds(contents_view_bounds); +} + +aura_shell::internal::TooltipController* GetController() { + return static_cast<aura_shell::internal::TooltipController*>( + aura::client::GetTooltipClient()); +} + +void SimulateMouseMoveAtPoint(const gfx::Point& point) { + aura::MouseEvent event(ui::ET_MOUSE_MOVED, point, 0); + aura::RootWindow::GetInstance()->DispatchMouseEvent(&event); +} + +} // namespace + +class TooltipControllerTest : public AuraShellTestBase { + public: + TooltipControllerTest() {} + virtual ~TooltipControllerTest() {} + + string16 GetTooltipText() { + return GetController()->tooltip_text_; + } + + aura::Window* GetTooltipWindow() { + return GetController()->tooltip_window_; + } + + void FireTooltipTimer() { + GetController()->TooltipTimerFired(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest); +}; + +TEST_F(TooltipControllerTest, NonNullTooltipClient) { + EXPECT_TRUE(aura::client::GetTooltipClient() != NULL); + EXPECT_EQ(ASCIIToUTF16(""), GetTooltipText()); + EXPECT_EQ(NULL, GetTooltipWindow()); +} + +TEST_F(TooltipControllerTest, ViewTooltip) { + views::Widget* widget = CreateNewWidget(); + TooltipTestView* view = new TooltipTestView; + AddViewToWidgetAndResize(widget, view); + view->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); + EXPECT_EQ(ASCIIToUTF16(""), GetTooltipText()); + EXPECT_EQ(NULL, GetTooltipWindow()); + + gfx::Point point = gfx::Rect(view->bounds()).CenterPoint(); + SimulateMouseMoveAtPoint(point); + aura::Window* window = widget->GetNativeView(); + EXPECT_EQ(window, + aura::RootWindow::GetInstance()->GetEventHandlerForPoint(point)); + EXPECT_TRUE(aura::client::GetTooltipText(window) != NULL); + string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); + EXPECT_EQ(expected_tooltip, *aura::client::GetTooltipText(window)); + EXPECT_EQ(ASCIIToUTF16(""), GetTooltipText()); + EXPECT_EQ(window, GetTooltipWindow()); + + // Fire tooltip timer so tooltip becomes visible. + FireTooltipTimer(); + + point.Offset(1, 0); + SimulateMouseMoveAtPoint(point); + + EXPECT_TRUE(aura::client::GetTooltipText(window) != NULL); + EXPECT_EQ(expected_tooltip, *aura::client::GetTooltipText(window)); + EXPECT_EQ(expected_tooltip, GetTooltipText()); + EXPECT_EQ(window, GetTooltipWindow()); +} + +TEST_F(TooltipControllerTest, TooltipsInMultipleViews) { + views::Widget* widget = CreateNewWidget(); + TooltipTestView* view1 = new TooltipTestView; + AddViewToWidgetAndResize(widget, view1); + view1->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); + EXPECT_EQ(ASCIIToUTF16(""), GetTooltipText()); + EXPECT_EQ(NULL, GetTooltipWindow()); + + TooltipTestView* view2 = new TooltipTestView; + AddViewToWidgetAndResize(widget, view2); + + aura::Window* window = widget->GetNativeView(); + gfx::Point point = gfx::Rect(view1->bounds()).CenterPoint(); + + // Fire tooltip timer so tooltip becomes visible. + SimulateMouseMoveAtPoint(point); + FireTooltipTimer(); + for (int i = 0; i < 50; i++) { + point.Offset(1, 0); + SimulateMouseMoveAtPoint(point); + EXPECT_EQ(window, + aura::RootWindow::GetInstance()->GetEventHandlerForPoint(point)); + EXPECT_TRUE(aura::client::GetTooltipText(window) != NULL); + string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); + EXPECT_EQ(expected_tooltip, *aura::client::GetTooltipText(window)); + EXPECT_EQ(expected_tooltip, GetTooltipText()); + EXPECT_EQ(window, GetTooltipWindow()); + } + for (int i = 0; i < 50; i++) { + point.Offset(1, 0); + SimulateMouseMoveAtPoint(point); + EXPECT_EQ(window, + aura::RootWindow::GetInstance()->GetEventHandlerForPoint(point)); + EXPECT_TRUE(aura::client::GetTooltipText(window) != NULL); + string16 expected_tooltip = ASCIIToUTF16(""); + EXPECT_EQ(expected_tooltip, *aura::client::GetTooltipText(window)); + EXPECT_EQ(expected_tooltip, GetTooltipText()); + EXPECT_EQ(window, GetTooltipWindow()); + } +} + +} // namespace test +} // namespace aura_shell diff --git a/ash/wm/activation_controller_unittest.cc b/ash/wm/activation_controller_unittest.cc index e2b1470..1d3ad2d 100644 --- a/ash/wm/activation_controller_unittest.cc +++ b/ash/wm/activation_controller_unittest.cc @@ -4,14 +4,14 @@ #include "ash/wm/activation_controller.h" +#include "ash/test/aura_shell_test_base.h" +#include "ash/test/test_activation_delegate.h" #include "ash/wm/window_util.h" #include "ui/aura/focus_manager.h" #include "ui/aura/root_window.h" #include "ui/aura/test/event_generator.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/test/test_window_delegate.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" -#include "ui/aura_shell/test/test_activation_delegate.h" #if defined(OS_WIN) // Windows headers define macros for these function names which screw with us. diff --git a/ash/wm/image_grid_unittest.cc b/ash/wm/image_grid_unittest.cc index cc7b260..3bb8714 100644 --- a/ash/wm/image_grid_unittest.cc +++ b/ash/wm/image_grid_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/test/aura_shell_test_base.h" #include "ash/wm/image_grid.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" #include "ui/gfx/image/image.h" using aura_shell::internal::ImageGrid; diff --git a/ash/wm/modal_container_layout_manager_unittest.cc b/ash/wm/modal_container_layout_manager_unittest.cc index b55bc94..4264a86 100644 --- a/ash/wm/modal_container_layout_manager_unittest.cc +++ b/ash/wm/modal_container_layout_manager_unittest.cc @@ -4,6 +4,7 @@ #include "ash/wm/modal_container_layout_manager.h" +#include "ash/test/aura_shell_test_base.h" #include "ash/wm/window_util.h" #include "base/compiler_specific.h" #include "ui/aura/root_window.h" @@ -11,7 +12,6 @@ #include "ui/aura/window.h" #include "ui/aura_shell/shell.h" #include "ui/aura_shell/shell_window_ids.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" diff --git a/ash/wm/root_window_event_filter_unittest.cc b/ash/wm/root_window_event_filter_unittest.cc index c3b8392..7b1a2b4 100644 --- a/ash/wm/root_window_event_filter_unittest.cc +++ b/ash/wm/root_window_event_filter_unittest.cc @@ -4,6 +4,7 @@ #include "ash/wm/root_window_event_filter.h" +#include "ash/test/test_activation_delegate.h" #include "ash/wm/activation_controller.h" #include "ash/wm/window_util.h" #include "ui/aura/client/activation_delegate.h" @@ -16,7 +17,6 @@ #include "ui/aura/test/test_event_filter.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura_shell/shell_window_ids.h" -#include "ui/aura_shell/test/test_activation_delegate.h" #include "ui/base/hit_test.h" #include "ui/gfx/screen.h" diff --git a/ash/wm/shadow_controller_unittest.cc b/ash/wm/shadow_controller_unittest.cc index 5bc57ce..6f8efe4 100644 --- a/ash/wm/shadow_controller_unittest.cc +++ b/ash/wm/shadow_controller_unittest.cc @@ -7,6 +7,7 @@ #include <algorithm> #include <vector> +#include "ash/test/aura_shell_test_base.h" #include "ash/wm/shadow.h" #include "ash/wm/shadow_types.h" #include "ash/wm/window_properties.h" @@ -14,7 +15,6 @@ #include "ui/aura/root_window.h" #include "ui/aura/window.h" #include "ui/aura_shell/shell.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" #include "ui/gfx/compositor/layer.h" namespace aura_shell { diff --git a/ash/wm/shelf_layout_manager_unittest.cc b/ash/wm/shelf_layout_manager_unittest.cc index 77974b1..c1daf9a 100644 --- a/ash/wm/shelf_layout_manager_unittest.cc +++ b/ash/wm/shelf_layout_manager_unittest.cc @@ -5,12 +5,12 @@ #include "ash/wm/shelf_layout_manager.h" #include "ash/launcher/launcher.h" +#include "ash/test/aura_shell_test_base.h" #include "ui/aura/root_window.h" #include "ui/aura/screen_aura.h" #include "ui/aura/window.h" #include "ui/aura_shell/shell.h" #include "ui/aura_shell/shell_window_ids.h" -#include "ui/aura_shell/test/aura_shell_test_base.h" #include "ui/base/animation/animation_container_element.h" #include "ui/gfx/compositor/layer_animator.h" #include "ui/gfx/compositor/layer.h" |