Bug 869940 - APZC Metro front end implementation, pref'ed off initially. r=jimm

This commit is contained in:
Brian R. Bondy 2013-07-25 13:15:13 -04:00
parent ffa4a02e06
commit bb5d35077d
9 changed files with 187 additions and 11 deletions

View File

@ -61,7 +61,7 @@ var NavButtonSlider = {
this._back.customDragger = this;
this._plus.customDragger = this;
Elements.browsers.addEventListener("ContentSizeChanged", this, true);
let events = ["mousedown", "mouseup", "mousemove", "click"];
let events = ["mousedown", "mouseup", "mousemove", "click", "touchstart", "touchmove", "touchend"];
events.forEach(function (value) {
this._back.addEventListener(value, this, true);
this._plus.addEventListener(value, this, true);
@ -135,20 +135,47 @@ var NavButtonSlider = {
case "ContentSizeChanged":
this._updateStops();
break;
case "touchstart":
if (aEvent.touches.length != 1)
break;
aEvent.preventDefault();
aEvent = aEvent.touches[0];
case "mousedown":
this._getPosition();
this._mouseDown = true;
this._mouseMoveStarted = false;
this._mouseY = aEvent.clientY;
aEvent.originalTarget.setCapture();
if (aEvent.originalTarget)
aEvent.originalTarget.setCapture();
this._back.setAttribute("mousedrag", true);
this._plus.setAttribute("mousedrag", true);
break;
case "touchend":
if (aEvent.touches.length != 0)
break;
this._mouseDown = false;
this._back.removeAttribute("mousedrag");
this._plus.removeAttribute("mousedrag");
if (!this._mouseMoveStarted) {
if (aEvent.originalTarget == this._back) {
CommandUpdater.doCommand('cmd_back');
} else {
CommandUpdater.doCommand('cmd_newTab');
}
}
break;
case "mouseup":
this._mouseDown = false;
this._back.removeAttribute("mousedrag");
this._plus.removeAttribute("mousedrag");
break;
case "touchmove":
if (aEvent.touches.length != 1)
break;
aEvent = aEvent.touches[0];
case "mousemove":
// Check to be sure this is a drag operation
if (!this._mouseDown) {

View File

@ -0,0 +1,120 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
let Cr = Components.results;
/**
* Handler for APZC display port and pan begin/end notifications.
* These notifications are only sent by widget/windows/winrt code when
* the pref: layers.async-pan-zoom.enabled is true.
*/
var APZCObserver = {
init: function() {
this._enabled = Services.prefs.getBoolPref(kAsyncPanZoomEnabled);
if (!this._enabled) {
return;
}
let os = Services.obs;
os.addObserver(this, "apzc-request-content-repaint", false);
os.addObserver(this, "apzc-handle-pan-begin", false);
os.addObserver(this, "apzc-handle-pan-end", false);
Elements.tabList.addEventListener("TabSelect", this, true);
Elements.tabList.addEventListener("TabOpen", this, true);
Elements.tabList.addEventListener("TabClose", this, true);
},
handleEvent: function APZC_handleEvent(aEvent) {
switch (aEvent.type) {
case 'pageshow':
case 'TabSelect':
Services.obs.notifyObservers(null, "viewport-needs-updating", null);
break;
case 'TabOpen': {
let browser = aEvent.originalTarget.linkedBrowser;
browser.addEventListener("pageshow", this, true);
break;
}
case 'TabClose': {
let browser = aEvent.originalTarget.linkedBrowser;
browser.removeEventListener("pageshow", this);
break;
}
}
},
shutdown: function shutdown() {
if (!this._enabled) {
return;
}
Elements.tabList.removeEventListener("TabSelect", this, true);
Elements.tabList.removeEventListener("TabOpen", this, true);
Elements.tabList.removeEventListener("TabClose", this, true);
let os = Services.obs;
os.removeObserver(this, "apzc-request-content-repaint");
os.removeObserver(this, "apzc-handle-pan-begin");
os.removeObserver(this, "apzc-handle-pan-end");
},
observe: function ao_observe(aSubject, aTopic, aData) {
if (aTopic == "apzc-request-content-repaint") {
let frameMetrics = JSON.parse(aData);
let scrollTo = frameMetrics.scrollTo;
let displayPort = frameMetrics.displayPort;
let resolution = frameMetrics.resolution;
let compositedRect = frameMetrics.compositedRect;
if (StartUI.isStartPageVisible) {
let windowUtils = Browser.windowUtils;
Browser.selectedBrowser.contentWindow.scrollTo(scrollTo.x, scrollTo.y);
windowUtils.setResolution(resolution, resolution);
windowUtils.setDisplayPortForElement(displayPort.x * resolution,
displayPort.y * resolution,
displayPort.width * resolution,
displayPort.height * resolution,
Elements.startUI);
} else {
let windowUtils = Browser.selectedBrowser.contentWindow.
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
windowUtils.setScrollPositionClampingScrollPortSize(compositedRect.width,
compositedRect.height);
Browser.selectedBrowser.messageManager.sendAsyncMessage("Content:SetCacheViewport", {
scrollX: scrollTo.x,
scrollY: scrollTo.y,
x: displayPort.x + scrollTo.x,
y: displayPort.y + scrollTo.y,
w: displayPort.width,
h: displayPort.height,
scale: resolution,
id: 1
});
}
Util.dumpLn("APZC scrollTo.x: " + scrollTo.x + ", scrollTo.y: " + scrollTo.y);
Util.dumpLn("APZC setResolution: " + resolution);
Util.dumpLn("APZC setDisplayPortForElement: displayPort.x: " +
displayPort.x + ", displayPort.y: " + displayPort.y +
", displayPort.width: " + displayPort.width +
", displayort.height: " + displayPort.height);
} else if (aTopic == "apzc-handle-pan-begin") {
// When we're panning, hide the main scrollbars by setting imprecise
// input (which sets a property on the browser which hides the scrollbar
// via CSS). This reduces jittering from left to right. We may be able
// to get rid of this once we implement axis locking in /gfx APZC.
Util.dumpLn("APZC pan-begin");
if (InputSourceHelper.isPrecise) {
InputSourceHelper._imprecise();
}
} else if (aTopic == "apzc-handle-pan-end") {
Util.dumpLn("APZC pan-end");
}
}
};

View File

@ -614,7 +614,7 @@ let ContentScroll = {
break;
// Set the scroll offset for this element if specified
if (json.scrollX >= 0 && json.scrollY >= 0) {
if (json.scrollX >= 0 || json.scrollY >= 0) {
this.setScrollOffsetForElement(element, json.scrollX, json.scrollY)
if (json.id == 1)
this._scrollOffset = this.getScrollOffset(content);

View File

@ -72,6 +72,7 @@ var Browser = {
GestureModule.init();
BrowserTouchHandler.init();
PopupBlockerObserver.init();
APZCObserver.init();
// Init the touch scrollbox
this.contentScrollbox = Elements.browsers;
@ -235,6 +236,7 @@ var Browser = {
},
shutdown: function shutdown() {
APZCObserver.shutdown();
BrowserUI.uninit();
ContentAreaObserver.shutdown();

View File

@ -47,7 +47,8 @@
<script type="application/javascript" src="chrome://browser/content/browser-ui.js"/>
<script type="application/javascript" src="chrome://browser/content/Util.js"/>
<script type="application/javascript" src="chrome://browser/content/input.js"/>
<script type="application/javascript;version=1.8" src="chrome://browser/content/appbar.js"/>
<script type="application/javascript" src="chrome://browser/content/appbar.js"/>
<script type="application/javascript" src="chrome://browser/content/apzc.js"/>
<broadcasterset id="broadcasterset">
<broadcaster id="bcast_contentShowing" disabled="false"/>
<broadcaster id="bcast_urlbarState" mode="view"/>

View File

@ -511,15 +511,18 @@ var SelectionHelperUI = {
messageManager.addMessageListener("Content:HandlerShutdown", this);
messageManager.addMessageListener("Content:SelectionHandlerPong", this);
// capture phase
window.addEventListener("keypress", this, true);
window.addEventListener("click", this, false);
window.addEventListener("touchstart", this, true);
window.addEventListener("touchend", this, true);
window.addEventListener("touchmove", this, true);
window.addEventListener("MozPrecisePointer", this, true);
window.addEventListener("MozDeckOffsetChanging", this, true);
window.addEventListener("MozDeckOffsetChanged", this, true);
// bubble phase
window.addEventListener("click", this, false);
window.addEventListener("touchstart", this, false);
window.addEventListener("touchend", this, false);
window.addEventListener("touchmove", this, false);
Elements.browsers.addEventListener("URLChanged", this, true);
Elements.browsers.addEventListener("SizeChanged", this, true);
Elements.browsers.addEventListener("ZoomChanged", this, true);
@ -540,9 +543,9 @@ var SelectionHelperUI = {
window.removeEventListener("keypress", this, true);
window.removeEventListener("click", this, false);
window.removeEventListener("touchstart", this, true);
window.removeEventListener("touchend", this, true);
window.removeEventListener("touchmove", this, true);
window.removeEventListener("touchstart", this, false);
window.removeEventListener("touchend", this, false);
window.removeEventListener("touchmove", this, false);
window.removeEventListener("MozPrecisePointer", this, true);
window.removeEventListener("MozDeckOffsetChanging", this, true);
window.removeEventListener("MozDeckOffsetChanged", this, true);
@ -1013,6 +1016,11 @@ var SelectionHelperUI = {
case "touchstart": {
if (aEvent.touches.length != 1)
break;
// Only prevent default if we're dragging so that
// APZC doesn't scroll.
if (this._checkForActiveDrag()) {
aEvent.preventDefault();
}
let touch = aEvent.touches[0];
this._movement.x = touch.clientX;
this._movement.y = touch.clientY;

View File

@ -42,6 +42,7 @@ const kDebugSelectionDisplayPref = "metro.debug.selection.displayRanges";
const kDebugSelectionDumpPref = "metro.debug.selection.dumpRanges";
// Dump message manager event traffic for selection.
const kDebugSelectionDumpEvents = "metro.debug.selection.dumpEvents";
const kAsyncPanZoomEnabled = "layers.async-pan-zoom.enabled"
/**
* TouchModule
@ -199,6 +200,11 @@ var TouchModule = {
/** Begin possible pan and send tap down event. */
_onTouchStart: function _onTouchStart(aEvent) {
if (Services.prefs.getBoolPref(kAsyncPanZoomEnabled) &&
!StartUI.isStartPageVisible) {
return;
}
if (aEvent.touches.length > 1)
return;
@ -250,6 +256,11 @@ var TouchModule = {
/** Send tap up event and any necessary full taps. */
_onTouchEnd: function _onTouchEnd(aEvent) {
if (Services.prefs.getBoolPref(kAsyncPanZoomEnabled) &&
!StartUI.isStartPageVisible) {
return;
}
if (aEvent.touches.length > 0 || this._isCancelled || !this._targetScrollbox)
return;
@ -266,6 +277,11 @@ var TouchModule = {
* If we're in a drag, do what we have to do to drag on.
*/
_onTouchMove: function _onTouchMove(aEvent) {
if (Services.prefs.getBoolPref(kAsyncPanZoomEnabled) &&
!StartUI.isStartPageVisible) {
return;
}
if (aEvent.touches.length > 1)
return;

View File

@ -96,6 +96,7 @@ chrome.jar:
#endif
content/NavButtonSlider.js (content/NavButtonSlider.js)
content/ContextUI.js (content/ContextUI.js)
content/apzc.js (content/apzc.js)
% override chrome://global/content/config.xul chrome://browser/content/config.xul
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml

View File

@ -25,6 +25,7 @@ pref("metro.debug.selection.dumpEvents", false);
// Enable off main thread compositing
pref("layers.offmainthreadcomposition.enabled", true);
pref("layers.async-pan-zoom.enabled", false);
// Enable Microsoft TSF support by default for imes.
pref("intl.enable_tsf_support", true);