- Revision
- 170957
- Author
- [email protected]
- Date
- 2014-07-09 23:08:58 -0700 (Wed, 09 Jul 2014)
Log Message
Fire connected/disconnected events for Gamepads.
https://bugs.webkit.org/show_bug.cgi?id=134386
Reviewed by Dean Jackson.
No new tests (No effect in a currently tested config)
* Modules/gamepad/GamepadManager.cpp:
(WebCore::navigatorGamepadFromDOMWindow): Handling converting a possibly-null Navigator into
a possibly null NavigatorGamepad.
(WebCore::GamepadManager::platformGamepadConnected): Notify blind Navigator/DOMWindows of all
previously attached Gamepads, then notify everybody of this new gamepad.
(WebCore::GamepadManager::platformGamepadDisconnected): Handle dispatching the disconnected
event to all registered DOMWindows.
(WebCore::GamepadManager::platformGamepadInputActivity): Notify blind Navigator/DOMWindows of all
attached Gamepads.
(WebCore::GamepadManager::makeGamepadVisible): Handles notifying setting up a new gamepads
with all NavigatorGamepads as well as dispatching the connected even to DOMWindows.
(WebCore::GamepadManager::registerDOMWindow):
(WebCore::GamepadManager::unregisterDOMWindow):
(WebCore::GamepadManager::makeGamepadsVisibileToBlindNavigators): Deleted.
* Modules/gamepad/GamepadManager.h:
* Modules/gamepad/NavigatorGamepad.cpp:
(WebCore::NavigatorGamepad::gamepadAtIndex):
* Modules/gamepad/NavigatorGamepad.h:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (170956 => 170957)
--- trunk/Source/WebCore/ChangeLog 2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/ChangeLog 2014-07-10 06:08:58 UTC (rev 170957)
@@ -1,3 +1,32 @@
+2014-07-09 Brady Eidson <[email protected]>
+
+ Fire connected/disconnected events for Gamepads.
+ https://bugs.webkit.org/show_bug.cgi?id=134386
+
+ Reviewed by Dean Jackson.
+
+ No new tests (No effect in a currently tested config)
+
+ * Modules/gamepad/GamepadManager.cpp:
+ (WebCore::navigatorGamepadFromDOMWindow): Handling converting a possibly-null Navigator into
+ a possibly null NavigatorGamepad.
+ (WebCore::GamepadManager::platformGamepadConnected): Notify blind Navigator/DOMWindows of all
+ previously attached Gamepads, then notify everybody of this new gamepad.
+ (WebCore::GamepadManager::platformGamepadDisconnected): Handle dispatching the disconnected
+ event to all registered DOMWindows.
+ (WebCore::GamepadManager::platformGamepadInputActivity): Notify blind Navigator/DOMWindows of all
+ attached Gamepads.
+ (WebCore::GamepadManager::makeGamepadVisible): Handles notifying setting up a new gamepads
+ with all NavigatorGamepads as well as dispatching the connected even to DOMWindows.
+ (WebCore::GamepadManager::registerDOMWindow):
+ (WebCore::GamepadManager::unregisterDOMWindow):
+ (WebCore::GamepadManager::makeGamepadsVisibileToBlindNavigators): Deleted.
+ * Modules/gamepad/GamepadManager.h:
+
+ * Modules/gamepad/NavigatorGamepad.cpp:
+ (WebCore::NavigatorGamepad::gamepadAtIndex):
+ * Modules/gamepad/NavigatorGamepad.h:
+
2014-07-09 Benjamin Poulain <[email protected]>
[iOS][WK2] Disable text quantization while actively changing the page's scale factor
Modified: trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp (170956 => 170957)
--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp 2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp 2014-07-10 06:08:58 UTC (rev 170957)
@@ -27,7 +27,10 @@
#if ENABLE(GAMEPAD)
+#include "DOMWindow.h"
+#include "Document.h"
#include "Gamepad.h"
+#include "GamepadEvent.h"
#include "GamepadProvider.h"
#include "Logging.h"
#include "NavigatorGamepad.h"
@@ -35,6 +38,15 @@
namespace WebCore {
+static NavigatorGamepad* navigatorGamepadFromDOMWindow(DOMWindow* window)
+{
+ Navigator* navigator = window->navigator();
+ if (!navigator)
+ return nullptr;
+
+ return NavigatorGamepad::from(navigator);
+}
+
GamepadManager& GamepadManager::shared()
{
static NeverDestroyed<GamepadManager> sharedManager;
@@ -48,43 +60,95 @@
void GamepadManager::platformGamepadConnected(PlatformGamepad& platformGamepad)
{
- for (auto& navigator : m_navigators) {
- if (!m_gamepadBlindNavigators.contains(navigator))
- navigator->gamepadConnected(platformGamepad);
+ // Notify blind Navigators and Windows about all gamepads except for this one.
+ for (auto* gamepad : GamepadProvider::shared().platformGamepads()) {
+ if (!gamepad || gamepad == &platformGamepad)
+ continue;
- // FIXME: Fire connected event to all pages with listeners.
+ makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
}
- makeGamepadsVisibileToBlindNavigators();
+ m_gamepadBlindNavigators.clear();
+ m_gamepadBlindDOMWindows.clear();
+
+ // Notify everyone of this new gamepad.
+ makeGamepadVisible(platformGamepad, m_navigators, m_domWindows);
}
void GamepadManager::platformGamepadDisconnected(PlatformGamepad& platformGamepad)
{
- for (auto& navigator : m_navigators) {
- if (!m_gamepadBlindNavigators.contains(navigator))
- navigator->gamepadDisconnected(platformGamepad);
+ Vector<DOMWindow*> domWindowVector;
+ copyToVector(m_domWindows, domWindowVector);
- // FIXME: Fire disconnected event to all pages with listeners.
+ HashSet<NavigatorGamepad*> notifiedNavigators;
+
+ // Handle the disconnect for all DOMWindows with event listeners and their Navigators.
+ for (auto* window : domWindowVector) {
+ // Event dispatch might have made this window go away.
+ if (!m_domWindows.contains(window))
+ continue;
+
+ NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+ if (!navigator)
+ continue;
+
+ // If this Navigator hasn't seen gamepads yet then its Window should not get the disconnect event.
+ if (m_gamepadBlindNavigators.contains(navigator))
+ continue;
+
+ RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
+ ASSERT(gamepad);
+
+ navigator->gamepadDisconnected(platformGamepad);
+ notifiedNavigators.add(navigator);
+
+ window->dispatchEvent(GamepadEvent::create(eventNames().gamepaddisconnectedEvent, gamepad.get()), window->document());
}
+
+ // Notify all the Navigators that haven't already been notified.
+ for (auto* navigator : m_navigators) {
+ if (!notifiedNavigators.contains(navigator))
+ navigator->gamepadDisconnected(platformGamepad);
+ }
}
void GamepadManager::platformGamepadInputActivity()
{
- makeGamepadsVisibileToBlindNavigators();
+ if (m_gamepadBlindNavigators.isEmpty() && m_gamepadBlindDOMWindows.isEmpty())
+ return;
+
+ for (auto* gamepad : GamepadProvider::shared().platformGamepads())
+ makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
+
+ m_gamepadBlindNavigators.clear();
+ m_gamepadBlindDOMWindows.clear();
}
-void GamepadManager::makeGamepadsVisibileToBlindNavigators()
+void GamepadManager::makeGamepadVisible(PlatformGamepad& platformGamepad, HashSet<NavigatorGamepad*>& navigatorSet, HashSet<DOMWindow*>& domWindowSet)
{
- for (auto& navigator : m_gamepadBlindNavigators) {
- // FIXME: Here we notify a blind Navigator of each existing gamepad.
- // But we also need to fire the connected event to its corresponding DOMWindow objects.
- for (auto& platformGamepad : GamepadProvider::shared().platformGamepads()) {
- if (platformGamepad)
- navigator->gamepadConnected(*platformGamepad);
- }
+ if (navigatorSet.isEmpty() && domWindowSet.isEmpty())
+ return;
+
+ for (auto* navigator : navigatorSet)
+ navigator->gamepadConnected(platformGamepad);
+
+ Vector<DOMWindow*> domWindowVector;
+ copyToVector(domWindowSet, domWindowVector);
+
+ for (auto* window : domWindowVector) {
+ // Event dispatch might have made this window go away.
+ if (!m_domWindows.contains(window))
+ continue;
+
+ NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+ if (!navigator)
+ continue;
+
+ RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
+ ASSERT(gamepad);
+
+ window->dispatchEvent(GamepadEvent::create(eventNames().gamepadconnectedEvent, gamepad.get()), window->document());
}
-
- m_gamepadBlindNavigators.clear();
}
void GamepadManager::registerNavigator(NavigatorGamepad* navigator)
@@ -116,6 +180,18 @@
ASSERT(!m_domWindows.contains(window));
m_domWindows.add(window);
+ // Anytime we register a DOMWindow, we should also double check that its NavigatorGamepad is registered.
+ NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+ ASSERT(navigator);
+
+ if (m_navigators.add(navigator).isNewEntry)
+ m_gamepadBlindNavigators.add(navigator);
+
+ // If this DOMWindow's NavigatorGamepad was already registered but was still blind,
+ // then this DOMWindow should be blind.
+ if (m_gamepadBlindNavigators.contains(navigator))
+ m_gamepadBlindDOMWindows.add(window);
+
maybeStartMonitoringGamepads();
}
@@ -125,6 +201,7 @@
ASSERT(m_domWindows.contains(window));
m_domWindows.remove(window);
+ m_gamepadBlindDOMWindows.remove(window);
maybeStopMonitoringGamepads();
}
Modified: trunk/Source/WebCore/Modules/gamepad/GamepadManager.h (170956 => 170957)
--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.h 2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.h 2014-07-10 06:08:58 UTC (rev 170957)
@@ -32,6 +32,7 @@
#include <wtf/HashSet.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/AtomicString.h>
namespace WebCore {
@@ -57,7 +58,8 @@
private:
GamepadManager();
- void makeGamepadsVisibileToBlindNavigators();
+ void makeGamepadVisible(PlatformGamepad&, HashSet<NavigatorGamepad*>&, HashSet<DOMWindow*>&);
+ void dispatchGamepadEvent(const WTF::AtomicString& eventName, PlatformGamepad&);
void maybeStartMonitoringGamepads();
void maybeStopMonitoringGamepads();
@@ -67,6 +69,7 @@
HashSet<NavigatorGamepad*> m_navigators;
HashSet<NavigatorGamepad*> m_gamepadBlindNavigators;
HashSet<DOMWindow*> m_domWindows;
+ HashSet<DOMWindow*> m_gamepadBlindDOMWindows;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp (170956 => 170957)
--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp 2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp 2014-07-10 06:08:58 UTC (rev 170957)
@@ -72,6 +72,13 @@
return supplement;
}
+Gamepad* NavigatorGamepad::gamepadAtIndex(unsigned index)
+{
+ if (index >= m_gamepads.size())
+ return nullptr;
+ return m_gamepads[index].get();
+}
+
const Vector<RefPtr<Gamepad>>& NavigatorGamepad::getGamepads(Navigator* navigator)
{
return NavigatorGamepad::from(navigator)->gamepads();
Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h (170956 => 170957)
--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h 2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h 2014-07-10 06:08:58 UTC (rev 170957)
@@ -53,6 +53,8 @@
void gamepadConnected(PlatformGamepad&);
void gamepadDisconnected(PlatformGamepad&);
+ Gamepad* gamepadAtIndex(unsigned index);
+
private:
static const char* supplementName();