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