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/workspace/multi_window_resize_controller.h" | 5 #include "ash/wm/workspace/multi_window_resize_controller.h" |
6 | 6 |
7 #include "ash/ash_constants.h" | |
8 #include "ash/frame/custom_frame_view_ash.h" | |
9 #include "ash/shell.h" | 7 #include "ash/shell.h" |
10 #include "ash/test/ash_test_base.h" | 8 #include "ash/test/ash_test_base.h" |
11 #include "ash/test/shell_test_api.h" | 9 #include "ash/test/shell_test_api.h" |
12 #include "ash/wm/window_util.h" | 10 #include "ash/wm/window_util.h" |
13 #include "ash/wm/workspace/workspace_event_handler_test_helper.h" | 11 #include "ash/wm/workspace/workspace_event_handler_test_helper.h" |
14 #include "ash/wm/workspace_controller.h" | 12 #include "ash/wm/workspace_controller.h" |
15 #include "ash/wm/workspace_controller_test_helper.h" | 13 #include "ash/wm/workspace_controller_test_helper.h" |
16 #include "ui/aura/test/test_window_delegate.h" | 14 #include "ui/aura/test/test_window_delegate.h" |
17 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
18 #include "ui/base/hit_test.h" | 16 #include "ui/base/hit_test.h" |
19 #include "ui/events/test/event_generator.h" | 17 #include "ui/events/test/event_generator.h" |
20 #include "ui/gfx/screen.h" | 18 #include "ui/gfx/screen.h" |
21 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
22 #include "ui/views/widget/widget_delegate.h" | |
23 | 20 |
24 namespace ash { | 21 namespace ash { |
25 | 22 |
26 namespace { | |
27 | |
28 // WidgetDelegate for a resizable widget which creates a NonClientFrameView | |
29 // which is actually used in Ash. | |
30 class TestWidgetDelegate : public views::WidgetDelegateView { | |
31 public: | |
32 TestWidgetDelegate() {} | |
33 ~TestWidgetDelegate() override {} | |
34 | |
35 bool CanResize() const override { | |
36 return true; | |
37 } | |
38 | |
39 views::NonClientFrameView* CreateNonClientFrameView( | |
40 views::Widget* widget) override { | |
41 return new CustomFrameViewAsh(widget); | |
42 } | |
43 | |
44 private: | |
45 DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate); | |
46 }; | |
47 | |
48 } // namespace | |
49 | |
50 class MultiWindowResizeControllerTest : public test::AshTestBase { | 23 class MultiWindowResizeControllerTest : public test::AshTestBase { |
51 public: | 24 public: |
52 MultiWindowResizeControllerTest() : resize_controller_(NULL) {} | 25 MultiWindowResizeControllerTest() : resize_controller_(NULL) {} |
53 ~MultiWindowResizeControllerTest() override {} | 26 ~MultiWindowResizeControllerTest() override {} |
54 | 27 |
55 void SetUp() override { | 28 void SetUp() override { |
56 test::AshTestBase::SetUp(); | 29 test::AshTestBase::SetUp(); |
57 WorkspaceController* wc = | 30 WorkspaceController* wc = |
58 test::ShellTestApi(Shell::GetInstance()).workspace_controller(); | 31 test::ShellTestApi(Shell::GetInstance()).workspace_controller(); |
59 WorkspaceEventHandler* event_handler = | 32 WorkspaceEventHandler* event_handler = |
(...skipping 19 matching lines...) Expand all Loading... |
79 } | 52 } |
80 | 53 |
81 bool IsShowing() { | 54 bool IsShowing() { |
82 return resize_controller_->IsShowing(); | 55 return resize_controller_->IsShowing(); |
83 } | 56 } |
84 | 57 |
85 bool HasPendingShow() { | 58 bool HasPendingShow() { |
86 return resize_controller_->show_timer_.IsRunning(); | 59 return resize_controller_->show_timer_.IsRunning(); |
87 } | 60 } |
88 | 61 |
| 62 bool HasPendingHide() { |
| 63 return resize_controller_->hide_timer_.IsRunning(); |
| 64 } |
| 65 |
89 void Hide() { | 66 void Hide() { |
90 resize_controller_->Hide(); | 67 resize_controller_->Hide(); |
91 } | 68 } |
92 | 69 |
93 bool HasTarget(aura::Window* window) { | 70 bool HasTarget(aura::Window* window) { |
94 if (!resize_controller_->windows_.is_valid()) | 71 if (!resize_controller_->windows_.is_valid()) |
95 return false; | 72 return false; |
96 if ((resize_controller_->windows_.window1 == window || | 73 if ((resize_controller_->windows_.window1 == window || |
97 resize_controller_->windows_.window2 == window)) | 74 resize_controller_->windows_.window2 == window)) |
98 return true; | 75 return true; |
(...skipping 26 matching lines...) Expand all Loading... |
125 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); | 102 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); |
126 delegate1.set_window_component(HTRIGHT); | 103 delegate1.set_window_component(HTRIGHT); |
127 aura::test::TestWindowDelegate delegate2; | 104 aura::test::TestWindowDelegate delegate2; |
128 scoped_ptr<aura::Window> w2( | 105 scoped_ptr<aura::Window> w2( |
129 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); | 106 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); |
130 delegate2.set_window_component(HTRIGHT); | 107 delegate2.set_window_component(HTRIGHT); |
131 ui::test::EventGenerator generator(w1->GetRootWindow()); | 108 ui::test::EventGenerator generator(w1->GetRootWindow()); |
132 generator.MoveMouseTo(w1->bounds().CenterPoint()); | 109 generator.MoveMouseTo(w1->bounds().CenterPoint()); |
133 EXPECT_TRUE(HasPendingShow()); | 110 EXPECT_TRUE(HasPendingShow()); |
134 EXPECT_TRUE(IsShowing()); | 111 EXPECT_TRUE(IsShowing()); |
| 112 EXPECT_FALSE(HasPendingHide()); |
135 | 113 |
136 // Force a show now. | 114 // Force a show now. |
137 ShowNow(); | 115 ShowNow(); |
138 EXPECT_FALSE(HasPendingShow()); | 116 EXPECT_FALSE(HasPendingShow()); |
139 EXPECT_TRUE(IsShowing()); | 117 EXPECT_TRUE(IsShowing()); |
| 118 EXPECT_FALSE(HasPendingHide()); |
140 | 119 |
141 EXPECT_FALSE(IsOverWindows(gfx::Point(200, 200))); | 120 EXPECT_FALSE(IsOverWindows(gfx::Point(200, 200))); |
142 | 121 |
143 // Have to explicitly invoke this as MouseWatcher listens for native events. | 122 // Have to explicitly invoke this as MouseWatcher listens for native events. |
144 resize_controller_->MouseMovedOutOfHost(); | 123 resize_controller_->MouseMovedOutOfHost(); |
145 EXPECT_FALSE(HasPendingShow()); | 124 EXPECT_FALSE(HasPendingShow()); |
146 EXPECT_FALSE(IsShowing()); | 125 EXPECT_FALSE(IsShowing()); |
147 } | 126 EXPECT_FALSE(HasPendingHide()); |
148 | |
149 // Test the behavior of IsOverWindows(). | |
150 TEST_F(MultiWindowResizeControllerTest, IsOverWindows) { | |
151 // Create the following layout: | |
152 // __________________ | |
153 // | w1 | w2 | | |
154 // | |________| | |
155 // | | w3 | | |
156 // |________|________| | |
157 scoped_ptr<views::Widget> w1(new views::Widget); | |
158 views::Widget::InitParams params1; | |
159 params1.delegate = new TestWidgetDelegate; | |
160 params1.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
161 params1.bounds = gfx::Rect(100, 200); | |
162 params1.context = CurrentContext(); | |
163 w1->Init(params1); | |
164 w1->Show(); | |
165 | |
166 scoped_ptr<views::Widget> w2(new views::Widget); | |
167 views::Widget::InitParams params2; | |
168 params2.delegate = new TestWidgetDelegate; | |
169 params2.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
170 params2.bounds = gfx::Rect(100, 0, 100, 100); | |
171 params2.context = CurrentContext(); | |
172 w2->Init(params2); | |
173 w2->Show(); | |
174 | |
175 scoped_ptr<views::Widget> w3(new views::Widget); | |
176 views::Widget::InitParams params3; | |
177 params3.delegate = new TestWidgetDelegate; | |
178 params3.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
179 params3.bounds = gfx::Rect(100, 100, 100, 100); | |
180 params3.context = CurrentContext(); | |
181 w3->Init(params3); | |
182 w3->Show(); | |
183 | |
184 ui::test::EventGenerator& generator = GetEventGenerator(); | |
185 generator.MoveMouseTo(gfx::Point(100, 150)); | |
186 EXPECT_TRUE(HasPendingShow()); | |
187 EXPECT_TRUE(IsShowing()); | |
188 ShowNow(); | |
189 EXPECT_TRUE(IsShowing()); | |
190 | |
191 // Check that the multi-window resize handle does not hide while the mouse is | |
192 // over a window's resize area. A window's resize area extends outside the | |
193 // window's bounds. | |
194 EXPECT_TRUE(w3->IsActive()); | |
195 ASSERT_LT(kResizeInsideBoundsSize, kResizeOutsideBoundsSize); | |
196 | |
197 EXPECT_TRUE(IsOverWindows(gfx::Point(100, 150))); | |
198 EXPECT_TRUE(IsOverWindows(gfx::Point(100 - kResizeOutsideBoundsSize, 150))); | |
199 EXPECT_FALSE( | |
200 IsOverWindows(gfx::Point(100 - kResizeOutsideBoundsSize - 1, 150))); | |
201 EXPECT_TRUE( | |
202 IsOverWindows(gfx::Point(100 + kResizeInsideBoundsSize - 1, 150))); | |
203 EXPECT_FALSE(IsOverWindows(gfx::Point(100 + kResizeInsideBoundsSize, 150))); | |
204 EXPECT_FALSE( | |
205 IsOverWindows(gfx::Point(100 + kResizeOutsideBoundsSize - 1, 150))); | |
206 | |
207 w1->Activate(); | |
208 EXPECT_TRUE(IsOverWindows(gfx::Point(100, 150))); | |
209 EXPECT_TRUE(IsOverWindows(gfx::Point(100 - kResizeInsideBoundsSize, 150))); | |
210 EXPECT_FALSE( | |
211 IsOverWindows(gfx::Point(100 - kResizeInsideBoundsSize - 1, 150))); | |
212 EXPECT_FALSE(IsOverWindows(gfx::Point(100 - kResizeOutsideBoundsSize, 150))); | |
213 EXPECT_TRUE( | |
214 IsOverWindows(gfx::Point(100 + kResizeOutsideBoundsSize - 1, 150))); | |
215 EXPECT_FALSE(IsOverWindows(gfx::Point(100 + kResizeOutsideBoundsSize, 150))); | |
216 | |
217 // Check that the multi-window resize handles eventually hide if the mouse | |
218 // moves between |w1| and |w2|. | |
219 EXPECT_FALSE(IsOverWindows(gfx::Point(100, 50))); | |
220 } | 127 } |
221 | 128 |
222 // Makes sure deleting a window hides. | 129 // Makes sure deleting a window hides. |
223 TEST_F(MultiWindowResizeControllerTest, DeleteWindow) { | 130 TEST_F(MultiWindowResizeControllerTest, DeleteWindow) { |
224 aura::test::TestWindowDelegate delegate1; | 131 aura::test::TestWindowDelegate delegate1; |
225 scoped_ptr<aura::Window> w1( | 132 scoped_ptr<aura::Window> w1( |
226 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); | 133 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); |
227 delegate1.set_window_component(HTRIGHT); | 134 delegate1.set_window_component(HTRIGHT); |
228 aura::test::TestWindowDelegate delegate2; | 135 aura::test::TestWindowDelegate delegate2; |
229 scoped_ptr<aura::Window> w2( | 136 scoped_ptr<aura::Window> w2( |
230 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); | 137 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); |
231 delegate2.set_window_component(HTRIGHT); | 138 delegate2.set_window_component(HTRIGHT); |
232 ui::test::EventGenerator generator(w1->GetRootWindow()); | 139 ui::test::EventGenerator generator(w1->GetRootWindow()); |
233 generator.MoveMouseTo(w1->bounds().CenterPoint()); | 140 generator.MoveMouseTo(w1->bounds().CenterPoint()); |
234 EXPECT_TRUE(HasPendingShow()); | 141 EXPECT_TRUE(HasPendingShow()); |
235 EXPECT_TRUE(IsShowing()); | 142 EXPECT_TRUE(IsShowing()); |
| 143 EXPECT_FALSE(HasPendingHide()); |
236 | 144 |
237 // Force a show now. | 145 // Force a show now. |
238 ShowNow(); | 146 ShowNow(); |
239 EXPECT_FALSE(HasPendingShow()); | 147 EXPECT_FALSE(HasPendingShow()); |
240 EXPECT_TRUE(IsShowing()); | 148 EXPECT_TRUE(IsShowing()); |
| 149 EXPECT_FALSE(HasPendingHide()); |
241 | 150 |
242 // Move the mouse over the resize widget. | 151 // Move the mouse over the resize widget. |
243 ASSERT_TRUE(resize_widget()); | 152 ASSERT_TRUE(resize_widget()); |
244 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); | 153 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); |
245 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); | 154 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); |
246 EXPECT_FALSE(HasPendingShow()); | 155 EXPECT_FALSE(HasPendingShow()); |
247 EXPECT_TRUE(IsShowing()); | 156 EXPECT_TRUE(IsShowing()); |
| 157 EXPECT_FALSE(HasPendingHide()); |
248 | 158 |
249 // Move the resize widget | 159 // Move the resize widget |
250 generator.PressLeftButton(); | 160 generator.PressLeftButton(); |
251 generator.MoveMouseTo(bounds.x() + 10, bounds.y() + 10); | 161 generator.MoveMouseTo(bounds.x() + 10, bounds.y() + 10); |
252 | 162 |
253 // Delete w2. | 163 // Delete w2. |
254 w2.reset(); | 164 w2.reset(); |
255 EXPECT_TRUE(resize_widget() == NULL); | 165 EXPECT_TRUE(resize_widget() == NULL); |
256 EXPECT_FALSE(HasPendingShow()); | 166 EXPECT_FALSE(HasPendingShow()); |
257 EXPECT_FALSE(IsShowing()); | 167 EXPECT_FALSE(IsShowing()); |
| 168 EXPECT_FALSE(HasPendingHide()); |
258 EXPECT_FALSE(HasTarget(w1.get())); | 169 EXPECT_FALSE(HasTarget(w1.get())); |
259 } | 170 } |
260 | 171 |
261 // Tests resizing. | 172 // Tests resizing. |
262 TEST_F(MultiWindowResizeControllerTest, Drag) { | 173 TEST_F(MultiWindowResizeControllerTest, Drag) { |
263 aura::test::TestWindowDelegate delegate1; | 174 aura::test::TestWindowDelegate delegate1; |
264 scoped_ptr<aura::Window> w1( | 175 scoped_ptr<aura::Window> w1( |
265 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); | 176 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); |
266 delegate1.set_window_component(HTRIGHT); | 177 delegate1.set_window_component(HTRIGHT); |
267 aura::test::TestWindowDelegate delegate2; | 178 aura::test::TestWindowDelegate delegate2; |
268 scoped_ptr<aura::Window> w2( | 179 scoped_ptr<aura::Window> w2( |
269 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); | 180 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); |
270 delegate2.set_window_component(HTRIGHT); | 181 delegate2.set_window_component(HTRIGHT); |
271 ui::test::EventGenerator generator(w1->GetRootWindow()); | 182 ui::test::EventGenerator generator(w1->GetRootWindow()); |
272 generator.MoveMouseTo(w1->bounds().CenterPoint()); | 183 generator.MoveMouseTo(w1->bounds().CenterPoint()); |
273 EXPECT_TRUE(HasPendingShow()); | 184 EXPECT_TRUE(HasPendingShow()); |
274 EXPECT_TRUE(IsShowing()); | 185 EXPECT_TRUE(IsShowing()); |
| 186 EXPECT_FALSE(HasPendingHide()); |
275 | 187 |
276 // Force a show now. | 188 // Force a show now. |
277 ShowNow(); | 189 ShowNow(); |
278 EXPECT_FALSE(HasPendingShow()); | 190 EXPECT_FALSE(HasPendingShow()); |
279 EXPECT_TRUE(IsShowing()); | 191 EXPECT_TRUE(IsShowing()); |
| 192 EXPECT_FALSE(HasPendingHide()); |
280 | 193 |
281 // Move the mouse over the resize widget. | 194 // Move the mouse over the resize widget. |
282 ASSERT_TRUE(resize_widget()); | 195 ASSERT_TRUE(resize_widget()); |
283 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); | 196 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); |
284 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); | 197 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); |
285 EXPECT_FALSE(HasPendingShow()); | 198 EXPECT_FALSE(HasPendingShow()); |
286 EXPECT_TRUE(IsShowing()); | 199 EXPECT_TRUE(IsShowing()); |
| 200 EXPECT_FALSE(HasPendingHide()); |
287 | 201 |
288 // Move the resize widget | 202 // Move the resize widget |
289 generator.PressLeftButton(); | 203 generator.PressLeftButton(); |
290 generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10); | 204 generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10); |
291 generator.ReleaseLeftButton(); | 205 generator.ReleaseLeftButton(); |
292 | 206 |
293 EXPECT_TRUE(resize_widget()); | 207 EXPECT_TRUE(resize_widget()); |
294 EXPECT_FALSE(HasPendingShow()); | 208 EXPECT_FALSE(HasPendingShow()); |
295 EXPECT_TRUE(IsShowing()); | 209 EXPECT_TRUE(IsShowing()); |
| 210 EXPECT_FALSE(HasPendingHide()); |
296 EXPECT_EQ("0,0 110x100", w1->bounds().ToString()); | 211 EXPECT_EQ("0,0 110x100", w1->bounds().ToString()); |
297 EXPECT_EQ("110,0 100x100", w2->bounds().ToString()); | 212 EXPECT_EQ("110,0 100x100", w2->bounds().ToString()); |
298 } | 213 } |
299 | 214 |
300 // Makes sure three windows are picked up. | 215 // Makes sure three windows are picked up. |
301 TEST_F(MultiWindowResizeControllerTest, Three) { | 216 TEST_F(MultiWindowResizeControllerTest, Three) { |
302 aura::test::TestWindowDelegate delegate1; | 217 aura::test::TestWindowDelegate delegate1; |
303 scoped_ptr<aura::Window> w1( | 218 scoped_ptr<aura::Window> w1( |
304 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); | 219 CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100))); |
305 delegate1.set_window_component(HTRIGHT); | 220 delegate1.set_window_component(HTRIGHT); |
306 aura::test::TestWindowDelegate delegate2; | 221 aura::test::TestWindowDelegate delegate2; |
307 scoped_ptr<aura::Window> w2( | 222 scoped_ptr<aura::Window> w2( |
308 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); | 223 CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100))); |
309 delegate2.set_window_component(HTRIGHT); | 224 delegate2.set_window_component(HTRIGHT); |
310 aura::test::TestWindowDelegate delegate3; | 225 aura::test::TestWindowDelegate delegate3; |
311 scoped_ptr<aura::Window> w3( | 226 scoped_ptr<aura::Window> w3( |
312 CreateTestWindow(&delegate3, gfx::Rect(200, 0, 100, 100))); | 227 CreateTestWindow(&delegate3, gfx::Rect(200, 0, 100, 100))); |
313 delegate3.set_window_component(HTRIGHT); | 228 delegate3.set_window_component(HTRIGHT); |
314 | 229 |
315 ui::test::EventGenerator generator(w1->GetRootWindow()); | 230 ui::test::EventGenerator generator(w1->GetRootWindow()); |
316 generator.MoveMouseTo(w1->bounds().CenterPoint()); | 231 generator.MoveMouseTo(w1->bounds().CenterPoint()); |
317 EXPECT_TRUE(HasPendingShow()); | 232 EXPECT_TRUE(HasPendingShow()); |
318 EXPECT_TRUE(IsShowing()); | 233 EXPECT_TRUE(IsShowing()); |
| 234 EXPECT_FALSE(HasPendingHide()); |
319 EXPECT_FALSE(HasTarget(w3.get())); | 235 EXPECT_FALSE(HasTarget(w3.get())); |
320 | 236 |
321 ShowNow(); | 237 ShowNow(); |
322 EXPECT_FALSE(HasPendingShow()); | 238 EXPECT_FALSE(HasPendingShow()); |
323 EXPECT_TRUE(IsShowing()); | 239 EXPECT_TRUE(IsShowing()); |
| 240 EXPECT_FALSE(HasPendingHide()); |
324 | 241 |
325 // w3 should be picked up when resize is started. | 242 // w3 should be picked up when resize is started. |
326 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); | 243 gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen()); |
327 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); | 244 generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1); |
328 generator.PressLeftButton(); | 245 generator.PressLeftButton(); |
329 generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10); | 246 generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10); |
330 | 247 |
331 EXPECT_TRUE(HasTarget(w3.get())); | 248 EXPECT_TRUE(HasTarget(w3.get())); |
332 | 249 |
333 // Release the mouse. The resizer should still be visible and a subsequent | 250 // Release the mouse. The resizer should still be visible and a subsequent |
334 // press should not trigger a DCHECK. | 251 // press should not trigger a DCHECK. |
335 generator.ReleaseLeftButton(); | 252 generator.ReleaseLeftButton(); |
336 EXPECT_TRUE(IsShowing()); | 253 EXPECT_TRUE(IsShowing()); |
337 generator.PressLeftButton(); | 254 generator.PressLeftButton(); |
338 } | 255 } |
339 | 256 |
340 } // namespace ash | 257 } // namespace ash |
OLD | NEW |