summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authoroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 00:29:18 +0000
committeroshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-08 00:29:18 +0000
commit60a978b79ab70b3c9d0e26aefa6d0106cc016df2 (patch)
tree7ae6ef143e2486d1afb7dc35c08181e0a883490d /ui
parent0724a8404d68deeafb013c75eb0e954b65ed7c66 (diff)
downloadchromium_src-60a978b79ab70b3c9d0e26aefa6d0106cc016df2.zip
chromium_src-60a978b79ab70b3c9d0e26aefa6d0106cc016df2.tar.gz
chromium_src-60a978b79ab70b3c9d0e26aefa6d0106cc016df2.tar.bz2
Factor out capture code from RootWindow to CaptureClient
BUG=123160 TEST=no functional change. all test should pass. Review URL: https://chromiumcodereview.appspot.com/10525005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141131 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/aura.gyp5
-rw-r--r--ui/aura/client/capture_client.cc34
-rw-r--r--ui/aura/client/capture_client.h45
-rw-r--r--ui/aura/client/capture_delegate.h35
-rw-r--r--ui/aura/root_window.cc93
-rw-r--r--ui/aura/root_window.h30
-rw-r--r--ui/aura/root_window_host_linux.cc10
-rw-r--r--ui/aura/root_window_host_win.cc5
-rw-r--r--ui/aura/shared/compound_event_filter_unittest.cc5
-rw-r--r--ui/aura/shared/root_window_capture_client.cc56
-rw-r--r--ui/aura/shared/root_window_capture_client.h39
-rw-r--r--ui/aura/test/DEPS3
-rw-r--r--ui/aura/test/aura_test_helper.cc7
-rw-r--r--ui/aura/test/aura_test_helper.h4
-rw-r--r--ui/aura/window.cc10
-rw-r--r--ui/aura/window_unittest.cc7
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.cc4
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.h5
18 files changed, 312 insertions, 85 deletions
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index f8efe8c..0ddb6e5 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -33,6 +33,9 @@
'client/activation_delegate.h',
'client/aura_constants.cc',
'client/aura_constants.h',
+ 'client/capture_client.cc',
+ 'client/capture_client.h',
+ 'client/capture_delegate.h',
'client/dispatcher_client.cc',
'client/dispatcher_client.h',
'client/drag_drop_client.cc',
@@ -106,6 +109,8 @@
'shared/compound_event_filter.h',
'shared/input_method_event_filter.cc',
'shared/input_method_event_filter.h',
+ 'shared/root_window_capture_client.cc',
+ 'shared/root_window_capture_client.h',
'single_monitor_manager.cc',
'single_monitor_manager.h',
'ui_controls_win.cc',
diff --git a/ui/aura/client/capture_client.cc b/ui/aura/client/capture_client.cc
new file mode 100644
index 0000000..d74940a
--- /dev/null
+++ b/ui/aura/client/capture_client.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/aura/client/capture_client.h"
+
+#include "ui/aura/root_window.h"
+#include "ui/aura/window_property.h"
+
+DECLARE_WINDOW_PROPERTY_TYPE(aura::client::CaptureClient*)
+
+namespace aura {
+namespace client {
+
+DEFINE_WINDOW_PROPERTY_KEY(
+ CaptureClient*, kRootWindowCaptureClientKey, NULL);
+
+void SetCaptureClient(RootWindow* root_window, CaptureClient* client) {
+ root_window->SetProperty(kRootWindowCaptureClientKey, client);
+}
+
+CaptureClient* GetCaptureClient(RootWindow* root_window) {
+ return root_window ?
+ root_window->GetProperty(kRootWindowCaptureClientKey) : NULL;
+}
+
+Window* GetCaptureWindow(Window* window) {
+ RootWindow* root_window = window->GetRootWindow();
+ return root_window ?
+ GetCaptureClient(root_window)->GetCaptureWindow() : NULL;
+}
+
+} // namespace client
+} // namespace aura
diff --git a/ui/aura/client/capture_client.h b/ui/aura/client/capture_client.h
new file mode 100644
index 0000000..8de0aff
--- /dev/null
+++ b/ui/aura/client/capture_client.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_AURA_CLIENT_CAPTURE_CLIENT_H_
+#define UI_AURA_CLIENT_CAPTURE_CLIENT_H_
+#pragma once
+
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+class RootWindow;
+class Window;
+
+namespace client {
+
+// An interface implemented by an object that manages input capture.
+class AURA_EXPORT CaptureClient {
+ public:
+ // Does a capture on the |window|.
+ virtual void SetCapture(Window* window) = 0;
+
+ // Releases a capture from the |window|.
+ virtual void ReleaseCapture(Window* window) = 0;
+
+ // Returns the current capture window.
+ virtual Window* GetCaptureWindow() = 0;
+
+ protected:
+ virtual ~CaptureClient() {}
+};
+
+// Sets/Gets the capture client on the RootWindow.
+AURA_EXPORT void SetCaptureClient(RootWindow* root_window,
+ CaptureClient* client);
+AURA_EXPORT CaptureClient* GetCaptureClient(RootWindow* root_window);
+
+// A utility function to get the current capture window. Returns NULL
+// if the window doesn't have a root window, or there is no capture window.
+AURA_EXPORT Window* GetCaptureWindow(Window* window);
+
+} // namespace clients
+} // namespace aura
+
+#endif // UI_AURA_CLIENT_CAPTURE_CLIENT_H_
diff --git a/ui/aura/client/capture_delegate.h b/ui/aura/client/capture_delegate.h
new file mode 100644
index 0000000..340fccf
--- /dev/null
+++ b/ui/aura/client/capture_delegate.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_AURA_CLIENT_CAPTURE_DELEGATE_H_
+#define UI_AURA_CLIENT_CAPTURE_DELEGATE_H_
+#pragma once
+
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+class Window;
+namespace client {
+
+// This interface provides API to change the RootWindow's capture state
+// without 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.
+ virtual void UpdateCapture(aura::Window* old_capture,
+ aura::Window* new_capture) = 0;
+ // Sets/Release a native capture on host windows.
+ virtual void SetNativeCapture() = 0;
+ virtual void ReleaseNativeCapture() = 0;
+
+ protected:
+ virtual ~CaptureDelegate() {}
+};
+
+} // namespace client
+} // namespace aura
+
+#endif // UI_AURA_CLIENT_CAPTURE_DELEGATE_H_
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 7755e4d..88e9f89 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -13,6 +13,7 @@
#include "base/message_loop.h"
#include "ui/aura/aura_switches.h"
#include "ui/aura/client/activation_client.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/event_client.h"
#include "ui/aura/env.h"
#include "ui/aura/event.h"
@@ -114,13 +115,12 @@ bool RootWindow::hide_host_cursor_ = false;
RootWindow::RootWindow(const gfx::Rect& initial_bounds)
: Window(NULL),
- host_(aura::RootWindowHost::Create(initial_bounds)),
+ host_(RootWindowHost::Create(initial_bounds)),
ALLOW_THIS_IN_INITIALIZER_LIST(schedule_paint_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(event_factory_(this)),
mouse_button_flags_(0),
touch_ids_down_(0),
last_cursor_(ui::kCursorNull),
- capture_window_(NULL),
mouse_pressed_handler_(NULL),
mouse_moved_handler_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(
@@ -286,8 +286,8 @@ bool RootWindow::DispatchScrollEvent(ScrollEvent* event) {
last_mouse_location_ = event->location();
synthesize_mouse_move_ = false;
- Window* target =
- mouse_pressed_handler_ ? mouse_pressed_handler_ : capture_window_;
+ Window* target = mouse_pressed_handler_ ?
+ mouse_pressed_handler_ : client::GetCaptureWindow(this);
if (!target)
target = GetEventHandlerForPoint(event->location());
@@ -327,7 +327,7 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) {
event->UpdateForRootTransform(transform);
bool handled = false;
ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN;
- Window* target = capture_window_;
+ Window* target = client::GetCaptureWindow(this);
if (!target) {
target = ConsumerToWindow(
gesture_recognizer_->GetTouchLockedTarget(event));
@@ -368,7 +368,7 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) {
bool RootWindow::DispatchGestureEvent(GestureEvent* event) {
DispatchHeldMouseMove();
- Window* target = capture_window_;
+ Window* target = client::GetCaptureWindow(this);
if (!target) {
target = ConsumerToWindow(
gesture_recognizer_->GetTargetForGestureEvent(event));
@@ -464,36 +464,6 @@ void RootWindow::ConvertPointToNativeScreen(gfx::Point* point) const {
point->Offset(location.x(), location.y());
}
-void RootWindow::SetCapture(Window* window) {
- if (capture_window_ == window)
- return;
-
- gesture_recognizer_->TransferEventsTo(capture_window_, window);
-
- aura::Window* old_capture_window = capture_window_;
- capture_window_ = window;
-
- HandleMouseCaptureChanged(old_capture_window);
-
- if (capture_window_) {
- // Make all subsequent mouse events and touch go to the capture window. We
- // shouldn't need to send an event here as OnCaptureLost should take care of
- // that.
- if (mouse_moved_handler_ || mouse_button_flags_ != 0)
- mouse_moved_handler_ = capture_window_;
- } else {
- // Make sure mouse_moved_handler gets updated.
- SynthesizeMouseMoveEvent();
- }
- mouse_pressed_handler_ = NULL;
-}
-
-void RootWindow::ReleaseCapture(Window* window) {
- if (capture_window_ != window)
- return;
- SetCapture(NULL);
-}
-
void RootWindow::AdvanceQueuedTouchEvent(Window* window, bool processed) {
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
gestures.reset(gesture_recognizer_->AdvanceTouchQueue(window, processed));
@@ -628,24 +598,46 @@ FocusManager* RootWindow::GetFocusManager() {
}
////////////////////////////////////////////////////////////////////////////////
-// RootWindow, private:
+// RootWindow, overridden from aura::client::CaptureDelegate:
-void RootWindow::HandleMouseCaptureChanged(Window* old_capture_window) {
- if (capture_window_)
- host_->SetCapture();
- else
- host_->ReleaseCapture();
+void RootWindow::UpdateCapture(Window* old_capture,
+ Window* new_capture) {
+ DCHECK(!new_capture || new_capture->GetRootWindow() == this);
+ DCHECK(!old_capture || old_capture->GetRootWindow() == this);
- if (old_capture_window && old_capture_window->delegate()) {
+ if (old_capture && old_capture->delegate()) {
// Send a capture changed event with bogus location data.
MouseEvent event(
ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(), gfx::Point(), 0);
- ProcessMouseEvent(old_capture_window, &event);
+ ProcessMouseEvent(old_capture, &event);
- old_capture_window->delegate()->OnCaptureLost();
+ old_capture->delegate()->OnCaptureLost();
}
+
+ if (new_capture) {
+ // Make all subsequent mouse events and touch go to the capture window. We
+ // shouldn't need to send an event here as OnCaptureLost should take care of
+ // that.
+ if (mouse_moved_handler_ || mouse_button_flags_ != 0)
+ mouse_moved_handler_ = new_capture;
+ } else {
+ // Make sure mouse_moved_handler gets updated.
+ SynthesizeMouseMoveEvent();
+ }
+ mouse_pressed_handler_ = NULL;
}
+void RootWindow::SetNativeCapture() {
+ host_->SetCapture();
+}
+
+void RootWindow::ReleaseNativeCapture() {
+ host_->ReleaseCapture();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RootWindow, private:
+
void RootWindow::HandleMouseMoved(const MouseEvent& event, Window* target) {
if (target == mouse_moved_handler_)
return;
@@ -833,7 +825,7 @@ bool RootWindow::ProcessGestures(ui::GestureRecognizer::Gestures* gestures) {
}
void RootWindow::OnWindowRemovedFromRootWindow(Window* detached) {
- DCHECK(capture_window_ != this);
+ DCHECK(aura::client::GetCaptureWindow(this) != this);
OnWindowHidden(detached, false);
@@ -868,10 +860,11 @@ void RootWindow::OnWindowHidden(Window* invisible, bool destroyed) {
}
GetFocusManager()->SetFocusedWindow(focus_to, NULL);
}
+ Window* capture_window = aura::client::GetCaptureWindow(this);
// If the ancestor of the capture window is hidden,
// release the capture.
- if (invisible->Contains(capture_window_) && invisible != this)
- ReleaseCapture(capture_window_);
+ if (invisible->Contains(capture_window) && invisible != this)
+ capture_window->ReleaseCapture();
// If the ancestor of any event handler windows are invisible, release the
// pointer to those windows.
@@ -932,8 +925,8 @@ bool RootWindow::DispatchMouseEventImpl(MouseEvent* event) {
ui::Transform transform = layer()->transform();
transform.ConcatScale(scale, scale);
event->UpdateForRootTransform(transform);
- Window* target =
- mouse_pressed_handler_ ? mouse_pressed_handler_ : capture_window_;
+ Window* target = mouse_pressed_handler_ ?
+ mouse_pressed_handler_ : client::GetCaptureWindow(this);
if (!target)
target = GetEventHandlerForPoint(event->location());
return DispatchMouseEventToTarget(event, target);
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 336962c..141a109 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "ui/aura/aura_export.h"
+#include "ui/aura/client/capture_delegate.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/events.h"
@@ -77,7 +78,8 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
public ui::CompositorObserver,
public Window,
public ui::GestureEventHelper,
- public ui::LayerAnimationObserver {
+ public ui::LayerAnimationObserver,
+ public aura::client::CaptureDelegate {
public:
explicit RootWindow(const gfx::Rect& initial_bounds);
virtual ~RootWindow();
@@ -93,7 +95,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
gfx::Point last_mouse_location() const { return last_mouse_location_; }
gfx::NativeCursor last_cursor() const { return last_cursor_; }
Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
- Window* capture_window() { return capture_window_; }
void set_focus_manager(FocusManager* focus_manager) {
focus_manager_ = focus_manager;
@@ -127,9 +128,7 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Moves the cursor to the specified location relative to the root window.
void MoveCursorTo(const gfx::Point& location);
- // Clips the cursor movement to |capture_window_|. Should be invoked only
- // after SetCapture(). ReleaseCapture() implicitly removes any confines set
- // using this function. Returns true if successful.
+ // Clips the cursor movement to the root_window.
bool ConfineCursorToWindow();
// Draws the necessary set of windows.
@@ -194,14 +193,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// screen's.
void ConvertPointToNativeScreen(gfx::Point* point) const;
- // Capture -------------------------------------------------------------------
-
- // Sets capture to the specified window.
- void SetCapture(Window* window);
-
- // If |window| has capture, the current capture window is set to NULL.
- void ReleaseCapture(Window* window);
-
// Gesture Recognition -------------------------------------------------------
// When a touch event is dispatched to a Window, it can notify the RootWindow
@@ -268,6 +259,11 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
virtual bool CanReceiveEvents() const OVERRIDE;
virtual FocusManager* GetFocusManager() OVERRIDE;
+ // Overridden from aura::client::CaptureDelegate:
+ virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE;
+ virtual void SetNativeCapture() OVERRIDE;
+ virtual void ReleaseNativeCapture() OVERRIDE;
+
private:
friend class Window;
friend class CompositorLock;
@@ -276,10 +272,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// sending exited and entered events as its value changes.
void HandleMouseMoved(const MouseEvent& event, Window* target);
- // Called whenever the |capture_window_| changes.
- // Sends capture changed events to event filters for old capture window.
- void HandleMouseCaptureChanged(Window* old_capture_window);
-
bool ProcessMouseEvent(Window* target, MouseEvent* event);
bool ProcessKeyEvent(Window* target, KeyEvent* event);
ui::TouchStatus ProcessTouchEvent(Window* target, TouchEvent* event);
@@ -379,10 +371,6 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
ObserverList<RootWindowObserver> observers_;
- // The capture window. When not-null, this window receives all the mouse and
- // touch events.
- Window* capture_window_;
-
Window* mouse_pressed_handler_;
Window* mouse_moved_handler_;
FocusManager* focus_manager_;
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index c9fe9c2..aa71322 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -18,6 +18,7 @@
#include "base/stringprintf.h"
#include "grit/ui_resources_standard.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/user_action_client.h"
#include "ui/aura/dispatcher_linux.h"
#include "ui/aura/env.h"
@@ -610,8 +611,11 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
break;
}
case FocusOut:
- if (xev->xfocus.mode != NotifyGrab)
- root_window_->SetCapture(NULL);
+ if (xev->xfocus.mode != NotifyGrab) {
+ Window* capture_window = client::GetCaptureWindow(root_window_);
+ if (capture_window && capture_window->GetRootWindow() == root_window_)
+ capture_window->ReleaseCapture();
+ }
break;
case ConfigureNotify: {
DCHECK_EQ(xwindow_, xev->xconfigure.window);
@@ -834,9 +838,11 @@ gfx::Point RootWindowHostLinux::GetLocationOnNativeScreen() const {
}
void RootWindowHostLinux::SetCapture() {
+ // TODO(oshima): Grab x input.
}
void RootWindowHostLinux::ReleaseCapture() {
+ // TODO(oshima): Release x input.
}
void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) {
diff --git a/ui/aura/root_window_host_win.cc b/ui/aura/root_window_host_win.cc
index bedc179..d04b352 100644
--- a/ui/aura/root_window_host_win.cc
+++ b/ui/aura/root_window_host_win.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include "base/message_loop.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/env.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
@@ -330,7 +331,9 @@ LRESULT RootWindowHostWin::OnCaptureChanged(UINT message,
LPARAM l_param) {
if (has_capture_) {
has_capture_ = false;
- root_window_->SetCapture(NULL);
+ Window* capture_window = client::GetCaptureWindow(root_window_);
+ if (capture_window && capture_window->GetRootWindow() == root_window_)
+ capture_window->ReleaseCapture();
}
return 0;
}
diff --git a/ui/aura/shared/compound_event_filter_unittest.cc b/ui/aura/shared/compound_event_filter_unittest.cc
index ef98222..85ecc47 100644
--- a/ui/aura/shared/compound_event_filter_unittest.cc
+++ b/ui/aura/shared/compound_event_filter_unittest.cc
@@ -8,6 +8,7 @@
#include "ui/aura/cursor_manager.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
+#include "ui/aura/shared/root_window_capture_client.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_activation_client.h"
#include "ui/aura/test/test_windows.h"
@@ -27,11 +28,13 @@ TEST_F(CompoundEventFilterTest, TouchHidesCursor) {
aura::Env::GetInstance()->SetEventFilter(new shared::CompoundEventFilter());
aura::client::SetActivationClient(root_window(),
new TestActivationClient(root_window()));
+ aura::client::SetCaptureClient(
+ root_window(), new shared::RootWindowCaptureClient(root_window()));
TestWindowDelegate delegate;
scoped_ptr<Window> window(CreateTestWindowWithDelegate(&delegate, 1234,
gfx::Rect(5, 5, 100, 100), NULL));
window->Show();
- root_window()->SetCapture(window.get());
+ window->SetCapture();
CursorManager* cursor_manager = aura::Env::GetInstance()->cursor_manager();
MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
diff --git a/ui/aura/shared/root_window_capture_client.cc b/ui/aura/shared/root_window_capture_client.cc
new file mode 100644
index 0000000..0608dad
--- /dev/null
+++ b/ui/aura/shared/root_window_capture_client.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/aura/shared/root_window_capture_client.h"
+
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+
+namespace aura {
+namespace shared {
+
+////////////////////////////////////////////////////////////////////////////////
+// RootWindowCaptureClient, public:
+
+RootWindowCaptureClient::RootWindowCaptureClient(RootWindow* root_window)
+ : root_window_(root_window),
+ capture_window_(NULL) {
+ client::SetCaptureClient(root_window, this);
+}
+
+RootWindowCaptureClient::~RootWindowCaptureClient() {
+ client::SetCaptureClient(root_window_, NULL);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RootWindowCaptureClient, client::CaptureClient implementation:
+
+void RootWindowCaptureClient::SetCapture(Window* window) {
+ if (capture_window_ == window)
+ return;
+ root_window_->gesture_recognizer()->TransferEventsTo(capture_window_, window);
+
+ aura::Window* old_capture_window = capture_window_;
+ capture_window_ = window;
+
+ if (capture_window_)
+ root_window_->SetNativeCapture();
+ else
+ root_window_->ReleaseNativeCapture();
+
+ root_window_->UpdateCapture(old_capture_window, capture_window_);
+}
+
+void RootWindowCaptureClient::ReleaseCapture(Window* window) {
+ if (capture_window_ != window)
+ return;
+ SetCapture(NULL);
+}
+
+Window* RootWindowCaptureClient::GetCaptureWindow() {
+ return capture_window_;
+}
+
+} // namespace shared
+} // namespace aura
diff --git a/ui/aura/shared/root_window_capture_client.h b/ui/aura/shared/root_window_capture_client.h
new file mode 100644
index 0000000..ee979b5
--- /dev/null
+++ b/ui/aura/shared/root_window_capture_client.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_AURA_SHARED_ROOT_WINDOW_CAPTURE_CLIENT_H_
+#define UI_AURA_SHARED_ROOT_WINDOW_CAPTURE_CLIENT_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/client/capture_client.h"
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+class RootWindow;
+
+namespace shared {
+
+class AURA_EXPORT RootWindowCaptureClient : public client::CaptureClient {
+ public:
+ explicit RootWindowCaptureClient(RootWindow* root_window);
+ virtual ~RootWindowCaptureClient();
+
+ // Overridden from client::CaptureClient:
+ virtual void SetCapture(Window* window) OVERRIDE;
+ virtual void ReleaseCapture(Window* window) OVERRIDE;
+ virtual Window* GetCaptureWindow() OVERRIDE;
+
+ private:
+ RootWindow* root_window_;
+ Window* capture_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(RootWindowCaptureClient);
+};
+
+} // namespace shared
+} // namespace aura
+
+#endif // UI_AURA_SHARED_ROOT_WINDOW_CAPTURE_CLIENT_H_
diff --git a/ui/aura/test/DEPS b/ui/aura/test/DEPS
new file mode 100644
index 0000000..6c07d07
--- /dev/null
+++ b/ui/aura/test/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+ui/aura/shared", # Test code can include shared code.
+]
diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc
index 12f4657..c8549ba 100644
--- a/ui/aura/test/aura_test_helper.cc
+++ b/ui/aura/test/aura_test_helper.cc
@@ -10,6 +10,7 @@
#include "ui/aura/focus_manager.h"
#include "ui/aura/monitor_manager.h"
#include "ui/aura/root_window.h"
+#include "ui/aura/shared/root_window_capture_client.h"
#include "ui/aura/single_monitor_manager.h"
#include "ui/aura/test/test_activation_client.h"
#include "ui/aura/test/test_screen.h"
@@ -23,7 +24,6 @@
namespace aura {
namespace test {
-
AuraTestHelper::AuraTestHelper(MessageLoopForUI* message_loop)
: setup_called_(false),
teardown_called_(false),
@@ -52,7 +52,9 @@ void AuraTestHelper::SetUp() {
root_window_->set_focus_manager(focus_manager_.get());
stacking_client_.reset(new TestStackingClient(root_window_.get()));
test_activation_client_.reset(
- new aura::test::TestActivationClient(root_window_.get()));
+ new test::TestActivationClient(root_window_.get()));
+ root_window_capture_client_.reset(
+ new shared::RootWindowCaptureClient(root_window_.get()));
test_input_method_.reset(new ui::test::DummyInputMethod);
root_window_->SetProperty(
aura::client::kRootWindowInputMethodKey,
@@ -68,6 +70,7 @@ void AuraTestHelper::TearDown() {
test_input_method_.reset();
stacking_client_.reset();
test_activation_client_.reset();
+ root_window_capture_client_.reset();
focus_manager_.reset();
root_window_.reset();
aura::Env::DeleteInstance();
diff --git a/ui/aura/test/aura_test_helper.h b/ui/aura/test/aura_test_helper.h
index 94f2846..3cbaa8d 100644
--- a/ui/aura/test/aura_test_helper.h
+++ b/ui/aura/test/aura_test_helper.h
@@ -22,6 +22,9 @@ class InputMethod;
namespace aura {
class FocusManager;
class RootWindow;
+namespace shared {
+class RootWindowCaptureClient;
+}
namespace test {
class TestActivationClient;
class TestStackingClient;
@@ -54,6 +57,7 @@ class AuraTestHelper {
scoped_ptr<RootWindow> root_window_;
scoped_ptr<TestStackingClient> stacking_client_;
scoped_ptr<TestActivationClient> test_activation_client_;
+ scoped_ptr<shared::RootWindowCaptureClient> root_window_capture_client_;
scoped_ptr<ui::InputMethod> test_input_method_;
scoped_ptr<FocusManager> focus_manager_;
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index ef3a8b9..db35362 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -13,6 +13,7 @@
#include "base/stl_util.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/event_client.h"
#include "ui/aura/client/stacking_client.h"
#include "ui/aura/client/visibility_client.h"
@@ -517,21 +518,20 @@ void Window::SetCapture() {
RootWindow* root_window = GetRootWindow();
if (!root_window)
return;
-
- root_window->SetCapture(this);
+ client::GetCaptureClient(root_window)->SetCapture(this);
}
void Window::ReleaseCapture() {
RootWindow* root_window = GetRootWindow();
if (!root_window)
return;
-
- root_window->ReleaseCapture(this);
+ client::GetCaptureClient(root_window)->ReleaseCapture(this);
}
bool Window::HasCapture() {
RootWindow* root_window = GetRootWindow();
- return root_window && root_window->capture_window() == this;
+ return root_window &&
+ client::GetCaptureClient(root_window)->GetCaptureWindow() == this;
}
void Window::SuppressPaint() {
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 94c80fe..bda4a76 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/stacking_client.h"
#include "ui/aura/client/visibility_client.h"
#include "ui/aura/event.h"
@@ -608,10 +609,10 @@ TEST_F(WindowTest, CaptureTests) {
// Removing the capture window from parent should reset the capture window
// in the root window.
window->SetCapture();
- EXPECT_EQ(window.get(), root_window()->capture_window());
+ EXPECT_EQ(window.get(), aura::client::GetCaptureWindow(root_window()));
window->parent()->RemoveChild(window.get());
EXPECT_FALSE(window->HasCapture());
- EXPECT_EQ(NULL, root_window()->capture_window());
+ EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
}
TEST_F(WindowTest, TouchCaptureCancelsOtherTouches) {
@@ -794,7 +795,7 @@ TEST_F(WindowTest, ReleaseCaptureOnDestroy) {
// Make sure the root window doesn't reference the window anymore.
EXPECT_EQ(NULL, root_window()->mouse_pressed_handler());
- EXPECT_EQ(NULL, root_window()->capture_window());
+ EXPECT_EQ(NULL, aura::client::GetCaptureWindow(root_window()));
}
TEST_F(WindowTest, GetBoundsInRootWindow) {
diff --git a/ui/views/widget/desktop_native_widget_helper_aura.cc b/ui/views/widget/desktop_native_widget_helper_aura.cc
index 0f1b799..efc0493 100644
--- a/ui/views/widget/desktop_native_widget_helper_aura.cc
+++ b/ui/views/widget/desktop_native_widget_helper_aura.cc
@@ -13,6 +13,7 @@
#include "ui/aura/root_window.h"
#include "ui/aura/shared/compound_event_filter.h"
#include "ui/aura/shared/input_method_event_filter.h"
+#include "ui/aura/shared/root_window_capture_client.h"
#include "ui/views/widget/native_widget_aura.h"
#if defined(OS_WIN)
@@ -126,6 +127,9 @@ void DesktopNativeWidgetHelperAura::PreInitialize(
input_method_filter_->SetInputMethodPropertyInRootWindow(root_window_.get());
root_window_event_filter_->AddFilter(input_method_filter_.get());
+ capture_client_.reset(
+ new aura::shared::RootWindowCaptureClient(root_window_.get()));
+
aura::DesktopActivationClient* activation_client =
new aura::DesktopActivationClient(root_window_.get());
diff --git a/ui/views/widget/desktop_native_widget_helper_aura.h b/ui/views/widget/desktop_native_widget_helper_aura.h
index 203b0d8..6f89bfc 100644
--- a/ui/views/widget/desktop_native_widget_helper_aura.h
+++ b/ui/views/widget/desktop_native_widget_helper_aura.h
@@ -20,6 +20,7 @@ class ScreenPositionClient;
namespace shared {
class CompoundEventFilter;
class InputMethodEventFilter;
+class RootWindowCaptureClient;
}
}
@@ -71,6 +72,10 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura
// An event filter that pre-handles all key events to send them to an IME.
scoped_ptr<aura::shared::InputMethodEventFilter> input_method_filter_;
+ // TODO(erg): This is temporary. Find out what needs to be done for desktop
+ // environment.
+ scoped_ptr<aura::shared::RootWindowCaptureClient> capture_client_;
+
// We want some windows (omnibox, status bar) to have their own
// NativeWidgetAura, but still act as if they're screen bounded toplevel
// windows.