Bug 953012 - Opening a new tab using the overlay while a website is loading creates two about:start tabs r=jimm

--HG--
extra : rebase_source : c6f62fe85d6eb49e6d70708ce24f14dfabe22f57
This commit is contained in:
Rodrigo Silveira 2014-02-26 21:42:49 -08:00
parent 4fd3905464
commit deb45ace05
2 changed files with 110 additions and 55 deletions

View File

@ -14,7 +14,6 @@
#include "UIABridgePrivate.h"
#include "MetroAppShell.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/Preferences.h" // for Preferences
#include "WinUtils.h"
#include "nsIPresShell.h"
@ -22,7 +21,6 @@
// System headers (alphabetical)
#include <windows.ui.core.h> // ABI::Window::UI::Core namespace
#include <windows.ui.input.h> // ABI::Window::UI::Input namespace
//#define DEBUG_INPUT
@ -238,20 +236,6 @@ namespace {
aData->mChanged = false;
return PL_DHASH_NEXT;
}
// Helper for making sure event ptrs get freed.
class AutoDeleteEvent
{
public:
AutoDeleteEvent(WidgetGUIEvent* aPtr) :
mPtr(aPtr) {}
~AutoDeleteEvent() {
if (mPtr) {
delete mPtr;
}
}
WidgetGUIEvent* mPtr;
};
}
namespace mozilla {
@ -540,19 +524,19 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
LogFunction();
#endif
WRL::ComPtr<UI::Input::IPointerPoint> currentPoint;
UI::Input::IPointerPoint* currentPoint;
WRL::ComPtr<Devices::Input::IPointerDevice> device;
Devices::Input::PointerDeviceType deviceType;
aArgs->get_CurrentPoint(currentPoint.GetAddressOf());
aArgs->get_CurrentPoint(&currentPoint);
currentPoint->get_PointerDevice(device.GetAddressOf());
device->get_PointerDeviceType(&deviceType);
// For mouse and pen input, simply call our helper function
if (deviceType !=
Devices::Input::PointerDeviceType::PointerDeviceType_Touch) {
OnPointerNonTouch(currentPoint.Get());
mGestureRecognizer->ProcessDownEvent(currentPoint.Get());
OnPointerNonTouch(currentPoint);
mGestureRecognizer->ProcessDownEvent(currentPoint);
return S_OK;
}
@ -562,7 +546,7 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
// Create the new touch point and add it to our event.
uint32_t pointerId;
currentPoint->get_PointerId(&pointerId);
nsRefPtr<Touch> touch = CreateDOMTouch(currentPoint.Get());
nsRefPtr<Touch> touch = CreateDOMTouch(currentPoint);
touch->mChanged = true;
mTouches.Put(pointerId, touch);
@ -582,25 +566,31 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
}
InitTouchEventTouchList(touchEvent);
DispatchAsyncTouchEvent(touchEvent);
DispatchAsyncTouchEvent(new TouchEventQueueEntry(touchEvent, currentPoint));
if (ShouldDeliverInputToRecognizer()) {
mGestureRecognizer->ProcessDownEvent(currentPoint.Get());
}
return S_OK;
}
void
MetroInput::AddPointerMoveDataToRecognizer(UI::Core::IPointerEventArgs* aArgs)
MetroInput::AddPointerMoveDataToRecognizer(IPointerEventArgs* aArgs)
{
if (ShouldDeliverInputToRecognizer()) {
WRL::ComPtr<Foundation::Collections::IVector<UI::Input::PointerPoint*>>
pointerPoints;
WRL::ComPtr<PointerPointVector> pointerPoints;
aArgs->GetIntermediatePoints(pointerPoints.GetAddressOf());
mGestureRecognizer->ProcessMoveEvents(pointerPoints.Get());
}
}
void
MetroInput::DeliverNextQueuedNoMoveTouch() {
nsAutoPtr<TouchEventQueueEntry> queueEntry =
static_cast<TouchEventQueueEntry*>(mInputEventQueue.PopFront());
if (ShouldDeliverInputToRecognizer()) {
mGestureRecognizer->ProcessMoveEvents(queueEntry->GetPointerPoints());
}
}
// This event is raised when the user moves the mouse, moves a pen that is
// in contact with the surface, or moves a finger that is in contact with
// a touch screen.
@ -644,12 +634,19 @@ MetroInput::OnPointerMoved(UI::Core::ICoreWindow* aSender,
return S_OK;
}
AddPointerMoveDataToRecognizer(aArgs);
PointerPointVector* pointerPoints;
aArgs->GetIntermediatePoints(&pointerPoints);
// If the point hasn't moved, filter it out per the spec. Pres shell does
// this as well, but we need to know when our first touchmove is going to
// get delivered so we can check the result.
if (!HasPointMoved(touch, currentPoint.Get())) {
// Even when the pointer has not moved, the gesture recognizer requires it.
// Doing it asynchronously to keep the event's order.
mInputEventQueue.Push(new TouchEventQueueEntry(nullptr, pointerPoints));
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(this, &MetroInput::DeliverNextQueuedNoMoveTouch);
NS_DispatchToCurrentThread(runnable);
return S_OK;
}
@ -661,7 +658,8 @@ MetroInput::OnPointerMoved(UI::Core::ICoreWindow* aSender,
WidgetTouchEvent* touchEvent =
new WidgetTouchEvent(true, NS_TOUCH_MOVE, mWidget.Get());
InitTouchEventTouchList(touchEvent);
DispatchAsyncTouchEvent(touchEvent);
DispatchAsyncTouchEvent(new TouchEventQueueEntry(touchEvent, pointerPoints));
return S_OK;
}
@ -676,19 +674,19 @@ MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender,
LogFunction();
#endif
WRL::ComPtr<UI::Input::IPointerPoint> currentPoint;
UI::Input::IPointerPoint* currentPoint;
WRL::ComPtr<Devices::Input::IPointerDevice> device;
Devices::Input::PointerDeviceType deviceType;
aArgs->get_CurrentPoint(currentPoint.GetAddressOf());
aArgs->get_CurrentPoint(&currentPoint);
currentPoint->get_PointerDevice(device.GetAddressOf());
device->get_PointerDeviceType(&deviceType);
// For mouse and pen input, simply call our helper function
if (deviceType !=
Devices::Input::PointerDeviceType::PointerDeviceType_Touch) {
OnPointerNonTouch(currentPoint.Get());
mGestureRecognizer->ProcessUpEvent(currentPoint.Get());
OnPointerNonTouch(currentPoint);
mGestureRecognizer->ProcessUpEvent(currentPoint);
return S_OK;
}
@ -705,7 +703,7 @@ MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender,
WidgetTouchEvent* touchEvent =
new WidgetTouchEvent(true, NS_TOUCH_MOVE, mWidget.Get());
InitTouchEventTouchList(touchEvent);
DispatchAsyncTouchEvent(touchEvent);
DispatchAsyncTouchEvent(new TouchEventQueueEntry(touchEvent, (IPointerPoint*)nullptr));
}
// Remove this touch point from our map. Eventually all touch points are
@ -716,12 +714,8 @@ MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender,
// touchend events only have a single touch; the touch that has been removed
WidgetTouchEvent* touchEvent =
new WidgetTouchEvent(true, NS_TOUCH_END, mWidget.Get());
touchEvent->touches.AppendElement(CreateDOMTouch(currentPoint.Get()));
DispatchAsyncTouchEvent(touchEvent);
if (ShouldDeliverInputToRecognizer()) {
mGestureRecognizer->ProcessUpEvent(currentPoint.Get());
}
touchEvent->touches.AppendElement(CreateDOMTouch(currentPoint));
DispatchAsyncTouchEvent(new TouchEventQueueEntry(touchEvent, currentPoint));
return S_OK;
}
@ -1136,12 +1130,13 @@ MetroInput::DeliverNextQueuedEventIgnoreStatus()
}
void
MetroInput::DispatchAsyncTouchEvent(WidgetTouchEvent* aEvent)
MetroInput::DispatchAsyncTouchEvent(TouchEventQueueEntry* queueEntry)
{
aEvent->time = ::GetMessageTime();
WidgetTouchEvent* event = queueEntry->GetEvent();
event->time = ::GetMessageTime();
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(*aEvent);
mInputEventQueue.Push(aEvent);
mModifierKeyState.InitInputEvent(*event);
mInputEventQueue.Push(queueEntry);
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethod(this, &MetroInput::DeliverNextQueuedTouchEvent);
NS_DispatchToCurrentThread(runnable);
@ -1352,11 +1347,12 @@ MetroInput::DeliverNextQueuedTouchEvent()
*/
nsEventStatus status = nsEventStatus_eIgnore;
WidgetTouchEvent* event =
static_cast<WidgetTouchEvent*>(mInputEventQueue.PopFront());
MOZ_ASSERT(event);
nsAutoPtr<TouchEventQueueEntry> queueEntry =
static_cast<TouchEventQueueEntry*>(mInputEventQueue.PopFront());
AutoDeleteEvent wrap(event);
WidgetTouchEvent* event = queueEntry->GetEvent();
MOZ_ASSERT(event);
// Test for non-apz vs. apz target. To do this we only use the first touch
// point since that will be the input batch target. Cache this for touch events
@ -1387,6 +1383,25 @@ MetroInput::DeliverNextQueuedTouchEvent()
mCancelable = false;
}
}
}
if (ShouldDeliverInputToRecognizer()) {
switch (event->message) {
case NS_TOUCH_START:
mGestureRecognizer->ProcessDownEvent(queueEntry->GetPointerPoint());
break;
case NS_TOUCH_END:
mGestureRecognizer->ProcessUpEvent(queueEntry->GetPointerPoint());
break;
case NS_TOUCH_MOVE:
if (queueEntry->GetPointerPoints()) {
mGestureRecognizer->ProcessMoveEvents(queueEntry->GetPointerPoints());
}
break;
}
}
if (mNonApzTargetForTouch) {
return;
}

View File

@ -8,15 +8,17 @@
// Moz headers (alphabetical)
#include "keyboardlayout.h" // mModifierKeyState
#include "nsBaseHashtable.h" // mTouches
#include "nsHashKeys.h" // type of key for mTouches
#include "mozwrlbase.h"
#include "nsDeque.h"
#include "nsHashKeys.h" // type of key for mTouches
#include "mozilla/EventForwards.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/TouchEvents.h"
#include "mozwrlbase.h"
// System headers (alphabetical)
#include <EventToken.h> // EventRegistrationToken
#include <stdint.h> // uint32_t
#include <windows.ui.input.h> // ABI::Window::UI::Input namespace
#include <wrl\client.h> // Microsoft::WRL::ComPtr class
#include <wrl\implements.h> // Microsoft::WRL::InspectableClass macro
@ -68,6 +70,41 @@ namespace mozilla {
namespace widget {
namespace winrt {
class TouchEventQueueEntry {
private:
typedef ABI::Windows::UI::Input::IPointerPoint IPointerPoint;
typedef ABI::Windows::UI::Input::PointerPoint PointerPoint;
typedef ABI::Windows::Foundation::Collections::IVector<PointerPoint*> PointerPointVector;
Microsoft::WRL::ComPtr<PointerPointVector> mPointerPoints;
Microsoft::WRL::ComPtr<IPointerPoint> mPointerPoint;
nsAutoPtr<WidgetTouchEvent> mTouchEvent;
public:
TouchEventQueueEntry(WidgetTouchEvent* aTouchEvent, IPointerPoint* aPointerPoint)
: mTouchEvent(aTouchEvent), mPointerPoint(aPointerPoint)
{
}
TouchEventQueueEntry(WidgetTouchEvent* aTouchEvent, PointerPointVector* aPointerPoints)
: mTouchEvent(aTouchEvent), mPointerPoints(aPointerPoints)
{
}
IPointerPoint* GetPointerPoint() {
return mPointerPoint.Get();
}
PointerPointVector* GetPointerPoints() {
return mPointerPoints.Get();
}
WidgetTouchEvent* GetEvent() {
return mTouchEvent;
}
};
class MetroInput : public Microsoft::WRL::RuntimeClass<IInspectable>
{
InspectableClass(L"MetroInput", BaseTrust);
@ -79,9 +116,6 @@ private:
// Devices
typedef ABI::Windows::Devices::Input::PointerDeviceType PointerDeviceType;
// Foundation
typedef ABI::Windows::Foundation::Point Point;
// UI::Core
typedef ABI::Windows::UI::Core::ICoreWindow ICoreWindow;
typedef ABI::Windows::UI::Core::IAcceleratorKeyEventArgs \
@ -103,6 +137,11 @@ private:
typedef ABI::Windows::UI::Input::IRightTappedEventArgs IRightTappedEventArgs;
typedef ABI::Windows::UI::Input::ITappedEventArgs ITappedEventArgs;
typedef ABI::Windows::UI::Input::ManipulationDelta ManipulationDelta;
typedef ABI::Windows::UI::Input::PointerPoint PointerPoint;
// Foundation
typedef ABI::Windows::Foundation::Point Point;
typedef ABI::Windows::Foundation::Collections::IVector<PointerPoint*> PointerPointVector;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
@ -283,11 +322,12 @@ private:
// Async event dispatching
void DispatchAsyncEventIgnoreStatus(WidgetInputEvent* aEvent);
void DispatchAsyncTouchEvent(WidgetTouchEvent* aEvent);
void DispatchAsyncTouchEvent(TouchEventQueueEntry* queueEntry);
// Async event callbacks
void DeliverNextQueuedEventIgnoreStatus();
void DeliverNextQueuedTouchEvent();
void DeliverNextQueuedNoMoveTouch();
void HandleFirstTouchStartEvent(WidgetTouchEvent* aEvent);
void HandleFirstTouchMoveEvent(WidgetTouchEvent* aEvent);