Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Unified Diff: content/renderer/pepper_plugin_delegate_impl.cc

Issue 7863003: Mouse lock implementation, including the renderer side and the Windows version of the browser side. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove two tab chars. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/pepper_plugin_delegate_impl.cc
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc
index 1bb13eefc8dfab4c78398712dc96c88470ec8bc1..999b1f53ef918505550060919e0097bfda2c3d33 100644
--- a/content/renderer/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper_plugin_delegate_impl.cc
@@ -52,8 +52,10 @@
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_preferences.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserCompletion.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -650,10 +652,15 @@ PepperPluginDelegateImpl::PepperPluginDelegateImpl(RenderView* render_view)
has_saved_context_menu_action_(false),
saved_context_menu_action_(0),
id_generator_(0),
- is_pepper_plugin_focused_(false) {
+ is_pepper_plugin_focused_(false),
+ mouse_lock_owner_(NULL),
+ mouse_locked_(false),
+ pending_lock_request_(false),
+ pending_unlock_request_(false) {
}
PepperPluginDelegateImpl::~PepperPluginDelegateImpl() {
+ DCHECK(!mouse_lock_owner_);
}
scoped_refptr<webkit::ppapi::PluginModule>
@@ -837,6 +844,8 @@ void PepperPluginDelegateImpl::PluginCrashed(
webkit::ppapi::PluginInstance* instance) {
subscribed_to_policy_updates_.erase(instance);
render_view_->PluginCrashed(instance->module()->path());
+
+ UnlockMouse(instance);
}
void PepperPluginDelegateImpl::InstanceCreated(
@@ -851,6 +860,14 @@ void PepperPluginDelegateImpl::InstanceDeleted(
webkit::ppapi::PluginInstance* instance) {
active_instances_.erase(instance);
subscribed_to_policy_updates_.erase(instance);
+
+ if (mouse_lock_owner_ && mouse_lock_owner_ == instance) {
+ // UnlockMouse() will determine whether a ViewHostMsg_UnlockMouse needs to
+ // be sent, and set internal state properly. We only need to forget about
+ // the current |mouse_lock_owner_|.
+ UnlockMouse(mouse_lock_owner_);
+ mouse_lock_owner_ = NULL;
+ }
}
SkBitmap* PepperPluginDelegateImpl::GetSadPluginBitmap() {
@@ -1011,7 +1028,7 @@ void PepperPluginDelegateImpl::OnAsyncFileOpened(
void PepperPluginDelegateImpl::OnSetFocus(bool has_focus) {
for (std::set<webkit::ppapi::PluginInstance*>::iterator i =
- active_instances_.begin();
+ active_instances_.begin();
i != active_instances_.end(); ++i)
(*i)->SetContentAreaFocus(has_focus);
}
@@ -1020,6 +1037,64 @@ bool PepperPluginDelegateImpl::IsPluginFocused() const {
return is_pepper_plugin_focused_;
}
+void PepperPluginDelegateImpl::OnLockMouseACK(bool succeeded) {
+ DCHECK(!mouse_locked_ && pending_lock_request_);
+
+ mouse_locked_ = succeeded;
+ pending_lock_request_ = false;
+ if (pending_unlock_request_ && !succeeded) {
+ // We have sent an unlock request after the lock request. However, since
+ // the lock request has failed, the unlock request will be ignored by the
+ // browser side and there won't be any response to it.
+ pending_unlock_request_ = false;
+ }
+ // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL.
+ if (mouse_lock_owner_) {
+ webkit::ppapi::PluginInstance* last_mouse_lock_owner = mouse_lock_owner_;
+ if (!succeeded) {
+ // Reset |mouse_lock_owner_| to NULL before calling OnLockMouseACK(), so
+ // that if OnLockMouseACK() results in calls to any mouse lock method
+ // (e.g., LockMouse()), the method will see consistent internal state.
+ mouse_lock_owner_ = NULL;
+ }
+
+ last_mouse_lock_owner->OnLockMouseACK(succeeded ? PP_OK : PP_ERROR_FAILED);
+ }
+}
+
+void PepperPluginDelegateImpl::OnMouseLockLost() {
+ DCHECK(mouse_locked_ && !pending_lock_request_);
+
+ mouse_locked_ = false;
+ pending_unlock_request_ = false;
+ // If the PluginInstance has been deleted, |mouse_lock_owner_| can be NULL.
+ if (mouse_lock_owner_) {
+ // Reset |mouse_lock_owner_| to NULL before calling OnMouseLockLost(), so
+ // that if OnMouseLockLost() results in calls to any mouse lock method
+ // (e.g., LockMouse()), the method will see consistent internal state.
+ webkit::ppapi::PluginInstance* last_mouse_lock_owner = mouse_lock_owner_;
+ mouse_lock_owner_ = NULL;
+
+ last_mouse_lock_owner->OnMouseLockLost();
+ }
+}
+
+bool PepperPluginDelegateImpl::DispatchLockedMouseEvent(
+ const WebKit::WebMouseEvent& event) {
+ if (mouse_locked_) {
+ if (mouse_lock_owner_) {
+ // |cursor_info| is ignored since it is hidden when the mouse is locked.
+ WebKit::WebCursorInfo cursor_info;
+ mouse_lock_owner_->HandleInputEvent(event, &cursor_info);
+ }
+
+ // If the mouse is locked, only the current owner of the mouse lock can
+ // process mouse events.
+ return true;
+ }
+ return false;
+}
+
bool PepperPluginDelegateImpl::OpenFileSystem(
const GURL& url,
fileapi::FileSystemType type,
@@ -1474,6 +1549,58 @@ ppapi::Preferences PepperPluginDelegateImpl::GetPreferences() {
return ppapi::Preferences(render_view_->webkit_preferences());
}
+void PepperPluginDelegateImpl::LockMouse(
+ webkit::ppapi::PluginInstance* instance) {
+ DCHECK(instance);
+ if (!MouseLockedOrPending()) {
+ DCHECK(!mouse_lock_owner_);
+ pending_lock_request_ = true;
+ mouse_lock_owner_ = instance;
+
+ render_view_->Send(
+ new ViewHostMsg_LockMouse(render_view_->routing_id()));
+ } else if (instance != mouse_lock_owner_) {
+ // Another plugin instance is using mouse lock. Fail immediately.
+ instance->OnLockMouseACK(PP_ERROR_FAILED);
+ } else {
+ if (mouse_locked_) {
+ instance->OnLockMouseACK(PP_OK);
+ } else if (pending_lock_request_) {
+ instance->OnLockMouseACK(PP_ERROR_INPROGRESS);
+ } else {
+ // The only case left here is
+ // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_,
+ // which is not possible.
+ NOTREACHED();
+ instance->OnLockMouseACK(PP_ERROR_FAILED);
+ }
+ }
+}
+
+void PepperPluginDelegateImpl::UnlockMouse(
+ webkit::ppapi::PluginInstance* instance) {
+ DCHECK(instance);
+
+ // If no one is using mouse lock or the user is not |instance|, ignore
+ // the unlock request.
+ if (MouseLockedOrPending() && mouse_lock_owner_ == instance) {
+ if (mouse_locked_ || pending_lock_request_) {
+ DCHECK(!mouse_locked_ || !pending_lock_request_);
+ if (!pending_unlock_request_) {
+ pending_unlock_request_ = true;
+
+ render_view_->Send(
+ new ViewHostMsg_UnlockMouse(render_view_->routing_id()));
+ }
+ } else {
+ // The only case left here is
+ // !mouse_locked_ && !pending_lock_request_ && pending_unlock_request_,
+ // which is not possible.
+ NOTREACHED();
+ }
+ }
+}
+
int PepperPluginDelegateImpl::GetRoutingId() const {
return render_view_->routing_id();
}

Powered by Google App Engine
This is Rietveld 408576698