summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/aura/client/capture_delegate.h11
-rw-r--r--ui/aura/root_window.cc5
-rw-r--r--ui/aura/root_window.h1
-rw-r--r--ui/views/corewm/desktop_capture_controller_unittest.cc33
-rw-r--r--ui/views/widget/desktop_aura/desktop_capture_client.cc25
-rw-r--r--ui/views/widget/desktop_aura/desktop_capture_client.h6
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);
};