Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: ash/wm/maximize_mode/maximize_mode_event_blocker.cc

Issue 313913004: Block internal PlatformEvents before they are dispatched in touchview. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove obsolete comment and unnecessary includes. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/maximize_mode/maximize_mode_event_blocker.h" 5 #include "ash/wm/maximize_mode/maximize_mode_event_blocker.h"
6 6
7 #include "ash/display/display_controller.h"
8 #include "ash/screen_util.h"
7 #include "ash/shell.h" 9 #include "ash/shell.h"
8 #include "ash/wm/maximize_mode/internal_input_device_list.h" 10 #include "ash/wm/maximize_mode/internal_input_device_list.h"
9 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
10 #include "ui/aura/client/cursor_client.h" 12 #include "ui/aura/client/cursor_client.h"
13 #include "ui/aura/client/screen_position_client.h"
14 #include "ui/aura/env.h"
11 #include "ui/aura/window_event_dispatcher.h" 15 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 16 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event_targeter.h" 17 #include "ui/events/event_utils.h"
14 #include "ui/events/keycodes/keyboard_codes.h" 18 #include "ui/events/keycodes/keyboard_codes.h"
15 #include "ui/gfx/point.h" 19 #include "ui/events/platform/platform_event_source.h"
16 20
17 #if defined(USE_X11) 21 #if defined(USE_X11)
18 #include "ash/wm/maximize_mode/internal_input_device_list_x11.h" 22 #include "ash/wm/maximize_mode/internal_input_device_list_x11.h"
19 #endif 23 #endif
20 24
21 namespace ash { 25 namespace ash {
22 26
23 namespace { 27 namespace {
24 28
25 // Event targeter to prevent delivery of mouse and touchpad events while 29 gfx::Point GetMouseLocationInScreen() {
26 // maximize mode is active. Other events such as touch are passed on to the 30 return aura::Env::GetInstance()->last_mouse_location();
27 // default targeter.
28 class BlockKeyboardAndTouchpadTargeter : public ui::EventTargeter {
29 public:
30 BlockKeyboardAndTouchpadTargeter(
31 aura::Window* root_window,
32 MaximizeModeEventBlocker* event_blocker);
33 virtual ~BlockKeyboardAndTouchpadTargeter();
34
35 // Sets the default targeter to use when the event is not being blocked.
36 void SetDefaultTargeter(EventTargeter* default_targeter);
37
38 // Overridden from ui::EventTargeter:
39 virtual ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
40 ui::Event* event) OVERRIDE;
41
42 private:
43 // A weak pointer to the root window on which this targeter will be set. The
44 // root window owns this targeter.
45 aura::Window* root_window_;
46
47 // A weak pointer to the event blocker which owns the scoped targeter owning
48 // this targeter.
49 MaximizeModeEventBlocker* event_blocker_;
50
51 // A weak pointer to the targeter this targeter is wrapping. The
52 // default_targeter is owned by the ScopedWindowTargeter which will be valid
53 // as long as this targeter is alive.
54 ui::EventTargeter* default_targeter_;
55
56 // The last known mouse location to lock the cursor in place to when events
57 // come from the internal touchpad.
58 gfx::Point last_mouse_location_;
59
60 DISALLOW_COPY_AND_ASSIGN(BlockKeyboardAndTouchpadTargeter);
61 };
62
63 BlockKeyboardAndTouchpadTargeter::BlockKeyboardAndTouchpadTargeter(
64 aura::Window* root_window,
65 MaximizeModeEventBlocker* event_blocker)
66 : root_window_(root_window),
67 event_blocker_(event_blocker),
68 default_targeter_(NULL),
69 last_mouse_location_(root_window->GetHost()->dispatcher()->
70 GetLastMouseLocationInRoot()) {
71 } 31 }
72 32
73 BlockKeyboardAndTouchpadTargeter::~BlockKeyboardAndTouchpadTargeter() { 33 void SetMouseLocationInScreen(const gfx::Point& screen_location) {
74 } 34 gfx::Display display = ash::ScreenUtil::FindDisplayContainingPoint(
75 35 screen_location);
76 void BlockKeyboardAndTouchpadTargeter::SetDefaultTargeter( 36 if (!display.is_valid())
77 ui::EventTargeter* default_targeter) { 37 return;
78 default_targeter_ = default_targeter; 38 aura::Window* root_window = Shell::GetInstance()->display_controller()->
79 } 39 GetRootWindowForDisplayId(display.id());
80 40 gfx::Point host_location(screen_location);
81 ui::EventTarget* BlockKeyboardAndTouchpadTargeter::FindTargetForEvent( 41 aura::client::ScreenPositionClient* client =
82 ui::EventTarget* root, 42 aura::client::GetScreenPositionClient(root_window);
83 ui::Event* event) { 43 if (client)
84 bool internal_device = event_blocker_->internal_devices() && 44 client->ConvertPointFromScreen(root_window, &host_location);
85 event_blocker_->internal_devices()->IsEventFromInternalDevice(event); 45 root_window->GetHost()->MoveCursorTo(host_location);
86 if (event->IsMouseEvent()) {
87 if (internal_device) {
88 // The cursor movement is handled at a lower level which is not blocked.
89 // Move the mouse cursor back to its last known location resulting from
90 // an external mouse to prevent the internal touchpad from moving it.
91 root_window_->GetHost()->MoveCursorToHostLocation(
92 last_mouse_location_);
93 return NULL;
94 } else {
95 // Track the last location seen from an external mouse event.
96 last_mouse_location_ =
97 static_cast<ui::MouseEvent*>(event)->root_location();
98 root_window_->GetHost()->ConvertPointToHost(&last_mouse_location_);
99 }
100 } else if (internal_device && (event->IsMouseWheelEvent() ||
101 event->IsScrollEvent())) {
102 return NULL;
103 } else if (event->IsKeyEvent() && event->HasNativeEvent()) {
104 // TODO(flackr): Disable events only from the internal keyboard device
105 // when we begin using XI2 events for keyboard events
106 // (http://crbug.com/368750) and can tell which device the event is
107 // coming from, http://crbug.com/362881.
108 // TODO(bruthig): Fix this to block rewritten volume keys
109 // (i.e. F9 and F10) from the device's keyboard. https://crbug.com/368669
110 ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(event);
111 if (key_event->key_code() != ui::VKEY_VOLUME_DOWN &&
112 key_event->key_code() != ui::VKEY_VOLUME_UP
113 #if defined(OS_CHROMEOS)
114 && key_event->key_code() != ui::VKEY_POWER
115 #endif
116 ) {
117 return NULL;
118 }
119 }
120 return default_targeter_->FindTargetForEvent(root, event);
121 } 46 }
122 47
123 } // namespace 48 } // namespace
124 49
125 MaximizeModeEventBlocker::MaximizeModeEventBlocker() 50 MaximizeModeEventBlocker::MaximizeModeEventBlocker()
51 : last_mouse_location_(GetMouseLocationInScreen())
126 #if defined(USE_X11) 52 #if defined(USE_X11)
127 : internal_devices_(new InternalInputDeviceListX11) 53 , internal_devices_(new InternalInputDeviceListX11)
128 #endif 54 #endif
129 { 55 {
130 Shell::GetInstance()->AddShellObserver(this); 56 ui::PlatformEventSource::GetInstance()->AddPlatformEventFilter(this);
131
132 // Hide the cursor as mouse events will be blocked. 57 // Hide the cursor as mouse events will be blocked.
133 aura::client::CursorClient* cursor_client_ = 58 aura::client::CursorClient* cursor_client_ =
134 aura::client::GetCursorClient(Shell::GetTargetRootWindow()); 59 aura::client::GetCursorClient(Shell::GetTargetRootWindow());
135 if (cursor_client_) 60 if (cursor_client_)
136 cursor_client_->HideCursor(); 61 cursor_client_->HideCursor();
137
138 // Block keyboard and mouse events on all existing and new root windows for
139 // the lifetime of this class.
140 aura::Window::Windows root_windows(Shell::GetAllRootWindows());
141 for (aura::Window::Windows::iterator iter = root_windows.begin();
142 iter != root_windows.end(); ++iter) {
143 AddEventTargeterOn(*iter);
144 }
145 } 62 }
146 63
147 MaximizeModeEventBlocker::~MaximizeModeEventBlocker() { 64 MaximizeModeEventBlocker::~MaximizeModeEventBlocker() {
148 Shell::GetInstance()->RemoveShellObserver(this); 65 ui::PlatformEventSource::GetInstance()->RemovePlatformEventFilter(this);
149 } 66 }
150 67
151 void MaximizeModeEventBlocker::OnRootWindowAdded(aura::Window* root_window) { 68 bool MaximizeModeEventBlocker::ShouldDispatchEvent(
152 AddEventTargeterOn(root_window); 69 const ui::PlatformEvent& event) {
153 } 70 bool internal_device = internal_devices_ &&
71 internal_devices_->IsEventFromInternalDevice(event);
72 ui::EventType type(ui::EventTypeFromNative(event));
73 if (type == ui::ET_MOUSE_MOVED ||
74 type == ui::ET_MOUSE_DRAGGED ||
75 type == ui::ET_MOUSE_ENTERED ||
76 type == ui::ET_MOUSE_EXITED ||
77 type == ui::ET_MOUSE_PRESSED ||
78 type == ui::ET_MOUSE_RELEASED ||
79 type == ui::ET_MOUSE_CAPTURE_CHANGED) {
80 if (internal_device) {
81 // The cursor movement is handled at a lower level which is not blocked.
82 // Move the mouse cursor back to its last known location resulting from
83 // an external mouse to prevent the internal touchpad from moving it.
84 SetMouseLocationInScreen(last_mouse_location_);
85 return false;
86 } else {
87 // Track the last location seen from an external mouse event.
88 last_mouse_location_ = GetMouseLocationInScreen();
89 }
90 } else if (type == ui::ET_KEY_PRESSED || type == ui::ET_KEY_RELEASED) {
91 // TODO(flackr): Disable events only from the internal keyboard device
92 // when we begin using XI2 events for keyboard events
93 // (http://crbug.com/368750) and can tell which device the event is
94 // coming from, http://crbug.com/362881.
95 ui::KeyboardCode key_code = ui::KeyboardCodeFromNative(event);
96 if (key_code == ui::VKEY_VOLUME_DOWN ||
97 key_code == ui::VKEY_VOLUME_UP
98 #if defined(OS_CHROMEOS)
99 || key_code == ui::VKEY_POWER
100 #endif
101 ) {
102 return true;
103 }
104 return false;
105 }
106 if (!internal_device)
107 return true;
154 108
155 void MaximizeModeEventBlocker::AddEventTargeterOn( 109 if (type == ui::ET_MOUSEWHEEL ||
156 aura::Window* root_window) { 110 (!(ui::EventFlagsFromNative(event) & ui::EF_FROM_TOUCH) && (
157 BlockKeyboardAndTouchpadTargeter* targeter = 111 type == ui::ET_SCROLL_FLING_START ||
158 new BlockKeyboardAndTouchpadTargeter(root_window, this); 112 type == ui::ET_SCROLL_FLING_CANCEL))) {
159 aura::ScopedWindowTargeter* scoped_targeter = new aura::ScopedWindowTargeter( 113 // Prevent scroll flings from the internal touchpad.
160 root_window, scoped_ptr<ui::EventTargeter>(targeter)); 114 return false;
161 targeter->SetDefaultTargeter(scoped_targeter->old_targeter()); 115 }
162 targeters_.push_back(scoped_targeter); 116 return true;
163 } 117 }
164 118
165 } // namespace ash 119 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698