зеркало из https://github.com/mozilla/gecko-dev.git
Bug 376679 part.2 EventStateManager should treat plugin frame as scrollable frame if the plugin wants to handle wheel events as default action r=smaug
This commit is contained in:
Родитель
1376b5162b
Коммит
5f2c3f035e
|
@ -50,6 +50,7 @@
|
|||
#include "nsIContentViewer.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "nsPluginFrame.h"
|
||||
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
|
@ -2346,6 +2347,13 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
// hasn't moved.
|
||||
nsIFrame* lastScrollFrame = WheelTransaction::GetTargetFrame();
|
||||
if (lastScrollFrame) {
|
||||
if (aOptions & INCLUDE_PLUGIN_AS_TARGET) {
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(lastScrollFrame);
|
||||
if (pluginFrame &&
|
||||
pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
|
||||
return lastScrollFrame;
|
||||
}
|
||||
}
|
||||
nsIScrollableFrame* scrollableFrame =
|
||||
lastScrollFrame->GetScrollTargetFrame();
|
||||
if (scrollableFrame) {
|
||||
|
@ -2375,6 +2383,18 @@ EventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
|
|||
// Check whether the frame wants to provide us with a scrollable view.
|
||||
nsIScrollableFrame* scrollableFrame = scrollFrame->GetScrollTargetFrame();
|
||||
if (!scrollableFrame) {
|
||||
// If the frame is a plugin frame, then, the plugin content may handle
|
||||
// wheel events. Only when the caller computes the scroll target for
|
||||
// default action handling, we should assume the plugin frame as
|
||||
// scrollable if the plugin wants to handle wheel events as default
|
||||
// action.
|
||||
if (aOptions & INCLUDE_PLUGIN_AS_TARGET) {
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(scrollFrame);
|
||||
if (pluginFrame &&
|
||||
pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
|
||||
return scrollFrame;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -3121,10 +3141,23 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* scrollTarget =
|
||||
do_QueryFrame(ComputeScrollTarget(aTargetFrame, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET));
|
||||
nsIFrame* frameToScroll =
|
||||
ComputeScrollTarget(aTargetFrame, wheelEvent,
|
||||
COMPUTE_DEFAULT_ACTION_TARGET);
|
||||
|
||||
// XXX Temporarily, we should check if the target is a plugin frame
|
||||
// here. In the following patch, this should be checked before
|
||||
// checking wheel action since if the default action handler is
|
||||
// a plugin, our pref shouldn't decide the default action.
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
|
||||
if (pluginFrame) {
|
||||
// XXX Needs to work with WheelTransaction, will be fixed in
|
||||
// the following patch.
|
||||
pluginFrame->HandleWheelEventAsDefaultAction(wheelEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* scrollTarget = do_QueryFrame(frameToScroll);
|
||||
ScrollbarsForWheel::SetActiveScrollTarget(scrollTarget);
|
||||
|
||||
nsIFrame* rootScrollFrame = !aTargetFrame ? nullptr :
|
||||
|
|
|
@ -617,10 +617,11 @@ protected:
|
|||
// COMPUTE_*.
|
||||
enum
|
||||
{
|
||||
PREFER_MOUSE_WHEEL_TRANSACTION = 1,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS = 2,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS = 4,
|
||||
START_FROM_PARENT = 8
|
||||
PREFER_MOUSE_WHEEL_TRANSACTION = 0x00000001,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS = 0x00000002,
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS = 0x00000004,
|
||||
START_FROM_PARENT = 0x00000008,
|
||||
INCLUDE_PLUGIN_AS_TARGET = 0x00000010
|
||||
};
|
||||
enum ComputeScrollTargetOptions
|
||||
{
|
||||
|
@ -630,10 +631,13 @@ protected:
|
|||
// Default action prefers the scrolled element immediately before if it's
|
||||
// still under the mouse cursor. Otherwise, it prefers the nearest
|
||||
// scrollable ancestor which will be scrolled actually.
|
||||
// When this is specified, the result may be nsPluginFrame. In such case,
|
||||
// the frame doesn't have nsIScrollableFrame interface.
|
||||
COMPUTE_DEFAULT_ACTION_TARGET =
|
||||
(PREFER_MOUSE_WHEEL_TRANSACTION |
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS |
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS),
|
||||
PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS |
|
||||
INCLUDE_PLUGIN_AS_TARGET),
|
||||
// Look for the nearest scrollable ancestor which can be scrollable with
|
||||
// aEvent.
|
||||
COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS =
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "gfxMatrix.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#ifdef XP_WIN
|
||||
// This is needed for DoublePassRenderingEvent.
|
||||
#include "mozilla/plugins/PluginMessageUtils.h"
|
||||
|
@ -1846,6 +1847,48 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginFrame::HandleWheelEventAsDefaultAction(WidgetWheelEvent* aWheelEvent)
|
||||
{
|
||||
MOZ_ASSERT(WantsToHandleWheelEventAsDefaultAction());
|
||||
MOZ_ASSERT(!aWheelEvent->mFlags.mDefaultPrevented);
|
||||
|
||||
if (NS_WARN_IF(!mInstanceOwner) ||
|
||||
NS_WARN_IF(aWheelEvent->mMessage != eWheel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the wheel event has native message, it should may be handled by
|
||||
// HandleEvent() in the future. In such case, we should do nothing here.
|
||||
if (NS_WARN_IF(!!aWheelEvent->mPluginEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mInstanceOwner->ProcessEvent(*aWheelEvent);
|
||||
// We need to assume that the event is always consumed/handled by the
|
||||
// plugin. There is no way to know if it's actually consumed/handled.
|
||||
aWheelEvent->mViewPortIsOverscrolled = false;
|
||||
aWheelEvent->overflowDeltaX = 0;
|
||||
aWheelEvent->overflowDeltaY = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPluginFrame::WantsToHandleWheelEventAsDefaultAction() const
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
if (!mInstanceOwner) {
|
||||
return false;
|
||||
}
|
||||
NPWindow* window = nullptr;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
// On Windows, only when the plugin is windowless, we need to send wheel
|
||||
// events as default action.
|
||||
return window->type == NPWindowTypeDrawable;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define nsPluginFrame_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "nsIObjectFrame.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsRegion.h"
|
||||
|
@ -205,6 +206,19 @@ public:
|
|||
*/
|
||||
void SetScrollVisibility(bool aState);
|
||||
|
||||
/**
|
||||
* HandleWheelEventAsDefaultAction() handles eWheel event as default action.
|
||||
* This should be called only when WantsToHandleWheelEventAsDefaultAction()
|
||||
* returns true.
|
||||
*/
|
||||
void HandleWheelEventAsDefaultAction(mozilla::WidgetWheelEvent* aEvent);
|
||||
|
||||
/**
|
||||
* WantsToHandleWheelEventAsDefaultAction() returns true if the plugin
|
||||
* may want to handle wheel events as default action.
|
||||
*/
|
||||
bool WantsToHandleWheelEventAsDefaultAction() const;
|
||||
|
||||
protected:
|
||||
explicit nsPluginFrame(nsStyleContext* aContext);
|
||||
virtual ~nsPluginFrame();
|
||||
|
|
Загрузка…
Ссылка в новой задаче