Bug 1299286 - Enable touchdown to start dragging on elements with touchdownstartsdrag attributes. r=kats
MozReview-Commit-ID: 8TL9VfY88ip
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -4281,16 +4281,57 @@ bool nsWindow::DispatchPluginEvent(UINT
bool ret = nsWindowBase::DispatchPluginEvent(
WinUtils::InitMSG(aMessage, aWParam, aLParam, mWnd));
if (aDispatchPendingEvents && !Destroyed()) {
DispatchPendingEvents();
}
return ret;
}
+bool nsWindow::TouchEventShouldStartDrag(EventMessage aEventMessage,
+ LayoutDeviceIntPoint aEventPoint)
+{
+ // Allow users to start dragging by double-tapping.
+ if (aEventMessage == eMouseDoubleClick) {
+ return true;
+ }
+
+ // In chrome UI, allow touchdownstartsdrag attributes
+ // to cause any touchdown event to trigger a drag.
+ if (aEventMessage == eMouseDown) {
+ WidgetMouseEvent hittest(true, eMouseHitTest, this,
+ WidgetMouseEvent::eReal);
+ hittest.mRefPoint = aEventPoint;
+ hittest.mIgnoreRootScrollFrame = true;
+ hittest.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
+ DispatchInputEvent(&hittest);
+
+ EventTarget* target = hittest.GetDOMEventTarget();
+ if (target) {
+ nsCOMPtr<nsIContent> node = do_QueryInterface(target);
+
+ // Check if the element or any parent element has the
+ // attribute we're looking for.
+ while (node) {
+ if (node->IsElement()) {
+ nsAutoString startDrag;
+ node->AsElement()->GetAttribute(
+ NS_LITERAL_STRING("touchdownstartsdrag"), startDrag);
+ if (!startDrag.IsEmpty()) {
+ return true;
+ }
+ }
+ node = node->GetParent();
+ }
+ }
+ }
+
+ return false;
+}
+
// Deal with all sort of mouse event
bool
nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam,
LPARAM lParam, bool aIsContextMenuKey,
int16_t aButton, uint16_t aInputSource,
WinPointerInfo* aPointerInfo)
{
enum
@@ -4332,22 +4373,23 @@ nsWindow::DispatchMouseEvent(EventMessag
sTouchInputActiveState = eTouch;
nsCOMPtr<nsIObserverService> obsServ =
mozilla::services::GetObserverService();
obsServ->NotifyObservers(nullptr, "touch-input-detected", nullptr);
}
if (mTouchWindow) {
// If mTouchWindow is true, then we must have APZ enabled and be
- // feeding it raw touch events. In that case we don't need to
- // send touch-generated mouse events to content. The only exception is
- // the touch-generated mouse double-click, which is used to start off the
- // touch-based drag-and-drop gesture.
+ // feeding it raw touch events. In that case we only want to
+ // send touch-generated mouse events to content if they should
+ // start a touch-based drag-and-drop gesture, such as on
+ // double-tapping or when tapping elements marked with the
+ // touchdownstartsdrag attribute in chrome UI.
MOZ_ASSERT(mAPZC);
- if (aEventMessage == eMouseDoubleClick) {
+ if (TouchEventShouldStartDrag(aEventMessage, eventPoint)) {
aEventMessage = eMouseTouchDrag;
} else {
return result;
}
}
} else {
// Fire an observer when the user initially uses a mouse or pen.
if (sTouchInputActiveState != ePrecise) {
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -263,16 +263,18 @@ public:
/**
* Misc.
*/
virtual bool AutoErase(HDC dc);
bool WidgetTypeSupportsAcceleration() override;
void ForcePresent();
+ bool TouchEventShouldStartDrag(mozilla::EventMessage aEventMessage,
+ LayoutDeviceIntPoint aEventPoint);
/**
* AssociateDefaultIMC() associates or disassociates the default IMC for
* the window.
*
* @param aAssociate TRUE, associates the default IMC with the window.
* Otherwise, disassociates the default IMC from the
* window.