diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 17:00:18 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-25 17:00:18 +0000 |
commit | fbfe5e5483677eaffd57d4d98a427841f9fece73 (patch) | |
tree | 331d0d373df812e0595bfc6e6c31f564607e19c5 /ash/wm | |
parent | 3a94b248df450e40596b57b27a06ffb4a9dc42df (diff) | |
download | chromium_src-fbfe5e5483677eaffd57d4d98a427841f9fece73.zip chromium_src-fbfe5e5483677eaffd57d4d98a427841f9fece73.tar.gz chromium_src-fbfe5e5483677eaffd57d4d98a427841f9fece73.tar.bz2 |
Revert "Block internal PlatformEvents before they are dispatched in touchview."
This reverts r279732.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279734 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm')
11 files changed, 532 insertions, 213 deletions
diff --git a/ash/wm/maximize_mode/internal_input_device_list.h b/ash/wm/maximize_mode/internal_input_device_list.h new file mode 100644 index 0000000..ab8c86b --- /dev/null +++ b/ash/wm/maximize_mode/internal_input_device_list.h @@ -0,0 +1,32 @@ +// 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_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_H_ +#define ASH_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_H_ + +#include "ash/ash_export.h" +#include "base/macros.h" + +namespace ui { +class Event; +} + +namespace ash { + +// Identifies which input devices are internal and provides a helper function to +// test if an input event came from an internal device. +class ASH_EXPORT InternalInputDeviceList { + public: + InternalInputDeviceList() {} + virtual ~InternalInputDeviceList() {} + + virtual bool IsEventFromInternalDevice(const ui::Event* event) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(InternalInputDeviceList); +}; + +} // namespace ash + +#endif // ASH_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_H_ diff --git a/ash/wm/maximize_mode/internal_input_device_list_x11.cc b/ash/wm/maximize_mode/internal_input_device_list_x11.cc new file mode 100644 index 0000000..93727ec --- /dev/null +++ b/ash/wm/maximize_mode/internal_input_device_list_x11.cc @@ -0,0 +1,58 @@ +// 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/wm/maximize_mode/internal_input_device_list_x11.h" + +#include <X11/extensions/XInput2.h> +#include <X11/Xlib.h> + +#include "base/strings/string_util.h" +#include "ui/events/event.h" +#include "ui/events/x/device_data_manager_x11.h" +#include "ui/events/x/device_list_cache_x.h" +#include "ui/gfx/x/x11_types.h" + +namespace ash { + +namespace { + +// The name of the xinput device corresponding to the internal touchpad. +const char kInternalTouchpadName[] = "Elan Touchpad"; + +// The name of the xinput device corresponding to the internal keyboard. +const char kInternalKeyboardName[] = "AT Translated Set 2 keyboard"; + +} // namespace + +InternalInputDeviceListX11::InternalInputDeviceListX11() { + if (ui::DeviceDataManagerX11::GetInstance()->IsXInput2Available()) { + XIDeviceList xi_dev_list = ui::DeviceListCacheX::GetInstance()-> + GetXI2DeviceList(gfx::GetXDisplay()); + for (int i = 0; i < xi_dev_list.count; ++i) { + std::string device_name(xi_dev_list[i].name); + base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name); + if (device_name == kInternalTouchpadName || + device_name == kInternalKeyboardName) + internal_device_ids_.insert(xi_dev_list[i].deviceid); + } + } +} + +InternalInputDeviceListX11::~InternalInputDeviceListX11() { +} + +bool InternalInputDeviceListX11::IsEventFromInternalDevice( + const ui::Event* event) { + if (!event->HasNativeEvent() || + event->native_event()->type != GenericEvent) { + return false; + } + + XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>( + event->native_event()->xcookie.data); + return internal_device_ids_.find(xiev->sourceid) != + internal_device_ids_.end(); +} + +} // namespace ash diff --git a/ash/wm/maximize_mode/internal_input_device_list_x11.h b/ash/wm/maximize_mode/internal_input_device_list_x11.h new file mode 100644 index 0000000..3ef0de8 --- /dev/null +++ b/ash/wm/maximize_mode/internal_input_device_list_x11.h @@ -0,0 +1,38 @@ +// 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_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_X11_H_ +#define ASH_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_X11_H_ + +#include <set> + +#include "ash/wm/maximize_mode/internal_input_device_list.h" +#include "base/macros.h" + +namespace ui { +class Event; +} + +namespace ash { + +// Identifies which input devices are internal and provides a helper function to +// test if an input event came from an internal device. +class InternalInputDeviceListX11 : public InternalInputDeviceList { + public: + InternalInputDeviceListX11(); + virtual ~InternalInputDeviceListX11(); + + // InternalInputDeviceList: + virtual bool IsEventFromInternalDevice(const ui::Event* event) OVERRIDE; + + private: + // Tracks the device ids of internal input devices. + std::set<int> internal_device_ids_; + + DISALLOW_COPY_AND_ASSIGN(InternalInputDeviceListX11); +}; + +} // namespace ash + +#endif // ASH_WM_MAXIMIZE_MODE_INTERNAL_INPUT_DEVICE_LIST_X11_H_ diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc index 36f6f25..a32812a 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller.cc @@ -10,8 +10,8 @@ #include "ash/ash_switches.h" #include "ash/display/display_manager.h" #include "ash/shell.h" +#include "ash/wm/maximize_mode/maximize_mode_event_blocker.h" #include "ash/wm/maximize_mode/maximize_mode_window_manager.h" -#include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h" #include "base/auto_reset.h" #include "base/command_line.h" #include "base/metrics/histogram.h" @@ -21,10 +21,6 @@ #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/vector3d_f.h" -#if defined(USE_X11) -#include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h" -#endif - namespace ash { namespace { @@ -354,9 +350,7 @@ void MaximizeModeController::EnterMaximizeMode() { current_rotation_ = user_rotation_ = display_manager-> GetDisplayInfo(gfx::Display::InternalDisplayId()).rotation(); EnableMaximizeModeWindowManager(true); -#if defined(USE_X11) - event_blocker_.reset(new ScopedDisableInternalMouseAndKeyboardX11); -#endif + event_blocker_.reset(new MaximizeModeEventBlocker); #if defined(OS_CHROMEOS) event_handler_.reset(new ScreenshotActionHandler); #endif diff --git a/ash/wm/maximize_mode/maximize_mode_controller.h b/ash/wm/maximize_mode/maximize_mode_controller.h index 54db3f3..8445bfa 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller.h +++ b/ash/wm/maximize_mode/maximize_mode_controller.h @@ -23,7 +23,7 @@ class EventHandler; namespace ash { class MaximizeModeControllerTest; -class ScopedDisableInternalMouseAndKeyboard; +class MaximizeModeEventBlocker; class MaximizeModeWindowManager; class MaximizeModeWindowManagerTest; @@ -136,9 +136,9 @@ class ASH_EXPORT MaximizeModeController : public AccelerometerObserver, // The maximized window manager (if enabled). scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_; - // A helper class which when instantiated will block native events from the - // internal keyboard and touchpad. - scoped_ptr<ScopedDisableInternalMouseAndKeyboard> event_blocker_; + // An event targeter controller which traps mouse and keyboard events while + // maximize mode is engaged. + scoped_ptr<MaximizeModeEventBlocker> event_blocker_; // An event handler used to detect screenshot actions while in maximize mode. scoped_ptr<ui::EventHandler> event_handler_; diff --git a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc index 089a232..8afb9e3 100644 --- a/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc +++ b/ash/wm/maximize_mode/maximize_mode_controller_unittest.cc @@ -14,6 +14,8 @@ #include "ash/test/test_screenshot_delegate.h" #include "ash/test/test_system_tray_delegate.h" #include "ash/test/test_volume_control_delegate.h" +#include "ash/wm/maximize_mode/internal_input_device_list.h" +#include "ash/wm/maximize_mode/maximize_mode_event_blocker.h" #include "ui/aura/test/event_generator.h" #include "ui/events/event_handler.h" #include "ui/gfx/vector3d_f.h" @@ -29,6 +31,54 @@ namespace { const float kDegreesToRadians = 3.14159265f / 180.0f; +// Filter to count the number of events seen. +class EventCounter : public ui::EventHandler { + public: + EventCounter(); + virtual ~EventCounter(); + + // Overridden from ui::EventHandler: + virtual void OnEvent(ui::Event* event) OVERRIDE; + + void reset() { + event_count_ = 0; + } + + size_t event_count() const { return event_count_; } + + private: + size_t event_count_; + + DISALLOW_COPY_AND_ASSIGN(EventCounter); +}; + +EventCounter::EventCounter() : event_count_(0) { + Shell::GetInstance()->AddPreTargetHandler(this); +} + +EventCounter::~EventCounter() { + Shell::GetInstance()->RemovePreTargetHandler(this); +} + +void EventCounter::OnEvent(ui::Event* event) { + event_count_++; +} + +// A test internal input device list which pretends that all events are from +// internal devices to allow verifying that the event blocking works. +class TestInternalInputDeviceList : public InternalInputDeviceList { + public: + TestInternalInputDeviceList() {} + virtual ~TestInternalInputDeviceList() {} + + virtual bool IsEventFromInternalDevice(const ui::Event* event) OVERRIDE { + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestInternalInputDeviceList); +}; + } // namespace // Test accelerometer data taken with the lid at less than 180 degrees while @@ -80,6 +130,13 @@ class MaximizeModeControllerTest : public test::AshTestBase { return maximize_mode_controller()->IsMaximizeModeWindowManagerEnabled(); } + // Overrides the internal input device list for the current event targeters + // with one which always returns true. + void InstallTestInternalDeviceList() { + maximize_mode_controller()->event_blocker_->internal_devices_.reset( + new TestInternalInputDeviceList); + } + gfx::Display::Rotation GetInternalDisplayRotation() const { return Shell::GetInstance()->display_manager()->GetDisplayInfo( gfx::Display::InternalDisplayId()).rotation(); @@ -263,6 +320,78 @@ TEST_F(MaximizeModeControllerTest, RotationOnlyInMaximizeMode) { EXPECT_EQ(gfx::Display::ROTATE_0, GetInternalDisplayRotation()); } +// Tests that maximize mode blocks keyboard and mouse events but not touch +// events. +TEST_F(MaximizeModeControllerTest, BlocksKeyboardAndMouse) { + aura::Window* root = Shell::GetPrimaryRootWindow(); + aura::test::EventGenerator event_generator(root, root); + EventCounter counter; + + event_generator.PressKey(ui::VKEY_ESCAPE, 0); + event_generator.ReleaseKey(ui::VKEY_ESCAPE, 0); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + event_generator.ClickLeftButton(); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + event_generator.ScrollSequence( + gfx::Point(), base::TimeDelta::FromMilliseconds(5), 0, 100, 5, 2); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + event_generator.MoveMouseWheel(0, 10); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + event_generator.PressTouch(); + event_generator.ReleaseTouch(); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + // Open up 270 degrees. + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f), + gfx::Vector3dF(1.0f, 0.0f, 0.0f)); + ASSERT_TRUE(IsMaximizeModeStarted()); + InstallTestInternalDeviceList(); + + event_generator.PressKey(ui::VKEY_ESCAPE, 0); + event_generator.ReleaseKey(ui::VKEY_ESCAPE, 0); + EXPECT_EQ(0u, counter.event_count()); + counter.reset(); + + event_generator.ClickLeftButton(); + EXPECT_EQ(0u, counter.event_count()); + counter.reset(); + + event_generator.ScrollSequence( + gfx::Point(), base::TimeDelta::FromMilliseconds(5), 0, 100, 5, 2); + EXPECT_EQ(0u, counter.event_count()); + counter.reset(); + + event_generator.MoveMouseWheel(0, 10); + EXPECT_EQ(0u, counter.event_count()); + counter.reset(); + + // Touch should not be blocked. + event_generator.PressTouch(); + event_generator.ReleaseTouch(); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); + + gfx::Vector3dF base; + + // Lid open 90 degrees. + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, 1.0f), + gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); + + event_generator.PressKey(ui::VKEY_ESCAPE, 0); + event_generator.ReleaseKey(ui::VKEY_ESCAPE, 0); + EXPECT_GT(counter.event_count(), 0u); + counter.reset(); +} + #if defined(OS_CHROMEOS) // Tests that a screenshot can be taken in maximize mode by holding volume down // and pressing power. @@ -293,6 +422,57 @@ TEST_F(MaximizeModeControllerTest, Screenshot) { } #endif // OS_CHROMEOS +#if defined(USE_X11) +// Tests that maximize mode allows volume up/down events originating +// from dedicated buttons versus remapped keyboard buttons. +TEST_F(MaximizeModeControllerTest, AllowsVolumeControl) { + aura::Window* root = Shell::GetPrimaryRootWindow(); + aura::test::EventGenerator event_generator(root, root); + + TestVolumeControlDelegate* volume_delegate = + new TestVolumeControlDelegate(true); + ash::Shell::GetInstance()->system_tray_delegate()->SetVolumeControlDelegate( + scoped_ptr<VolumeControlDelegate>(volume_delegate).Pass()); + + // Trigger maximize mode by opening to 270 to begin the test in maximize mode. + TriggerAccelerometerUpdate(gfx::Vector3dF(0.0f, 0.0f, -1.0f), + gfx::Vector3dF(-1.0f, 0.0f, 0.0f)); + ASSERT_TRUE(IsMaximizeModeStarted()); + + ui::ScopedXI2Event xevent; + + // Verify F9 button event is blocked + ASSERT_EQ(0, volume_delegate->handle_volume_down_count()); + xevent.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_DOWN, ui::EF_NONE); + ui::KeyEvent press_f9(xevent, false /* is_char */); + press_f9.set_flags(ui::EF_FUNCTION_KEY); + event_generator.Dispatch(&press_f9); + EXPECT_EQ(0, volume_delegate->handle_volume_down_count()); + + // Verify F10 button event is blocked + ASSERT_EQ(0, volume_delegate->handle_volume_up_count()); + xevent.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_UP, ui::EF_NONE); + ui::KeyEvent press_f10(xevent, false /* is_char */); + press_f10.set_flags(ui::EF_FUNCTION_KEY); + event_generator.Dispatch(&press_f10); + EXPECT_EQ(0, volume_delegate->handle_volume_up_count()); + + // Verify volume down button event is not blocked + ASSERT_EQ(0, volume_delegate->handle_volume_down_count()); + xevent.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_DOWN, ui::EF_NONE); + ui::KeyEvent press_vol_down(xevent, false /* is_char */); + event_generator.Dispatch(&press_vol_down); + EXPECT_EQ(1, volume_delegate->handle_volume_down_count()); + + // Verify volume up event is not blocked + ASSERT_EQ(0, volume_delegate->handle_volume_up_count()); + xevent.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_VOLUME_UP, ui::EF_NONE); + ui::KeyEvent press_vol_up(xevent, false /* is_char */); + event_generator.Dispatch(&press_vol_up); + EXPECT_EQ(1, volume_delegate->handle_volume_up_count()); +} +#endif // defined(USE_X11) + TEST_F(MaximizeModeControllerTest, LaptopTest) { // Feeds in sample accelerometer data and verifies that there are no // transitions into touchview / maximize mode while shaking the device around diff --git a/ash/wm/maximize_mode/maximize_mode_event_blocker.cc b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc new file mode 100644 index 0000000..24b1d7d --- /dev/null +++ b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc @@ -0,0 +1,165 @@ +// 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/wm/maximize_mode/maximize_mode_event_blocker.h" + +#include "ash/shell.h" +#include "ash/wm/maximize_mode/internal_input_device_list.h" +#include "base/memory/scoped_ptr.h" +#include "ui/aura/client/cursor_client.h" +#include "ui/aura/window_event_dispatcher.h" +#include "ui/aura/window_tree_host.h" +#include "ui/events/event_targeter.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/point.h" + +#if defined(USE_X11) +#include "ash/wm/maximize_mode/internal_input_device_list_x11.h" +#endif + +namespace ash { + +namespace { + +// Event targeter to prevent delivery of mouse and touchpad events while +// maximize mode is active. Other events such as touch are passed on to the +// default targeter. +class BlockKeyboardAndTouchpadTargeter : public ui::EventTargeter { + public: + BlockKeyboardAndTouchpadTargeter( + aura::Window* root_window, + MaximizeModeEventBlocker* event_blocker); + virtual ~BlockKeyboardAndTouchpadTargeter(); + + // Sets the default targeter to use when the event is not being blocked. + void SetDefaultTargeter(EventTargeter* default_targeter); + + // Overridden from ui::EventTargeter: + virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, + ui::Event* event) OVERRIDE; + + private: + // A weak pointer to the root window on which this targeter will be set. The + // root window owns this targeter. + aura::Window* root_window_; + + // A weak pointer to the event blocker which owns the scoped targeter owning + // this targeter. + MaximizeModeEventBlocker* event_blocker_; + + // A weak pointer to the targeter this targeter is wrapping. The + // default_targeter is owned by the ScopedWindowTargeter which will be valid + // as long as this targeter is alive. + ui::EventTargeter* default_targeter_; + + // The last known mouse location to lock the cursor in place to when events + // come from the internal touchpad. + gfx::Point last_mouse_location_; + + DISALLOW_COPY_AND_ASSIGN(BlockKeyboardAndTouchpadTargeter); +}; + +BlockKeyboardAndTouchpadTargeter::BlockKeyboardAndTouchpadTargeter( + aura::Window* root_window, + MaximizeModeEventBlocker* event_blocker) + : root_window_(root_window), + event_blocker_(event_blocker), + default_targeter_(NULL), + last_mouse_location_(root_window->GetHost()->dispatcher()-> + GetLastMouseLocationInRoot()) { +} + +BlockKeyboardAndTouchpadTargeter::~BlockKeyboardAndTouchpadTargeter() { +} + +void BlockKeyboardAndTouchpadTargeter::SetDefaultTargeter( + ui::EventTargeter* default_targeter) { + default_targeter_ = default_targeter; +} + +ui::EventTarget* BlockKeyboardAndTouchpadTargeter::FindTargetForEvent( + ui::EventTarget* root, + ui::Event* event) { + bool internal_device = event_blocker_->internal_devices() && + event_blocker_->internal_devices()->IsEventFromInternalDevice(event); + if (event->IsMouseEvent()) { + if (internal_device) { + // The cursor movement is handled at a lower level which is not blocked. + // Move the mouse cursor back to its last known location resulting from + // an external mouse to prevent the internal touchpad from moving it. + root_window_->GetHost()->MoveCursorToHostLocation( + last_mouse_location_); + return NULL; + } else { + // Track the last location seen from an external mouse event. + last_mouse_location_ = + static_cast<ui::MouseEvent*>(event)->root_location(); + root_window_->GetHost()->ConvertPointToHost(&last_mouse_location_); + } + } else if (internal_device && (event->IsMouseWheelEvent() || + event->IsScrollEvent())) { + return NULL; + } else if (event->IsKeyEvent() && event->HasNativeEvent()) { + // TODO(flackr): Disable events only from the internal keyboard device + // when we begin using XI2 events for keyboard events + // (http://crbug.com/368750) and can tell which device the event is + // coming from, http://crbug.com/362881. + ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(event); + if ((key_event->flags() & ui::EF_FUNCTION_KEY) || + (key_event->key_code() != ui::VKEY_VOLUME_DOWN && + key_event->key_code() != ui::VKEY_VOLUME_UP +#if defined(OS_CHROMEOS) + && key_event->key_code() != ui::VKEY_POWER +#endif + ) + ) { + return NULL; + } + } + return default_targeter_->FindTargetForEvent(root, event); +} + +} // namespace + +MaximizeModeEventBlocker::MaximizeModeEventBlocker() +#if defined(USE_X11) + : internal_devices_(new InternalInputDeviceListX11) +#endif + { + Shell::GetInstance()->AddShellObserver(this); + + // Hide the cursor as mouse events will be blocked. + aura::client::CursorClient* cursor_client_ = + aura::client::GetCursorClient(Shell::GetTargetRootWindow()); + if (cursor_client_) + cursor_client_->HideCursor(); + + // Block keyboard and mouse events on all existing and new root windows for + // the lifetime of this class. + aura::Window::Windows root_windows(Shell::GetAllRootWindows()); + for (aura::Window::Windows::iterator iter = root_windows.begin(); + iter != root_windows.end(); ++iter) { + AddEventTargeterOn(*iter); + } +} + +MaximizeModeEventBlocker::~MaximizeModeEventBlocker() { + Shell::GetInstance()->RemoveShellObserver(this); +} + +void MaximizeModeEventBlocker::OnRootWindowAdded(aura::Window* root_window) { + AddEventTargeterOn(root_window); +} + +void MaximizeModeEventBlocker::AddEventTargeterOn( + aura::Window* root_window) { + BlockKeyboardAndTouchpadTargeter* targeter = + new BlockKeyboardAndTouchpadTargeter(root_window, this); + aura::ScopedWindowTargeter* scoped_targeter = new aura::ScopedWindowTargeter( + root_window, scoped_ptr<ui::EventTargeter>(targeter)); + targeter->SetDefaultTargeter(scoped_targeter->old_targeter()); + targeters_.push_back(scoped_targeter); +} + +} // namespace ash diff --git a/ash/wm/maximize_mode/maximize_mode_event_blocker.h b/ash/wm/maximize_mode/maximize_mode_event_blocker.h new file mode 100644 index 0000000..4f7fae7 --- /dev/null +++ b/ash/wm/maximize_mode/maximize_mode_event_blocker.h @@ -0,0 +1,53 @@ +// 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_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_EVENT_BLOCKER_H_ +#define ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_EVENT_BLOCKER_H_ + +#include <set> + +#include "ash/shell_observer.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "ui/aura/scoped_window_targeter.h" + +namespace aura { +class Window; +} // namespace aura + +namespace ash { + +class InternalInputDeviceList; +class MaximizeModeControllerTest; + +// A class which blocks mouse and keyboard events while instantiated by +// replacing the root window event targeter. +class MaximizeModeEventBlocker : public ShellObserver { + public: + MaximizeModeEventBlocker(); + virtual ~MaximizeModeEventBlocker(); + + InternalInputDeviceList* internal_devices() { + return internal_devices_.get(); + } + + // ShellObserver: + virtual void OnRootWindowAdded(aura::Window* root_window) OVERRIDE; + + private: + friend class MaximizeModeControllerTest; + + // Adds an event targeter on |root_window| to block mouse and keyboard events. + void AddEventTargeterOn(aura::Window* root_window); + + ScopedVector<aura::ScopedWindowTargeter> targeters_; + scoped_ptr<InternalInputDeviceList> internal_devices_; + + DISALLOW_COPY_AND_ASSIGN(MaximizeModeEventBlocker); +}; + +} // namespace ash + +#endif // ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_EVENT_BLOCKER_H_ diff --git a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h b/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h deleted file mode 100644 index 6a1cbde..0000000 --- a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h +++ /dev/null @@ -1,17 +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. - -#ifndef ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_H_ -#define ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_H_ - -namespace ash { - -class ScopedDisableInternalMouseAndKeyboard { - public: - virtual ~ScopedDisableInternalMouseAndKeyboard() {} -}; - -} // namespace ash - -#endif // ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_H_ diff --git a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc b/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc deleted file mode 100644 index 0997333..0000000 --- a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.cc +++ /dev/null @@ -1,141 +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/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h" - -#include <set> -#include <X11/extensions/XInput2.h> -#include <X11/Xlib.h> - -#include "ash/display/display_controller.h" -#include "ash/screen_util.h" -#include "ash/shell.h" -#include "base/memory/scoped_ptr.h" -#include "base/strings/string_util.h" -#include "ui/aura/client/screen_position_client.h" -#include "ui/aura/env.h" -#include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/aura/window_tree_host.h" -#include "ui/events/event.h" -#include "ui/events/event_utils.h" -#include "ui/events/keycodes/keyboard_codes_posix.h" -#include "ui/events/platform/platform_event_source.h" -#include "ui/events/x/device_data_manager_x11.h" -#include "ui/events/x/device_list_cache_x.h" -#include "ui/gfx/x/x11_types.h" - -namespace ash { - -namespace { - -// The name of the xinput device corresponding to the internal touchpad. -const char kInternalTouchpadName[] = "Elan Touchpad"; - -// The name of the xinput device corresponding to the internal keyboard. -const char kInternalKeyboardName[] = "AT Translated Set 2 keyboard"; - -// Device id used to indicate that a device has not been detected. -const int kDeviceIdNone = -1; - -gfx::Point GetMouseLocationInScreen() { - return aura::Env::GetInstance()->last_mouse_location(); -} - -void SetMouseLocationInScreen(const gfx::Point& screen_location) { - gfx::Display display = ash::ScreenUtil::FindDisplayContainingPoint( - screen_location); - if (!display.is_valid()) - return; - aura::Window* root_window = Shell::GetInstance()->display_controller()-> - GetRootWindowForDisplayId(display.id()); - gfx::Point host_location(screen_location); - aura::client::ScreenPositionClient* client = - aura::client::GetScreenPositionClient(root_window); - if (client) - client->ConvertPointFromScreen(root_window, &host_location); - root_window->GetHost()->MoveCursorTo(host_location); -} - -} // namespace - -ScopedDisableInternalMouseAndKeyboardX11:: - ScopedDisableInternalMouseAndKeyboardX11() - : touchpad_device_id_(kDeviceIdNone), - keyboard_device_id_(kDeviceIdNone), - last_mouse_location_(GetMouseLocationInScreen()) { - - ui::DeviceDataManagerX11* device_data_manager = - static_cast<ui::DeviceDataManagerX11*>( - ui::DeviceDataManager::GetInstance()); - if (device_data_manager->IsXInput2Available()) { - XIDeviceList xi_dev_list = ui::DeviceListCacheX::GetInstance()-> - GetXI2DeviceList(gfx::GetXDisplay()); - for (int i = 0; i < xi_dev_list.count; ++i) { - std::string device_name(xi_dev_list[i].name); - base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name); - if (device_name == kInternalTouchpadName) { - touchpad_device_id_ = xi_dev_list[i].deviceid; - device_data_manager->DisableDevice(touchpad_device_id_); - } else if (device_name == kInternalKeyboardName) { - keyboard_device_id_ = xi_dev_list[i].deviceid; - device_data_manager->DisableDevice(keyboard_device_id_); - } - } - } - // Allow the accessible keys present on the side of some devices to continue - // working. - scoped_ptr<std::set<ui::KeyboardCode> > excepted_keys( - new std::set<ui::KeyboardCode>); - excepted_keys->insert(ui::VKEY_VOLUME_DOWN); - excepted_keys->insert(ui::VKEY_VOLUME_UP); - excepted_keys->insert(ui::VKEY_POWER); - device_data_manager->DisableKeyboard(excepted_keys.Pass()); - ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); -} - -ScopedDisableInternalMouseAndKeyboardX11:: - ~ScopedDisableInternalMouseAndKeyboardX11() { - ui::DeviceDataManagerX11* device_data_manager = - static_cast<ui::DeviceDataManagerX11*>( - ui::DeviceDataManager::GetInstance()); - if (touchpad_device_id_ != kDeviceIdNone) - device_data_manager->EnableDevice(touchpad_device_id_); - if (keyboard_device_id_ != kDeviceIdNone) - device_data_manager->EnableDevice(keyboard_device_id_); - device_data_manager->EnableKeyboard(); - ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); -} - -void ScopedDisableInternalMouseAndKeyboardX11::WillProcessEvent( - const ui::PlatformEvent& event) { -} - -void ScopedDisableInternalMouseAndKeyboardX11::DidProcessEvent( - const ui::PlatformEvent& event) { - if (event->type != GenericEvent) - return; - XIDeviceEvent* xievent = - static_cast<XIDeviceEvent*>(event->xcookie.data); - ui::DeviceDataManagerX11* device_data_manager = - static_cast<ui::DeviceDataManagerX11*>( - ui::DeviceDataManager::GetInstance()); - if (xievent->evtype != XI_Motion || - device_data_manager->IsFlingEvent(event) || - device_data_manager->IsScrollEvent(event) || - device_data_manager->IsCMTMetricsEvent(event)) { - return; - } - if (xievent->sourceid == touchpad_device_id_) { - // The cursor will have already moved even though the move event will be - // blocked. Move the mouse cursor back to its last known location resulting - // from an external mouse to prevent the internal touchpad from moving it. - SetMouseLocationInScreen(last_mouse_location_); - } else { - // Track the last location seen from an external mouse event. - last_mouse_location_ = GetMouseLocationInScreen(); - } -} - -} // namespace ash diff --git a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h b/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h deleted file mode 100644 index 2a1416b..0000000 --- a/ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard_x11.h +++ /dev/null @@ -1,43 +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. - -#ifndef ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_X11_H_ -#define ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_X11_H_ - -#include <vector> - -#include "ash/ash_export.h" -#include "ash/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard.h" -#include "base/macros.h" -#include "ui/events/platform/platform_event_observer.h" -#include "ui/gfx/point.h" - -namespace ash { - -// Identifies which input devices are internal and provides a helper function to -// test if an input event came from an internal device. -class ScopedDisableInternalMouseAndKeyboardX11 - : public ScopedDisableInternalMouseAndKeyboard, - public ui::PlatformEventObserver { - public: - ScopedDisableInternalMouseAndKeyboardX11(); - virtual ~ScopedDisableInternalMouseAndKeyboardX11(); - - // ui::PlatformEventObserver: - virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE; - virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE; - private: - int touchpad_device_id_; - int keyboard_device_id_; - - // Tracks the last known mouse cursor location caused before blocking the - // internal touchpad or caused by an external mouse. - gfx::Point last_mouse_location_; - - DISALLOW_COPY_AND_ASSIGN(ScopedDisableInternalMouseAndKeyboardX11); -}; - -} // namespace ash - -#endif // ASH_WM_MAXIMIZE_MODE_SCOPED_DISABLE_INTERNAL_MOUSE_AND_KEYBOARD_X11_H_ |