| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/views/widget/native_widget_aura.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/command_line.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 #include "ui/aura/client/aura_constants.h" | |
| 13 #include "ui/aura/env.h" | |
| 14 #include "ui/aura/layout_manager.h" | |
| 15 #include "ui/aura/test/aura_test_base.h" | |
| 16 #include "ui/aura/window.h" | |
| 17 #include "ui/aura/window_tree_host.h" | |
| 18 #include "ui/events/event.h" | |
| 19 #include "ui/events/event_utils.h" | |
| 20 #include "ui/gfx/screen.h" | |
| 21 #include "ui/views/layout/fill_layout.h" | |
| 22 #include "ui/views/widget/root_view.h" | |
| 23 #include "ui/views/widget/widget_delegate.h" | |
| 24 #include "ui/wm/core/default_activation_client.h" | |
| 25 | |
| 26 namespace views { | |
| 27 namespace { | |
| 28 | |
| 29 NativeWidgetAura* Init(aura::Window* parent, Widget* widget) { | |
| 30 Widget::InitParams params(Widget::InitParams::TYPE_POPUP); | |
| 31 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 32 params.parent = parent; | |
| 33 widget->Init(params); | |
| 34 return static_cast<NativeWidgetAura*>(widget->native_widget()); | |
| 35 } | |
| 36 | |
| 37 class NativeWidgetAuraTest : public aura::test::AuraTestBase { | |
| 38 public: | |
| 39 NativeWidgetAuraTest() {} | |
| 40 virtual ~NativeWidgetAuraTest() {} | |
| 41 | |
| 42 // testing::Test overrides: | |
| 43 virtual void SetUp() override { | |
| 44 AuraTestBase::SetUp(); | |
| 45 new wm::DefaultActivationClient(root_window()); | |
| 46 host()->SetBounds(gfx::Rect(640, 480)); | |
| 47 } | |
| 48 | |
| 49 private: | |
| 50 DISALLOW_COPY_AND_ASSIGN(NativeWidgetAuraTest); | |
| 51 }; | |
| 52 | |
| 53 TEST_F(NativeWidgetAuraTest, CenterWindowLargeParent) { | |
| 54 // Make a parent window larger than the host represented by | |
| 55 // WindowEventDispatcher. | |
| 56 scoped_ptr<aura::Window> parent(new aura::Window(NULL)); | |
| 57 parent->Init(aura::WINDOW_LAYER_NOT_DRAWN); | |
| 58 parent->SetBounds(gfx::Rect(0, 0, 1024, 800)); | |
| 59 scoped_ptr<Widget> widget(new Widget()); | |
| 60 NativeWidgetAura* window = Init(parent.get(), widget.get()); | |
| 61 | |
| 62 window->CenterWindow(gfx::Size(100, 100)); | |
| 63 EXPECT_EQ(gfx::Rect( (640 - 100) / 2, | |
| 64 (480 - 100) / 2, | |
| 65 100, 100), | |
| 66 window->GetNativeWindow()->bounds()); | |
| 67 widget->CloseNow(); | |
| 68 } | |
| 69 | |
| 70 TEST_F(NativeWidgetAuraTest, CenterWindowSmallParent) { | |
| 71 // Make a parent window smaller than the host represented by | |
| 72 // WindowEventDispatcher. | |
| 73 scoped_ptr<aura::Window> parent(new aura::Window(NULL)); | |
| 74 parent->Init(aura::WINDOW_LAYER_NOT_DRAWN); | |
| 75 parent->SetBounds(gfx::Rect(0, 0, 480, 320)); | |
| 76 scoped_ptr<Widget> widget(new Widget()); | |
| 77 NativeWidgetAura* window = Init(parent.get(), widget.get()); | |
| 78 | |
| 79 window->CenterWindow(gfx::Size(100, 100)); | |
| 80 EXPECT_EQ(gfx::Rect( (480 - 100) / 2, | |
| 81 (320 - 100) / 2, | |
| 82 100, 100), | |
| 83 window->GetNativeWindow()->bounds()); | |
| 84 widget->CloseNow(); | |
| 85 } | |
| 86 | |
| 87 // Verifies CenterWindow() constrains to parent size. | |
| 88 TEST_F(NativeWidgetAuraTest, CenterWindowSmallParentNotAtOrigin) { | |
| 89 // Make a parent window smaller than the host represented by | |
| 90 // WindowEventDispatcher and offset it slightly from the origin. | |
| 91 scoped_ptr<aura::Window> parent(new aura::Window(NULL)); | |
| 92 parent->Init(aura::WINDOW_LAYER_NOT_DRAWN); | |
| 93 parent->SetBounds(gfx::Rect(20, 40, 480, 320)); | |
| 94 scoped_ptr<Widget> widget(new Widget()); | |
| 95 NativeWidgetAura* window = Init(parent.get(), widget.get()); | |
| 96 window->CenterWindow(gfx::Size(500, 600)); | |
| 97 | |
| 98 // |window| should be no bigger than |parent|. | |
| 99 EXPECT_EQ("20,40 480x320", window->GetNativeWindow()->bounds().ToString()); | |
| 100 widget->CloseNow(); | |
| 101 } | |
| 102 | |
| 103 class TestLayoutManagerBase : public aura::LayoutManager { | |
| 104 public: | |
| 105 TestLayoutManagerBase() {} | |
| 106 virtual ~TestLayoutManagerBase() {} | |
| 107 | |
| 108 // aura::LayoutManager: | |
| 109 virtual void OnWindowResized() override {} | |
| 110 virtual void OnWindowAddedToLayout(aura::Window* child) override {} | |
| 111 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) override {} | |
| 112 virtual void OnWindowRemovedFromLayout(aura::Window* child) override {} | |
| 113 virtual void OnChildWindowVisibilityChanged(aura::Window* child, | |
| 114 bool visible) override {} | |
| 115 virtual void SetChildBounds(aura::Window* child, | |
| 116 const gfx::Rect& requested_bounds) override {} | |
| 117 | |
| 118 private: | |
| 119 DISALLOW_COPY_AND_ASSIGN(TestLayoutManagerBase); | |
| 120 }; | |
| 121 | |
| 122 // Used by ShowMaximizedDoesntBounceAround. See it for details. | |
| 123 class MaximizeLayoutManager : public TestLayoutManagerBase { | |
| 124 public: | |
| 125 MaximizeLayoutManager() {} | |
| 126 virtual ~MaximizeLayoutManager() {} | |
| 127 | |
| 128 private: | |
| 129 // aura::LayoutManager: | |
| 130 virtual void OnWindowAddedToLayout(aura::Window* child) override { | |
| 131 // This simulates what happens when adding a maximized window. | |
| 132 SetChildBoundsDirect(child, gfx::Rect(0, 0, 300, 300)); | |
| 133 } | |
| 134 | |
| 135 DISALLOW_COPY_AND_ASSIGN(MaximizeLayoutManager); | |
| 136 }; | |
| 137 | |
| 138 // This simulates BrowserView, which creates a custom RootView so that | |
| 139 // OnNativeWidgetSizeChanged that is invoked during Init matters. | |
| 140 class TestWidget : public views::Widget { | |
| 141 public: | |
| 142 TestWidget() : did_size_change_more_than_once_(false) { | |
| 143 } | |
| 144 | |
| 145 // Returns true if the size changes to a non-empty size, and then to another | |
| 146 // size. | |
| 147 bool did_size_change_more_than_once() const { | |
| 148 return did_size_change_more_than_once_; | |
| 149 } | |
| 150 | |
| 151 virtual void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override { | |
| 152 if (last_size_.IsEmpty()) | |
| 153 last_size_ = new_size; | |
| 154 else if (!did_size_change_more_than_once_ && new_size != last_size_) | |
| 155 did_size_change_more_than_once_ = true; | |
| 156 Widget::OnNativeWidgetSizeChanged(new_size); | |
| 157 } | |
| 158 | |
| 159 private: | |
| 160 bool did_size_change_more_than_once_; | |
| 161 gfx::Size last_size_; | |
| 162 | |
| 163 DISALLOW_COPY_AND_ASSIGN(TestWidget); | |
| 164 }; | |
| 165 | |
| 166 // Verifies the size of the widget doesn't change more than once during Init if | |
| 167 // the window ends up maximized. This is important as otherwise | |
| 168 // RenderWidgetHostViewAura ends up getting resized during construction, which | |
| 169 // leads to noticable flashes. | |
| 170 TEST_F(NativeWidgetAuraTest, ShowMaximizedDoesntBounceAround) { | |
| 171 root_window()->SetBounds(gfx::Rect(0, 0, 640, 480)); | |
| 172 root_window()->SetLayoutManager(new MaximizeLayoutManager); | |
| 173 scoped_ptr<TestWidget> widget(new TestWidget()); | |
| 174 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); | |
| 175 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 176 params.parent = NULL; | |
| 177 params.context = root_window(); | |
| 178 params.show_state = ui::SHOW_STATE_MAXIMIZED; | |
| 179 params.bounds = gfx::Rect(10, 10, 100, 200); | |
| 180 widget->Init(params); | |
| 181 EXPECT_FALSE(widget->did_size_change_more_than_once()); | |
| 182 widget->CloseNow(); | |
| 183 } | |
| 184 | |
| 185 class PropertyTestLayoutManager : public TestLayoutManagerBase { | |
| 186 public: | |
| 187 PropertyTestLayoutManager() : added_(false) {} | |
| 188 virtual ~PropertyTestLayoutManager() {} | |
| 189 | |
| 190 bool added() const { return added_; } | |
| 191 | |
| 192 private: | |
| 193 // aura::LayoutManager: | |
| 194 virtual void OnWindowAddedToLayout(aura::Window* child) override { | |
| 195 EXPECT_TRUE(child->GetProperty(aura::client::kCanMaximizeKey)); | |
| 196 EXPECT_TRUE(child->GetProperty(aura::client::kCanMinimizeKey)); | |
| 197 EXPECT_TRUE(child->GetProperty(aura::client::kCanResizeKey)); | |
| 198 added_ = true; | |
| 199 } | |
| 200 | |
| 201 bool added_; | |
| 202 | |
| 203 DISALLOW_COPY_AND_ASSIGN(PropertyTestLayoutManager); | |
| 204 }; | |
| 205 | |
| 206 class PropertyTestWidgetDelegate : public views::WidgetDelegate { | |
| 207 public: | |
| 208 explicit PropertyTestWidgetDelegate(Widget* widget) : widget_(widget) {} | |
| 209 virtual ~PropertyTestWidgetDelegate() {} | |
| 210 | |
| 211 private: | |
| 212 // views::WidgetDelegate: | |
| 213 virtual bool CanMaximize() const override { | |
| 214 return true; | |
| 215 } | |
| 216 virtual bool CanMinimize() const override { | |
| 217 return true; | |
| 218 } | |
| 219 virtual bool CanResize() const override { | |
| 220 return true; | |
| 221 } | |
| 222 virtual void DeleteDelegate() override { | |
| 223 delete this; | |
| 224 } | |
| 225 virtual Widget* GetWidget() override { | |
| 226 return widget_; | |
| 227 } | |
| 228 virtual const Widget* GetWidget() const override { | |
| 229 return widget_; | |
| 230 } | |
| 231 | |
| 232 Widget* widget_; | |
| 233 DISALLOW_COPY_AND_ASSIGN(PropertyTestWidgetDelegate); | |
| 234 }; | |
| 235 | |
| 236 // Verifies that the kCanMaximizeKey/kCanMinimizeKey/kCanResizeKey have the | |
| 237 // correct value when added to the layout manager. | |
| 238 TEST_F(NativeWidgetAuraTest, TestPropertiesWhenAddedToLayout) { | |
| 239 root_window()->SetBounds(gfx::Rect(0, 0, 640, 480)); | |
| 240 PropertyTestLayoutManager* layout_manager = new PropertyTestLayoutManager(); | |
| 241 root_window()->SetLayoutManager(layout_manager); | |
| 242 scoped_ptr<TestWidget> widget(new TestWidget()); | |
| 243 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); | |
| 244 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 245 params.delegate = new PropertyTestWidgetDelegate(widget.get()); | |
| 246 params.parent = NULL; | |
| 247 params.context = root_window(); | |
| 248 widget->Init(params); | |
| 249 EXPECT_TRUE(layout_manager->added()); | |
| 250 widget->CloseNow(); | |
| 251 } | |
| 252 | |
| 253 TEST_F(NativeWidgetAuraTest, GetClientAreaScreenBounds) { | |
| 254 // Create a widget. | |
| 255 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); | |
| 256 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 257 params.context = root_window(); | |
| 258 params.bounds.SetRect(10, 20, 300, 400); | |
| 259 scoped_ptr<Widget> widget(new Widget()); | |
| 260 widget->Init(params); | |
| 261 | |
| 262 // For Aura, client area bounds match window bounds. | |
| 263 gfx::Rect client_bounds = widget->GetClientAreaBoundsInScreen(); | |
| 264 EXPECT_EQ(10, client_bounds.x()); | |
| 265 EXPECT_EQ(20, client_bounds.y()); | |
| 266 EXPECT_EQ(300, client_bounds.width()); | |
| 267 EXPECT_EQ(400, client_bounds.height()); | |
| 268 } | |
| 269 | |
| 270 // View subclass that tracks whether it has gotten a gesture event. | |
| 271 class GestureTrackingView : public views::View { | |
| 272 public: | |
| 273 GestureTrackingView() | |
| 274 : got_gesture_event_(false), | |
| 275 consume_gesture_event_(true) {} | |
| 276 | |
| 277 void set_consume_gesture_event(bool value) { | |
| 278 consume_gesture_event_ = value; | |
| 279 } | |
| 280 | |
| 281 void clear_got_gesture_event() { | |
| 282 got_gesture_event_ = false; | |
| 283 } | |
| 284 bool got_gesture_event() const { | |
| 285 return got_gesture_event_; | |
| 286 } | |
| 287 | |
| 288 // View overrides: | |
| 289 virtual void OnGestureEvent(ui::GestureEvent* event) override { | |
| 290 got_gesture_event_ = true; | |
| 291 if (consume_gesture_event_) | |
| 292 event->StopPropagation(); | |
| 293 } | |
| 294 | |
| 295 private: | |
| 296 // Was OnGestureEvent() invoked? | |
| 297 bool got_gesture_event_; | |
| 298 | |
| 299 // Dictates what OnGestureEvent() returns. | |
| 300 bool consume_gesture_event_; | |
| 301 | |
| 302 DISALLOW_COPY_AND_ASSIGN(GestureTrackingView); | |
| 303 }; | |
| 304 | |
| 305 // Verifies a capture isn't set on touch press and that the view that gets | |
| 306 // the press gets the release. | |
| 307 TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) { | |
| 308 // Create two views (both sized the same). |child| is configured not to | |
| 309 // consume the gesture event. | |
| 310 GestureTrackingView* view = new GestureTrackingView(); | |
| 311 GestureTrackingView* child = new GestureTrackingView(); | |
| 312 child->set_consume_gesture_event(false); | |
| 313 view->SetLayoutManager(new FillLayout); | |
| 314 view->AddChildView(child); | |
| 315 scoped_ptr<TestWidget> widget(new TestWidget()); | |
| 316 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
| 317 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 318 params.context = root_window(); | |
| 319 params.bounds = gfx::Rect(0, 0, 100, 200); | |
| 320 widget->Init(params); | |
| 321 widget->SetContentsView(view); | |
| 322 widget->Show(); | |
| 323 | |
| 324 ui::TouchEvent press( | |
| 325 ui::ET_TOUCH_PRESSED, gfx::Point(41, 51), 1, ui::EventTimeForNow()); | |
| 326 ui::EventDispatchDetails details = | |
| 327 event_processor()->OnEventFromSource(&press); | |
| 328 ASSERT_FALSE(details.dispatcher_destroyed); | |
| 329 // Both views should get the press. | |
| 330 EXPECT_TRUE(view->got_gesture_event()); | |
| 331 EXPECT_TRUE(child->got_gesture_event()); | |
| 332 view->clear_got_gesture_event(); | |
| 333 child->clear_got_gesture_event(); | |
| 334 // Touch events should not automatically grab capture. | |
| 335 EXPECT_FALSE(widget->HasCapture()); | |
| 336 | |
| 337 // Release touch. Only |view| should get the release since that it consumed | |
| 338 // the press. | |
| 339 ui::TouchEvent release( | |
| 340 ui::ET_TOUCH_RELEASED, gfx::Point(250, 251), 1, ui::EventTimeForNow()); | |
| 341 details = event_processor()->OnEventFromSource(&release); | |
| 342 ASSERT_FALSE(details.dispatcher_destroyed); | |
| 343 EXPECT_TRUE(view->got_gesture_event()); | |
| 344 EXPECT_FALSE(child->got_gesture_event()); | |
| 345 view->clear_got_gesture_event(); | |
| 346 | |
| 347 // Work around for bug in NativeWidgetAura. | |
| 348 // TODO: fix bug and remove this. | |
| 349 widget->Close(); | |
| 350 } | |
| 351 | |
| 352 // Verifies views with layers are targeted for events properly. | |
| 353 TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) { | |
| 354 // Create two widgets: |parent| and |child|. |child| is a child of |parent|. | |
| 355 views::View* parent_root = new views::View; | |
| 356 scoped_ptr<Widget> parent(new Widget()); | |
| 357 Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
| 358 parent_params.ownership = | |
| 359 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 360 parent_params.context = root_window(); | |
| 361 parent->Init(parent_params); | |
| 362 parent->SetContentsView(parent_root); | |
| 363 parent->SetBounds(gfx::Rect(0, 0, 400, 400)); | |
| 364 parent->Show(); | |
| 365 | |
| 366 scoped_ptr<Widget> child(new Widget()); | |
| 367 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL); | |
| 368 child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 369 child_params.parent = parent->GetNativeWindow(); | |
| 370 child->Init(child_params); | |
| 371 child->SetBounds(gfx::Rect(0, 0, 200, 200)); | |
| 372 child->Show(); | |
| 373 | |
| 374 // Point is over |child|. | |
| 375 EXPECT_EQ(child->GetNativeWindow(), | |
| 376 parent->GetNativeWindow()->GetEventHandlerForPoint( | |
| 377 gfx::Point(50, 50))); | |
| 378 | |
| 379 // Create a view with a layer and stack it at the bottom (below |child|). | |
| 380 views::View* view_with_layer = new views::View; | |
| 381 parent_root->AddChildView(view_with_layer); | |
| 382 view_with_layer->SetBounds(0, 0, 50, 50); | |
| 383 view_with_layer->SetPaintToLayer(true); | |
| 384 | |
| 385 // Make sure that |child| still gets the event. | |
| 386 EXPECT_EQ(child->GetNativeWindow(), | |
| 387 parent->GetNativeWindow()->GetEventHandlerForPoint( | |
| 388 gfx::Point(20, 20))); | |
| 389 | |
| 390 // Move |view_with_layer| to the top and make sure it gets the | |
| 391 // event when the point is within |view_with_layer|'s bounds. | |
| 392 view_with_layer->layer()->parent()->StackAtTop( | |
| 393 view_with_layer->layer()); | |
| 394 EXPECT_EQ(parent->GetNativeWindow(), | |
| 395 parent->GetNativeWindow()->GetEventHandlerForPoint( | |
| 396 gfx::Point(20, 20))); | |
| 397 | |
| 398 // Point is over |child|, it should get the event. | |
| 399 EXPECT_EQ(child->GetNativeWindow(), | |
| 400 parent->GetNativeWindow()->GetEventHandlerForPoint( | |
| 401 gfx::Point(70, 70))); | |
| 402 | |
| 403 delete view_with_layer; | |
| 404 view_with_layer = NULL; | |
| 405 | |
| 406 EXPECT_EQ(child->GetNativeWindow(), | |
| 407 parent->GetNativeWindow()->GetEventHandlerForPoint( | |
| 408 gfx::Point(20, 20))); | |
| 409 | |
| 410 // Work around for bug in NativeWidgetAura. | |
| 411 // TODO: fix bug and remove this. | |
| 412 parent->Close(); | |
| 413 } | |
| 414 | |
| 415 // Verifies that widget->FlashFrame() sets aura::client::kDrawAttentionKey, | |
| 416 // and activating the window clears it. | |
| 417 TEST_F(NativeWidgetAuraTest, FlashFrame) { | |
| 418 scoped_ptr<Widget> widget(new Widget()); | |
| 419 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); | |
| 420 params.context = root_window(); | |
| 421 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 422 widget->Init(params); | |
| 423 aura::Window* window = widget->GetNativeWindow(); | |
| 424 EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey)); | |
| 425 widget->FlashFrame(true); | |
| 426 EXPECT_TRUE(window->GetProperty(aura::client::kDrawAttentionKey)); | |
| 427 widget->FlashFrame(false); | |
| 428 EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey)); | |
| 429 widget->FlashFrame(true); | |
| 430 EXPECT_TRUE(window->GetProperty(aura::client::kDrawAttentionKey)); | |
| 431 widget->Activate(); | |
| 432 EXPECT_FALSE(window->GetProperty(aura::client::kDrawAttentionKey)); | |
| 433 } | |
| 434 | |
| 435 TEST_F(NativeWidgetAuraTest, NoCrashOnThemeAfterClose) { | |
| 436 scoped_ptr<aura::Window> parent(new aura::Window(NULL)); | |
| 437 parent->Init(aura::WINDOW_LAYER_NOT_DRAWN); | |
| 438 parent->SetBounds(gfx::Rect(0, 0, 480, 320)); | |
| 439 scoped_ptr<Widget> widget(new Widget()); | |
| 440 Init(parent.get(), widget.get()); | |
| 441 widget->Show(); | |
| 442 widget->Close(); | |
| 443 base::MessageLoop::current()->RunUntilIdle(); | |
| 444 widget->GetNativeTheme(); // Shouldn't crash. | |
| 445 } | |
| 446 | |
| 447 // Used to track calls to WidgetDelegate::OnWidgetMove(). | |
| 448 class MoveTestWidgetDelegate : public WidgetDelegateView { | |
| 449 public: | |
| 450 MoveTestWidgetDelegate() : got_move_(false) {} | |
| 451 virtual ~MoveTestWidgetDelegate() {} | |
| 452 | |
| 453 void ClearGotMove() { got_move_ = false; } | |
| 454 bool got_move() const { return got_move_; } | |
| 455 | |
| 456 // WidgetDelegate overrides: | |
| 457 virtual void OnWidgetMove() override { got_move_ = true; } | |
| 458 | |
| 459 private: | |
| 460 bool got_move_; | |
| 461 | |
| 462 DISALLOW_COPY_AND_ASSIGN(MoveTestWidgetDelegate); | |
| 463 }; | |
| 464 | |
| 465 // This test simulates what happens when a window is normally maximized. That | |
| 466 // is, it's layer is acquired for animation then the window is maximized. | |
| 467 // Acquiring the layer resets the bounds of the window. This test verifies the | |
| 468 // Widget is still notified correctly of a move in this case. | |
| 469 TEST_F(NativeWidgetAuraTest, OnWidgetMovedInvokedAfterAcquireLayer) { | |
| 470 // |delegate| deletes itself when the widget is destroyed. | |
| 471 MoveTestWidgetDelegate* delegate = new MoveTestWidgetDelegate; | |
| 472 Widget* widget = | |
| 473 Widget::CreateWindowWithContextAndBounds(delegate, | |
| 474 root_window(), | |
| 475 gfx::Rect(10, 10, 100, 200)); | |
| 476 widget->Show(); | |
| 477 delegate->ClearGotMove(); | |
| 478 // Simulate a maximize with animation. | |
| 479 delete widget->GetNativeView()->RecreateLayer().release(); | |
| 480 widget->SetBounds(gfx::Rect(0, 0, 500, 500)); | |
| 481 EXPECT_TRUE(delegate->got_move()); | |
| 482 widget->CloseNow(); | |
| 483 } | |
| 484 | |
| 485 } // namespace | |
| 486 } // namespace views | |
| OLD | NEW |