diff options
-rw-r--r-- | athena/athena.gyp | 6 | ||||
-rw-r--r-- | athena/home/DEPS | 1 | ||||
-rw-r--r-- | athena/home/home_card_impl.cc | 29 | ||||
-rw-r--r-- | athena/input/DEPS | 13 | ||||
-rw-r--r-- | athena/input/accelerator_manager_impl.cc | 190 | ||||
-rw-r--r-- | athena/input/accelerator_manager_impl.h | 76 | ||||
-rw-r--r-- | athena/input/accelerator_manager_unittest.cc | 120 | ||||
-rw-r--r-- | athena/input/input_manager_impl.cc | 122 | ||||
-rw-r--r-- | athena/input/public/DEPS | 4 | ||||
-rw-r--r-- | athena/input/public/accelerator_manager.h | 72 | ||||
-rw-r--r-- | athena/input/public/input_manager.h | 41 | ||||
-rw-r--r-- | athena/main/DEPS | 1 | ||||
-rw-r--r-- | athena/main/athena_launcher.cc | 3 |
13 files changed, 677 insertions, 1 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp index c7adae5..6fdb64c 100644 --- a/athena/athena.gyp +++ b/athena/athena.gyp @@ -36,6 +36,11 @@ 'home/app_list_view_delegate.h', 'home/home_card_impl.cc', 'home/public/home_card.h', + 'input/public/input_manager.h', + 'input/public/accelerator_manager.h', + 'input/input_manager_impl.cc', + 'input/accelerator_manager_impl.cc', + 'input/accelerator_manager_impl.h', 'screen/background_controller.cc', 'screen/background_controller.h', 'screen/public/screen_manager.h', @@ -104,6 +109,7 @@ ], 'sources': [ 'test/athena_unittests.cc', + 'input/accelerator_manager_unittest.cc', 'wm/window_manager_unittest.cc', ], } diff --git a/athena/home/DEPS b/athena/home/DEPS index 660f468..3c13d2d 100644 --- a/athena/home/DEPS +++ b/athena/home/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+athena/input/public", "+athena/screen/public", "+third_party/skia/include", "+ui/aura", diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc index 13723af..949d551 100644 --- a/athena/home/home_card_impl.cc +++ b/athena/home/home_card_impl.cc @@ -5,6 +5,8 @@ #include "athena/home/public/home_card.h" #include "athena/home/app_list_view_delegate.h" +#include "athena/input/public/accelerator_manager.h" +#include "athena/input/public/input_manager.h" #include "athena/screen/public/screen_manager.h" #include "ui/app_list/pagination_model.h" #include "ui/app_list/views/app_list_view.h" @@ -68,7 +70,7 @@ class HomeCardLayoutManager : public aura::LayoutManager { DISALLOW_COPY_AND_ASSIGN(HomeCardLayoutManager); }; -class HomeCardImpl : public HomeCard { +class HomeCardImpl : public HomeCard, public AcceleratorHandler { public: HomeCardImpl(); virtual ~HomeCardImpl(); @@ -76,6 +78,20 @@ class HomeCardImpl : public HomeCard { void Init(); private: + enum Command { + COMMAND_SHOW_HOME_CARD, + }; + void InstallAccelerators(); + + // AcceleratorHandler: + virtual bool IsCommandEnabled(int command_id) const OVERRIDE { return true; } + virtual bool OnAcceleratorFired(int command_id, + const ui::Accelerator& accelerator) OVERRIDE { + DCHECK_EQ(COMMAND_SHOW_HOME_CARD, command_id); + home_card_widget_->Show(); + return true; + } + views::Widget* home_card_widget_; DISALLOW_COPY_AND_ASSIGN(HomeCardImpl); @@ -94,6 +110,8 @@ HomeCardImpl::~HomeCardImpl() { } void HomeCardImpl::Init() { + InstallAccelerators(); + aura::Window* container = ScreenManager::Get()->CreateContainer("HomeCardContainer"); container->SetLayoutManager(new HomeCardLayoutManager(container)); @@ -111,6 +129,15 @@ void HomeCardImpl::Init() { view->ShowWhenReady(); } +void HomeCardImpl::InstallAccelerators() { + const AcceleratorData accelerator_data[] = { + {TRIGGER_ON_PRESS, ui::VKEY_L, ui::EF_CONTROL_DOWN, + COMMAND_SHOW_HOME_CARD, AF_NONE}, + }; + InputManager::Get()->GetAcceleratorManager()->RegisterAccelerators( + accelerator_data, arraysize(accelerator_data), this); +} + } // namespace // static diff --git a/athena/input/DEPS b/athena/input/DEPS new file mode 100644 index 0000000..5b66b22 --- /dev/null +++ b/athena/input/DEPS @@ -0,0 +1,13 @@ +include_rules = [ + "+ui/aura", + "+ui/base", + "+ui/events", + "+ui/wm/core", + "+ui/wm/public", +] + +specific_include_rules = { + ".*unittest\.cc": [ + "+athena/test", + ], +} diff --git a/athena/input/accelerator_manager_impl.cc b/athena/input/accelerator_manager_impl.cc new file mode 100644 index 0000000..cdd4673 --- /dev/null +++ b/athena/input/accelerator_manager_impl.cc @@ -0,0 +1,190 @@ +// Copyright 2014 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 "athena/input/accelerator_manager_impl.h" + +#include "athena/input/public/input_manager.h" +#include "base/logging.h" +#include "ui/aura/window.h" +#include "ui/base/accelerators/accelerator_manager.h" +#include "ui/events/event.h" +#include "ui/events/event_target.h" +#include "ui/wm/core/accelerator_delegate.h" +#include "ui/wm/core/accelerator_filter.h" +#include "ui/wm/core/nested_accelerator_controller.h" +#include "ui/wm/core/nested_accelerator_delegate.h" +#include "ui/wm/public/dispatcher_client.h" + +namespace athena { + +namespace { + +// Accelerators inside nested message loop are handled by +// wm::NestedAcceleratorController while accelerators in normal case are +// handled by wm::AcceleratorFilter. These delegates act bridges in these +// two different environment so that AcceleratorManagerImpl can handle +// accelerators in an uniform way. + +class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate { + public: + explicit NestedAcceleratorDelegate( + AcceleratorManagerImpl* accelerator_manager) + : accelerator_manager_(accelerator_manager) {} + virtual ~NestedAcceleratorDelegate() {} + + private: + // wm::NestedAcceleratorDelegate: + virtual Result ProcessAccelerator( + const ui::Accelerator& accelerator) OVERRIDE { + return accelerator_manager_->ProcessAccelerator(accelerator) + ? RESULT_PROCESSED + : RESULT_NOT_PROCESSED; + } + + AcceleratorManagerImpl* accelerator_manager_; + + DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate); +}; + +class AcceleratorDelegate : public wm::AcceleratorDelegate { + public: + explicit AcceleratorDelegate(AcceleratorManagerImpl* accelerator_manager) + : accelerator_manager_(accelerator_manager) {} + virtual ~AcceleratorDelegate() {} + + private: + // wm::AcceleratorDelegate: + virtual bool ProcessAccelerator(const ui::KeyEvent& event, + const ui::Accelerator& accelerator, + KeyType key_type) OVERRIDE { + aura::Window* target = static_cast<aura::Window*>(event.target()); + if (!target->IsRootWindow() && + !accelerator_manager_->IsReservedAccelerator(accelerator)) { + // TODO(oshima): do the same when the active window is in fullscreen. + return false; + } + return accelerator_manager_->ProcessAccelerator(accelerator); + } + + AcceleratorManagerImpl* accelerator_manager_; + DISALLOW_COPY_AND_ASSIGN(AcceleratorDelegate); +}; + +} // namespace + +class AcceleratorManagerImpl::InternalData { + public: + InternalData(int command_id, AcceleratorHandler* handler, int flags) + : command_id_(command_id), handler_(handler), flags_(flags) {} + + bool IsNonAutoRepeatable() const { return flags_ & AF_NON_AUTO_REPEATABLE; } + bool IsDebug() const { return flags_ & AF_DEBUG; } + bool IsReserved() const { return flags_ & AF_RESERVED; } + + bool IsCommandEnabled() const { + return handler_->IsCommandEnabled(command_id_); + } + + bool OnAcceleratorFired(const ui::Accelerator& accelerator) { + return handler_->OnAcceleratorFired(command_id_, accelerator); + } + + private: + int command_id_; + AcceleratorHandler* handler_; + int flags_; + + // This class is copyable by design. +}; + +AcceleratorManagerImpl::AcceleratorManagerImpl() + : accelerator_manager_(new ui::AcceleratorManager) { +} + +AcceleratorManagerImpl::~AcceleratorManagerImpl() { + nested_accelerator_controller_.reset(); + accelerator_filter_.reset(); +} + +void AcceleratorManagerImpl::Init() { + ui::EventTarget* toplevel = InputManager::Get()->GetTopmostEventTarget(); + nested_accelerator_controller_.reset( + new wm::NestedAcceleratorController(new NestedAcceleratorDelegate(this))); + + scoped_ptr<wm::AcceleratorDelegate> accelerator_delegate( + new AcceleratorDelegate(this)); + + accelerator_filter_.reset( + new wm::AcceleratorFilter(accelerator_delegate.Pass())); + toplevel->AddPreTargetHandler(accelerator_filter_.get()); +} + +void AcceleratorManagerImpl::OnRootWindowCreated(aura::Window* root_window) { + aura::client::SetDispatcherClient(root_window, + nested_accelerator_controller_.get()); +} + +bool AcceleratorManagerImpl::IsReservedAccelerator( + const ui::Accelerator& accelerator) const { + std::map<ui::Accelerator, InternalData>::const_iterator iter = + accelerators_.find(accelerator); + if (iter == accelerators_.end()) + return false; + return iter->second.IsReserved(); +} + +bool AcceleratorManagerImpl::ProcessAccelerator( + const ui::Accelerator& accelerator) { + return accelerator_manager_->Process(accelerator); +} + +void AcceleratorManagerImpl::RegisterAccelerators( + const AcceleratorData accelerators[], + size_t num_accelerators, + AcceleratorHandler* handler) { + for (size_t i = 0; i < num_accelerators; ++i) + RegisterAccelerator(accelerators[i], handler); +} + +void AcceleratorManagerImpl::EnableDebugAccelerators() { + debug_accelerators_enabled_ = true; +} + +bool AcceleratorManagerImpl::AcceleratorPressed( + const ui::Accelerator& accelerator) { + std::map<ui::Accelerator, InternalData>::iterator iter = + accelerators_.find(accelerator); + DCHECK(iter != accelerators_.end()); + if (iter == accelerators_.end()) + return false; + InternalData& data = iter->second; + if (data.IsDebug() && !debug_accelerators_enabled_) + return false; + if (accelerator.IsRepeat() && data.IsNonAutoRepeatable()) + return false; + return data.IsCommandEnabled() ? data.OnAcceleratorFired(accelerator) : false; +} + +bool AcceleratorManagerImpl::CanHandleAccelerators() const { + return true; +} + +void AcceleratorManagerImpl::RegisterAccelerator( + const AcceleratorData& accelerator_data, + AcceleratorHandler* handler) { + ui::Accelerator accelerator(accelerator_data.keycode, + accelerator_data.keyevent_flags); + accelerator.set_type(accelerator_data.trigger_event == TRIGGER_ON_PRESS + ? ui::ET_KEY_PRESSED + : ui::ET_KEY_RELEASED); + accelerator_manager_->Register( + accelerator, ui::AcceleratorManager::kNormalPriority, this); + accelerators_.insert( + std::make_pair(accelerator, + InternalData(accelerator_data.command_id, + handler, + accelerator_data.accelerator_flags))); +} + +} // namespace athena diff --git a/athena/input/accelerator_manager_impl.h b/athena/input/accelerator_manager_impl.h new file mode 100644 index 0000000..1a5e8a9 --- /dev/null +++ b/athena/input/accelerator_manager_impl.h @@ -0,0 +1,76 @@ +// Copyright 2014 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 ATHENA_INPUT_ACCELERATOR_MANAGER_H_ +#define ATHENA_INPUT_ACCELERATOR_MANAGER_H_ + +#include "athena/input/public/accelerator_manager.h" + +#include <map> + +#include "base/macros.h" +#include "ui/base/accelerators/accelerator.h" +#include "ui/events/event_target_iterator.h" + +namespace aura { +class Window; +} + +namespace ui { +class AcceleratorManager; +} + +namespace wm { +class AcceleratorFilter; +class NestedAcceleratorController; +} + +namespace athena { + +// AcceleratorManagerImpl provides a API to register accelerators +// for athena modules. It hides various details on accelerator handling +// such as how to handle accelerator in a nested loop, reserved accelerators +// and repeated accelerators. +class AcceleratorManagerImpl : public AcceleratorManager, + public ui::AcceleratorTarget { + public: + AcceleratorManagerImpl(); + virtual ~AcceleratorManagerImpl(); + + void Init(); + + void OnRootWindowCreated(aura::Window* root_window); + + bool IsReservedAccelerator(const ui::Accelerator& accelerator) const; + bool ProcessAccelerator(const ui::Accelerator& accelerator); + + private: + // AcceleratorManager: + virtual void RegisterAccelerators(const AcceleratorData accelerators[], + size_t num_accelerators, + AcceleratorHandler* handler) OVERRIDE; + virtual void EnableDebugAccelerators() OVERRIDE; + + // ui::AcceleratorTarget: + virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; + virtual bool CanHandleAccelerators() const OVERRIDE; + + class InternalData; + + void RegisterAccelerator(const AcceleratorData& accelerator, + AcceleratorHandler* handler); + + bool debug_accelerators_enabled_; + std::map<ui::Accelerator, InternalData> accelerators_; + scoped_ptr<ui::AcceleratorManager> accelerator_manager_; + + scoped_ptr<wm::AcceleratorFilter> accelerator_filter_; + scoped_ptr<wm::NestedAcceleratorController> nested_accelerator_controller_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratorManagerImpl); +}; + +} // namespace athena + +#endif // ATHENA_INPUT_ACCELERATOR_MANAGER_H_ diff --git a/athena/input/accelerator_manager_unittest.cc b/athena/input/accelerator_manager_unittest.cc new file mode 100644 index 0000000..cd80e86 --- /dev/null +++ b/athena/input/accelerator_manager_unittest.cc @@ -0,0 +1,120 @@ +// Copyright 2014 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 "athena/input/public/accelerator_manager.h" + +#include "athena/input/public/input_manager.h" +#include "athena/test/athena_test_base.h" +#include "ui/aura/test/event_generator.h" + +namespace athena { +namespace { + +const int kInvalidCommandId = -1; + +class TestHandler : public AcceleratorHandler { + public: + TestHandler() : fired_command_id_(kInvalidCommandId), enabled_(true) {} + virtual ~TestHandler() {} + + void set_enabled(bool enabled) { enabled_ = enabled; } + + int GetFiredCommandIdAndReset() { + int fired = fired_command_id_; + fired_command_id_ = kInvalidCommandId; + return fired; + } + + private: + // AcceleratorHandler: + virtual bool IsCommandEnabled(int command_id) const OVERRIDE { + return enabled_; + } + virtual bool OnAcceleratorFired(int command_id, + const ui::Accelerator& accelerator) OVERRIDE { + fired_command_id_ = command_id; + return true; + } + + int fired_command_id_; + bool enabled_; + + DISALLOW_COPY_AND_ASSIGN(TestHandler); +}; + +} // namespace athena + +typedef test::AthenaTestBase InputManagerTest; + +TEST_F(InputManagerTest, Basic) { + enum TestCommandId { + COMMAND_A, + COMMAND_B, + COMMAND_C, + COMMAND_D, + COMMAND_E, + }; + const AcceleratorData data[] = { + {TRIGGER_ON_PRESS, ui::VKEY_A, ui::EF_SHIFT_DOWN, COMMAND_A, AF_RESERVED}, + {TRIGGER_ON_RELEASE, ui::VKEY_B, ui::EF_SHIFT_DOWN, COMMAND_B, + AF_RESERVED}, + {TRIGGER_ON_PRESS, ui::VKEY_C, ui::EF_SHIFT_DOWN, COMMAND_C, + AF_RESERVED | AF_DEBUG}, + {TRIGGER_ON_PRESS, ui::VKEY_D, ui::EF_SHIFT_DOWN, COMMAND_D, + AF_RESERVED | AF_NON_AUTO_REPEATABLE}, + {TRIGGER_ON_PRESS, ui::VKEY_E, ui::EF_SHIFT_DOWN, COMMAND_E, AF_NONE}, + }; + AcceleratorManager* accelerator_manager = + InputManager::Get()->GetAcceleratorManager(); + TestHandler test_handler; + accelerator_manager->RegisterAccelerators( + data, arraysize(data), &test_handler); + + aura::test::EventGenerator generator(root_window()); + generator.PressKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + + // Trigger on press. + generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); + EXPECT_EQ(COMMAND_A, test_handler.GetFiredCommandIdAndReset()); + generator.ReleaseKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + + // Trigger on release. + generator.PressKey(ui::VKEY_B, ui::EF_SHIFT_DOWN); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + generator.ReleaseKey(ui::VKEY_B, ui::EF_SHIFT_DOWN); + EXPECT_EQ(COMMAND_B, test_handler.GetFiredCommandIdAndReset()); + + // Disable command. + test_handler.set_enabled(false); + generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + test_handler.set_enabled(true); + generator.PressKey(ui::VKEY_A, ui::EF_SHIFT_DOWN); + EXPECT_EQ(COMMAND_A, test_handler.GetFiredCommandIdAndReset()); + + // Debug accelerators. + generator.PressKey(ui::VKEY_C, ui::EF_SHIFT_DOWN); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + + accelerator_manager->EnableDebugAccelerators(); + generator.PressKey(ui::VKEY_C, ui::EF_SHIFT_DOWN); + EXPECT_EQ(COMMAND_C, test_handler.GetFiredCommandIdAndReset()); + + // Non auto repeatable + generator.PressKey(ui::VKEY_D, ui::EF_SHIFT_DOWN); + EXPECT_EQ(COMMAND_D, test_handler.GetFiredCommandIdAndReset()); + generator.PressKey(ui::VKEY_D, ui::EF_SHIFT_DOWN | ui::EF_IS_REPEAT); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); + + // Non reserved accelerator won't be handled unless there is + // a view's focus manager. + // TODO(oshima): Support view's focus manager. Investigate we can implement + // the non reserved behavior without view's focus manager. + generator.PressKey(ui::VKEY_E, ui::EF_SHIFT_DOWN); + EXPECT_EQ(kInvalidCommandId, test_handler.GetFiredCommandIdAndReset()); +} + +} // namespace athena diff --git a/athena/input/input_manager_impl.cc b/athena/input/input_manager_impl.cc new file mode 100644 index 0000000..3d1c803 --- /dev/null +++ b/athena/input/input_manager_impl.cc @@ -0,0 +1,122 @@ +// Copyright 2014 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 "athena/input/public/input_manager.h" + +#include "athena/input/accelerator_manager_impl.h" +#include "base/logging.h" +#include "ui/aura/client/event_client.h" +#include "ui/aura/env.h" +#include "ui/events/event_target.h" + +namespace athena { +namespace { + +InputManager* instance = NULL; + +class InputManagerImpl : public InputManager, + public ui::EventTarget, + public aura::client::EventClient { + public: + InputManagerImpl(); + virtual ~InputManagerImpl(); + + void Init(); + void Shutdown(); + + private: + // InputManager: + virtual void OnRootWindowCreated(aura::Window* root_window) OVERRIDE; + virtual ui::EventTarget* GetTopmostEventTarget() OVERRIDE { return this; } + virtual AcceleratorManager* GetAcceleratorManager() OVERRIDE { + return accelerator_manager_.get(); + } + + // Overridden from aura::client::EventClient: + virtual bool CanProcessEventsWithinSubtree( + const aura::Window* window) const OVERRIDE { + return true; + } + virtual ui::EventTarget* GetToplevelEventTarget() OVERRIDE { return this; } + + // ui::EventTarget: + virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE; + virtual ui::EventTarget* GetParentTarget() OVERRIDE; + virtual scoped_ptr<ui::EventTargetIterator> GetChildIterator() const OVERRIDE; + virtual ui::EventTargeter* GetEventTargeter() OVERRIDE; + virtual void OnEvent(ui::Event* event) OVERRIDE; + + scoped_ptr<AcceleratorManagerImpl> accelerator_manager_; + + DISALLOW_COPY_AND_ASSIGN(InputManagerImpl); +}; + +InputManagerImpl::InputManagerImpl() + : accelerator_manager_(new AcceleratorManagerImpl) { + DCHECK(!instance); + instance = this; +} + +InputManagerImpl::~InputManagerImpl() { + DCHECK_EQ(instance, this); + Shutdown(); + instance = NULL; +} + +void InputManagerImpl::Init() { + accelerator_manager_->Init(); +} + +void InputManagerImpl::Shutdown() { + accelerator_manager_.reset(); +} + +void InputManagerImpl::OnRootWindowCreated(aura::Window* root_window) { + aura::client::SetEventClient(root_window, this); + accelerator_manager_->OnRootWindowCreated(root_window); +} + +bool InputManagerImpl::CanAcceptEvent(const ui::Event& event) { + return true; +} + +ui::EventTarget* InputManagerImpl::GetParentTarget() { + return aura::Env::GetInstance(); +} + +scoped_ptr<ui::EventTargetIterator> InputManagerImpl::GetChildIterator() const { + return scoped_ptr<ui::EventTargetIterator>(); +} + +ui::EventTargeter* InputManagerImpl::GetEventTargeter() { + NOTREACHED(); + return NULL; +} + +void InputManagerImpl::OnEvent(ui::Event* event) { +} + +} // namespace + +// static +InputManager* InputManager::Create() { + (new InputManagerImpl)->Init(); + DCHECK(instance); + return instance; +} + +// static +InputManager* InputManager::Get() { + DCHECK(instance); + return instance; +} + +// static +void InputManager::Shutdown() { + DCHECK(instance); + delete instance; + DCHECK(!instance); +} + +} // namespace athena diff --git a/athena/input/public/DEPS b/athena/input/public/DEPS new file mode 100644 index 0000000..941cfac --- /dev/null +++ b/athena/input/public/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "-athena/input", + "+athena/athena_export.h", +] diff --git a/athena/input/public/accelerator_manager.h b/athena/input/public/accelerator_manager.h new file mode 100644 index 0000000..e0a1ad4 --- /dev/null +++ b/athena/input/public/accelerator_manager.h @@ -0,0 +1,72 @@ +// Copyright 2014 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 ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_ +#define ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_ + +#include "athena/athena_export.h" +#include "ui/events/keycodes/keyboard_codes.h" + +namespace ui { +class Accelerator; +} + +namespace athena { + +enum TriggerEvent { + TRIGGER_ON_PRESS, + TRIGGER_ON_RELEASE, +}; + +// Accelerator flags. +enum AcceleratorFlags { + AF_NONE = 0, + // Used for accelerators that should not be fired on auto repeated + // key event, such as toggling fullscrren. + AF_NON_AUTO_REPEATABLE = 1 << 0, + // Most key events are sent to applications first as they may + // want to consume them. Reserverd accelerators are reserved for OS + // and cannot be consumed by apps. (such as window cycling) + AF_RESERVED = 1 << 1, + // Used for accelerators that are useful only in debug mode. + AF_DEBUG = 1 << 2, +}; + +struct AcceleratorData { + // true if the accelerator should be triggered upon ui::ET_KEY_PRESSED + TriggerEvent trigger_event; + ui::KeyboardCode keycode; // KeyEvent event flags. + int keyevent_flags; // Combination of ui::KeyEventFlags + int command_id; // ID to distinguish + int accelerator_flags; // Combination of AcceleratorFlags; +}; + +// An interface that implements behavior for the set of +// accelerators. +class ATHENA_EXPORT AcceleratorHandler { + public: + virtual ~AcceleratorHandler() {} + + virtual bool IsCommandEnabled(int command_id) const = 0; + virtual bool OnAcceleratorFired(int command_id, + const ui::Accelerator& accelerator) = 0; +}; + +class AcceleratorManager { + public: + virtual ~AcceleratorManager() {} + + // Register accelerators and its handler that will be invoked when + // one of accelerator is fired. + virtual void RegisterAccelerators(const AcceleratorData accelerators[], + size_t num_accelerators, + AcceleratorHandler* handler) = 0; + + // Enables accelerators that has a AF_DEBUG flag. + virtual void EnableDebugAccelerators() = 0; +}; + +} // namespace athena + +#endif // ATHENA_INPUT_PUBLIC_ACCELERATOR_MANAGER_H_ diff --git a/athena/input/public/input_manager.h b/athena/input/public/input_manager.h new file mode 100644 index 0000000..cc70175 --- /dev/null +++ b/athena/input/public/input_manager.h @@ -0,0 +1,41 @@ +// Copyright 2014 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 ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_ +#define ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_ + +#include "athena/athena_export.h" + +namespace aura { +class Window; +} + +namespace ui { +class EventTarget; +} + +namespace athena { +class AcceleratorManager; + +class ATHENA_EXPORT InputManager { + public: + // Creates and deletes the singleton object of the InputManager + // implementation. + static InputManager* Create(); + static InputManager* Get(); + static void Shutdown(); + + // TODO(oshima): Fix the initialization process and replace this + // with EnvObserver::WindowInitialized + virtual void OnRootWindowCreated(aura::Window* root_window) = 0; + + virtual ui::EventTarget* GetTopmostEventTarget() = 0; + virtual AcceleratorManager* GetAcceleratorManager() = 0; + + virtual ~InputManager() {} +}; + +} // namespace athena + +#endif // ATHENA_INPUT_PUBLIC_INPUT_MANAGER_H_ diff --git a/athena/main/DEPS b/athena/main/DEPS index 9d9de5a..2f77e06 100644 --- a/athena/main/DEPS +++ b/athena/main/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+athena/activity/public", "+athena/content/public", "+athena/home/public", + "+athena/input/public", "+athena/screen/public", "+athena/task/public", "+athena/wm/public", diff --git a/athena/main/athena_launcher.cc b/athena/main/athena_launcher.cc index 89e8452..6faa396 100644 --- a/athena/main/athena_launcher.cc +++ b/athena/main/athena_launcher.cc @@ -7,6 +7,7 @@ #include "athena/activity/public/activity_factory.h" #include "athena/activity/public/activity_manager.h" #include "athena/home/public/home_card.h" +#include "athena/input/public/input_manager.h" #include "athena/main/placeholder.h" #include "athena/screen/public/screen_manager.h" #include "athena/wm/public/window_manager.h" @@ -47,6 +48,7 @@ void StartAthena(aura::Window* root_window, aura::client::SetVisibilityClient(root_window, root_window_state->visibility_client.get()); + athena::InputManager::Create()->OnRootWindowCreated(root_window); athena::ScreenManager::Create(root_window); athena::WindowManager::Create(); athena::HomeCard::Create(); @@ -61,6 +63,7 @@ void ShutdownAthena() { athena::HomeCard::Shutdown(); athena::WindowManager::Shutdown(); athena::ScreenManager::Shutdown(); + athena::InputManager::Shutdown(); } } // namespace athena |