| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/system_gesture_event_filter.h" | 5 #include "ash/wm/system_gesture_event_filter.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/accelerators/accelerator_controller.h" | 9 #include "ash/accelerators/accelerator_controller.h" |
| 10 #include "ash/aura/wm_window_aura.h" | 10 #include "ash/aura/wm_window_aura.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 bool CanMinimize() const override { return true; } | 56 bool CanMinimize() const override { return true; } |
| 57 void DeleteDelegate() override { delete this; } | 57 void DeleteDelegate() override { delete this; } |
| 58 | 58 |
| 59 DISALLOW_COPY_AND_ASSIGN(ResizableWidgetDelegate); | 59 DISALLOW_COPY_AND_ASSIGN(ResizableWidgetDelegate); |
| 60 }; | 60 }; |
| 61 | 61 |
| 62 // Support class for testing windows with a maximum size. | 62 // Support class for testing windows with a maximum size. |
| 63 class MaxSizeNCFV : public views::NonClientFrameView { | 63 class MaxSizeNCFV : public views::NonClientFrameView { |
| 64 public: | 64 public: |
| 65 MaxSizeNCFV() {} | 65 MaxSizeNCFV() {} |
| 66 |
| 66 private: | 67 private: |
| 67 gfx::Size GetMaximumSize() const override { return gfx::Size(200, 200); } | 68 gfx::Size GetMaximumSize() const override { return gfx::Size(200, 200); } |
| 68 gfx::Rect GetBoundsForClientView() const override { return gfx::Rect(); }; | 69 gfx::Rect GetBoundsForClientView() const override { return gfx::Rect(); }; |
| 69 | 70 |
| 70 gfx::Rect GetWindowBoundsForClientBounds( | 71 gfx::Rect GetWindowBoundsForClientBounds( |
| 71 const gfx::Rect& client_bounds) const override { | 72 const gfx::Rect& client_bounds) const override { |
| 72 return gfx::Rect(); | 73 return gfx::Rect(); |
| 73 }; | 74 }; |
| 74 | 75 |
| 75 // This function must ask the ClientView to do a hittest. We don't do this in | 76 // This function must ask the ClientView to do a hittest. We don't do this in |
| (...skipping 21 matching lines...) Expand all Loading... |
| 97 bool CanMinimize() const override { return true; } | 98 bool CanMinimize() const override { return true; } |
| 98 void DeleteDelegate() override { delete this; } | 99 void DeleteDelegate() override { delete this; } |
| 99 views::NonClientFrameView* CreateNonClientFrameView( | 100 views::NonClientFrameView* CreateNonClientFrameView( |
| 100 views::Widget* widget) override { | 101 views::Widget* widget) override { |
| 101 return new MaxSizeNCFV; | 102 return new MaxSizeNCFV; |
| 102 } | 103 } |
| 103 | 104 |
| 104 DISALLOW_COPY_AND_ASSIGN(MaxSizeWidgetDelegate); | 105 DISALLOW_COPY_AND_ASSIGN(MaxSizeWidgetDelegate); |
| 105 }; | 106 }; |
| 106 | 107 |
| 107 } // namespace | 108 } // namespace |
| 108 | 109 |
| 109 class SystemGestureEventFilterTest : public AshTestBase { | 110 class SystemGestureEventFilterTest : public AshTestBase { |
| 110 public: | 111 public: |
| 111 SystemGestureEventFilterTest() : AshTestBase() {} | 112 SystemGestureEventFilterTest() : AshTestBase() {} |
| 112 ~SystemGestureEventFilterTest() override {} | 113 ~SystemGestureEventFilterTest() override {} |
| 113 | 114 |
| 114 // Overridden from AshTestBase: | 115 // Overridden from AshTestBase: |
| 115 void SetUp() override { | 116 void SetUp() override { |
| 116 // TODO(jonross): TwoFingerDragDelayed() and ThreeFingerGestureStopsDrag() | 117 // TODO(jonross): TwoFingerDragDelayed() and ThreeFingerGestureStopsDrag() |
| 117 // both use hardcoded touch points, assuming that they target empty header | 118 // both use hardcoded touch points, assuming that they target empty header |
| 118 // space. Window control order now reflects configuration files and can | 119 // space. Window control order now reflects configuration files and can |
| 119 // change. The tests should be improved to dynamically decide touch points. | 120 // change. The tests should be improved to dynamically decide touch points. |
| 120 // To address this we specify the originally expected window control | 121 // To address this we specify the originally expected window control |
| 121 // positions to be consistent across tests. | 122 // positions to be consistent across tests. |
| 122 std::vector<views::FrameButton> leading; | 123 std::vector<views::FrameButton> leading; |
| 123 std::vector<views::FrameButton> trailing; | 124 std::vector<views::FrameButton> trailing; |
| 124 trailing.push_back(views::FRAME_BUTTON_MINIMIZE); | 125 trailing.push_back(views::FRAME_BUTTON_MINIMIZE); |
| 125 trailing.push_back(views::FRAME_BUTTON_MAXIMIZE); | 126 trailing.push_back(views::FRAME_BUTTON_MAXIMIZE); |
| 126 trailing.push_back(views::FRAME_BUTTON_CLOSE); | 127 trailing.push_back(views::FRAME_BUTTON_CLOSE); |
| 127 views::WindowButtonOrderProvider::GetInstance()-> | 128 views::WindowButtonOrderProvider::GetInstance()->SetWindowButtonOrder( |
| 128 SetWindowButtonOrder(leading, trailing); | 129 leading, trailing); |
| 129 | 130 |
| 130 test::AshTestBase::SetUp(); | 131 test::AshTestBase::SetUp(); |
| 131 // Enable brightness key. | 132 // Enable brightness key. |
| 132 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay(); | 133 test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay(); |
| 133 } | 134 } |
| 134 | 135 |
| 135 private: | 136 private: |
| 136 DISALLOW_COPY_AND_ASSIGN(SystemGestureEventFilterTest); | 137 DISALLOW_COPY_AND_ASSIGN(SystemGestureEventFilterTest); |
| 137 }; | 138 }; |
| 138 | 139 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 149 TEST_F(SystemGestureEventFilterTest, TwoFingerDrag) { | 150 TEST_F(SystemGestureEventFilterTest, TwoFingerDrag) { |
| 150 gfx::Rect bounds(0, 0, 600, 600); | 151 gfx::Rect bounds(0, 0, 600, 600); |
| 151 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 152 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 152 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 153 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 153 new ResizableWidgetDelegate, root_window, bounds); | 154 new ResizableWidgetDelegate, root_window, bounds); |
| 154 toplevel->Show(); | 155 toplevel->Show(); |
| 155 | 156 |
| 156 const int kSteps = 15; | 157 const int kSteps = 15; |
| 157 const int kTouchPoints = 2; | 158 const int kTouchPoints = 2; |
| 158 gfx::Point points[kTouchPoints] = { | 159 gfx::Point points[kTouchPoints] = { |
| 159 gfx::Point(250, 250), | 160 gfx::Point(250, 250), gfx::Point(350, 350), |
| 160 gfx::Point(350, 350), | |
| 161 }; | 161 }; |
| 162 | 162 |
| 163 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); | 163 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); |
| 164 | 164 |
| 165 wm::WindowState* toplevel_state = | 165 wm::WindowState* toplevel_state = |
| 166 wm::GetWindowState(toplevel->GetNativeWindow()); | 166 wm::GetWindowState(toplevel->GetNativeWindow()); |
| 167 // Swipe down to minimize. | 167 // Swipe down to minimize. |
| 168 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); | 168 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); |
| 169 EXPECT_TRUE(toplevel_state->IsMinimized()); | 169 EXPECT_TRUE(toplevel_state->IsMinimized()); |
| 170 | 170 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 184 gfx::Rect right_tile_bounds = toplevel->GetWindowBoundsInScreen(); | 184 gfx::Rect right_tile_bounds = toplevel->GetWindowBoundsInScreen(); |
| 185 EXPECT_NE(normal_bounds.ToString(), right_tile_bounds.ToString()); | 185 EXPECT_NE(normal_bounds.ToString(), right_tile_bounds.ToString()); |
| 186 | 186 |
| 187 // Swipe left to snap. | 187 // Swipe left to snap. |
| 188 gfx::Point left_points[kTouchPoints]; | 188 gfx::Point left_points[kTouchPoints]; |
| 189 for (int i = 0; i < kTouchPoints; ++i) { | 189 for (int i = 0; i < kTouchPoints; ++i) { |
| 190 left_points[i] = points[i]; | 190 left_points[i] = points[i]; |
| 191 left_points[i].Offset(right_tile_bounds.x(), right_tile_bounds.y()); | 191 left_points[i].Offset(right_tile_bounds.x(), right_tile_bounds.y()); |
| 192 } | 192 } |
| 193 generator.GestureMultiFingerScroll(kTouchPoints, left_points, 15, kSteps, | 193 generator.GestureMultiFingerScroll(kTouchPoints, left_points, 15, kSteps, |
| 194 -150, 0); | 194 -150, 0); |
| 195 gfx::Rect left_tile_bounds = toplevel->GetWindowBoundsInScreen(); | 195 gfx::Rect left_tile_bounds = toplevel->GetWindowBoundsInScreen(); |
| 196 EXPECT_NE(normal_bounds.ToString(), left_tile_bounds.ToString()); | 196 EXPECT_NE(normal_bounds.ToString(), left_tile_bounds.ToString()); |
| 197 EXPECT_NE(right_tile_bounds.ToString(), left_tile_bounds.ToString()); | 197 EXPECT_NE(right_tile_bounds.ToString(), left_tile_bounds.ToString()); |
| 198 | 198 |
| 199 // Swipe right again. | 199 // Swipe right again. |
| 200 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); | 200 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); |
| 201 gfx::Rect current_bounds = toplevel->GetWindowBoundsInScreen(); | 201 gfx::Rect current_bounds = toplevel->GetWindowBoundsInScreen(); |
| 202 EXPECT_NE(current_bounds.ToString(), left_tile_bounds.ToString()); | 202 EXPECT_NE(current_bounds.ToString(), left_tile_bounds.ToString()); |
| 203 EXPECT_EQ(current_bounds.ToString(), right_tile_bounds.ToString()); | 203 EXPECT_EQ(current_bounds.ToString(), right_tile_bounds.ToString()); |
| 204 } | 204 } |
| 205 | 205 |
| 206 TEST_F(SystemGestureEventFilterTest, WindowsWithMaxSizeDontSnap) { | 206 TEST_F(SystemGestureEventFilterTest, WindowsWithMaxSizeDontSnap) { |
| 207 gfx::Rect bounds(250, 150, 100, 100); | 207 gfx::Rect bounds(250, 150, 100, 100); |
| 208 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 208 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 209 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 209 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 210 new MaxSizeWidgetDelegate, root_window, bounds); | 210 new MaxSizeWidgetDelegate, root_window, bounds); |
| 211 toplevel->Show(); | 211 toplevel->Show(); |
| 212 | 212 |
| 213 const int kSteps = 15; | 213 const int kSteps = 15; |
| 214 const int kTouchPoints = 2; | 214 const int kTouchPoints = 2; |
| 215 gfx::Point points[kTouchPoints] = { | 215 gfx::Point points[kTouchPoints] = { |
| 216 gfx::Point(bounds.x() + 10, bounds.y() + 30), | 216 gfx::Point(bounds.x() + 10, bounds.y() + 30), |
| 217 gfx::Point(bounds.x() + 30, bounds.y() + 20), | 217 gfx::Point(bounds.x() + 30, bounds.y() + 20), |
| 218 }; | 218 }; |
| 219 | 219 |
| 220 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); | 220 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); |
| 221 | 221 |
| 222 // Swipe down to minimize. | 222 // Swipe down to minimize. |
| 223 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); | 223 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); |
| 224 wm::WindowState* toplevel_state = | 224 wm::WindowState* toplevel_state = |
| 225 wm::GetWindowState(toplevel->GetNativeWindow()); | 225 wm::GetWindowState(toplevel->GetNativeWindow()); |
| 226 EXPECT_TRUE(toplevel_state->IsMinimized()); | 226 EXPECT_TRUE(toplevel_state->IsMinimized()); |
| 227 | 227 |
| 228 toplevel->Restore(); | 228 toplevel->Restore(); |
| 229 toplevel->GetNativeWindow()->SetBounds(bounds); | 229 toplevel->GetNativeWindow()->SetBounds(bounds); |
| 230 | 230 |
| 231 // Check that swiping up doesn't maximize. | 231 // Check that swiping up doesn't maximize. |
| 232 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, -150); | 232 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, -150); |
| 233 EXPECT_FALSE(toplevel_state->IsMaximized()); | 233 EXPECT_FALSE(toplevel_state->IsMaximized()); |
| 234 | 234 |
| 235 toplevel->Restore(); | 235 toplevel->Restore(); |
| 236 toplevel->GetNativeWindow()->SetBounds(bounds); | 236 toplevel->GetNativeWindow()->SetBounds(bounds); |
| 237 | 237 |
| 238 // Check that swiping right doesn't snap. | 238 // Check that swiping right doesn't snap. |
| 239 gfx::Rect normal_bounds = toplevel->GetWindowBoundsInScreen(); | 239 gfx::Rect normal_bounds = toplevel->GetWindowBoundsInScreen(); |
| 240 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); | 240 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); |
| 241 normal_bounds.set_x(normal_bounds.x() + 150); | 241 normal_bounds.set_x(normal_bounds.x() + 150); |
| 242 EXPECT_EQ(normal_bounds.ToString(), | 242 EXPECT_EQ(normal_bounds.ToString(), |
| 243 toplevel->GetWindowBoundsInScreen().ToString()); | 243 toplevel->GetWindowBoundsInScreen().ToString()); |
| 244 | 244 |
| 245 toplevel->GetNativeWindow()->SetBounds(bounds); | 245 toplevel->GetNativeWindow()->SetBounds(bounds); |
| 246 | 246 |
| 247 // Check that swiping left doesn't snap. | 247 // Check that swiping left doesn't snap. |
| 248 normal_bounds = toplevel->GetWindowBoundsInScreen(); | 248 normal_bounds = toplevel->GetWindowBoundsInScreen(); |
| 249 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, -150, 0); | 249 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, -150, 0); |
| 250 normal_bounds.set_x(normal_bounds.x() - 150); | 250 normal_bounds.set_x(normal_bounds.x() - 150); |
| 251 EXPECT_EQ(normal_bounds.ToString(), | 251 EXPECT_EQ(normal_bounds.ToString(), |
| 252 toplevel->GetWindowBoundsInScreen().ToString()); | 252 toplevel->GetWindowBoundsInScreen().ToString()); |
| 253 | 253 |
| 254 toplevel->GetNativeWindow()->SetBounds(bounds); | 254 toplevel->GetNativeWindow()->SetBounds(bounds); |
| 255 | 255 |
| 256 // Swipe right again, make sure the window still doesn't snap. | 256 // Swipe right again, make sure the window still doesn't snap. |
| 257 normal_bounds = toplevel->GetWindowBoundsInScreen(); | 257 normal_bounds = toplevel->GetWindowBoundsInScreen(); |
| 258 normal_bounds.set_x(normal_bounds.x() + 150); | 258 normal_bounds.set_x(normal_bounds.x() + 150); |
| 259 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); | 259 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0); |
| 260 EXPECT_EQ(normal_bounds.ToString(), | 260 EXPECT_EQ(normal_bounds.ToString(), |
| 261 toplevel->GetWindowBoundsInScreen().ToString()); | 261 toplevel->GetWindowBoundsInScreen().ToString()); |
| 262 } | 262 } |
| 263 | 263 |
| 264 TEST_F(SystemGestureEventFilterTest, DISABLED_TwoFingerDragEdge) { | 264 TEST_F(SystemGestureEventFilterTest, DISABLED_TwoFingerDragEdge) { |
| 265 gfx::Rect bounds(0, 0, 200, 100); | 265 gfx::Rect bounds(0, 0, 200, 100); |
| 266 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 266 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 267 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 267 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 268 new ResizableWidgetDelegate, root_window, bounds); | 268 new ResizableWidgetDelegate, root_window, bounds); |
| 269 toplevel->Show(); | 269 toplevel->Show(); |
| 270 | 270 |
| 271 const int kSteps = 15; | 271 const int kSteps = 15; |
| 272 const int kTouchPoints = 2; | 272 const int kTouchPoints = 2; |
| 273 gfx::Point points[kTouchPoints] = { | 273 gfx::Point points[kTouchPoints] = { |
| 274 gfx::Point(30, 20), // Caption | 274 gfx::Point(30, 20), // Caption |
| 275 gfx::Point(0, 40), // Left edge | 275 gfx::Point(0, 40), // Left edge |
| 276 }; | 276 }; |
| 277 | 277 |
| 278 EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()-> | 278 EXPECT_EQ(HTCAPTION, |
| 279 GetNonClientComponent(points[0])); | 279 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 280 EXPECT_EQ(HTLEFT, toplevel->GetNativeWindow()->delegate()-> | 280 points[0])); |
| 281 GetNonClientComponent(points[1])); | 281 EXPECT_EQ(HTLEFT, |
| 282 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 283 points[1])); |
| 282 | 284 |
| 283 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); | 285 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); |
| 284 | 286 |
| 285 bounds = toplevel->GetNativeWindow()->bounds(); | 287 bounds = toplevel->GetNativeWindow()->bounds(); |
| 286 // Swipe down. Nothing should happen. | 288 // Swipe down. Nothing should happen. |
| 287 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); | 289 generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150); |
| 288 EXPECT_EQ(bounds.ToString(), | 290 EXPECT_EQ(bounds.ToString(), |
| 289 toplevel->GetNativeWindow()->bounds().ToString()); | 291 toplevel->GetNativeWindow()->bounds().ToString()); |
| 290 } | 292 } |
| 291 | 293 |
| 292 // We do not allow resizing a window via multiple edges simultaneously. Test | 294 // We do not allow resizing a window via multiple edges simultaneously. Test |
| 293 // that the behavior is reasonable if a user attempts to resize a window via | 295 // that the behavior is reasonable if a user attempts to resize a window via |
| 294 // several edges. | 296 // several edges. |
| 295 TEST_F(SystemGestureEventFilterTest, | 297 TEST_F(SystemGestureEventFilterTest, |
| 296 TwoFingerAttemptResizeLeftAndRightEdgesSimultaneously) { | 298 TwoFingerAttemptResizeLeftAndRightEdgesSimultaneously) { |
| 297 gfx::Rect initial_bounds(0, 0, 400, 400); | 299 gfx::Rect initial_bounds(0, 0, 400, 400); |
| 298 views::Widget* toplevel = | 300 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 299 views::Widget::CreateWindowWithContextAndBounds( | 301 new ResizableWidgetDelegate, CurrentContext(), initial_bounds); |
| 300 new ResizableWidgetDelegate, CurrentContext(), initial_bounds); | |
| 301 toplevel->Show(); | 302 toplevel->Show(); |
| 302 | 303 |
| 303 const int kSteps = 15; | 304 const int kSteps = 15; |
| 304 const int kTouchPoints = 2; | 305 const int kTouchPoints = 2; |
| 305 gfx::Point points[kTouchPoints] = { | 306 gfx::Point points[kTouchPoints] = { |
| 306 gfx::Point(0, 40), // Left edge | 307 gfx::Point(0, 40), // Left edge |
| 307 gfx::Point(399, 40), // Right edge | 308 gfx::Point(399, 40), // Right edge |
| 308 }; | 309 }; |
| 309 int delays[kTouchPoints] = {0, 120}; | 310 int delays[kTouchPoints] = {0, 120}; |
| 310 | 311 |
| 311 EXPECT_EQ(HTLEFT, toplevel->GetNonClientComponent(points[0])); | 312 EXPECT_EQ(HTLEFT, toplevel->GetNonClientComponent(points[0])); |
| 312 EXPECT_EQ(HTRIGHT, toplevel->GetNonClientComponent(points[1])); | 313 EXPECT_EQ(HTRIGHT, toplevel->GetNonClientComponent(points[1])); |
| 313 | 314 |
| 314 GetEventGenerator().GestureMultiFingerScrollWithDelays( | 315 GetEventGenerator().GestureMultiFingerScrollWithDelays( |
| 315 kTouchPoints, points, delays, 15, kSteps, 0, 40); | 316 kTouchPoints, points, delays, 15, kSteps, 0, 40); |
| 316 | 317 |
| 317 // The window bounds should not have changed because neither of the fingers | 318 // The window bounds should not have changed because neither of the fingers |
| 318 // moved horizontally. | 319 // moved horizontally. |
| 319 EXPECT_EQ(initial_bounds.ToString(), | 320 EXPECT_EQ(initial_bounds.ToString(), |
| 320 toplevel->GetNativeWindow()->bounds().ToString()); | 321 toplevel->GetNativeWindow()->bounds().ToString()); |
| 321 } | 322 } |
| 322 | 323 |
| 323 TEST_F(SystemGestureEventFilterTest, TwoFingerDragDelayed) { | 324 TEST_F(SystemGestureEventFilterTest, TwoFingerDragDelayed) { |
| 324 gfx::Rect bounds(0, 0, 200, 100); | 325 gfx::Rect bounds(0, 0, 200, 100); |
| 325 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 326 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 326 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 327 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 327 new ResizableWidgetDelegate, root_window, bounds); | 328 new ResizableWidgetDelegate, root_window, bounds); |
| 328 toplevel->Show(); | 329 toplevel->Show(); |
| 329 | 330 |
| 330 const int kSteps = 15; | 331 const int kSteps = 15; |
| 331 const int kTouchPoints = 2; | 332 const int kTouchPoints = 2; |
| 332 gfx::Point points[kTouchPoints] = { | 333 gfx::Point points[kTouchPoints] = { |
| 333 gfx::Point(30, 20), // Caption | 334 gfx::Point(30, 20), // Caption |
| 334 gfx::Point(34, 20), // Caption | 335 gfx::Point(34, 20), // Caption |
| 335 }; | 336 }; |
| 336 int delays[kTouchPoints] = {0, 120}; | 337 int delays[kTouchPoints] = {0, 120}; |
| 337 | 338 |
| 338 EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()-> | 339 EXPECT_EQ(HTCAPTION, |
| 339 GetNonClientComponent(points[0])); | 340 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 340 EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()-> | 341 points[0])); |
| 341 GetNonClientComponent(points[1])); | 342 EXPECT_EQ(HTCAPTION, |
| 343 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 344 points[1])); |
| 342 | 345 |
| 343 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); | 346 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); |
| 344 | 347 |
| 345 bounds = toplevel->GetNativeWindow()->bounds(); | 348 bounds = toplevel->GetNativeWindow()->bounds(); |
| 346 // Swipe right and down starting with one finger. | 349 // Swipe right and down starting with one finger. |
| 347 // Add another finger after 120ms and continue dragging. | 350 // Add another finger after 120ms and continue dragging. |
| 348 // The window should move and the drag should be determined by the center | 351 // The window should move and the drag should be determined by the center |
| 349 // point between the fingers. | 352 // point between the fingers. |
| 350 generator.GestureMultiFingerScrollWithDelays( | 353 generator.GestureMultiFingerScrollWithDelays(kTouchPoints, points, delays, 15, |
| 351 kTouchPoints, points, delays, 15, kSteps, 150, 150); | 354 kSteps, 150, 150); |
| 352 bounds += gfx::Vector2d(150 + (points[1].x() - points[0].x()) / 2, 150); | 355 bounds += gfx::Vector2d(150 + (points[1].x() - points[0].x()) / 2, 150); |
| 353 EXPECT_EQ(bounds.ToString(), | 356 EXPECT_EQ(bounds.ToString(), |
| 354 toplevel->GetNativeWindow()->bounds().ToString()); | 357 toplevel->GetNativeWindow()->bounds().ToString()); |
| 355 } | 358 } |
| 356 | 359 |
| 357 TEST_F(SystemGestureEventFilterTest, ThreeFingerGestureStopsDrag) { | 360 TEST_F(SystemGestureEventFilterTest, ThreeFingerGestureStopsDrag) { |
| 358 gfx::Rect bounds(0, 0, 200, 100); | 361 gfx::Rect bounds(0, 0, 200, 100); |
| 359 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 362 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 360 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 363 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 361 new ResizableWidgetDelegate, root_window, bounds); | 364 new ResizableWidgetDelegate, root_window, bounds); |
| 362 toplevel->Show(); | 365 toplevel->Show(); |
| 363 | 366 |
| 364 const int kSteps = 10; | 367 const int kSteps = 10; |
| 365 const int kTouchPoints = 3; | 368 const int kTouchPoints = 3; |
| 366 gfx::Point points[kTouchPoints] = { | 369 gfx::Point points[kTouchPoints] = { |
| 367 gfx::Point(30, 20), // Caption | 370 gfx::Point(30, 20), // Caption |
| 368 gfx::Point(34, 20), // Caption | 371 gfx::Point(34, 20), // Caption |
| 369 gfx::Point(38, 20), // Caption | 372 gfx::Point(38, 20), // Caption |
| 370 }; | 373 }; |
| 371 int delays[kTouchPoints] = {0, 0, 120}; | 374 int delays[kTouchPoints] = {0, 0, 120}; |
| 372 | 375 |
| 373 EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()-> | 376 EXPECT_EQ(HTCAPTION, |
| 374 GetNonClientComponent(points[0])); | 377 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 375 EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()-> | 378 points[0])); |
| 376 GetNonClientComponent(points[1])); | 379 EXPECT_EQ(HTCAPTION, |
| 380 toplevel->GetNativeWindow()->delegate()->GetNonClientComponent( |
| 381 points[1])); |
| 377 | 382 |
| 378 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); | 383 ui::test::EventGenerator generator(root_window, toplevel->GetNativeWindow()); |
| 379 | 384 |
| 380 bounds = toplevel->GetNativeWindow()->bounds(); | 385 bounds = toplevel->GetNativeWindow()->bounds(); |
| 381 // Swipe right and down starting with two fingers. | 386 // Swipe right and down starting with two fingers. |
| 382 // Add third finger after 120ms and continue dragging. | 387 // Add third finger after 120ms and continue dragging. |
| 383 // The window should start moving but stop when the 3rd finger touches down. | 388 // The window should start moving but stop when the 3rd finger touches down. |
| 384 const int kEventSeparation = 15; | 389 const int kEventSeparation = 15; |
| 385 generator.GestureMultiFingerScrollWithDelays( | 390 generator.GestureMultiFingerScrollWithDelays( |
| 386 kTouchPoints, points, delays, kEventSeparation, kSteps, 150, 150); | 391 kTouchPoints, points, delays, kEventSeparation, kSteps, 150, 150); |
| 387 int expected_drag = 150 / kSteps * 120 / kEventSeparation; | 392 int expected_drag = 150 / kSteps * 120 / kEventSeparation; |
| 388 bounds += gfx::Vector2d(expected_drag, expected_drag); | 393 bounds += gfx::Vector2d(expected_drag, expected_drag); |
| 389 EXPECT_EQ(bounds.ToString(), | 394 EXPECT_EQ(bounds.ToString(), |
| 390 toplevel->GetNativeWindow()->bounds().ToString()); | 395 toplevel->GetNativeWindow()->bounds().ToString()); |
| 391 } | 396 } |
| 392 | 397 |
| 393 TEST_F(SystemGestureEventFilterTest, DragLeftNearEdgeSnaps) { | 398 TEST_F(SystemGestureEventFilterTest, DragLeftNearEdgeSnaps) { |
| 394 gfx::Rect bounds(200, 150, 400, 100); | 399 gfx::Rect bounds(200, 150, 400, 100); |
| 395 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 400 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 396 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 401 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 397 new ResizableWidgetDelegate, root_window, bounds); | 402 new ResizableWidgetDelegate, root_window, bounds); |
| 398 toplevel->Show(); | 403 toplevel->Show(); |
| 399 | 404 |
| 400 const int kSteps = 15; | 405 const int kSteps = 15; |
| 401 const int kTouchPoints = 2; | 406 const int kTouchPoints = 2; |
| 402 gfx::Point points[kTouchPoints] = { | 407 gfx::Point points[kTouchPoints] = { |
| 403 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), | 408 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), |
| 404 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), | 409 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), |
| 405 }; | 410 }; |
| 406 aura::Window* toplevel_window = toplevel->GetNativeWindow(); | 411 aura::Window* toplevel_window = toplevel->GetNativeWindow(); |
| 407 ui::test::EventGenerator generator(root_window, toplevel_window); | 412 ui::test::EventGenerator generator(root_window, toplevel_window); |
| 408 | 413 |
| 409 // Check that dragging left snaps before reaching the screen edge. | 414 // Check that dragging left snaps before reaching the screen edge. |
| 410 gfx::Rect work_area = display::Screen::GetScreen() | 415 gfx::Rect work_area = display::Screen::GetScreen() |
| 411 ->GetDisplayNearestWindow(root_window) | 416 ->GetDisplayNearestWindow(root_window) |
| 412 .work_area(); | 417 .work_area(); |
| 413 int drag_x = work_area.x() + 20 - points[0].x(); | 418 int drag_x = work_area.x() + 20 - points[0].x(); |
| 414 generator.GestureMultiFingerScroll( | 419 generator.GestureMultiFingerScroll(kTouchPoints, points, 120, kSteps, drag_x, |
| 415 kTouchPoints, points, 120, kSteps, drag_x, 0); | 420 0); |
| 416 | 421 |
| 417 EXPECT_EQ(ash::wm::GetDefaultLeftSnappedWindowBoundsInParent( | 422 EXPECT_EQ(ash::wm::GetDefaultLeftSnappedWindowBoundsInParent( |
| 418 ash::WmWindowAura::Get(toplevel_window)) | 423 ash::WmWindowAura::Get(toplevel_window)) |
| 419 .ToString(), | 424 .ToString(), |
| 420 toplevel_window->bounds().ToString()); | 425 toplevel_window->bounds().ToString()); |
| 421 } | 426 } |
| 422 | 427 |
| 423 TEST_F(SystemGestureEventFilterTest, DragRightNearEdgeSnaps) { | 428 TEST_F(SystemGestureEventFilterTest, DragRightNearEdgeSnaps) { |
| 424 gfx::Rect bounds(200, 150, 400, 100); | 429 gfx::Rect bounds(200, 150, 400, 100); |
| 425 aura::Window* root_window = Shell::GetPrimaryRootWindow(); | 430 aura::Window* root_window = Shell::GetPrimaryRootWindow(); |
| 426 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( | 431 views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds( |
| 427 new ResizableWidgetDelegate, root_window, bounds); | 432 new ResizableWidgetDelegate, root_window, bounds); |
| 428 toplevel->Show(); | 433 toplevel->Show(); |
| 429 | 434 |
| 430 const int kSteps = 15; | 435 const int kSteps = 15; |
| 431 const int kTouchPoints = 2; | 436 const int kTouchPoints = 2; |
| 432 gfx::Point points[kTouchPoints] = { | 437 gfx::Point points[kTouchPoints] = { |
| 433 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), | 438 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), |
| 434 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), | 439 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5), |
| 435 }; | 440 }; |
| 436 aura::Window* toplevel_window = toplevel->GetNativeWindow(); | 441 aura::Window* toplevel_window = toplevel->GetNativeWindow(); |
| 437 ui::test::EventGenerator generator(root_window, toplevel_window); | 442 ui::test::EventGenerator generator(root_window, toplevel_window); |
| 438 | 443 |
| 439 // Check that dragging right snaps before reaching the screen edge. | 444 // Check that dragging right snaps before reaching the screen edge. |
| 440 gfx::Rect work_area = display::Screen::GetScreen() | 445 gfx::Rect work_area = display::Screen::GetScreen() |
| 441 ->GetDisplayNearestWindow(root_window) | 446 ->GetDisplayNearestWindow(root_window) |
| 442 .work_area(); | 447 .work_area(); |
| 443 int drag_x = work_area.right() - 20 - points[0].x(); | 448 int drag_x = work_area.right() - 20 - points[0].x(); |
| 444 generator.GestureMultiFingerScroll( | 449 generator.GestureMultiFingerScroll(kTouchPoints, points, 120, kSteps, drag_x, |
| 445 kTouchPoints, points, 120, kSteps, drag_x, 0); | 450 0); |
| 446 EXPECT_EQ(wm::GetDefaultRightSnappedWindowBoundsInParent( | 451 EXPECT_EQ(wm::GetDefaultRightSnappedWindowBoundsInParent( |
| 447 WmWindowAura::Get(toplevel_window)) | 452 WmWindowAura::Get(toplevel_window)) |
| 448 .ToString(), | 453 .ToString(), |
| 449 toplevel_window->bounds().ToString()); | 454 toplevel_window->bounds().ToString()); |
| 450 } | 455 } |
| 451 | 456 |
| 452 // Tests that the window manager does not consume gesture events targeted to | 457 // Tests that the window manager does not consume gesture events targeted to |
| 453 // windows of type WINDOW_TYPE_CONTROL. This is important because the web | 458 // windows of type WINDOW_TYPE_CONTROL. This is important because the web |
| 454 // contents are often (but not always) of type WINDOW_TYPE_CONTROL. | 459 // contents are often (but not always) of type WINDOW_TYPE_CONTROL. |
| 455 TEST_F(SystemGestureEventFilterTest, | 460 TEST_F(SystemGestureEventFilterTest, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 475 for (int i = 1; i <= 3; ++i) | 480 for (int i = 1; i <= 3; ++i) |
| 476 GetEventGenerator().ReleaseTouchId(i); | 481 GetEventGenerator().ReleaseTouchId(i); |
| 477 EXPECT_EQ(event_handler.num_gesture_events(), | 482 EXPECT_EQ(event_handler.num_gesture_events(), |
| 478 delegate.GetGestureCountAndReset()); | 483 delegate.GetGestureCountAndReset()); |
| 479 | 484 |
| 480 aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler); | 485 aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler); |
| 481 } | 486 } |
| 482 | 487 |
| 483 } // namespace test | 488 } // namespace test |
| 484 } // namespace ash | 489 } // namespace ash |
| OLD | NEW |