summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-24 13:23:04 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-24 13:23:04 +0000
commit339e312781ed3be0e10a79d9c8855dcb110154d5 (patch)
treee4489415c3b43a9657ad3b959848e6d689c42c99
parenta306aaae14d5c582d8f0916624e9c7819df7dee4 (diff)
downloadchromium_src-339e312781ed3be0e10a79d9c8855dcb110154d5.zip
chromium_src-339e312781ed3be0e10a79d9c8855dcb110154d5.tar.gz
chromium_src-339e312781ed3be0e10a79d9c8855dcb110154d5.tar.bz2
Refactor and move ash independent accelerator handling code in nested loop to ui/wm/core
I also renamed classes to NestedAcceleratorXxx. I felt this is a bit more clearer than NestedDispatcher, especially in ui/wm/core. Please let me know if you disagree or have better suggestion. I'm happy to rename them. BUG=None Review URL: https://codereview.chromium.org/298703007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272740 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/accelerators/accelerator_dispatcher.h58
-rw-r--r--ash/accelerators/nested_accelerator_delegate.cc (renamed from ash/accelerators/accelerator_dispatcher.cc)23
-rw-r--r--ash/accelerators/nested_accelerator_delegate.h28
-rw-r--r--ash/accelerators/nested_dispatcher_controller_unittest.cc151
-rw-r--r--ash/ash.gyp11
-rw-r--r--ash/shell.cc12
-rw-r--r--ash/shell.h4
-rw-r--r--ui/wm/core/DEPS1
-rw-r--r--ui/wm/core/nested_accelerator_controller.cc (renamed from ash/accelerators/nested_dispatcher_controller.cc)28
-rw-r--r--ui/wm/core/nested_accelerator_controller.h (renamed from ash/accelerators/nested_dispatcher_controller.h)28
-rw-r--r--ui/wm/core/nested_accelerator_controller_unittest.cc201
-rw-r--r--ui/wm/core/nested_accelerator_delegate.h31
-rw-r--r--ui/wm/core/nested_accelerator_dispatcher.cc21
-rw-r--r--ui/wm/core/nested_accelerator_dispatcher.h55
-rw-r--r--ui/wm/core/nested_accelerator_dispatcher_linux.cc (renamed from ash/accelerators/accelerator_dispatcher_linux.cc)32
-rw-r--r--ui/wm/core/nested_accelerator_dispatcher_win.cc (renamed from ash/accelerators/accelerator_dispatcher_win.cc)33
-rw-r--r--ui/wm/wm.gyp9
17 files changed, 440 insertions, 286 deletions
diff --git a/ash/accelerators/accelerator_dispatcher.h b/ash/accelerators/accelerator_dispatcher.h
deleted file mode 100644
index 72b5df7..0000000
--- a/ash/accelerators/accelerator_dispatcher.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_
-#define ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_
-
-#include "ash/ash_export.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace base {
-class MessagePumpDispatcher;
-class RunLoop;
-}
-
-namespace ui {
-class KeyEvent;
-}
-
-namespace ash {
-
-// Dispatcher for handling accelerators from menu.
-//
-// Wraps a nested dispatcher to which control is passed if no accelerator key
-// has been pressed. If the nested dispatcher is NULL, then the control is
-// passed back to the default dispatcher.
-// TODO(pkotwicz): Add support for a |nested_dispatcher| which sends
-// events to a system IME.
-class ASH_EXPORT AcceleratorDispatcher {
- public:
- virtual ~AcceleratorDispatcher() {}
-
- static scoped_ptr<AcceleratorDispatcher> Create(
- base::MessagePumpDispatcher* nested_dispatcher);
-
- // Creates a base::RunLoop object to run a nested message loop.
- virtual scoped_ptr<base::RunLoop> CreateRunLoop() = 0;
-
- protected:
- AcceleratorDispatcher() {}
-
- // Closes any open menu if the key-event could potentially be a system
- // accelerator.
- // Returns whether a menu was closed.
- bool MenuClosedForPossibleAccelerator(const ui::KeyEvent& key_event);
-
- // Attempts to trigger an accelerator for the key-event.
- // Returns whether an accelerator was triggered.
- bool AcceleratorProcessedForKeyEvent(const ui::KeyEvent& key_event);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AcceleratorDispatcher);
-};
-
-} // namespace ash
-
-#endif // ASH_ACCELERATORS_ACCELERATOR_DISPATCHER_H_
diff --git a/ash/accelerators/accelerator_dispatcher.cc b/ash/accelerators/nested_accelerator_delegate.cc
index fe194f3..eb83a21 100644
--- a/ash/accelerators/accelerator_dispatcher.cc
+++ b/ash/accelerators/nested_accelerator_delegate.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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 "ash/accelerators/accelerator_dispatcher.h"
+#include "ash/accelerators/nested_accelerator_delegate.h"
#include "ash/accelerators/accelerator_controller.h"
#include "ash/shell.h"
@@ -35,21 +35,28 @@ bool IsPossibleAcceleratorNotForMenu(const ui::KeyEvent& key_event) {
} // namespace
-bool AcceleratorDispatcher::MenuClosedForPossibleAccelerator(
+NestedAcceleratorDelegate::NestedAcceleratorDelegate() {
+ LOG(ERROR) << "NAD";
+}
+
+NestedAcceleratorDelegate::~NestedAcceleratorDelegate() {
+ LOG(ERROR) << "~NAD";
+}
+
+bool NestedAcceleratorDelegate::ShouldProcessEventNow(
const ui::KeyEvent& key_event) {
if (!IsPossibleAcceleratorNotForMenu(key_event))
- return false;
+ return true;
if (views::MenuController* menu_controller =
views::MenuController::GetActiveInstance()) {
menu_controller->CancelAll();
- return true;
+ return false;
}
- return false;
+ return true;
}
-bool AcceleratorDispatcher::AcceleratorProcessedForKeyEvent(
- const ui::KeyEvent& key_event) {
+bool NestedAcceleratorDelegate::ProcessEvent(const ui::KeyEvent& key_event) {
ash::AcceleratorController* accelerator_controller =
ash::Shell::GetInstance()->accelerator_controller();
if (!accelerator_controller)
diff --git a/ash/accelerators/nested_accelerator_delegate.h b/ash/accelerators/nested_accelerator_delegate.h
new file mode 100644
index 0000000..63bc498
--- /dev/null
+++ b/ash/accelerators/nested_accelerator_delegate.h
@@ -0,0 +1,28 @@
+// 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 ASH_ACCELERATORS_NESTED_ACCELERATOR_DELEGATE_H_
+#define ASH_ACCELERATORS_NESTED_ACCELERATOR_DELEGATE_H_
+
+#include "base/macros.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
+
+namespace ash {
+
+class NestedAcceleratorDelegate : public wm::NestedAcceleratorDelegate {
+ public:
+ NestedAcceleratorDelegate();
+ virtual ~NestedAcceleratorDelegate();
+
+ // wm::AcceleratorDispatcher::Delegate
+ virtual bool ShouldProcessEventNow(const ui::KeyEvent& key_event) OVERRIDE;
+ virtual bool ProcessEvent(const ui::KeyEvent& key_event) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDelegate);
+};
+
+} // namespace
+
+#endif // ASH_ACCELERATORS_NESTED_ACCELERATOR_DELEGATE_H_
diff --git a/ash/accelerators/nested_dispatcher_controller_unittest.cc b/ash/accelerators/nested_dispatcher_controller_unittest.cc
deleted file mode 100644
index e5aef88..0000000
--- a/ash/accelerators/nested_dispatcher_controller_unittest.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/accelerators/accelerator_controller.h"
-#include "ash/session/session_state_delegate.h"
-#include "ash/shell.h"
-#include "ash/shell_window_ids.h"
-#include "ash/test/ash_test_base.h"
-#include "base/bind.h"
-#include "base/event_types.h"
-#include "base/message_loop/message_loop.h"
-#include "ui/aura/test/test_windows.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
-#include "ui/base/accelerators/accelerator.h"
-#include "ui/events/event_constants.h"
-#include "ui/events/event_utils.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ui/events/platform/scoped_event_dispatcher.h"
-#include "ui/wm/public/dispatcher_client.h"
-
-#if defined(USE_X11)
-#include <X11/Xlib.h>
-#include "ui/events/test/events_test_utils_x11.h"
-#endif // USE_X11
-
-namespace ash {
-namespace test {
-
-namespace {
-
-class MockDispatcher : public ui::PlatformEventDispatcher {
- public:
- MockDispatcher() : num_key_events_dispatched_(0) {
- }
-
- int num_key_events_dispatched() { return num_key_events_dispatched_; }
-
- private:
- // ui::PlatformEventDispatcher:
- virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
- return true;
- }
- virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
- if (ui::EventTypeFromNative(event) == ui::ET_KEY_RELEASED)
- num_key_events_dispatched_++;
- return ui::POST_DISPATCH_NONE;
- }
-
- int num_key_events_dispatched_;
-
- DISALLOW_COPY_AND_ASSIGN(MockDispatcher);
-};
-
-class TestTarget : public ui::AcceleratorTarget {
- public:
- TestTarget() : accelerator_pressed_count_(0) {
- }
- virtual ~TestTarget() {
- }
-
- int accelerator_pressed_count() const {
- return accelerator_pressed_count_;
- }
-
- // Overridden from ui::AcceleratorTarget:
- virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
- accelerator_pressed_count_++;
- return true;
- }
- virtual bool CanHandleAccelerators() const OVERRIDE {
- return true;
- }
-
- private:
- int accelerator_pressed_count_;
-
- DISALLOW_COPY_AND_ASSIGN(TestTarget);
-};
-
-void DispatchKeyReleaseA() {
- // Sending both keydown and keyup is necessary here because the accelerator
- // manager only checks a keyup event following a keydown event. See
- // ShouldHandle() in ui/base/accelerators/accelerator_manager.cc for details.
-#if defined(OS_WIN)
- MSG native_event_down = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 };
- ash::Shell::GetPrimaryRootWindow()->host()->PostNativeEvent(
- native_event_down);
- MSG native_event_up = { NULL, WM_KEYUP, ui::VKEY_A, 0 };
- ash::Shell::GetPrimaryRootWindow()->host()->PostNativeEvent(native_event_up);
-#elif defined(USE_X11)
- ui::ScopedXI2Event native_event;
- native_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
- aura::WindowTreeHost* host = ash::Shell::GetPrimaryRootWindow()->GetHost();
- host->PostNativeEvent(native_event);
- native_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
- host->PostNativeEvent(native_event);
-#endif
- // Make sure the inner message-loop terminates after dispatching the events.
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::MessageLoop::current()->QuitClosure());
-}
-
-} // namespace
-
-typedef AshTestBase NestedDispatcherTest;
-
-// Aura window above lock screen in z order.
-TEST_F(NestedDispatcherTest, AssociatedWindowAboveLockScreen) {
- MockDispatcher inner_dispatcher;
-
- scoped_ptr<aura::Window> mock_lock_container(
- CreateTestWindowInShellWithId(0));
- aura::test::CreateTestWindowWithId(1, mock_lock_container.get());
- scoped_ptr<aura::Window> associated_window(CreateTestWindowInShellWithId(2));
- EXPECT_TRUE(aura::test::WindowIsAbove(associated_window.get(),
- mock_lock_container.get()));
-
- DispatchKeyReleaseA();
- aura::Window* root_window = ash::Shell::GetPrimaryRootWindow();
- scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher =
- ui::PlatformEventSource::GetInstance()->OverrideDispatcher(
- &inner_dispatcher);
- aura::client::GetDispatcherClient(root_window)->RunWithDispatcher(NULL);
- EXPECT_EQ(1, inner_dispatcher.num_key_events_dispatched());
-}
-
-// Test that the nested dispatcher handles accelerators.
-TEST_F(NestedDispatcherTest, AcceleratorsHandled) {
- MockDispatcher inner_dispatcher;
- aura::Window* root_window = ash::Shell::GetPrimaryRootWindow();
-
- ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
- accelerator.set_type(ui::ET_KEY_RELEASED);
- TestTarget target;
- Shell::GetInstance()->accelerator_controller()->Register(accelerator,
- &target);
-
- DispatchKeyReleaseA();
- scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher =
- ui::PlatformEventSource::GetInstance()->OverrideDispatcher(
- &inner_dispatcher);
- aura::client::GetDispatcherClient(root_window)->RunWithDispatcher(NULL);
- EXPECT_EQ(0, inner_dispatcher.num_key_events_dispatched());
- EXPECT_EQ(1, target.accelerator_pressed_count());
-}
-
-} // namespace test
-} // namespace ash
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 6d8fece..b42fe07 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -1,4 +1,4 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+#a Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -55,10 +55,8 @@
'accelerators/accelerator_commands.h',
'accelerators/accelerator_controller.cc',
'accelerators/accelerator_controller.h',
- 'accelerators/accelerator_dispatcher.cc',
- 'accelerators/accelerator_dispatcher.h',
- 'accelerators/accelerator_dispatcher_linux.cc',
- 'accelerators/accelerator_dispatcher_win.cc',
+ 'accelerators/nested_accelerator_delegate.cc',
+ 'accelerators/nested_accelerator_delegate.h',
'accelerators/accelerator_filter.cc',
'accelerators/accelerator_filter.h',
'accelerators/accelerator_table.cc',
@@ -73,8 +71,6 @@
'accelerators/focus_manager_factory.h',
'accelerators/magnifier_key_scroller.cc',
'accelerators/magnifier_key_scroller.h',
- 'accelerators/nested_dispatcher_controller.cc',
- 'accelerators/nested_dispatcher_controller.h',
'accelerators/spoken_feedback_toggler.cc',
'accelerators/spoken_feedback_toggler.h',
'accelerometer/accelerometer_controller.cc',
@@ -920,7 +916,6 @@
'accelerators/accelerator_filter_unittest.cc',
'accelerators/accelerator_table_unittest.cc',
'accelerators/magnifier_key_scroller_unittest.cc',
- 'accelerators/nested_dispatcher_controller_unittest.cc',
'accelerators/spoken_feedback_toggler_unittest.cc',
'autoclick/autoclick_unittest.cc',
'desktop_background/desktop_background_controller_unittest.cc',
diff --git a/ash/shell.cc b/ash/shell.cc
index c0a1765..1904f96 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -10,7 +10,7 @@
#include "ash/accelerators/accelerator_controller.h"
#include "ash/accelerators/accelerator_filter.h"
#include "ash/accelerators/focus_manager_factory.h"
-#include "ash/accelerators/nested_dispatcher_controller.h"
+#include "ash/accelerators/nested_accelerator_delegate.h"
#include "ash/accelerometer/accelerometer_controller.h"
#include "ash/ash_switches.h"
#include "ash/autoclick/autoclick_controller.h"
@@ -108,6 +108,7 @@
#include "ui/wm/core/compound_event_filter.h"
#include "ui/wm/core/focus_controller.h"
#include "ui/wm/core/input_method_event_filter.h"
+#include "ui/wm/core/nested_accelerator_controller.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/user_activity_detector.h"
#include "ui/wm/core/visibility_controller.h"
@@ -753,7 +754,7 @@ Shell::~Shell() {
partial_magnification_controller_.reset();
tooltip_controller_.reset();
event_client_.reset();
- nested_dispatcher_controller_.reset();
+ nested_accelerator_controller_.reset();
toplevel_window_event_handler_.reset();
visibility_controller_.reset();
// |shelf_item_delegate_manager_| observes |shelf_model_|. It must be
@@ -879,7 +880,8 @@ void Shell::Init(const ShellInitParams& init_params) {
cursor_manager_.SetDisplay(GetScreen()->GetPrimaryDisplay());
- nested_dispatcher_controller_.reset(new NestedDispatcherController);
+ nested_accelerator_controller_.reset(
+ new ::wm::NestedAcceleratorController(new NestedAcceleratorDelegate));
accelerator_controller_.reset(new AcceleratorController);
maximize_mode_controller_.reset(new MaximizeModeController());
@@ -1092,9 +1094,9 @@ void Shell::InitRootWindow(aura::Window* root_window) {
root_window->AddPreTargetHandler(toplevel_window_event_handler_.get());
root_window->AddPostTargetHandler(toplevel_window_event_handler_.get());
- if (nested_dispatcher_controller_) {
+ if (nested_accelerator_controller_) {
aura::client::SetDispatcherClient(root_window,
- nested_dispatcher_controller_.get());
+ nested_accelerator_controller_.get());
}
}
diff --git a/ash/shell.h b/ash/shell.h
index e889131..354d653 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -64,6 +64,7 @@ class TooltipController;
namespace wm {
class CompoundEventFilter;
class InputMethodEventFilter;
+class NestedAcceleratorController;
class ShadowController;
class VisibilityController;
class UserActivityDetector;
@@ -106,7 +107,6 @@ class MaximizeModeWindowManager;
class MediaDelegate;
class MouseCursorEventFilter;
class MruWindowTracker;
-class NestedDispatcherController;
class NewWindowDelegate;
class OverlayEventFilter;
class PartialMagnificationController;
@@ -623,7 +623,7 @@ class ASH_EXPORT Shell : public SystemModalContainerEventFilterDelegate,
std::vector<WindowAndBoundsPair> to_restore_;
scoped_ptr<UserMetricsRecorder> user_metrics_recorder_;
- scoped_ptr<NestedDispatcherController> nested_dispatcher_controller_;
+ scoped_ptr< ::wm::NestedAcceleratorController> nested_accelerator_controller_;
scoped_ptr<AcceleratorController> accelerator_controller_;
scoped_ptr<ShellDelegate> delegate_;
scoped_ptr<SystemTrayDelegate> system_tray_delegate_;
diff --git a/ui/wm/core/DEPS b/ui/wm/core/DEPS
index 54c7090..8540601 100644
--- a/ui/wm/core/DEPS
+++ b/ui/wm/core/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+grit/ui_resources.h",
"+ui/aura",
+ "+ui/base/accelerators",
"+ui/base/cursor",
"+ui/base/hit_test.h",
"+ui/base/ime",
diff --git a/ash/accelerators/nested_dispatcher_controller.cc b/ui/wm/core/nested_accelerator_controller.cc
index d963db0..782ac6d 100644
--- a/ash/accelerators/nested_dispatcher_controller.cc
+++ b/ui/wm/core/nested_accelerator_controller.cc
@@ -1,30 +1,34 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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 "ash/accelerators/nested_dispatcher_controller.h"
+#include "ui/wm/core/nested_accelerator_controller.h"
-#include "ash/accelerators/accelerator_dispatcher.h"
-#include "ash/shell.h"
#include "base/auto_reset.h"
#include "base/run_loop.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
+#include "ui/wm/core/nested_accelerator_dispatcher.h"
-namespace ash {
+namespace wm {
-NestedDispatcherController::NestedDispatcherController() {
+NestedAcceleratorController::NestedAcceleratorController(
+ NestedAcceleratorDelegate* delegate)
+ : dispatcher_delegate_(delegate) {
+ DCHECK(delegate);
}
-NestedDispatcherController::~NestedDispatcherController() {
+NestedAcceleratorController::~NestedAcceleratorController() {
}
-void NestedDispatcherController::RunWithDispatcher(
+void NestedAcceleratorController::RunWithDispatcher(
base::MessagePumpDispatcher* nested_dispatcher) {
base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
- scoped_ptr<AcceleratorDispatcher> old_accelerator_dispatcher =
+ scoped_ptr<NestedAcceleratorDispatcher> old_accelerator_dispatcher =
accelerator_dispatcher_.Pass();
- accelerator_dispatcher_ = AcceleratorDispatcher::Create(nested_dispatcher);
+ accelerator_dispatcher_ = NestedAcceleratorDispatcher::Create(
+ dispatcher_delegate_.get(), nested_dispatcher);
// TODO(jbates) crbug.com/134753 Find quitters of this RunLoop and have them
// use run_loop.QuitClosure().
@@ -35,10 +39,10 @@ void NestedDispatcherController::RunWithDispatcher(
accelerator_dispatcher_ = old_accelerator_dispatcher.Pass();
}
-void NestedDispatcherController::QuitNestedMessageLoop() {
+void NestedAcceleratorController::QuitNestedMessageLoop() {
CHECK(!quit_closure_.is_null());
quit_closure_.Run();
accelerator_dispatcher_.reset();
}
-} // namespace ash
+} // namespace wm
diff --git a/ash/accelerators/nested_dispatcher_controller.h b/ui/wm/core/nested_accelerator_controller.h
index ebac2d2..2adfcbc 100644
--- a/ash/accelerators/nested_dispatcher_controller.h
+++ b/ui/wm/core/nested_accelerator_controller.h
@@ -1,28 +1,29 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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 ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_
-#define ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_
+#ifndef UI_WM_CORE_NESTED_ACCELERATOR_CONTROLLER_H_
+#define UI_WM_CORE_NESTED_ACCELERATOR_CONTROLLER_H_
-#include "ash/ash_export.h"
#include "base/callback.h"
#include "base/message_loop/message_loop.h"
#include "ui/wm/public/dispatcher_client.h"
+#include "ui/wm/wm_export.h"
-namespace ash {
+namespace wm {
-class AcceleratorDispatcher;
+class NestedAcceleratorDelegate;
+class NestedAcceleratorDispatcher;
// Creates a dispatcher which wraps another dispatcher.
// The outer dispatcher runs first and performs ash specific handling.
// If it does not consume the event it forwards the event to the nested
// dispatcher.
-class ASH_EXPORT NestedDispatcherController
+class WM_EXPORT NestedAcceleratorController
: public aura::client::DispatcherClient {
public:
- NestedDispatcherController();
- virtual ~NestedDispatcherController();
+ explicit NestedAcceleratorController(NestedAcceleratorDelegate* delegate);
+ virtual ~NestedAcceleratorController();
// aura::client::DispatcherClient:
virtual void RunWithDispatcher(
@@ -31,11 +32,12 @@ class ASH_EXPORT NestedDispatcherController
private:
base::Closure quit_closure_;
- scoped_ptr<AcceleratorDispatcher> accelerator_dispatcher_;
+ scoped_ptr<NestedAcceleratorDispatcher> accelerator_dispatcher_;
+ scoped_ptr<NestedAcceleratorDelegate> dispatcher_delegate_;
- DISALLOW_COPY_AND_ASSIGN(NestedDispatcherController);
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorController);
};
-} // namespace ash
+} // namespace wm
-#endif // ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_H_
+#endif // UI_WM_CORE_NESTED_ACCELERATOR_CONTROLLER_H_
diff --git a/ui/wm/core/nested_accelerator_controller_unittest.cc b/ui/wm/core/nested_accelerator_controller_unittest.cc
new file mode 100644
index 0000000..b3bb3e8
--- /dev/null
+++ b/ui/wm/core/nested_accelerator_controller_unittest.cc
@@ -0,0 +1,201 @@
+// 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 "ui/wm/core/nested_accelerator_controller.h"
+
+#include "base/bind.h"
+#include "base/event_types.h"
+#include "base/message_loop/message_loop.h"
+#include "ui/aura/test/aura_test_base.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/accelerators/accelerator.h"
+#include "ui/base/accelerators/accelerator_manager.h"
+#include "ui/events/event_constants.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/events/platform/scoped_event_dispatcher.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
+#include "ui/wm/public/dispatcher_client.h"
+
+#if defined(USE_X11)
+#include <X11/Xlib.h>
+#include "ui/events/test/events_test_utils_x11.h"
+#endif // USE_X11
+
+namespace wm {
+namespace test {
+
+namespace {
+
+class MockDispatcher : public ui::PlatformEventDispatcher {
+ public:
+ MockDispatcher() : num_key_events_dispatched_(0) {}
+
+ int num_key_events_dispatched() { return num_key_events_dispatched_; }
+
+ private:
+ // ui::PlatformEventDispatcher:
+ virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
+ return true;
+ }
+ virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
+ if (ui::EventTypeFromNative(event) == ui::ET_KEY_RELEASED)
+ num_key_events_dispatched_++;
+ return ui::POST_DISPATCH_NONE;
+ }
+
+ int num_key_events_dispatched_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockDispatcher);
+};
+
+class TestTarget : public ui::AcceleratorTarget {
+ public:
+ TestTarget() : accelerator_pressed_count_(0) {}
+ virtual ~TestTarget() {}
+
+ int accelerator_pressed_count() const { return accelerator_pressed_count_; }
+
+ // Overridden from ui::AcceleratorTarget:
+ virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
+ accelerator_pressed_count_++;
+ return true;
+ }
+ virtual bool CanHandleAccelerators() const OVERRIDE { return true; }
+
+ private:
+ int accelerator_pressed_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestTarget);
+};
+
+void DispatchKeyReleaseA(aura::Window* root_window) {
+// Sending both keydown and keyup is necessary here because the accelerator
+// manager only checks a keyup event following a keydown event. See
+// ShouldHandle() in ui/base/accelerators/accelerator_manager.cc for details.
+#if defined(OS_WIN)
+ MSG native_event_down = {NULL, WM_KEYDOWN, ui::VKEY_A, 0};
+ root_window->host()->PostNativeEvent(native_event_down);
+ MSG native_event_up = {NULL, WM_KEYUP, ui::VKEY_A, 0};
+ root_window->host()->PostNativeEvent(native_event_up);
+#elif defined(USE_X11)
+ ui::ScopedXI2Event native_event;
+ native_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
+ aura::WindowTreeHost* host = root_window->GetHost();
+ host->PostNativeEvent(native_event);
+ native_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0);
+ host->PostNativeEvent(native_event);
+#endif
+ // Make sure the inner message-loop terminates after dispatching the events.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::MessageLoop::current()->QuitClosure());
+}
+
+class MockNestedAcceleratorDelegate : public NestedAcceleratorDelegate {
+ public:
+ MockNestedAcceleratorDelegate()
+ : accelerator_manager_(new ui::AcceleratorManager) {}
+ virtual ~MockNestedAcceleratorDelegate() {}
+
+ // NestedAcceleratorDelegate:
+ virtual bool ShouldProcessEventNow(const ui::KeyEvent& key_event) OVERRIDE {
+ return true;
+ }
+ virtual bool ProcessEvent(const ui::KeyEvent& key_event) OVERRIDE {
+ const int kModifierMask =
+ (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
+ ui::Accelerator accelerator(key_event.key_code(),
+ key_event.flags() & kModifierMask);
+ if (key_event.type() == ui::ET_KEY_RELEASED)
+ accelerator.set_type(ui::ET_KEY_RELEASED);
+ return accelerator_manager_->Process(accelerator);
+ }
+
+ void Register(const ui::Accelerator& accelerator,
+ ui::AcceleratorTarget* target) {
+ accelerator_manager_->Register(
+ accelerator, ui::AcceleratorManager::kNormalPriority, target);
+ }
+
+ private:
+ scoped_ptr<ui::AcceleratorManager> accelerator_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockNestedAcceleratorDelegate);
+};
+
+class NestedAcceleratorTest : public aura::test::AuraTestBase {
+ public:
+ NestedAcceleratorTest() {}
+ virtual ~NestedAcceleratorTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ AuraTestBase::SetUp();
+ delegate_ = new MockNestedAcceleratorDelegate();
+ nested_accelerator_controller_.reset(
+ new NestedAcceleratorController(delegate_));
+ aura::client::SetDispatcherClient(root_window(),
+ nested_accelerator_controller_.get());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ aura::client::SetDispatcherClient(root_window(), NULL);
+ AuraTestBase::TearDown();
+ delegate_ = NULL;
+ nested_accelerator_controller_.reset();
+ }
+
+ MockNestedAcceleratorDelegate* delegate() { return delegate_; }
+
+ private:
+ scoped_ptr<NestedAcceleratorController> nested_accelerator_controller_;
+ MockNestedAcceleratorDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorTest);
+};
+
+} // namespace
+
+// Aura window above lock screen in z order.
+TEST_F(NestedAcceleratorTest, AssociatedWindowAboveLockScreen) {
+ MockDispatcher inner_dispatcher;
+ scoped_ptr<aura::Window> mock_lock_container(
+ CreateNormalWindow(0, root_window(), NULL));
+ aura::test::CreateTestWindowWithId(1, mock_lock_container.get());
+
+ scoped_ptr<aura::Window> associated_window(
+ CreateNormalWindow(2, root_window(), NULL));
+ EXPECT_TRUE(aura::test::WindowIsAbove(associated_window.get(),
+ mock_lock_container.get()));
+
+ DispatchKeyReleaseA(root_window());
+ scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher =
+ ui::PlatformEventSource::GetInstance()->OverrideDispatcher(
+ &inner_dispatcher);
+ aura::client::GetDispatcherClient(root_window())->RunWithDispatcher(NULL);
+ EXPECT_EQ(1, inner_dispatcher.num_key_events_dispatched());
+}
+
+// Test that the nested dispatcher handles accelerators.
+TEST_F(NestedAcceleratorTest, AcceleratorsHandled) {
+ MockDispatcher inner_dispatcher;
+ ui::Accelerator accelerator(ui::VKEY_A, ui::EF_NONE);
+ accelerator.set_type(ui::ET_KEY_RELEASED);
+ TestTarget target;
+ delegate()->Register(accelerator, &target);
+
+ DispatchKeyReleaseA(root_window());
+ scoped_ptr<ui::ScopedEventDispatcher> override_dispatcher =
+ ui::PlatformEventSource::GetInstance()->OverrideDispatcher(
+ &inner_dispatcher);
+ aura::client::GetDispatcherClient(root_window())->RunWithDispatcher(NULL);
+ EXPECT_EQ(0, inner_dispatcher.num_key_events_dispatched());
+ EXPECT_EQ(1, target.accelerator_pressed_count());
+}
+
+} // namespace test
+} // namespace wm
diff --git a/ui/wm/core/nested_accelerator_delegate.h b/ui/wm/core/nested_accelerator_delegate.h
new file mode 100644
index 0000000..45b9e2a
--- /dev/null
+++ b/ui/wm/core/nested_accelerator_delegate.h
@@ -0,0 +1,31 @@
+// 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 UI_WM_CORE_NESTED_ACCELERATOR_DELEGATE_H_
+#define UI_WM_CORE_NESTED_ACCELERATOR_DELEGATE_H_
+
+namespace ui {
+class KeyEvent;
+}
+
+namespace wm {
+
+// A delegate interface that implements the behavior of nested accelerator
+// handling.
+class NestedAcceleratorDelegate {
+ public:
+ virtual ~NestedAcceleratorDelegate() {}
+
+ // If the key event should be ignored now and instead be reposted so that next
+ // event loop.
+ virtual bool ShouldProcessEventNow(const ui::KeyEvent& key_event) = 0;
+
+ // Attempts to process an accelerator for the key-event.
+ // Returns whether an accelerator was triggered and processed.
+ virtual bool ProcessEvent(const ui::KeyEvent& key_event) = 0;
+};
+
+} // namespace wm
+
+#endif // UI_WM_CORE_NESTED_ACCELERATOR_DELEGATE_H_
diff --git a/ui/wm/core/nested_accelerator_dispatcher.cc b/ui/wm/core/nested_accelerator_dispatcher.cc
new file mode 100644
index 0000000..d37c93c
--- /dev/null
+++ b/ui/wm/core/nested_accelerator_dispatcher.cc
@@ -0,0 +1,21 @@
+// 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 "ui/wm/core/nested_accelerator_dispatcher.h"
+
+#include "base/logging.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
+
+namespace wm {
+
+NestedAcceleratorDispatcher::NestedAcceleratorDispatcher(
+ NestedAcceleratorDelegate* delegate)
+ : delegate_(delegate) {
+ DCHECK(delegate);
+}
+
+NestedAcceleratorDispatcher::~NestedAcceleratorDispatcher() {
+}
+
+} // namespace wm
diff --git a/ui/wm/core/nested_accelerator_dispatcher.h b/ui/wm/core/nested_accelerator_dispatcher.h
new file mode 100644
index 0000000..df5dd08
--- /dev/null
+++ b/ui/wm/core/nested_accelerator_dispatcher.h
@@ -0,0 +1,55 @@
+// 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 UI_WM_CORE_NESTED_ACCELERATOR_DISPATCHER_H_
+#define UI_WM_CORE_NESTED_ACCELERATOR_DISPATCHER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/wm/wm_export.h"
+
+namespace base {
+class MessagePumpDispatcher;
+class RunLoop;
+}
+
+namespace ui {
+class KeyEvent;
+}
+
+namespace wm {
+
+class NestedAcceleratorDelegate;
+
+// Dispatcher for handling accelerators from menu.
+//
+// Wraps a nested dispatcher to which control is passed if no accelerator key
+// has been pressed. If the nested dispatcher is NULL, then the control is
+// passed back to the default dispatcher.
+// TODO(pkotwicz): Add support for a |nested_dispatcher| which sends
+// events to a system IME.
+class WM_EXPORT NestedAcceleratorDispatcher {
+ public:
+ virtual ~NestedAcceleratorDispatcher();
+
+ static scoped_ptr<NestedAcceleratorDispatcher> Create(
+ NestedAcceleratorDelegate* dispatcher_delegate,
+ base::MessagePumpDispatcher* nested_dispatcher);
+
+ // Creates a base::RunLoop object to run a nested message loop.
+ virtual scoped_ptr<base::RunLoop> CreateRunLoop() = 0;
+
+ protected:
+ explicit NestedAcceleratorDispatcher(NestedAcceleratorDelegate* delegate);
+
+ NestedAcceleratorDelegate*
+ delegate_; // Owned by NestedAcceleratorController.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDispatcher);
+};
+
+} // namespace wm
+
+#endif // UI_WM_CORE_NESTED_ACCELERATOR_DISPATCHER_H_
diff --git a/ash/accelerators/accelerator_dispatcher_linux.cc b/ui/wm/core/nested_accelerator_dispatcher_linux.cc
index b5494dd..bf21d3f 100644
--- a/ash/accelerators/accelerator_dispatcher_linux.cc
+++ b/ui/wm/core/nested_accelerator_dispatcher_linux.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ash/accelerators/accelerator_dispatcher.h"
+#include "ui/wm/core/nested_accelerator_dispatcher.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
@@ -10,12 +10,13 @@
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/scoped_event_dispatcher.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
#if defined(USE_X11)
#include <X11/Xlib.h>
#endif
-namespace ash {
+namespace wm {
namespace {
@@ -41,13 +42,14 @@ scoped_ptr<ui::ScopedEventDispatcher> OverrideDispatcher(
} // namespace
-class AcceleratorDispatcherLinux : public AcceleratorDispatcher,
- public ui::PlatformEventDispatcher {
+class NestedAcceleratorDispatcherLinux : public NestedAcceleratorDispatcher,
+ public ui::PlatformEventDispatcher {
public:
- AcceleratorDispatcherLinux()
- : restore_dispatcher_(OverrideDispatcher(this)) {}
+ explicit NestedAcceleratorDispatcherLinux(NestedAcceleratorDelegate* delegate)
+ : NestedAcceleratorDispatcher(delegate),
+ restore_dispatcher_(OverrideDispatcher(this)) {}
- virtual ~AcceleratorDispatcherLinux() {}
+ virtual ~NestedAcceleratorDispatcherLinux() {}
private:
// AcceleratorDispatcher:
@@ -63,7 +65,7 @@ class AcceleratorDispatcherLinux : public AcceleratorDispatcher,
virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE {
if (IsKeyEvent(event)) {
ui::KeyEvent key_event(event, false);
- if (MenuClosedForPossibleAccelerator(key_event)) {
+ if (!delegate_->ShouldProcessEventNow(key_event)) {
#if defined(USE_X11)
XPutBackEvent(event->xany.display, event);
#else
@@ -72,23 +74,25 @@ class AcceleratorDispatcherLinux : public AcceleratorDispatcher,
return ui::POST_DISPATCH_NONE;
}
- if (AcceleratorProcessedForKeyEvent(key_event))
+ if (delegate_->ProcessEvent(key_event))
return ui::POST_DISPATCH_NONE;
}
-
ui::PlatformEventDispatcher* prev = *restore_dispatcher_;
+
return prev ? prev->DispatchEvent(event)
: ui::POST_DISPATCH_PERFORM_DEFAULT;
}
scoped_ptr<ui::ScopedEventDispatcher> restore_dispatcher_;
- DISALLOW_COPY_AND_ASSIGN(AcceleratorDispatcherLinux);
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDispatcherLinux);
};
-scoped_ptr<AcceleratorDispatcher> AcceleratorDispatcher::Create(
+scoped_ptr<NestedAcceleratorDispatcher> NestedAcceleratorDispatcher::Create(
+ NestedAcceleratorDelegate* delegate,
base::MessagePumpDispatcher* nested_dispatcher) {
- return scoped_ptr<AcceleratorDispatcher>(new AcceleratorDispatcherLinux());
+ return scoped_ptr<NestedAcceleratorDispatcher>(
+ new NestedAcceleratorDispatcherLinux(delegate));
}
-} // namespace ash
+} // namespace wm
diff --git a/ash/accelerators/accelerator_dispatcher_win.cc b/ui/wm/core/nested_accelerator_dispatcher_win.cc
index 35005f3..a6a5bd9 100644
--- a/ash/accelerators/accelerator_dispatcher_win.cc
+++ b/ui/wm/core/nested_accelerator_dispatcher_win.cc
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ash/accelerators/accelerator_dispatcher.h"
+#include "ui/wm/core/nested_accelerator_dispatcher.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_pump_dispatcher.h"
#include "base/run_loop.h"
#include "ui/events/event.h"
+#include "ui/wm/core/nested_accelerator_delegate.h"
using base::MessagePumpDispatcher;
-namespace ash {
+namespace wm {
namespace {
@@ -22,15 +23,16 @@ bool IsKeyEvent(const MSG& msg) {
} // namespace
-class AcceleratorDispatcherWin : public AcceleratorDispatcher,
- public MessagePumpDispatcher {
+class NestedAcceleratorDispatcherWin : public NestedAcceleratorDispatcher,
+ public MessagePumpDispatcher {
public:
- explicit AcceleratorDispatcherWin(MessagePumpDispatcher* nested)
- : nested_dispatcher_(nested) {}
- virtual ~AcceleratorDispatcherWin() {}
+ NestedAcceleratorDispatcherWin(NestedAcceleratorDelegate* delegate,
+ MessagePumpDispatcher* nested)
+ : NestedAcceleratorDispatcher(delegate), nested_dispatcher_(nested) {}
+ virtual ~NestedAcceleratorDispatcherWin() {}
private:
- // AcceleratorDispatcher:
+ // NestedAcceleratorDispatcher:
virtual scoped_ptr<base::RunLoop> CreateRunLoop() OVERRIDE {
return scoped_ptr<base::RunLoop>(new base::RunLoop(this));
}
@@ -39,10 +41,10 @@ class AcceleratorDispatcherWin : public AcceleratorDispatcher,
virtual uint32_t Dispatch(const MSG& event) OVERRIDE {
if (IsKeyEvent(event)) {
ui::KeyEvent key_event(event, false);
- if (MenuClosedForPossibleAccelerator(key_event))
+ if (!delegate_->ShouldProcessEventNow(key_event))
return POST_DISPATCH_QUIT_LOOP;
- if (AcceleratorProcessedForKeyEvent(key_event))
+ if (delegate_->ProcessEvent(key_event))
return POST_DISPATCH_NONE;
}
@@ -52,13 +54,14 @@ class AcceleratorDispatcherWin : public AcceleratorDispatcher,
MessagePumpDispatcher* nested_dispatcher_;
- DISALLOW_COPY_AND_ASSIGN(AcceleratorDispatcherWin);
+ DISALLOW_COPY_AND_ASSIGN(NestedAcceleratorDispatcherWin);
};
-scoped_ptr<AcceleratorDispatcher> AcceleratorDispatcher::Create(
+scoped_ptr<NestedAcceleratorDispatcher> NestedAcceleratorDispatcher::Create(
+ NestedAcceleratorDelegate* delegate,
MessagePumpDispatcher* nested_dispatcher) {
- return scoped_ptr<AcceleratorDispatcher>(
- new AcceleratorDispatcherWin(nested_dispatcher));
+ return scoped_ptr<NestedAcceleratorDispatcher>(
+ new NestedAcceleratorDispatcherWin(delegate, nested_dispatcher));
}
-} // namespace ash
+} // namespace wm
diff --git a/ui/wm/wm.gyp b/ui/wm/wm.gyp
index 537f67a..1a86102 100644
--- a/ui/wm/wm.gyp
+++ b/ui/wm/wm.gyp
@@ -26,6 +26,14 @@
'WM_IMPLEMENTATION',
],
'sources': [
+ 'core/nested_accelerator_dispatcher_linux.cc',
+ 'core/nested_accelerator_dispatcher_win.cc',
+ 'core/nested_accelerator_dispatcher.cc',
+ 'core/nested_accelerator_dispatcher.h',
+ 'core/nested_accelerator_delegate.h',
+ 'core/nested_accelerator_controller.cc',
+ 'core/nested_accelerator_controller.h',
+ 'core/base_focus_rules.h',
'core/base_focus_rules.cc',
'core/base_focus_rules.h',
'core/capture_controller.cc',
@@ -121,6 +129,7 @@
'core/focus_controller_unittest.cc',
'core/input_method_event_filter_unittest.cc',
'core/image_grid_unittest.cc',
+ 'core/nested_accelerator_controller_unittest.cc',
'core/shadow_controller_unittest.cc',
'core/transient_window_manager_unittest.cc',
'core/transient_window_stacking_client_unittest.cc',