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

Unified Diff: Source/modules/gamepad/NavigatorGamepad.cpp

Issue 346273008: Gamepad: make gamepad events play well with page visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@gamepad-vis
Patch Set: PersistentHeapDequeWillBeHeapDeque Created 6 years, 5 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
« no previous file with comments | « Source/modules/gamepad/NavigatorGamepad.h ('k') | Source/platform/AsyncMethodRunner.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/gamepad/NavigatorGamepad.cpp
diff --git a/Source/modules/gamepad/NavigatorGamepad.cpp b/Source/modules/gamepad/NavigatorGamepad.cpp
index 6333946be8a506ee5138fe2e9e63869afac7b3f6..e9766a01037ce55991c53371e601805cd09177c0 100644
--- a/Source/modules/gamepad/NavigatorGamepad.cpp
+++ b/Source/modules/gamepad/NavigatorGamepad.cpp
@@ -126,6 +126,7 @@ void NavigatorGamepad::trace(Visitor* visitor)
{
visitor->trace(m_gamepads);
visitor->trace(m_webkitGamepads);
+ visitor->trace(m_pendingEvents);
WillBeHeapSupplement<Navigator>::trace(visitor);
}
@@ -152,14 +153,28 @@ void NavigatorGamepad::didUpdateData()
sampleGamepad(change.index, *gamepad, change.pad);
m_gamepads->set(change.index, gamepad);
- const AtomicString& eventName = change.pad.connected ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected;
+ m_pendingEvents.append(gamepad);
+ m_dispatchOneEventRunner.runAsync();
+}
+
+void NavigatorGamepad::dispatchOneEvent()
+{
+ ASSERT(window());
+ ASSERT(!m_pendingEvents.isEmpty());
+
+ Gamepad* gamepad = m_pendingEvents.takeFirst();
+ const AtomicString& eventName = gamepad->connected() ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected;
window()->dispatchEvent(GamepadEvent::create(eventName, false, true, gamepad));
+
+ if (!m_pendingEvents.isEmpty())
+ m_dispatchOneEventRunner.runAsync();
}
NavigatorGamepad::NavigatorGamepad(LocalFrame* frame)
: DOMWindowProperty(frame)
, DeviceEventControllerBase(frame ? frame->page() : 0)
, DOMWindowLifecycleObserver(frame ? frame->domWindow() : 0)
+ , m_dispatchOneEventRunner(this, &NavigatorGamepad::dispatchOneEvent)
{
}
@@ -187,10 +202,12 @@ void NavigatorGamepad::willDetachGlobalObjectFromFrame()
void NavigatorGamepad::registerWithDispatcher()
{
GamepadDispatcher::instance().addController(this);
+ m_dispatchOneEventRunner.resume();
}
void NavigatorGamepad::unregisterWithDispatcher()
{
+ m_dispatchOneEventRunner.suspend();
GamepadDispatcher::instance().removeController(this);
}
@@ -219,22 +236,58 @@ void NavigatorGamepad::didRemoveEventListener(LocalDOMWindow* window, const Atom
if (isGamepadEvent(eventType)
&& !window->hasEventListeners(EventTypeNames::gamepadconnected)
&& !window->hasEventListeners(EventTypeNames::gamepaddisconnected)) {
- m_hasEventListener = false;
+ didRemoveGamepadEventListeners();
}
}
void NavigatorGamepad::didRemoveAllEventListeners(LocalDOMWindow*)
{
+ didRemoveGamepadEventListeners();
+}
+
+void NavigatorGamepad::didRemoveGamepadEventListeners()
+{
m_hasEventListener = false;
+ m_dispatchOneEventRunner.stop();
+ m_pendingEvents.clear();
}
void NavigatorGamepad::pageVisibilityChanged()
{
// Inform the embedder whether it needs to provide gamepad data for us.
- if (page()->visibilityState() == PageVisibilityStateVisible && (m_hasEventListener || m_gamepads || m_webkitGamepads))
+ bool visible = page()->visibilityState() == PageVisibilityStateVisible;
+ if (visible && (m_hasEventListener || m_gamepads || m_webkitGamepads))
startUpdating();
else
stopUpdating();
+
+ if (!visible || !m_hasEventListener)
+ return;
+
+ // Tell the page what has changed. m_gamepads contains the state before we became hidden.
+ // We create a new snapshot and compare them.
+ GamepadList* oldGamepads = m_gamepads.release();
+ gamepads();
+ GamepadList* newGamepads = m_gamepads.get();
+ ASSERT(newGamepads);
+
+ for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) {
+ Gamepad* oldGamepad = oldGamepads ? oldGamepads->item(i) : 0;
+ Gamepad* newGamepad = newGamepads->item(i);
+ bool oldWasConnected = oldGamepad && oldGamepad->connected();
+ bool newIsConnected = newGamepad && newGamepad->connected();
+ bool connectedGamepadChanged = oldWasConnected && newIsConnected && oldGamepad->id() != newGamepad->id();
+ if (connectedGamepadChanged || (oldWasConnected && !newIsConnected)) {
+ oldGamepad->setConnected(false);
+ m_pendingEvents.append(oldGamepad);
+ }
+ if (connectedGamepadChanged || (!oldWasConnected && newIsConnected)) {
+ m_pendingEvents.append(newGamepad);
+ }
+ }
+
+ if (!m_pendingEvents.isEmpty())
+ m_dispatchOneEventRunner.runAsync();
}
} // namespace WebCore
« no previous file with comments | « Source/modules/gamepad/NavigatorGamepad.h ('k') | Source/platform/AsyncMethodRunner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698