| OLD | NEW |
| 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 "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" | 5 #include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "apps/ui/views/app_window_frame_view.h" | 9 #include "apps/ui/views/app_window_frame_view.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 ChromeNativeAppWindowViewsAura app_window_; | 60 ChromeNativeAppWindowViewsAura app_window_; |
| 61 | 61 |
| 62 DISALLOW_COPY_AND_ASSIGN(ShapedAppWindowTargeterTest); | 62 DISALLOW_COPY_AND_ASSIGN(ShapedAppWindowTargeterTest); |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 TEST_F(ShapedAppWindowTargeterTest, HitTestBasic) { | 65 TEST_F(ShapedAppWindowTargeterTest, HitTestBasic) { |
| 66 aura::Window* window = widget()->GetNativeWindow(); | 66 aura::Window* window = widget()->GetNativeWindow(); |
| 67 { | 67 { |
| 68 // Without any custom shapes, the event should be targeted correctly to the | 68 // Without any custom shapes, the event should be targeted correctly to the |
| 69 // window. | 69 // window. |
| 70 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(40, 40), | 70 ui::MouseEvent move( |
| 71 gfx::Point(40, 40), ui::EventTimeForNow(), ui::EF_NONE, | 71 ui::ET_MOUSE_MOVED, gfx::Point(40, 40), gfx::Point(40, 40), |
| 72 ui::EF_NONE); | 72 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 73 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 73 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 74 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 74 ASSERT_FALSE(details.dispatcher_destroyed); | 75 ASSERT_FALSE(details.dispatcher_destroyed); |
| 75 EXPECT_EQ(window, move.target()); | 76 EXPECT_EQ(window, move.target()); |
| 76 } | 77 } |
| 77 | 78 |
| 78 std::unique_ptr<SkRegion> region(new SkRegion); | 79 std::unique_ptr<SkRegion> region(new SkRegion); |
| 79 region->op(SkIRect::MakeXYWH(0, 0, 0, 0), SkRegion::kUnion_Op); | 80 region->op(SkIRect::MakeXYWH(0, 0, 0, 0), SkRegion::kUnion_Op); |
| 80 app_window()->UpdateShape(std::move(region)); | 81 app_window()->UpdateShape(std::move(region)); |
| 81 { | 82 { |
| 82 // With an empty custom shape, all events within the window should fall | 83 // With an empty custom shape, all events within the window should fall |
| 83 // through to the root window. | 84 // through to the root window. |
| 84 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(40, 40), | 85 ui::MouseEvent move( |
| 85 gfx::Point(40, 40), ui::EventTimeForNow(), ui::EF_NONE, | 86 ui::ET_MOUSE_MOVED, gfx::Point(40, 40), gfx::Point(40, 40), |
| 86 ui::EF_NONE); | 87 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 88 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 87 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 89 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 88 ASSERT_FALSE(details.dispatcher_destroyed); | 90 ASSERT_FALSE(details.dispatcher_destroyed); |
| 89 EXPECT_EQ(root_window(), move.target()); | 91 EXPECT_EQ(root_window(), move.target()); |
| 90 } | 92 } |
| 91 | 93 |
| 92 // Window shape (global coordinates) | 94 // Window shape (global coordinates) |
| 93 // 30 70 90 130 | 95 // 30 70 90 130 |
| 94 // 30 + +-----+ | 96 // 30 + +-----+ |
| 95 // . | | <- mouse move (40,40) | 97 // . | | <- mouse move (40,40) |
| 96 // 70 +--------+ +---------+ | 98 // 70 +--------+ +---------+ |
| 97 // | . | <- mouse move (80,80) | 99 // | . | <- mouse move (80,80) |
| 98 // 90 +--------+ +---------+ | 100 // 90 +--------+ +---------+ |
| 99 // | | | 101 // | | |
| 100 // 130 +-----+ | 102 // 130 +-----+ |
| 101 region.reset(new SkRegion); | 103 region.reset(new SkRegion); |
| 102 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); | 104 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); |
| 103 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); | 105 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); |
| 104 app_window()->UpdateShape(std::move(region)); | 106 app_window()->UpdateShape(std::move(region)); |
| 105 { | 107 { |
| 106 // With the custom shape, the events that don't fall within the custom shape | 108 // With the custom shape, the events that don't fall within the custom shape |
| 107 // will go through to the root window. | 109 // will go through to the root window. |
| 108 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(40, 40), | 110 ui::MouseEvent move( |
| 109 gfx::Point(40, 40), ui::EventTimeForNow(), ui::EF_NONE, | 111 ui::ET_MOUSE_MOVED, gfx::Point(40, 40), gfx::Point(40, 40), |
| 110 ui::EF_NONE); | 112 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 113 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 111 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 114 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 112 ASSERT_FALSE(details.dispatcher_destroyed); | 115 ASSERT_FALSE(details.dispatcher_destroyed); |
| 113 EXPECT_EQ(root_window(), move.target()); | 116 EXPECT_EQ(root_window(), move.target()); |
| 114 | 117 |
| 115 // But events within the shape will still reach the window. | 118 // But events within the shape will still reach the window. |
| 116 ui::MouseEvent move2(ui::ET_MOUSE_MOVED, gfx::Point(80, 80), | 119 ui::MouseEvent move2( |
| 117 gfx::Point(80, 80), ui::EventTimeForNow(), ui::EF_NONE, | 120 ui::ET_MOUSE_MOVED, gfx::Point(80, 80), gfx::Point(80, 80), |
| 118 ui::EF_NONE); | 121 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 122 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 119 details = event_sink()->OnEventFromSource(&move2); | 123 details = event_sink()->OnEventFromSource(&move2); |
| 120 ASSERT_FALSE(details.dispatcher_destroyed); | 124 ASSERT_FALSE(details.dispatcher_destroyed); |
| 121 EXPECT_EQ(window, move2.target()); | 125 EXPECT_EQ(window, move2.target()); |
| 122 } | 126 } |
| 123 } | 127 } |
| 124 | 128 |
| 125 TEST_F(ShapedAppWindowTargeterTest, HitTestOnlyForShapedWindow) { | 129 TEST_F(ShapedAppWindowTargeterTest, HitTestOnlyForShapedWindow) { |
| 126 // Install a window-targeter on the root window that allows a window to | 130 // Install a window-targeter on the root window that allows a window to |
| 127 // receive events outside of its bounds. Verify that this window-targeter is | 131 // receive events outside of its bounds. Verify that this window-targeter is |
| 128 // active unless the window has a custom shape. | 132 // active unless the window has a custom shape. |
| 129 gfx::Insets inset(-30); | 133 gfx::Insets inset(-30); |
| 130 root_window()->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( | 134 root_window()->SetEventTargeter(std::unique_ptr<ui::EventTargeter>( |
| 131 new wm::EasyResizeWindowTargeter(root_window(), inset, inset))); | 135 new wm::EasyResizeWindowTargeter(root_window(), inset, inset))); |
| 132 | 136 |
| 133 aura::Window* window = widget()->GetNativeWindow(); | 137 aura::Window* window = widget()->GetNativeWindow(); |
| 134 { | 138 { |
| 135 // Without any custom shapes, an event within the window bounds should be | 139 // Without any custom shapes, an event within the window bounds should be |
| 136 // targeted correctly to the window. | 140 // targeted correctly to the window. |
| 137 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(40, 40), | 141 ui::MouseEvent move( |
| 138 gfx::Point(40, 40), ui::EventTimeForNow(), ui::EF_NONE, | 142 ui::ET_MOUSE_MOVED, gfx::Point(40, 40), gfx::Point(40, 40), |
| 139 ui::EF_NONE); | 143 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 144 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 140 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 145 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 141 ASSERT_FALSE(details.dispatcher_destroyed); | 146 ASSERT_FALSE(details.dispatcher_destroyed); |
| 142 EXPECT_EQ(window, move.target()); | 147 EXPECT_EQ(window, move.target()); |
| 143 } | 148 } |
| 144 { | 149 { |
| 145 // Without any custom shapes, an event that falls just outside the window | 150 // Without any custom shapes, an event that falls just outside the window |
| 146 // bounds should also be targeted correctly to the window, because of the | 151 // bounds should also be targeted correctly to the window, because of the |
| 147 // targeter installed on the root-window. | 152 // targeter installed on the root-window. |
| 148 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), | 153 ui::MouseEvent move( |
| 149 gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE, | 154 ui::ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10), |
| 150 ui::EF_NONE); | 155 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 156 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 151 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 157 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 152 ASSERT_FALSE(details.dispatcher_destroyed); | 158 ASSERT_FALSE(details.dispatcher_destroyed); |
| 153 EXPECT_EQ(window, move.target()); | 159 EXPECT_EQ(window, move.target()); |
| 154 } | 160 } |
| 155 | 161 |
| 156 std::unique_ptr<SkRegion> region(new SkRegion); | 162 std::unique_ptr<SkRegion> region(new SkRegion); |
| 157 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); | 163 region->op(SkIRect::MakeXYWH(40, 0, 20, 100), SkRegion::kUnion_Op); |
| 158 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); | 164 region->op(SkIRect::MakeXYWH(0, 40, 100, 20), SkRegion::kUnion_Op); |
| 159 app_window()->UpdateShape(std::move(region)); | 165 app_window()->UpdateShape(std::move(region)); |
| 160 { | 166 { |
| 161 // With the custom shape, the events that don't fall within the custom shape | 167 // With the custom shape, the events that don't fall within the custom shape |
| 162 // will go through to the root window. | 168 // will go through to the root window. |
| 163 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), | 169 ui::MouseEvent move( |
| 164 gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE, | 170 ui::ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10), |
| 165 ui::EF_NONE); | 171 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 172 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 166 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 173 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 167 ASSERT_FALSE(details.dispatcher_destroyed); | 174 ASSERT_FALSE(details.dispatcher_destroyed); |
| 168 EXPECT_EQ(root_window(), move.target()); | 175 EXPECT_EQ(root_window(), move.target()); |
| 169 } | 176 } |
| 170 | 177 |
| 171 // Remove the custom shape. This should restore the behaviour of targeting the | 178 // Remove the custom shape. This should restore the behaviour of targeting the |
| 172 // app window for events just outside its bounds. | 179 // app window for events just outside its bounds. |
| 173 app_window()->UpdateShape(std::unique_ptr<SkRegion>()); | 180 app_window()->UpdateShape(std::unique_ptr<SkRegion>()); |
| 174 { | 181 { |
| 175 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(10, 10), | 182 ui::MouseEvent move( |
| 176 gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE, | 183 ui::ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10), |
| 177 ui::EF_NONE); | 184 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 185 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 178 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 186 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 179 ASSERT_FALSE(details.dispatcher_destroyed); | 187 ASSERT_FALSE(details.dispatcher_destroyed); |
| 180 EXPECT_EQ(window, move.target()); | 188 EXPECT_EQ(window, move.target()); |
| 181 } | 189 } |
| 182 } | 190 } |
| 183 | 191 |
| 184 // Tests targeting of events on a window with an EasyResizeWindowTargeter | 192 // Tests targeting of events on a window with an EasyResizeWindowTargeter |
| 185 // installed on its container. | 193 // installed on its container. |
| 186 TEST_F(ShapedAppWindowTargeterTest, ResizeInsetsWithinBounds) { | 194 TEST_F(ShapedAppWindowTargeterTest, ResizeInsetsWithinBounds) { |
| 187 aura::Window* window = widget()->GetNativeWindow(); | 195 aura::Window* window = widget()->GetNativeWindow(); |
| 188 { | 196 { |
| 189 // An event in the center of the window should always have | 197 // An event in the center of the window should always have |
| 190 // |window| as its target. | 198 // |window| as its target. |
| 191 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(80, 80), | 199 ui::MouseEvent move( |
| 192 gfx::Point(80, 80), ui::EventTimeForNow(), ui::EF_NONE, | 200 ui::ET_MOUSE_MOVED, gfx::Point(80, 80), gfx::Point(80, 80), |
| 193 ui::EF_NONE); | 201 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 202 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 194 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 203 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 195 ASSERT_FALSE(details.dispatcher_destroyed); | 204 ASSERT_FALSE(details.dispatcher_destroyed); |
| 196 EXPECT_EQ(window, move.target()); | 205 EXPECT_EQ(window, move.target()); |
| 197 } | 206 } |
| 198 { | 207 { |
| 199 // Without an EasyResizeTargeter on the container, an event | 208 // Without an EasyResizeTargeter on the container, an event |
| 200 // inside the window and within 5px of an edge should have | 209 // inside the window and within 5px of an edge should have |
| 201 // |window| as its target. | 210 // |window| as its target. |
| 202 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(32, 37), | 211 ui::MouseEvent move( |
| 203 gfx::Point(32, 37), ui::EventTimeForNow(), ui::EF_NONE, | 212 ui::ET_MOUSE_MOVED, gfx::Point(32, 37), gfx::Point(32, 37), |
| 204 ui::EF_NONE); | 213 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 214 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 205 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 215 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 206 ASSERT_FALSE(details.dispatcher_destroyed); | 216 ASSERT_FALSE(details.dispatcher_destroyed); |
| 207 EXPECT_EQ(window, move.target()); | 217 EXPECT_EQ(window, move.target()); |
| 208 } | 218 } |
| 209 | 219 |
| 210 #if !defined(OS_CHROMEOS) | 220 #if !defined(OS_CHROMEOS) |
| 211 // The non standard app frame has a easy resize targetter installed. | 221 // The non standard app frame has a easy resize targetter installed. |
| 212 std::unique_ptr<views::NonClientFrameView> frame( | 222 std::unique_ptr<views::NonClientFrameView> frame( |
| 213 app_window_views()->CreateNonStandardAppFrame()); | 223 app_window_views()->CreateNonStandardAppFrame()); |
| 214 { | 224 { |
| 215 // Ensure that the window has an event targeter (there should be an | 225 // Ensure that the window has an event targeter (there should be an |
| 216 // EasyResizeWindowTargeter installed). | 226 // EasyResizeWindowTargeter installed). |
| 217 EXPECT_TRUE(static_cast<ui::EventTarget*>(window)->GetEventTargeter()); | 227 EXPECT_TRUE(static_cast<ui::EventTarget*>(window)->GetEventTargeter()); |
| 218 } | 228 } |
| 219 { | 229 { |
| 220 // An event in the center of the window should always have | 230 // An event in the center of the window should always have |
| 221 // |window| as its target. | 231 // |window| as its target. |
| 222 // TODO(mgiuca): This isn't really testing anything (note that it has the | 232 // TODO(mgiuca): This isn't really testing anything (note that it has the |
| 223 // same expectation as the border case below). In the real environment, the | 233 // same expectation as the border case below). In the real environment, the |
| 224 // target will actually be the RenderWidgetHostViewAura's window that is the | 234 // target will actually be the RenderWidgetHostViewAura's window that is the |
| 225 // child of the child of |window|, whereas in the border case it *will* be | 235 // child of the child of |window|, whereas in the border case it *will* be |
| 226 // |window|. However, since this test environment does not have a | 236 // |window|. However, since this test environment does not have a |
| 227 // RenderWidgetHostViewAura, we cannot differentiate the two cases. Fix | 237 // RenderWidgetHostViewAura, we cannot differentiate the two cases. Fix |
| 228 // the test environment so that the test can assert that non-border events | 238 // the test environment so that the test can assert that non-border events |
| 229 // bubble down to a child of |window|. | 239 // bubble down to a child of |window|. |
| 230 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(80, 80), | 240 ui::MouseEvent move( |
| 231 gfx::Point(80, 80), ui::EventTimeForNow(), ui::EF_NONE, | 241 ui::ET_MOUSE_MOVED, gfx::Point(80, 80), gfx::Point(80, 80), |
| 232 ui::EF_NONE); | 242 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 243 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 233 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 244 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 234 ASSERT_FALSE(details.dispatcher_destroyed); | 245 ASSERT_FALSE(details.dispatcher_destroyed); |
| 235 EXPECT_EQ(window, move.target()); | 246 EXPECT_EQ(window, move.target()); |
| 236 } | 247 } |
| 237 { | 248 { |
| 238 // With an EasyResizeTargeter on the container, an event | 249 // With an EasyResizeTargeter on the container, an event |
| 239 // inside the window and within 5px of an edge should have | 250 // inside the window and within 5px of an edge should have |
| 240 // |window| as its target. | 251 // |window| as its target. |
| 241 ui::MouseEvent move(ui::ET_MOUSE_MOVED, gfx::Point(32, 37), | 252 ui::MouseEvent move( |
| 242 gfx::Point(32, 37), ui::EventTimeForNow(), ui::EF_NONE, | 253 ui::ET_MOUSE_MOVED, gfx::Point(32, 37), gfx::Point(32, 37), |
| 243 ui::EF_NONE); | 254 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE, |
| 255 ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE)); |
| 244 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); | 256 ui::EventDispatchDetails details = event_sink()->OnEventFromSource(&move); |
| 245 ASSERT_FALSE(details.dispatcher_destroyed); | 257 ASSERT_FALSE(details.dispatcher_destroyed); |
| 246 EXPECT_EQ(window, move.target()); | 258 EXPECT_EQ(window, move.target()); |
| 247 } | 259 } |
| 248 #endif // defined (OS_CHROMEOS) | 260 #endif // defined (OS_CHROMEOS) |
| 249 } | 261 } |
| OLD | NEW |