Bug 917385 - Move precise/imprecise input tracking down to widget thus making it more reliable with apz enabled. r=tabraldes, mbrubeck

This commit is contained in:
Jim Mathies 2013-10-16 12:14:55 -05:00
Родитель 5cc527680e
Коммит 42e157ed18
3 изменённых файлов: 78 добавлений и 46 удалений

Просмотреть файл

@ -1037,14 +1037,10 @@ var GestureModule = {
*/
var InputSourceHelper = {
isPrecise: false,
touchIsActive: false,
init: function ish_init() {
window.addEventListener("mousemove", this, true);
window.addEventListener("mousedown", this, true);
window.addEventListener("touchstart", this, true);
window.addEventListener("touchend", this, true);
window.addEventListener("touchcancel", this, true);
Services.obs.addObserver(this, "metro_precise_input", false);
Services.obs.addObserver(this, "metro_imprecise_input", false);
},
_precise: function () {
@ -1061,37 +1057,17 @@ var InputSourceHelper = {
}
},
handleEvent: function ish_handleEvent(aEvent) {
switch(aEvent.type) {
case "touchstart":
observe: function BrowserUI_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "metro_precise_input":
this._precise();
break;
case "metro_imprecise_input":
this._imprecise();
this.touchIsActive = true;
break;
case "touchend":
case "touchcancel":
this.touchIsActive = false;
break;
default:
// Ignore mouse movement when touch is active. Prevents both mouse scrollbars
// and touch scrollbars from displaying at the same time. Also works around
// odd win8 bug involving an erant mousemove event after a touch sequence
// starts (bug 896017).
if (this.touchIsActive) {
return;
}
switch (aEvent.mozInputSource) {
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_PEN:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_ERASER:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_CURSOR:
this._precise();
break;
}
break;
}
},
fireUpdate: function fireUpdate() {
if (this.isPrecise) {
this._fire("MozPrecisePointer");

Просмотреть файл

@ -206,6 +206,7 @@ MetroInput::MetroInput(MetroWidget* aWidget,
UI::Core::ICoreWindow* aWindow)
: mWidget(aWidget),
mChromeHitTestCacheForTouch(false),
mCurrentInputLevel(LEVEL_IMPRECISE),
mWindow(aWindow)
{
LogFunction();
@ -240,6 +241,51 @@ MetroInput::~MetroInput()
UnregisterInputEvents();
}
/**
* Tracks the current input level (precise/imprecise) and fires an observer
* when the mode changes.
*/
void
MetroInput::UpdateInputLevel(InputPrecisionLevel aInputLevel)
{
// ignore mouse input if we have active touch input.
if (aInputLevel == LEVEL_PRECISE && mTouches.Count() > 0) {
return;
}
if (mCurrentInputLevel != aInputLevel) {
mCurrentInputLevel = aInputLevel;
MetroUtils::FireObserver(mCurrentInputLevel == LEVEL_PRECISE ?
"metro_precise_input" : "metro_imprecise_input");
}
}
/**
* Processes an IEdgeGestureEventArgs and returns the input source type
* for the event. Also updates input level via UpdateInputLevel.
*/
uint16_t
MetroInput::ProcessInputTypeForGesture(UI::Input::IEdgeGestureEventArgs* aArgs)
{
MOZ_ASSERT(aArgs);
UI::Input::EdgeGestureKind kind;
aArgs->get_Kind(&kind);
switch(kind) {
case UI::Input::EdgeGestureKind::EdgeGestureKind_Touch:
UpdateInputLevel(LEVEL_PRECISE);
return nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
break;
case UI::Input::EdgeGestureKind::EdgeGestureKind_Keyboard:
return nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
break;
case UI::Input::EdgeGestureKind::EdgeGestureKind_Mouse:
UpdateInputLevel(LEVEL_IMPRECISE);
return nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
break;
}
return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
}
/**
* When the user swipes her/his finger in from the top of the screen,
* we receive this event.
@ -263,8 +309,7 @@ MetroInput::OnEdgeGestureStarted(UI::Input::IEdgeGesture* sender,
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(geckoEvent);
geckoEvent.time = ::GetMessageTime();
geckoEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs);
// Safe
DispatchEventIgnoreStatus(&geckoEvent);
@ -295,8 +340,7 @@ MetroInput::OnEdgeGestureCanceled(UI::Input::IEdgeGesture* sender,
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(geckoEvent);
geckoEvent.time = ::GetMessageTime();
geckoEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs);
// Safe
DispatchEventIgnoreStatus(&geckoEvent);
@ -326,15 +370,7 @@ MetroInput::OnEdgeGestureCompleted(UI::Input::IEdgeGesture* sender,
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(geckoEvent);
geckoEvent.time = ::GetMessageTime();
UI::Input::EdgeGestureKind value;
aArgs->get_Kind(&value);
if (value == UI::Input::EdgeGestureKind::EdgeGestureKind_Keyboard) {
geckoEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_KEYBOARD;
} else {
geckoEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
}
geckoEvent.inputSource = ProcessInputTypeForGesture(aArgs);
// Safe
DispatchEventIgnoreStatus(&geckoEvent);
@ -391,6 +427,7 @@ MetroInput::OnPointerNonTouch(UI::Input::IPointerPoint* aPoint) {
event->message = NS_MOUSE_BUTTON_UP;
break;
}
UpdateInputLevel(LEVEL_PRECISE);
InitGeckoMouseEventFromPointerPoint(event, aPoint);
DispatchAsyncEventIgnoreStatus(event);
}
@ -430,6 +467,8 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
}
// This is touch input.
UpdateInputLevel(LEVEL_IMPRECISE);
// Create the new touch point and add it to our event.
uint32_t pointerId;
currentPoint->get_PointerId(&pointerId);
@ -517,6 +556,8 @@ MetroInput::OnPointerMoved(UI::Core::ICoreWindow* aSender,
}
// This is touch input.
UpdateInputLevel(LEVEL_IMPRECISE);
// Get the touch associated with this touch point.
uint32_t pointerId;
currentPoint->get_PointerId(&pointerId);
@ -614,6 +655,8 @@ MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender,
}
// This is touch input.
UpdateInputLevel(LEVEL_IMPRECISE);
// Get the touch associated with this touch point.
uint32_t pointerId;
currentPoint->get_PointerId(&pointerId);
@ -748,9 +791,11 @@ MetroInput::OnPointerEntered(UI::Core::ICoreWindow* aSender,
WidgetMouseEvent* event =
new WidgetMouseEvent(true, NS_MOUSE_ENTER, mWidget.Get(),
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
UpdateInputLevel(LEVEL_PRECISE);
InitGeckoMouseEventFromPointerPoint(event, currentPoint.Get());
DispatchAsyncEventIgnoreStatus(event);
}
UpdateInputLevel(LEVEL_IMPRECISE);
return S_OK;
}
@ -779,9 +824,11 @@ MetroInput::OnPointerExited(UI::Core::ICoreWindow* aSender,
WidgetMouseEvent* event =
new WidgetMouseEvent(true, NS_MOUSE_EXIT, mWidget.Get(),
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
UpdateInputLevel(LEVEL_PRECISE);
InitGeckoMouseEventFromPointerPoint(event, currentPoint.Get());
DispatchAsyncEventIgnoreStatus(event);
}
UpdateInputLevel(LEVEL_IMPRECISE);
return S_OK;
}

Просмотреть файл

@ -155,6 +155,14 @@ private:
ModifierKeyState mModifierKeyState;
// Tracking input level
enum InputPrecisionLevel {
LEVEL_PRECISE,
LEVEL_IMPRECISE
};
InputPrecisionLevel mCurrentInputLevel;
void UpdateInputLevel(InputPrecisionLevel aInputLevel);
// Initialization/Uninitialization helpers
void RegisterInputEvents();
void UnregisterInputEvents();
@ -174,6 +182,7 @@ private:
Point const& aPosition,
uint32_t aMagEventType,
uint32_t aRotEventType);
uint16_t ProcessInputTypeForGesture(IEdgeGestureEventArgs* aArgs);
// The W3C spec states that "whether preventDefault has been called" should
// be tracked on a per-touchpoint basis, but it also states that touchstart