diff options
-rw-r--r-- | ui/aura/client/capture_delegate.h | 11 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 5 | ||||
-rw-r--r-- | ui/aura/root_window.h | 1 | ||||
-rw-r--r-- | ui/views/corewm/desktop_capture_controller_unittest.cc | 33 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_capture_client.cc | 25 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_capture_client.h | 6 |
6 files changed, 67 insertions, 14 deletions
diff --git a/ui/aura/client/capture_delegate.h b/ui/aura/client/capture_delegate.h index 3f3c691..7ebcaee 100644 --- a/ui/aura/client/capture_delegate.h +++ b/ui/aura/client/capture_delegate.h @@ -15,11 +15,16 @@ namespace client { // exposing them as RootWindow API. class AURA_EXPORT CaptureDelegate { public: - // Called when a capture is set on the |new_capture| which is owned by - // this root window, and/or a capture is released on the |old_capture| - // which is owned by this root window. + // Called when a capture is set on |new_capture| and/or a capture is + // released on |old_capture|. + // NOTE: |old_capture| and |new_capture| are not necessarily contained in the + // window hierarchy of the delegate. virtual void UpdateCapture(aura::Window* old_capture, aura::Window* new_capture) = 0; + + // Called when another root gets capture. + virtual void OnOtherRootGotCapture() = 0; + // Sets/Release a native capture on host windows. virtual void SetNativeCapture() = 0; virtual void ReleaseNativeCapture() = 0; diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index 8cecf47..6aa65fe 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -738,6 +738,11 @@ void RootWindow::UpdateCapture(Window* old_capture, mouse_pressed_handler_ = NULL; } +void RootWindow::OnOtherRootGotCapture() { + mouse_moved_handler_ = NULL; + mouse_pressed_handler_ = NULL; +} + void RootWindow::SetNativeCapture() { host_->SetCapture(); } diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index bbbc9b0..ad4c3eb 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -304,6 +304,7 @@ class AURA_EXPORT RootWindow : public Window, // Overridden from aura::client::CaptureDelegate: virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE; + virtual void OnOtherRootGotCapture() OVERRIDE; virtual void SetNativeCapture() OVERRIDE; virtual void ReleaseNativeCapture() OVERRIDE; diff --git a/ui/views/corewm/desktop_capture_controller_unittest.cc b/ui/views/corewm/desktop_capture_controller_unittest.cc index 8811be5..9661c98 100644 --- a/ui/views/corewm/desktop_capture_controller_unittest.cc +++ b/ui/views/corewm/desktop_capture_controller_unittest.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" +#include "ui/aura/test/event_generator.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/events/event.h" #include "ui/views/test/views_test_base.h" @@ -48,6 +49,38 @@ class DesktopViewInputTest : public View { DISALLOW_COPY_AND_ASSIGN(DesktopViewInputTest); }; +views::Widget* CreateWidget() { + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; + params.accept_events = true; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.native_widget = new DesktopNativeWidgetAura(widget); + params.bounds = gfx::Rect(0, 0, 200, 100); + widget->Init(params); + widget->Show(); + return widget; +} + +// Verifies mouse handlers are reset when a window gains capture. Specifically +// creates two widgets, does a mouse press in one, sets capture in the other and +// verifies state is reset in the first. +TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) { + scoped_ptr<Widget> w1(CreateWidget()); + scoped_ptr<Widget> w2(CreateWidget()); + aura::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow()); + generator1.MoveMouseToCenterOf(w1->GetNativeView()); + generator1.PressLeftButton(); + EXPECT_FALSE(w1->HasCapture()); + aura::RootWindow* w1_root = w1->GetNativeView()->GetRootWindow(); + EXPECT_TRUE(w1_root->mouse_pressed_handler() != NULL); + EXPECT_TRUE(w1_root->mouse_moved_handler() != NULL); + w2->SetCapture(w2->GetRootView()); + EXPECT_TRUE(w2->HasCapture()); + EXPECT_TRUE(w1_root->mouse_pressed_handler() == NULL); + EXPECT_TRUE(w1_root->mouse_moved_handler() == NULL); +} + // Tests aura::Window capture and whether gesture events are sent to the window // which has capture. // The test case creates two visible widgets and sets capture to the underlying diff --git a/ui/views/widget/desktop_aura/desktop_capture_client.cc b/ui/views/widget/desktop_aura/desktop_capture_client.cc index 5a5ec4e..a6348a9 100644 --- a/ui/views/widget/desktop_aura/desktop_capture_client.cc +++ b/ui/views/widget/desktop_aura/desktop_capture_client.cc @@ -10,20 +10,21 @@ namespace views { // static -DesktopCaptureClient::Roots* DesktopCaptureClient::roots_ = NULL; +DesktopCaptureClient::CaptureClients* +DesktopCaptureClient::capture_clients_ = NULL; DesktopCaptureClient::DesktopCaptureClient(aura::RootWindow* root) : root_(root), capture_window_(NULL) { - if (!roots_) - roots_ = new Roots; - roots_->insert(root_); + if (!capture_clients_) + capture_clients_ = new CaptureClients; + capture_clients_->insert(this); aura::client::SetCaptureClient(root, this); } DesktopCaptureClient::~DesktopCaptureClient() { aura::client::SetCaptureClient(root_, NULL); - roots_->erase(root_); + capture_clients_->erase(this); } void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) { @@ -38,9 +39,6 @@ void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) { aura::Window* old_capture_window = capture_window_; - // Copy the set in case it's modified out from under us. - Roots roots(*roots_); - // If we're actually starting capture, then cancel any touches/gestures // that aren't already locked to the new window, and transfer any on the // old capture window to the new one. When capture is released we have no @@ -62,6 +60,17 @@ void DesktopCaptureClient::SetCapture(aura::Window* new_capture_window) { delegate->ReleaseNativeCapture(); } else if (!old_capture_window) { delegate->SetNativeCapture(); + + // Notify the other roots that we got capture. This is important so that + // they reset state. + CaptureClients capture_clients(*capture_clients_); + for (CaptureClients::iterator i = capture_clients.begin(); + i != capture_clients.end(); ++i) { + if (*i != this) { + aura::client::CaptureDelegate* delegate = (*i)->root_; + delegate->OnOtherRootGotCapture(); + } + } } // else case is capture is remaining in our root, nothing to do. } diff --git a/ui/views/widget/desktop_aura/desktop_capture_client.h b/ui/views/widget/desktop_aura/desktop_capture_client.h index 5445f29..5f8cecf 100644 --- a/ui/views/widget/desktop_aura/desktop_capture_client.h +++ b/ui/views/widget/desktop_aura/desktop_capture_client.h @@ -31,13 +31,13 @@ class VIEWS_EXPORT DesktopCaptureClient : public aura::client::CaptureClient { virtual aura::Window* GetCaptureWindow() OVERRIDE; private: - typedef std::set<aura::RootWindow*> Roots; + typedef std::set<DesktopCaptureClient*> CaptureClients; aura::RootWindow* root_; aura::Window* capture_window_; - // Set of RootWindows DesktopCaptureClient has been created for. - static Roots* roots_; + // Set of DesktopCaptureClients. + static CaptureClients* capture_clients_; DISALLOW_COPY_AND_ASSIGN(DesktopCaptureClient); }; |