diff options
author | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 05:08:30 +0000 |
---|---|---|
committer | mazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 05:08:30 +0000 |
commit | 745816be61e207da7cef1f839591bfb35bd15fd3 (patch) | |
tree | 60828cb9a38973d9bce185f4013437d58b5dbd82 /ui | |
parent | 0f83a23a4d149948d5d5135468fb820bcf7cd543 (diff) | |
download | chromium_src-745816be61e207da7cef1f839591bfb35bd15fd3.zip chromium_src-745816be61e207da7cef1f839591bfb35bd15fd3.tar.gz chromium_src-745816be61e207da7cef1f839591bfb35bd15fd3.tar.bz2 |
Add ShellAcceleratorController that manages global keyboard accelerators.
- Create ShellAcceleratorController that manages global keyboard accelerators and also processes several accelerators as a target.
- Create ShellAcceleratorFilter, which is used by DesktopEventFilter to handle accelerators.
- Add a function to Shell for accessing ShellAcceleratorController.
The 1st attempt (http://crrev.com/110637) broke aura_shell_unittests and this fixes it.
The differences are
- moving ShellAcceleratorFilter to Shell from DesktopEventFilter, and
- adding the ShellAcceleratorFilter in Shell initialization code to DesktopEventFilter.
BUG=97255
TEST=Manual, aura_shell_unittests succeeds.
Review URL: http://codereview.chromium.org/8561012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111100 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/desktop.cc | 61 | ||||
-rw-r--r-- | ui/aura/desktop.h | 5 | ||||
-rw-r--r-- | ui/aura_shell/aura_shell.gyp | 4 | ||||
-rw-r--r-- | ui/aura_shell/shell.cc | 10 | ||||
-rw-r--r-- | ui/aura_shell/shell.h | 11 | ||||
-rw-r--r-- | ui/aura_shell/shell_accelerator_controller.cc | 126 | ||||
-rw-r--r-- | ui/aura_shell/shell_accelerator_controller.h | 62 | ||||
-rw-r--r-- | ui/aura_shell/shell_accelerator_filter.cc | 59 | ||||
-rw-r--r-- | ui/aura_shell/shell_accelerator_filter.h | 39 |
9 files changed, 322 insertions, 55 deletions
diff --git a/ui/aura/desktop.cc b/ui/aura/desktop.cc index 74b5e4e..056490b 100644 --- a/ui/aura/desktop.cc +++ b/ui/aura/desktop.cc @@ -26,10 +26,7 @@ #include "ui/base/hit_test.h" #include "ui/gfx/compositor/compositor.h" #include "ui/gfx/compositor/layer.h" -#include "ui/gfx/compositor/layer_animation_sequence.h" #include "ui/gfx/compositor/layer_animator.h" -#include "ui/gfx/compositor/screen_rotation.h" -#include "ui/gfx/interpolated_transform.h" #ifdef USE_WEBKIT_COMPOSITOR #include "ui/gfx/compositor/compositor_cc.h" @@ -99,50 +96,6 @@ void GetEventFiltersToNotify(Window* target, EventFilters* filters) { } } -#if !defined(NDEBUG) -bool MaybeFullScreen(DesktopHost* host, KeyEvent* event) { - if (event->key_code() == ui::VKEY_F11) { - host->ToggleFullScreen(); - return true; - } - return false; -} - -bool MaybeRotate(Desktop* desktop, KeyEvent* event) { - if ((event->flags() & ui::EF_CONTROL_DOWN) && - event->key_code() == ui::VKEY_HOME) { - 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; - desktop->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(desktop); - desktop->layer()->GetAnimator()->ScheduleAnimation( - screen_rotation.release()); - return true; - } - return false; -} -#endif - } // namespace Desktop* Desktop::instance_ = NULL; @@ -285,14 +238,6 @@ bool Desktop::DispatchMouseEvent(MouseEvent* event) { } bool Desktop::DispatchKeyEvent(KeyEvent* event) { -#if !defined(NDEBUG) - // TODO(beng): replace this hack with global keyboard event handlers. - if (event->type() == ui::ET_KEY_PRESSED) { - if (MaybeFullScreen(host_.get(), event) || MaybeRotate(this, event)) - return true; - } -#endif - if (focused_window_) { KeyEvent translated_event(*event); return ProcessKeyEvent(focused_window_, &translated_event); @@ -470,6 +415,12 @@ void Desktop::SetTransform(const ui::Transform& transform) { OnHostResized(host_->GetSize()); } +#if !defined(NDEBUG) +void Desktop::ToggleFullScreen() { + host_->ToggleFullScreen(); +} +#endif + void Desktop::HandleMouseMoved(const MouseEvent& event, Window* target) { if (target == mouse_moved_handler_) return; diff --git a/ui/aura/desktop.h b/ui/aura/desktop.h index 3f27d4b..7e8d0dc 100644 --- a/ui/aura/desktop.h +++ b/ui/aura/desktop.h @@ -142,6 +142,11 @@ class AURA_EXPORT Desktop : public ui::CompositorDelegate, // Overridden from Window: virtual void SetTransform(const ui::Transform& transform) OVERRIDE; +#if !defined(NDEBUG) + // Toggles the host's full screen state. + void ToggleFullScreen(); +#endif + private: // Called whenever the mouse moves, tracks the current |mouse_moved_handler_|, // sending exited and entered events as its value changes. diff --git a/ui/aura_shell/aura_shell.gyp b/ui/aura_shell/aura_shell.gyp index dd42888..ca63de3 100644 --- a/ui/aura_shell/aura_shell.gyp +++ b/ui/aura_shell/aura_shell.gyp @@ -84,6 +84,10 @@ 'shelf_layout_controller.h', 'shell.cc', 'shell.h', + 'shell_accelerator_controller.cc', + 'shell_accelerator_controller.h', + 'shell_accelerator_filter.cc', + 'shell_accelerator_filter.h', 'shell_delegate.h', 'shell_factory.h', 'shell_window_ids.h', diff --git a/ui/aura_shell/shell.cc b/ui/aura_shell/shell.cc index 0e1fb45..49e515f 100644 --- a/ui/aura_shell/shell.cc +++ b/ui/aura_shell/shell.cc @@ -22,6 +22,8 @@ #include "ui/aura_shell/modal_container_layout_manager.h" #include "ui/aura_shell/shadow_controller.h" #include "ui/aura_shell/shelf_layout_controller.h" +#include "ui/aura_shell/shell_accelerator_controller.h" +#include "ui/aura_shell/shell_accelerator_filter.h" #include "ui/aura_shell/shell_delegate.h" #include "ui/aura_shell/shell_factory.h" #include "ui/aura_shell/shell_window_ids.h" @@ -100,6 +102,7 @@ Shell* Shell::instance_ = NULL; Shell::Shell(ShellDelegate* delegate) : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + accelerator_controller_(new ShellAcceleratorController), delegate_(delegate) { aura::Desktop::GetInstance()->SetEventFilter( new internal::DesktopEventFilter); @@ -108,6 +111,8 @@ Shell::Shell(ShellDelegate* delegate) } Shell::~Shell() { + RemoveDesktopEventFilter(accelerator_filter_.get()); + // Drag drop controller needs a valid shell instance. We destroy it first. drag_drop_controller_.reset(); @@ -191,6 +196,11 @@ void Shell::Init() { // Force a layout. desktop_layout->OnWindowResized(); + // Initialize ShellAcceleratorFilter + accelerator_filter_.reset(new internal::ShellAcceleratorFilter); + AddDesktopEventFilter(accelerator_filter_.get()); + + // Initialize drag drop controller. drag_drop_controller_.reset(new internal::DragDropController); aura::Desktop::GetInstance()->SetProperty(aura::kDesktopDragDropClientKey, static_cast<aura::DragDropClient*>(drag_drop_controller_.get())); diff --git a/ui/aura_shell/shell.h b/ui/aura_shell/shell.h index 0ab72bc..228c00f 100644 --- a/ui/aura_shell/shell.h +++ b/ui/aura_shell/shell.h @@ -27,6 +27,7 @@ class Rect; namespace aura_shell { class Launcher; +class ShellAcceleratorController; class ShellDelegate; namespace internal { @@ -34,6 +35,7 @@ class AppList; class DragDropController; class ShadowController; class ShelfLayoutController; +class ShellAcceleratorFilter; class WorkspaceController; } @@ -66,6 +68,10 @@ class AURA_SHELL_EXPORT Shell { // Toggles app list. void ToggleAppList(); + ShellAcceleratorController* accelerator_controller() { + return accelerator_controller_.get(); + } + ShellDelegate* delegate() { return delegate_.get(); } Launcher* launcher() { return launcher_.get(); } @@ -91,6 +97,8 @@ class AURA_SHELL_EXPORT Shell { base::WeakPtrFactory<Shell> method_factory_; + scoped_ptr<ShellAcceleratorController> accelerator_controller_; + scoped_ptr<ShellDelegate> delegate_; scoped_ptr<Launcher> launcher_; @@ -102,6 +110,9 @@ class AURA_SHELL_EXPORT Shell { scoped_ptr<internal::ShelfLayoutController> shelf_layout_controller_; scoped_ptr<internal::ShadowController> shadow_controller_; + // An event filter that pre-handles global accelerators. + scoped_ptr<internal::ShellAcceleratorFilter> accelerator_filter_; + DISALLOW_COPY_AND_ASSIGN(Shell); }; diff --git a/ui/aura_shell/shell_accelerator_controller.cc b/ui/aura_shell/shell_accelerator_controller.cc new file mode 100644 index 0000000..9c67a9d --- /dev/null +++ b/ui/aura_shell/shell_accelerator_controller.cc @@ -0,0 +1,126 @@ +// 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 "ui/aura_shell/shell_accelerator_controller.h" + +#include "ui/aura/desktop.h" +#include "ui/aura/event.h" +#include "ui/aura_shell/shell.h" +#include "ui/base/accelerator_manager.h" +#include "ui/base/models/accelerator.h" +#include "ui/gfx/compositor/layer_animation_sequence.h" +#include "ui/gfx/compositor/layer_animator.h" +#include "ui/gfx/compositor/screen_rotation.h" + +namespace { + +// Acceleraters handled by ShellAcceleratorController. +struct AcceleratorData { + ui::KeyboardCode keycode; + bool shift; + bool ctrl; + bool alt; +} kAcceleratorData[] = { + { ui::VKEY_F11, false, false, false }, + { ui::VKEY_HOME, false, true, false }, +}; + +// Registers the accelerators with ShellAcceleratorController. +void RegisterAccelerators(aura_shell::ShellAcceleratorController* controller) { + for (size_t i = 0; i < arraysize(kAcceleratorData); ++i) { + controller->Register(ui::Accelerator(kAcceleratorData[i].keycode, + kAcceleratorData[i].shift, + kAcceleratorData[i].ctrl, + kAcceleratorData[i].alt), + controller); + } +} + +#if !defined(NDEBUG) +// Rotates the screen. +void RotateScreen() { + 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::Desktop::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::Desktop::GetInstance()); + aura::Desktop::GetInstance()->layer()->GetAnimator()->ScheduleAnimation( + screen_rotation.release()); +} +#endif + +} // namespace + +namespace aura_shell { + +//////////////////////////////////////////////////////////////////////////////// +// ShellAcceleratorController, public: + +ShellAcceleratorController::ShellAcceleratorController() + : accelerator_manager_(new ui::AcceleratorManager) { + RegisterAccelerators(this); +} + +ShellAcceleratorController::~ShellAcceleratorController() { +} + +void ShellAcceleratorController::Register( + const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target) { + accelerator_manager_->Register(accelerator, target); +} + +void ShellAcceleratorController::Unregister( + const ui::Accelerator& accelerator, + ui::AcceleratorTarget* target) { + accelerator_manager_->Unregister(accelerator, target); +} + +void ShellAcceleratorController::UnregisterAll( + ui::AcceleratorTarget* target) { + accelerator_manager_->UnregisterAll(target); +} + +bool ShellAcceleratorController::Process(const ui::Accelerator& accelerator) { + return accelerator_manager_->Process(accelerator); +} + +//////////////////////////////////////////////////////////////////////////////// +// ShellAcceleratorController, ui::AcceleratorTarget implementation: + +bool ShellAcceleratorController::AcceleratorPressed( + const ui::Accelerator& accelerator) { +#if !defined(NDEBUG) + if (accelerator.key_code() == ui::VKEY_F11) { + aura::Desktop::GetInstance()->ToggleFullScreen(); + return true; + } else if (accelerator.key_code() == ui::VKEY_HOME && + accelerator.IsCtrlDown()) { + RotateScreen(); + return true; + } +#endif + return false; +} + +} // namespace aura_shell diff --git a/ui/aura_shell/shell_accelerator_controller.h b/ui/aura_shell/shell_accelerator_controller.h new file mode 100644 index 0000000..14f1f3a --- /dev/null +++ b/ui/aura_shell/shell_accelerator_controller.h @@ -0,0 +1,62 @@ +// 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 UI_AURA_SHELL_SHELL_ACCELERATOR_CONTROLLER_H_ +#define UI_AURA_SHELL_SHELL_ACCELERATOR_CONTROLLER_H_ +#pragma once + +#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/models/accelerator.h" + +namespace ui { +class AcceleratorManager; +} // namespace ui + +namespace aura_shell { + +// ShellAcceleratorController 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 ShellAcceleratorController + : public ui::AcceleratorTarget { + public: + ShellAcceleratorController(); + virtual ~ShellAcceleratorController(); + + // 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; + + private: + scoped_ptr<ui::AcceleratorManager> accelerator_manager_; + + DISALLOW_COPY_AND_ASSIGN(ShellAcceleratorController); +}; + +} // namespace aura_shell + +#endif // UI_AURA_SHELL_SHELL_ACCELERATOR_CONTROLLER_H_ diff --git a/ui/aura_shell/shell_accelerator_filter.cc b/ui/aura_shell/shell_accelerator_filter.cc new file mode 100644 index 0000000..3a9cde5 --- /dev/null +++ b/ui/aura_shell/shell_accelerator_filter.cc @@ -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. + +#include "ui/aura_shell/shell_accelerator_filter.h" + +#include "ui/aura/desktop.h" +#include "ui/aura/event.h" +#include "ui/aura_shell/shell.h" +#include "ui/aura_shell/shell_accelerator_controller.h" +#include "ui/base/accelerator_manager.h" +#include "ui/base/models/accelerator.h" + +namespace { +const int kModifierFlagMask = (ui::EF_SHIFT_DOWN | + ui::EF_CONTROL_DOWN | + ui::EF_ALT_DOWN); +} // namespace + +namespace aura_shell { +namespace internal { + +//////////////////////////////////////////////////////////////////////////////// +// ShellAcceleratorFilter, public: + +ShellAcceleratorFilter::ShellAcceleratorFilter() + : EventFilter(aura::Desktop::GetInstance()) { +} + +ShellAcceleratorFilter::~ShellAcceleratorFilter() { +} + +//////////////////////////////////////////////////////////////////////////////// +// ShellAcceleratorFilter, EventFilter implementation: + +bool ShellAcceleratorFilter::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + if (event->type() == ui::ET_KEY_PRESSED && + Shell::GetInstance()->accelerator_controller()->Process( + ui::Accelerator(event->key_code(), + event->flags() & kModifierFlagMask))) { + return true; + } + return false; +} + +bool ShellAcceleratorFilter::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + return false; +} + +ui::TouchStatus ShellAcceleratorFilter::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +} // namespace internal +} // namespace aura_shell diff --git a/ui/aura_shell/shell_accelerator_filter.h b/ui/aura_shell/shell_accelerator_filter.h new file mode 100644 index 0000000..3e35ba6 --- /dev/null +++ b/ui/aura_shell/shell_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 UI_AURA_SHELL_SHELL_ACCELERATOR_FILTER_H_ +#define UI_AURA_SHELL_SHELL_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 { + +// ShellAcceleratorFilter filters key events for ShellAcceleratorControler +// handling global keyboard accelerators. +class AURA_SHELL_EXPORT ShellAcceleratorFilter : public aura::EventFilter { + public: + ShellAcceleratorFilter(); + virtual ~ShellAcceleratorFilter(); + + // 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(ShellAcceleratorFilter); +}; + +} // namespace internal +} // namespace aura_shell + +#endif // UI_AURA_SHELL_SHELL_ACCELERATOR_FILTER_H_ |