diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-27 17:46:37 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-27 17:46:37 +0000 |
commit | b6d1724783fa378a745be25973c1b908d8679620 (patch) | |
tree | 75863c85ae04e850de9e091f0e19aced2aa3fc26 /ash/accelerators | |
parent | 80552a8894bf45a427671e950e29452f77b904f0 (diff) | |
download | chromium_src-b6d1724783fa378a745be25973c1b908d8679620.zip chromium_src-b6d1724783fa378a745be25973c1b908d8679620.tar.gz chromium_src-b6d1724783fa378a745be25973c1b908d8679620.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
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=272740
R=ben@chromium.org
Review URL: https://codereview.chromium.org/298703007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/accelerators')
-rw-r--r-- | ash/accelerators/accelerator_dispatcher.h | 58 | ||||
-rw-r--r-- | ash/accelerators/accelerator_dispatcher_linux.cc | 94 | ||||
-rw-r--r-- | ash/accelerators/accelerator_dispatcher_win.cc | 64 | ||||
-rw-r--r-- | ash/accelerators/nested_accelerator_delegate.cc (renamed from ash/accelerators/accelerator_dispatcher.cc) | 19 | ||||
-rw-r--r-- | ash/accelerators/nested_accelerator_delegate.h | 28 | ||||
-rw-r--r-- | ash/accelerators/nested_dispatcher_controller.cc | 44 | ||||
-rw-r--r-- | ash/accelerators/nested_dispatcher_controller.h | 41 | ||||
-rw-r--r-- | ash/accelerators/nested_dispatcher_controller_unittest.cc | 151 |
8 files changed, 40 insertions, 459 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_linux.cc b/ash/accelerators/accelerator_dispatcher_linux.cc deleted file mode 100644 index b5494dd..0000000 --- a/ash/accelerators/accelerator_dispatcher_linux.cc +++ /dev/null @@ -1,94 +0,0 @@ -// 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 "base/memory/scoped_ptr.h" -#include "base/run_loop.h" -#include "ui/events/event.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" - -#if defined(USE_X11) -#include <X11/Xlib.h> -#endif - -namespace ash { - -namespace { - -#if defined(USE_OZONE) -bool IsKeyEvent(const base::NativeEvent& native_event) { - const ui::KeyEvent* event = static_cast<const ui::KeyEvent*>(native_event); - return event->IsKeyEvent(); -} -#elif defined(USE_X11) -bool IsKeyEvent(const XEvent* xev) { - return xev->type == KeyPress || xev->type == KeyRelease; -} -#else -#error Unknown build platform: you should have either use_ozone or use_x11. -#endif - -scoped_ptr<ui::ScopedEventDispatcher> OverrideDispatcher( - ui::PlatformEventDispatcher* dispatcher) { - ui::PlatformEventSource* source = ui::PlatformEventSource::GetInstance(); - return source ? source->OverrideDispatcher(dispatcher) - : scoped_ptr<ui::ScopedEventDispatcher>(); -} - -} // namespace - -class AcceleratorDispatcherLinux : public AcceleratorDispatcher, - public ui::PlatformEventDispatcher { - public: - AcceleratorDispatcherLinux() - : restore_dispatcher_(OverrideDispatcher(this)) {} - - virtual ~AcceleratorDispatcherLinux() {} - - private: - // AcceleratorDispatcher: - virtual scoped_ptr<base::RunLoop> CreateRunLoop() OVERRIDE { - return scoped_ptr<base::RunLoop>(new base::RunLoop()); - } - - // ui::PlatformEventDispatcher: - virtual bool CanDispatchEvent(const ui::PlatformEvent& event) OVERRIDE { - return true; - } - - virtual uint32_t DispatchEvent(const ui::PlatformEvent& event) OVERRIDE { - if (IsKeyEvent(event)) { - ui::KeyEvent key_event(event, false); - if (MenuClosedForPossibleAccelerator(key_event)) { -#if defined(USE_X11) - XPutBackEvent(event->xany.display, event); -#else - NOTIMPLEMENTED(); -#endif - return ui::POST_DISPATCH_NONE; - } - - if (AcceleratorProcessedForKeyEvent(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); -}; - -scoped_ptr<AcceleratorDispatcher> AcceleratorDispatcher::Create( - base::MessagePumpDispatcher* nested_dispatcher) { - return scoped_ptr<AcceleratorDispatcher>(new AcceleratorDispatcherLinux()); -} - -} // namespace ash diff --git a/ash/accelerators/accelerator_dispatcher_win.cc b/ash/accelerators/accelerator_dispatcher_win.cc deleted file mode 100644 index 35005f3..0000000 --- a/ash/accelerators/accelerator_dispatcher_win.cc +++ /dev/null @@ -1,64 +0,0 @@ -// 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 "base/memory/scoped_ptr.h" -#include "base/message_loop/message_pump_dispatcher.h" -#include "base/run_loop.h" -#include "ui/events/event.h" - -using base::MessagePumpDispatcher; - -namespace ash { - -namespace { - -bool IsKeyEvent(const MSG& msg) { - return msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN || - msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP; -} - -} // namespace - -class AcceleratorDispatcherWin : public AcceleratorDispatcher, - public MessagePumpDispatcher { - public: - explicit AcceleratorDispatcherWin(MessagePumpDispatcher* nested) - : nested_dispatcher_(nested) {} - virtual ~AcceleratorDispatcherWin() {} - - private: - // AcceleratorDispatcher: - virtual scoped_ptr<base::RunLoop> CreateRunLoop() OVERRIDE { - return scoped_ptr<base::RunLoop>(new base::RunLoop(this)); - } - - // MessagePumpDispatcher: - virtual uint32_t Dispatch(const MSG& event) OVERRIDE { - if (IsKeyEvent(event)) { - ui::KeyEvent key_event(event, false); - if (MenuClosedForPossibleAccelerator(key_event)) - return POST_DISPATCH_QUIT_LOOP; - - if (AcceleratorProcessedForKeyEvent(key_event)) - return POST_DISPATCH_NONE; - } - - return nested_dispatcher_ ? nested_dispatcher_->Dispatch(event) - : POST_DISPATCH_PERFORM_DEFAULT; - } - - MessagePumpDispatcher* nested_dispatcher_; - - DISALLOW_COPY_AND_ASSIGN(AcceleratorDispatcherWin); -}; - -scoped_ptr<AcceleratorDispatcher> AcceleratorDispatcher::Create( - MessagePumpDispatcher* nested_dispatcher) { - return scoped_ptr<AcceleratorDispatcher>( - new AcceleratorDispatcherWin(nested_dispatcher)); -} - -} // namespace ash diff --git a/ash/accelerators/accelerator_dispatcher.cc b/ash/accelerators/nested_accelerator_delegate.cc index fe194f3..9e5682b 100644 --- a/ash/accelerators/accelerator_dispatcher.cc +++ b/ash/accelerators/nested_accelerator_delegate.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 "ash/accelerators/nested_accelerator_delegate.h" #include "ash/accelerators/accelerator_controller.h" #include "ash/shell.h" @@ -35,21 +35,26 @@ bool IsPossibleAcceleratorNotForMenu(const ui::KeyEvent& key_event) { } // namespace -bool AcceleratorDispatcher::MenuClosedForPossibleAccelerator( +NestedAcceleratorDelegate::NestedAcceleratorDelegate() { +} + +NestedAcceleratorDelegate::~NestedAcceleratorDelegate() { +} + +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.cc b/ash/accelerators/nested_dispatcher_controller.cc deleted file mode 100644 index d963db0..0000000 --- a/ash/accelerators/nested_dispatcher_controller.cc +++ /dev/null @@ -1,44 +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/nested_dispatcher_controller.h" - -#include "ash/accelerators/accelerator_dispatcher.h" -#include "ash/shell.h" -#include "base/auto_reset.h" -#include "base/run_loop.h" - -namespace ash { - -NestedDispatcherController::NestedDispatcherController() { -} - -NestedDispatcherController::~NestedDispatcherController() { -} - -void NestedDispatcherController::RunWithDispatcher( - base::MessagePumpDispatcher* nested_dispatcher) { - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop); - - scoped_ptr<AcceleratorDispatcher> old_accelerator_dispatcher = - accelerator_dispatcher_.Pass(); - accelerator_dispatcher_ = AcceleratorDispatcher::Create(nested_dispatcher); - - // TODO(jbates) crbug.com/134753 Find quitters of this RunLoop and have them - // use run_loop.QuitClosure(). - scoped_ptr<base::RunLoop> run_loop = accelerator_dispatcher_->CreateRunLoop(); - base::AutoReset<base::Closure> reset_closure(&quit_closure_, - run_loop->QuitClosure()); - run_loop->Run(); - accelerator_dispatcher_ = old_accelerator_dispatcher.Pass(); -} - -void NestedDispatcherController::QuitNestedMessageLoop() { - CHECK(!quit_closure_.is_null()); - quit_closure_.Run(); - accelerator_dispatcher_.reset(); -} - -} // namespace ash diff --git a/ash/accelerators/nested_dispatcher_controller.h b/ash/accelerators/nested_dispatcher_controller.h deleted file mode 100644 index ebac2d2..0000000 --- a/ash/accelerators/nested_dispatcher_controller.h +++ /dev/null @@ -1,41 +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_NESTED_DISPATCHER_CONTROLLER_H_ -#define ASH_ACCELERATORS_NESTED_DISPATCHER_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" - -namespace ash { - -class AcceleratorDispatcher; - -// 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 - : public aura::client::DispatcherClient { - public: - NestedDispatcherController(); - virtual ~NestedDispatcherController(); - - // aura::client::DispatcherClient: - virtual void RunWithDispatcher( - base::MessagePumpDispatcher* dispatcher) OVERRIDE; - virtual void QuitNestedMessageLoop() OVERRIDE; - - private: - base::Closure quit_closure_; - scoped_ptr<AcceleratorDispatcher> accelerator_dispatcher_; - - DISALLOW_COPY_AND_ASSIGN(NestedDispatcherController); -}; - -} // namespace ash - -#endif // ASH_ACCELERATORS_NESTED_DISPATCHER_CONTROLLER_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 |