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"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/base/ui_base_paths.h"
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.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();
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::RegisterPathProvider();
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::FilePath ui_test_pak_path;
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ViewsTestBase::SetUp();
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// This class provides functionality to verify whether the View instance
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// received the gesture event.
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class DesktopViewInputTest : public View {
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DesktopViewInputTest()
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : received_gesture_event_(false) {}
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    received_gesture_event_ = true;
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return View::OnGestureEvent(event);
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Resets state maintained by this class.
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void Reset() {
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    received_gesture_event_ = false;
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool received_gesture_event() const { return received_gesture_event_; }
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool received_gesture_event_;
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest);
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)views::Widget* CreateWidget() {
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  views::Widget* widget = new views::Widget;
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  views::Widget::InitParams params;
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  params.accept_events = true;
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  params.native_widget = new DesktopNativeWidgetAura(widget);
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  params.bounds = gfx::Rect(0, 0, 200, 100);
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  widget->Init(params);
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  widget->Show();
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return widget;
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Verifies mouse handlers are reset when a window gains capture. Specifically
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// creates two widgets, does a mouse press in one, sets capture in the other and
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// verifies state is reset in the first.
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) {
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<Widget> w1(CreateWidget());
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<Widget> w2(CreateWidget());
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow());
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  generator1.MoveMouseToCenterOf(w1->GetNativeView());
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  generator1.PressLeftButton();
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(w1->HasCapture());
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::WindowEventDispatcher* w1_dispatcher =
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      w1->GetNativeView()->GetHost()->dispatcher();
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() != NULL);
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() != NULL);
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  w2->SetCapture(w2->GetRootView());
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(w2->HasCapture());
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(w1_dispatcher->mouse_pressed_handler() == NULL);
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(w1_dispatcher->mouse_moved_handler() == NULL);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  w2->ReleaseCapture();
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  RunPendingMessages();
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests aura::Window capture and whether gesture events are sent to the window
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// which has capture.
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// The test case creates two visible widgets and sets capture to the underlying
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// aura::Windows one by one. It then sends a gesture event and validates whether
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// the window which had capture receives the gesture.
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(sky): move this test, it should be part of ScopedCaptureClient tests.
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) {
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<Widget> widget1(new Widget());
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<wm::ScopedCaptureClient> scoped_capture_client(
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new wm::ScopedCaptureClient(params.context->GetRootWindow()));
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  aura::client::CaptureClient* capture_client =
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      scoped_capture_client->capture_client();
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  params.bounds = gfx::Rect(50, 50, 650, 650);
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  widget1->Init(params);
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  internal::RootView* root1 =
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      static_cast<internal::RootView*>(widget1->GetRootView());
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  desktop_position_client1.reset(
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new DesktopScreenPositionClient(params.context->GetRootWindow()));
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  aura::client::SetScreenPositionClient(
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      widget1->GetNativeView()->GetRootWindow(),
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      desktop_position_client1.get());
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DesktopViewInputTest* v1 = new DesktopViewInputTest();
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  v1->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  root1->AddChildView(v1);
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  widget1->Show();
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<Widget> widget2(new Widget());
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  params = CreateParams(Widget::InitParams::TYPE_POPUP);
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  params.bounds = gfx::Rect(50, 50, 650, 650);
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  widget2->Init(params);
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  internal::RootView* root2 =
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      static_cast<internal::RootView*>(widget2->GetRootView());
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  desktop_position_client2.reset(
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new DesktopScreenPositionClient(params.context->GetRootWindow()));
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  aura::client::SetScreenPositionClient(
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      widget2->GetNativeView()->GetRootWindow(),
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      desktop_position_client2.get());
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ui::EventDispatchDetails details;
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DesktopViewInputTest* v2 = new DesktopViewInputTest();
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  v2->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  root2->AddChildView(v2);
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  widget2->Show();
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(widget1->GetNativeView()->HasCapture());
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<aura::Window*>(0),
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            capture_client->GetCaptureWindow());
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  widget1->GetNativeView()->SetCapture();
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(widget1->GetNativeView()->HasCapture());
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(widget2->GetNativeView()->HasCapture());
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(capture_client->GetCaptureWindow(), widget1->GetNativeView());
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ui::GestureEvent g1(80,
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      80,
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      0,
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      base::TimeDelta(),
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
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