Index: ash/wm/maximize_mode/maximize_mode_event_blocker.cc |
diff --git a/ash/wm/maximize_mode/maximize_mode_event_blocker.cc b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc |
index fd2362f7f9327ab215ff55e53f5146bc03856916..572886c1e0f8db6e10a02d9b8ddbc934e1518c08 100644 |
--- a/ash/wm/maximize_mode/maximize_mode_event_blocker.cc |
+++ b/ash/wm/maximize_mode/maximize_mode_event_blocker.cc |
@@ -5,10 +5,18 @@ |
#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 { |
@@ -17,11 +25,11 @@ 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. |
-// TODO(flackr): This should only stop events from the internal keyboard and |
-// touchpad. |
class BlockKeyboardAndTouchpadTargeter : public ui::EventTargeter { |
public: |
- BlockKeyboardAndTouchpadTargeter(); |
+ BlockKeyboardAndTouchpadTargeter( |
+ aura::Window* root_window, |
+ MaximizeModeEventBlocker* event_blocker); |
virtual ~BlockKeyboardAndTouchpadTargeter(); |
// Sets the default targeter to use when the event is not being blocked. |
@@ -32,16 +40,34 @@ class BlockKeyboardAndTouchpadTargeter : public ui::EventTargeter { |
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() |
- : default_targeter_(NULL) { |
+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() { |
@@ -55,19 +81,37 @@ void BlockKeyboardAndTouchpadTargeter::SetDefaultTargeter( |
ui::EventTarget* BlockKeyboardAndTouchpadTargeter::FindTargetForEvent( |
ui::EventTarget* root, |
ui::Event* event) { |
- if (event->IsMouseEvent() || |
- event->IsMouseWheelEvent() || |
- event->IsScrollEvent()) { |
+ 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; |
- } |
- if (event->IsKeyEvent() && event->HasNativeEvent()) { |
+ } 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. |
// TODO(bruthig): Fix this to block rewritten volume keys |
// (i.e. F9 and F10) from the device's keyboard. https://crbug.com/368669 |
ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(event); |
if (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 |
+ && key_event->key_code() != ui::VKEY_POWER |
#endif |
) { |
return NULL; |
@@ -78,7 +122,11 @@ ui::EventTarget* BlockKeyboardAndTouchpadTargeter::FindTargetForEvent( |
} // namespace |
-MaximizeModeEventBlocker::MaximizeModeEventBlocker() { |
+MaximizeModeEventBlocker::MaximizeModeEventBlocker() |
+#if defined(USE_X11) |
+ : internal_devices_(new InternalInputDeviceListX11) |
+#endif |
+ { |
Shell::GetInstance()->AddShellObserver(this); |
// Hide the cursor as mouse events will be blocked. |
@@ -107,7 +155,7 @@ void MaximizeModeEventBlocker::OnRootWindowAdded(aura::Window* root_window) { |
void MaximizeModeEventBlocker::AddEventTargeterOn( |
aura::Window* root_window) { |
BlockKeyboardAndTouchpadTargeter* targeter = |
- new BlockKeyboardAndTouchpadTargeter(); |
+ 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()); |