Title: [135767] trunk/Source
Revision
135767
Author
jon...@apple.com
Date
2012-11-26 14:36:03 -0800 (Mon, 26 Nov 2012)

Log Message

Pass clicks through to the restarted plugin
https://bugs.webkit.org/show_bug.cgi?id=102150
<rdar://problem/12695575>

Reviewed by Simon Fraser.

Source/WebCore:

Add a new state to the machine for plugin snapshotting, called PlayingWithPendingMouseClick.
This represents the state where the plugin is playing, but before the pending mouse click
has been fired. Once the click is sent, the plugin state transitions to Playing. For
situations where the plugin just runs normally without a simulated click, the plugin state
jumps from DisplayingSnapshot straight to Playing, as before.

* html/HTMLPlugInElement.h: Add new display state to represent when the plugin is running,
but a pending mouse click is about to be sent to the plugin.
(WebCore::HTMLPlugInElement::dispatchPendingMouseClick): Called by the plugin when it is
ok for the element to send the pending mouse click.
* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::defaultEventHandler): Update the handler to pass the event
to the renderer to handle if the state is before PlayingWithPendingMouseClick.

* html/HTMLPlugInImageElement.h:
* html/HTMLPlugInImageElement.cpp: Add a click timer to delay the mouse click so that the
plugin has some time to initialize.
(WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Initialize the mouse timer.
(WebCore::HTMLPlugInImageElement::setPendingClickEvent): Keep track of the click event
the user made to restart the plugin.
(WebCore::HTMLPlugInImageElement::dispatchPendingMouseClick): Start the timer.
(WebCore::HTMLPlugInImageElement::simulatedMouseClickTimerFired): When the timer fires,
dispatch the simulated click, with mouse over, mouse down, and mouse up events. Transition
to the Playing state, and we no longer need the click event.

* rendering/RenderSnapshottedPlugIn.cpp: Change the threshold state to PlayingWithPendingMouseClick
instead of Playing, since that is the earliest state where the plugin is playing.
(WebCore::RenderSnapshottedPlugIn::paint):
(WebCore::RenderSnapshottedPlugIn::paintReplaced):
(WebCore::RenderSnapshottedPlugIn::getCursor):
(WebCore::RenderSnapshottedPlugIn::handleEvent): If the user clicked on the button, jump to
Playing, and don't send a simulated click. Otherwise, transition to PlayingWithPendingMouseClick,
and keep track of that mouse event.

* WebCore.exp.in: Export MouseRelatedEvent::offsetX() and offsetY().

Source/WebKit2:

Expose convertToRootView() as a public function for all plugins. It converts the click point
from local plugin coordinates to root view coordinates. When the events are sent to the
plugin, the coordinate gets converted back to the local reference frame.
* WebProcess/Plugins/Plugin.cpp:
(WebKit::Plugin::convertToRootView): Default implementation should not be reached.
* WebProcess/Plugins/Plugin.h: Promote convertToRootView() from NetscapePlugin.h.
* WebProcess/Plugins/Netscape/NetscapePlugin.h: An implementation already existed. Make the
method virtual.
* WebProcess/Plugins/PluginProxy.h:
* WebProcess/Plugins/PluginProxy.cpp:
(WebKit::PluginProxy::convertToRootView): Apply the transform to the provided point to return
a point in root view coordinates.

Change the threshold state to PlayingWithPendingMouseClick instead of Playing, since that is
the earliest state where the plugin is playing.
* WebProcess/Plugins/PluginView.cpp: Give the snapshot a little more time to generate.
(WebKit::PluginView::didInitializePlugin): When the plugin has initialized, tell the plugin
element to dispatch the pending mouse click.
(WebKit::PluginView::paint):
(WebKit::PluginView::createWebEvent): Helper function to convert a WebCore mouse event to a
WebMouseEvent.
(WebKit::PluginView::handleEvent): If the event is simulated, there is no source event from
the UI process. So we fabricate one based on the simulated event.
(WebKit::PluginView::invalidateRect):
(WebKit::PluginView::isAcceleratedCompositingEnabled):
* WebProcess/Plugins/PluginView.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (135766 => 135767)


--- trunk/Source/WebCore/ChangeLog	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/ChangeLog	2012-11-26 22:36:03 UTC (rev 135767)
@@ -1,3 +1,47 @@
+2012-11-26  Jon Lee  <jon...@apple.com>
+
+        Pass clicks through to the restarted plugin
+        https://bugs.webkit.org/show_bug.cgi?id=102150
+        <rdar://problem/12695575>
+
+        Reviewed by Simon Fraser.
+
+        Add a new state to the machine for plugin snapshotting, called PlayingWithPendingMouseClick.
+        This represents the state where the plugin is playing, but before the pending mouse click
+        has been fired. Once the click is sent, the plugin state transitions to Playing. For
+        situations where the plugin just runs normally without a simulated click, the plugin state
+        jumps from DisplayingSnapshot straight to Playing, as before.
+
+        * html/HTMLPlugInElement.h: Add new display state to represent when the plugin is running,
+        but a pending mouse click is about to be sent to the plugin.
+        (WebCore::HTMLPlugInElement::dispatchPendingMouseClick): Called by the plugin when it is
+        ok for the element to send the pending mouse click.
+        * html/HTMLPlugInElement.cpp:
+        (WebCore::HTMLPlugInElement::defaultEventHandler): Update the handler to pass the event
+        to the renderer to handle if the state is before PlayingWithPendingMouseClick.
+
+        * html/HTMLPlugInImageElement.h:
+        * html/HTMLPlugInImageElement.cpp: Add a click timer to delay the mouse click so that the
+        plugin has some time to initialize.
+        (WebCore::HTMLPlugInImageElement::HTMLPlugInImageElement): Initialize the mouse timer.
+        (WebCore::HTMLPlugInImageElement::setPendingClickEvent): Keep track of the click event
+        the user made to restart the plugin.
+        (WebCore::HTMLPlugInImageElement::dispatchPendingMouseClick): Start the timer.
+        (WebCore::HTMLPlugInImageElement::simulatedMouseClickTimerFired): When the timer fires,
+        dispatch the simulated click, with mouse over, mouse down, and mouse up events. Transition
+        to the Playing state, and we no longer need the click event.
+
+        * rendering/RenderSnapshottedPlugIn.cpp: Change the threshold state to PlayingWithPendingMouseClick
+        instead of Playing, since that is the earliest state where the plugin is playing.
+        (WebCore::RenderSnapshottedPlugIn::paint):
+        (WebCore::RenderSnapshottedPlugIn::paintReplaced):
+        (WebCore::RenderSnapshottedPlugIn::getCursor):
+        (WebCore::RenderSnapshottedPlugIn::handleEvent): If the user clicked on the button, jump to
+        Playing, and don't send a simulated click. Otherwise, transition to PlayingWithPendingMouseClick,
+        and keep track of that mouse event.
+
+        * WebCore.exp.in: Export MouseRelatedEvent::offsetX() and offsetY().
+
 2012-11-26  Dan Carney  <dcar...@google.com>
 
         Refactor V8 bindings to allow content scripts to access subframes

Modified: trunk/Source/WebCore/WebCore.exp.in (135766 => 135767)


--- trunk/Source/WebCore/WebCore.exp.in	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/WebCore.exp.in	2012-11-26 22:36:03 UTC (rev 135767)
@@ -491,6 +491,8 @@
 __ZN7WebCore17HistoryController33restoreScrollPositionAndViewStateEv
 __ZN7WebCore17JSDOMGlobalObject6s_infoE
 __ZN7WebCore17languageDidChangeEv
+__ZN7WebCore17MouseRelatedEvent7offsetXEv
+__ZN7WebCore17MouseRelatedEvent7offsetYEv
 __ZN7WebCore17RegularExpressionC1ERKN3WTF6StringENS1_19TextCaseSensitivityE
 __ZN7WebCore17RegularExpressionD1Ev
 __ZN7WebCore17SubresourceLoader6createEPNS_5FrameEPNS_14CachedResourceERKNS_15ResourceRequestERKNS_21ResourceLoaderOptionsE

Modified: trunk/Source/WebCore/html/HTMLPlugInElement.cpp (135766 => 135767)


--- trunk/Source/WebCore/html/HTMLPlugInElement.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/html/HTMLPlugInElement.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -201,7 +201,7 @@
             toRenderEmbeddedObject(r)->handleUnavailablePluginIndicatorEvent(event);
             return;
         }
-        if (r->isSnapshottedPlugIn() && displayState() < Playing) {
+        if (r->isSnapshottedPlugIn() && displayState() < PlayingWithPendingMouseClick) {
             toRenderSnapshottedPlugIn(r)->handleEvent(event);
             return;
         }

Modified: trunk/Source/WebCore/html/HTMLPlugInElement.h (135766 => 135767)


--- trunk/Source/WebCore/html/HTMLPlugInElement.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/html/HTMLPlugInElement.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -51,11 +51,13 @@
     enum DisplayState {
         WaitingForSnapshot,
         DisplayingSnapshot,
+        PlayingWithPendingMouseClick,
         Playing
     };
     DisplayState displayState() const { return m_displayState; }
     void setDisplayState(DisplayState state) { m_displayState = state; }
     virtual void updateSnapshot(PassRefPtr<Image>) { }
+    virtual void dispatchPendingMouseClick() { }
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
     NPObject* getNPObject();

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp (135766 => 135767)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -27,6 +27,7 @@
 #include "HTMLImageLoader.h"
 #include "HTMLNames.h"
 #include "Image.h"
+#include "MouseEvent.h"
 #include "NodeRenderStyle.h"
 #include "Page.h"
 #include "RenderEmbeddedObject.h"
@@ -38,6 +39,9 @@
 
 namespace WebCore {
 
+// This delay should not exceed the snapshot delay in PluginView.cpp
+static const double simulatedMouseClickTimerDelay = .75;
+
 HTMLPlugInImageElement::HTMLPlugInImageElement(const QualifiedName& tagName, Document* document, bool createdByParser, PreferPlugInsForImagesOption preferPlugInsForImagesOption)
     : HTMLPlugInElement(tagName, document)
     // m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
@@ -47,6 +51,7 @@
     , m_needsWidgetUpdate(!createdByParser)
     , m_shouldPreferPlugInsForImages(preferPlugInsForImagesOption == ShouldPreferPlugInsForImages)
     , m_needsDocumentActivationCallbacks(false)
+    , m_simulatedMouseClickTimer(this, &HTMLPlugInImageElement::simulatedMouseClickTimerFired, simulatedMouseClickTimerDelay)
 {
     setHasCustomCallbacks();
 
@@ -257,4 +262,26 @@
     setDisplayState(DisplayingSnapshot);
 }
 
+void HTMLPlugInImageElement::setPendingClickEvent(PassRefPtr<MouseEvent> event)
+{
+    m_pendingClickEventFromSnapshot = event;
+}
+
+void HTMLPlugInImageElement::dispatchPendingMouseClick()
+{
+    ASSERT(!m_simulatedMouseClickTimer.isActive());
+    m_simulatedMouseClickTimer.restart();
+}
+
+void HTMLPlugInImageElement::simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>*)
+{
+    ASSERT(displayState() == PlayingWithPendingMouseClick);
+    ASSERT(m_pendingClickEventFromSnapshot);
+
+    dispatchSimulatedClick(m_pendingClickEventFromSnapshot.get(), SendMouseOverUpDownEvents, DoNotShowPressedLook);
+
+    setDisplayState(Playing);
+    m_pendingClickEventFromSnapshot = nullptr;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/HTMLPlugInImageElement.h (135766 => 135767)


--- trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/html/HTMLPlugInImageElement.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -30,6 +30,7 @@
 
 class HTMLImageLoader;
 class FrameLoader;
+class MouseEvent;
 
 enum PluginCreationOption {
     CreateAnyWidgetType,
@@ -58,6 +59,8 @@
     bool needsWidgetUpdate() const { return m_needsWidgetUpdate; }
     void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
 
+    void setPendingClickEvent(PassRefPtr<MouseEvent>);
+
 protected:
     HTMLPlugInImageElement(const QualifiedName& tagName, Document*, bool createdByParser, PreferPlugInsForImagesOption);
 
@@ -91,11 +94,15 @@
     virtual bool useFallbackContent() const { return false; }
     
     virtual void updateSnapshot(PassRefPtr<Image>) OVERRIDE;
+    virtual void dispatchPendingMouseClick() OVERRIDE;
+    void simulatedMouseClickTimerFired(DeferrableOneShotTimer<HTMLPlugInImageElement>*);
 
     bool m_needsWidgetUpdate;
     bool m_shouldPreferPlugInsForImages;
     bool m_needsDocumentActivationCallbacks;
     RefPtr<RenderStyle> m_customStyleForPageCache;
+    RefPtr<MouseEvent> m_pendingClickEventFromSnapshot;
+    DeferrableOneShotTimer<HTMLPlugInImageElement> m_simulatedMouseClickTimer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp (135766 => 135767)


--- trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -72,7 +72,7 @@
 
 void RenderSnapshottedPlugIn::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
-    if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) {
+    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
         RenderReplaced::paint(paintInfo, paintOffset);
         return;
     }
@@ -82,7 +82,7 @@
 
 void RenderSnapshottedPlugIn::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
-    if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) {
+    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
         paintReplacedSnapshot(paintInfo, paintOffset);
         paintButton(paintInfo, paintOffset);
         return;
@@ -159,7 +159,7 @@
 
 CursorDirective RenderSnapshottedPlugIn::getCursor(const LayoutPoint& point, Cursor& overrideCursor) const
 {
-    if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) {
+    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
         overrideCursor = handCursor();
         return SetCursor;
     }
@@ -174,7 +174,12 @@
     MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
 
     if (event->type() == eventNames().clickEvent && mouseEvent->button() == LeftButton) {
-        plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing);
+        if (m_isMouseInButtonRect)
+            plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing);
+        else {
+            plugInImageElement()->setDisplayState(HTMLPlugInElement::PlayingWithPendingMouseClick);
+            plugInImageElement()->setPendingClickEvent(mouseEvent);
+        }
         if (widget()) {
             if (Frame* frame = document()->frame())
                 frame->loader()->client()->recreatePlugin(widget());

Modified: trunk/Source/WebKit2/ChangeLog (135766 => 135767)


--- trunk/Source/WebKit2/ChangeLog	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/ChangeLog	2012-11-26 22:36:03 UTC (rev 135767)
@@ -1,3 +1,38 @@
+2012-11-26  Jon Lee  <jon...@apple.com>
+
+        Pass clicks through to the restarted plugin
+        https://bugs.webkit.org/show_bug.cgi?id=102150
+        <rdar://problem/12695575>
+
+        Reviewed by Simon Fraser.
+
+        Expose convertToRootView() as a public function for all plugins. It converts the click point
+        from local plugin coordinates to root view coordinates. When the events are sent to the
+        plugin, the coordinate gets converted back to the local reference frame.
+        * WebProcess/Plugins/Plugin.cpp:
+        (WebKit::Plugin::convertToRootView): Default implementation should not be reached.
+        * WebProcess/Plugins/Plugin.h: Promote convertToRootView() from NetscapePlugin.h.
+        * WebProcess/Plugins/Netscape/NetscapePlugin.h: An implementation already existed. Make the
+        method virtual.
+        * WebProcess/Plugins/PluginProxy.h:
+        * WebProcess/Plugins/PluginProxy.cpp:
+        (WebKit::PluginProxy::convertToRootView): Apply the transform to the provided point to return
+        a point in root view coordinates.
+
+        Change the threshold state to PlayingWithPendingMouseClick instead of Playing, since that is
+        the earliest state where the plugin is playing.
+        * WebProcess/Plugins/PluginView.cpp: Give the snapshot a little more time to generate.
+        (WebKit::PluginView::didInitializePlugin): When the plugin has initialized, tell the plugin
+        element to dispatch the pending mouse click.
+        (WebKit::PluginView::paint):
+        (WebKit::PluginView::createWebEvent): Helper function to convert a WebCore mouse event to a
+        WebMouseEvent.
+        (WebKit::PluginView::handleEvent): If the event is simulated, there is no source event from
+        the UI process. So we fabricate one based on the simulated event.
+        (WebKit::PluginView::invalidateRect):
+        (WebKit::PluginView::isAcceleratedCompositingEnabled):
+        * WebProcess/Plugins/PluginView.h:
+
 2012-11-26  Kalev Lember  <kalevlem...@gmail.com>
 
         [GTK] Explicitly link against librt

Modified: trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -239,7 +239,7 @@
     bool supportsSnapshotting() const;
 
     // Convert the given point from plug-in coordinates to root view coordinates.
-    WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const;
+    virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const OVERRIDE;
 
     // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be
     // converted (if the transformation matrix isn't invertible).

Modified: trunk/Source/WebKit2/WebProcess/Plugins/Plugin.cpp (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/Plugin.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Plugin.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -105,4 +105,10 @@
 {
 }
 
+IntPoint Plugin::convertToRootView(const IntPoint&) const
+{
+    ASSERT_NOT_REACHED();
+    return IntPoint();
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/Plugin.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -250,6 +250,8 @@
     virtual RetainPtr<PDFDocument> pdfDocumentForPrinting() const { return 0; }
 #endif
 
+    virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint& pointInLocalCoordinates) const;
+
 protected:
     Plugin();
 

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -665,6 +665,11 @@
     controller()->invalidate(paintedRect);
 }
 
+IntPoint PluginProxy::convertToRootView(const IntPoint& point) const
+{
+    return m_pluginToRootViewTransform.mapPoint(point);
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(PLUGIN_PROCESS)

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginProxy.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -125,6 +125,8 @@
     virtual WebCore::Scrollbar* horizontalScrollbar();
     virtual WebCore::Scrollbar* verticalScrollbar();
 
+    virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const OVERRIDE;
+
     float contentsScaleFactor();
     bool needsBackingStore() const;
     bool updateBackingStore();

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp	2012-11-26 22:36:03 UTC (rev 135767)
@@ -68,7 +68,8 @@
 
 namespace WebKit {
 
-static const double pluginSnapshotTimerDelay = 1;
+// This simulated mouse click delay in HTMLPlugInImageElement.cpp should generally be the same or shorter than this delay.
+static const double pluginSnapshotTimerDelay = 1.1;
 
 class PluginView::URLRequest : public RefCounted<URLRequest> {
 public:
@@ -554,13 +555,17 @@
     redeliverManualStream();
 
 #if PLATFORM(MAC)
-    if (m_pluginElement->displayState() < HTMLPlugInElement::Playing)
+    if (m_pluginElement->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick)
         m_pluginSnapshotTimer.restart();
-    else if (m_plugin->pluginLayer()) {
-        if (frame()) {
-            frame()->view()->enterCompositingMode();
-            m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange);
+    else {
+        if (m_plugin->pluginLayer()) {
+            if (frame()) {
+                frame()->view()->enterCompositingMode();
+                m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange);
+            }
         }
+        if (m_pluginElement->displayState() < HTMLPlugInElement::Playing)
+            m_pluginElement->dispatchPendingMouseClick();
     }
 
     setWindowIsVisible(m_webPage->windowIsVisible());
@@ -686,7 +691,7 @@
 
 void PluginView::paint(GraphicsContext* context, const IntRect& /*dirtyRect*/)
 {
-    if (!m_plugin || !m_isInitialized || m_pluginElement->displayState() < HTMLPlugInElement::Playing)
+    if (!m_plugin || !m_isInitialized || m_pluginElement->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick)
         return;
 
     if (context->paintingDisabled()) {
@@ -728,12 +733,62 @@
         initializePlugin();
 }
 
+PassOwnPtr<WebEvent> PluginView::createWebEvent(MouseEvent* event) const
+{
+    WebEvent::Type type = WebEvent::NoType;
+    unsigned clickCount = 1;
+    if (event->type() == eventNames().mousedownEvent)
+        type = WebEvent::MouseDown;
+    else if (event->type() == eventNames().mouseupEvent)
+        type = WebEvent::MouseUp;
+    else if (event->type() == eventNames().mouseoverEvent) {
+        type = WebEvent::MouseMove;
+        clickCount = 0;
+    } else if (event->type() == eventNames().clickEvent)
+        return nullptr;
+    else
+        ASSERT_NOT_REACHED();
+
+    WebMouseEvent::Button button = WebMouseEvent::NoButton;
+    switch (event->button()) {
+    case WebCore::LeftButton:
+        button = WebMouseEvent::LeftButton;
+        break;
+    case WebCore::MiddleButton:
+        button = WebMouseEvent::MiddleButton;
+        break;
+    case WebCore::RightButton:
+        button = WebMouseEvent::RightButton;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+
+    unsigned modifiers = 0;
+    if (event->shiftKey())
+        modifiers |= WebEvent::ShiftKey;
+    if (event->ctrlKey())
+        modifiers |= WebEvent::ControlKey;
+    if (event->altKey())
+        modifiers |= WebEvent::AltKey;
+    if (event->metaKey())
+        modifiers |= WebEvent::MetaKey;
+
+    return adoptPtr(new WebMouseEvent(type, button, m_plugin->convertToRootView(IntPoint(event->offsetX(), event->offsetY())), event->screenLocation(), 0, 0, 0, clickCount, static_cast<WebEvent::Modifiers>(modifiers), 0));
+}
+
 void PluginView::handleEvent(Event* event)
 {
     if (!m_isInitialized || !m_plugin)
         return;
 
     const WebEvent* currentEvent = WebPage::currentEvent();
+    OwnPtr<WebEvent> simulatedWebEvent;
+    if (event->isMouseEvent() && toMouseEvent(event)->isSimulated()) {
+        simulatedWebEvent = createWebEvent(toMouseEvent(event));
+        currentEvent = simulatedWebEvent.get();
+    }
     if (!currentEvent)
         return;
 
@@ -1079,7 +1134,7 @@
         return;
 #endif
 
-    if (m_pluginElement->displayState() < HTMLPlugInElement::Playing)
+    if (m_pluginElement->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick)
         return;
 
     RenderBoxModelObject* renderer = toRenderBoxModelObject(m_pluginElement->renderer());
@@ -1237,7 +1292,7 @@
     if (!settings)
         return false;
 
-    if (m_pluginElement->displayState() < HTMLPlugInElement::Playing)
+    if (m_pluginElement->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick)
         return false;
     return settings->acceleratedCompositingEnabled();
 }

Modified: trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h (135766 => 135767)


--- trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h	2012-11-26 22:34:47 UTC (rev 135766)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PluginView.h	2012-11-26 22:36:03 UTC (rev 135767)
@@ -44,11 +44,14 @@
 namespace WebCore {
 class Frame;
 class HTMLPlugInElement;
+class MouseEvent;
 class RenderBoxModelObject;
 }
 
 namespace WebKit {
 
+class WebEvent;
+
 class PluginView : public WebCore::PluginViewBase, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener {
 public:
     static PassRefPtr<PluginView> create(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters&);
@@ -201,6 +204,8 @@
     virtual void didFinishLoad(WebFrame*);
     virtual void didFailLoad(WebFrame*, bool wasCancelled);
 
+    PassOwnPtr<WebEvent> createWebEvent(WebCore::MouseEvent*) const;
+
     RefPtr<WebCore::HTMLPlugInElement> m_pluginElement;
     RefPtr<Plugin> m_plugin;
     WebPage* m_webPage;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to