13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/capture_controller.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/logging.h" 823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/path_service.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/env.h" 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/test/event_generator.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_tree_host.h" 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/ui_base_paths.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/gl/gl_surface.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/test/views_test_base.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/view.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/root_view.h" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/widget.h" 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// NOTE: these tests do native capture, so they have to be in 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// interactive_ui_tests. 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace views { 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class DesktopCaptureControllerTest : public ViewsTestBase { 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public: 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DesktopCaptureControllerTest() {} 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual ~DesktopCaptureControllerTest() {} 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void SetUp() OVERRIDE { 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) gfx::GLSurface::InitializeOneOffForTests(); 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::FilePath pak_dir; 3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) PathService::Get(base::DIR_MODULE, &pak_dir); 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::FilePath pak_file; 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) pak_file = pak_dir.Append(FILE_PATH_LITERAL("ui_test.pak")); 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ViewsTestBase::SetUp(); 4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This class provides functionality to verify whether the View instance 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// received the gesture event. 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class DesktopViewInputTest : public View { 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DesktopViewInputTest() 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : received_gesture_event_(false) {} 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) received_gesture_event_ = true; 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return View::OnGestureEvent(event); 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Resets state maintained by this class. 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void Reset() { 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) received_gesture_event_ = false; 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool received_gesture_event() const { return received_gesture_event_; } 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool received_gesture_event_; 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest); 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)views::Widget* CreateWidget() { 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) views::Widget* widget = new views::Widget; 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) views::Widget::InitParams params; 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) params.accept_events = true; 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) params.native_widget = new DesktopNativeWidgetAura(widget); 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) params.bounds = gfx::Rect(0, 0, 200, 100); 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) widget->Init(params); 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) widget->Show(); 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return widget; 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Verifies mouse handlers are reset when a window gains capture. Specifically 861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// creates two widgets, does a mouse press in one, sets capture in the other and 871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// verifies state is reset in the first. 881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) { 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<Widget> w1(CreateWidget()); 901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<Widget> w2(CreateWidget()); 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow()); 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) generator1.MoveMouseToCenterOf(w1->GetNativeView()); 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) generator1.PressLeftButton(); 941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_FALSE(w1->HasCapture()); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::WindowEventDispatcher* w1_dispatcher = 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) w1->GetNativeView()->GetHost()->dispatcher(); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() != NULL); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() != NULL); 991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) w2->SetCapture(w2->GetRootView()); 1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_TRUE(w2->HasCapture()); 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() == NULL); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() == NULL); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) w2->ReleaseCapture(); 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RunPendingMessages(); 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests aura::Window capture and whether gesture events are sent to the window 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// which has capture. 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The test case creates two visible widgets and sets capture to the underlying 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// aura::Windows one by one. It then sends a gesture event and validates whether 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// the window which had capture receives the gesture. 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(sky): move this test, it should be part of ScopedCaptureClient tests. 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) { 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1; 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2; 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<Widget> widget1(new Widget()); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<wm::ScopedCaptureClient> scoped_capture_client( 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new wm::ScopedCaptureClient(params.context->GetRootWindow())); 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::client::CaptureClient* capture_client = 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_capture_client->capture_client(); 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.bounds = gfx::Rect(50, 50, 650, 650); 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget1->Init(params); 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) internal::RootView* root1 = 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<internal::RootView*>(widget1->GetRootView()); 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) desktop_position_client1.reset( 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new DesktopScreenPositionClient(params.context->GetRootWindow())); 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::client::SetScreenPositionClient( 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget1->GetNativeView()->GetRootWindow(), 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) desktop_position_client1.get()); 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DesktopViewInputTest* v1 = new DesktopViewInputTest(); 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) root1->AddChildView(v1); 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget1->Show(); 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<Widget> widget2(new Widget()); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params = CreateParams(Widget::InitParams::TYPE_POPUP); 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params.bounds = gfx::Rect(50, 50, 650, 650); 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget2->Init(params); 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) internal::RootView* root2 = 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) static_cast<internal::RootView*>(widget2->GetRootView()); 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) desktop_position_client2.reset( 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new DesktopScreenPositionClient(params.context->GetRootWindow())); 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) aura::client::SetScreenPositionClient( 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget2->GetNativeView()->GetRootWindow(), 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) desktop_position_client2.get()); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::EventDispatchDetails details; 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DesktopViewInputTest* v2 = new DesktopViewInputTest(); 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) root2->AddChildView(v2); 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget2->Show(); 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(widget1->GetNativeView()->HasCapture()); 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(widget2->GetNativeView()->HasCapture()); 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(reinterpret_cast<aura::Window*>(0), 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) capture_client->GetCaptureWindow()); 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget1->GetNativeView()->SetCapture(); 1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(widget1->GetNativeView()->HasCapture()); 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(widget2->GetNativeView()->HasCapture()); 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(capture_client->GetCaptureWindow(), widget1->GetNativeView()); 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::GestureEvent g1(ui::ET_GESTURE_LONG_PRESS, 80, 80, 0, 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::TimeDelta(), 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS, 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0.0f, 0.0f), 0); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) details = root1->OnEventFromSource(&g1); 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(details.dispatcher_destroyed); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(details.target_destroyed); 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(v1->received_gesture_event()); 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(v2->received_gesture_event()); 1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) v1->Reset(); 1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) v2->Reset(); 1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget2->GetNativeView()->SetCapture(); 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(widget1->GetNativeView()->HasCapture()); 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(widget2->GetNativeView()->HasCapture()); 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(capture_client->GetCaptureWindow(), widget2->GetNativeView()); 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) details = root2->OnEventFromSource(&g1); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(details.dispatcher_destroyed); 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(details.target_destroyed); 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(v2->received_gesture_event()); 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_FALSE(v1->received_gesture_event()); 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget1->CloseNow(); 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) widget2->CloseNow(); 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RunPendingMessages(); 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace views 203