Bug 898580 - Metro mechanism for content to inform APZC about scroll events. Handles multi-APZC. r=bbondy, r=kats

This commit is contained in:
Botond Ballo 2013-08-12 16:31:49 -04:00
Родитель e2eae8dab7
Коммит f4b3e0c923
5 изменённых файлов: 96 добавлений и 16 удалений

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

@ -46,11 +46,13 @@ var APZCObserver = {
case 'TabOpen': {
let browser = aEvent.originalTarget.linkedBrowser;
browser.addEventListener("pageshow", this, true);
browser.messageManager.addMessageListener("scroll", this);
break;
}
case 'TabClose': {
let browser = aEvent.originalTarget.linkedBrowser;
browser.removeEventListener("pageshow", this);
browser.removeEventListener("pageshow", this, true);
browser.messageManager.removeMessageListener("scroll", this);
break;
}
}
@ -113,5 +115,16 @@ var APZCObserver = {
} else if (aTopic == "apzc-handle-pan-end") {
Util.dumpLn("APZC pan-end");
}
},
receiveMessage: function(aMessage) {
let json = aMessage.json;
switch (aMessage.name) {
case "scroll": {
let data = json.viewId + " " + json.presShellId + " (" + json.scrollOffset.x + ", " + json.scrollOffset.y + ")";
Services.obs.notifyObservers(null, "scroll-offset-changed", data);
break;
}
}
}
};

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

@ -652,11 +652,7 @@ let ContentScroll = {
break;
case "scroll": {
let doc = aEvent.target;
if (doc != content.document)
break;
this.sendScroll();
this.sendScroll(aEvent.target);
break;
}
@ -683,13 +679,35 @@ let ContentScroll = {
}
},
sendScroll: function sendScroll() {
let scrollOffset = this.getScrollOffset(content);
if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y)
return;
sendScroll: function sendScroll(target) {
let isRoot = false;
if (target instanceof Ci.nsIDOMDocument) {
var window = target.defaultView;
var scrollOffset = this.getScrollOffset(window);
var element = target.documentElement;
this._scrollOffset = scrollOffset;
sendAsyncMessage("scroll", scrollOffset);
if (target == content.document) {
if (this._scrollOffset.x == scrollOffset.x && this._scrollOffset.y == scrollOffset.y) {
return;
}
this._scrollOffset = scrollOffset;
isRoot = true;
}
} else {
var window = target.currentDoc.defaultView;
var scrollOffset = this.getScrollOffsetForElement(target);
var element = target;
}
let utils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
let presShellId = {};
utils.getPresShellId(presShellId);
let viewId = utils.getViewId(element);
sendAsyncMessage("scroll", { presShellId: presShellId.value,
viewId: viewId,
scrollOffset: scrollOffset,
isRoot: isRoot });
}
};

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

@ -859,9 +859,11 @@
switch (aMessage.name) {
case "scroll":
if (!json.isRoot)
return;
if (!self.scrollSync)
return;
this.doScroll(json.x, json.y, 0);
this.doScroll(json.scrollOffset.x, json.scrollOffset.y, 0);
break;
}
},

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

@ -163,6 +163,7 @@ MetroWidget::MetroWidget() :
mWnd(NULL),
mMetroWndProc(NULL),
mTempBasicLayerInUse(false),
mRootLayerTreeId(),
nsWindowBase()
{
// Global initialization
@ -271,6 +272,14 @@ MetroWidget::Destroy()
nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
if (ShouldUseAPZC()) {
nsresult rv;
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
observerService->RemoveObserver(this, "scroll-offset-changed");
}
}
RemoveSubclass();
NotifyWindowDestroyed();
@ -829,6 +838,13 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
if (ShouldUseAPZC()) {
CompositorParent::SetControllerForLayerTree(compositor->RootLayerTreeId(), this);
MetroWidget::sAPZC = CompositorParent::GetAPZCTreeManager(compositor->RootLayerTreeId());
mRootLayerTreeId = compositor->RootLayerTreeId();
nsresult rv;
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
observerService->AddObserver(this, "scroll-offset-changed", false);
}
}
return compositor;
@ -1446,3 +1462,30 @@ MetroWidget::HandlePanEnd()
LogFunction();
MetroUtils::FireObserver("apzc-handle-pan-end", L"");
}
NS_IMETHODIMP
MetroWidget::Observe(nsISupports *subject, const char *topic, const PRUnichar *data)
{
NS_ENSURE_ARG_POINTER(topic);
if (!strcmp(topic, "scroll-offset-changed")) {
uint64_t scrollId;
int32_t presShellId;
CSSIntPoint scrollOffset;
int matched = sscanf(NS_LossyConvertUTF16toASCII(data).get(),
"%llu %d (%d, %d)",
&scrollId,
&presShellId,
&scrollOffset.x,
&scrollOffset.y);
if (matched != 4) {
NS_WARNING("Malformed scroll-offset-changed message");
return NS_ERROR_UNEXPECTED;
}
if (MetroWidget::sAPZC) {
MetroWidget::sAPZC->UpdateScrollOffset(
ScrollableLayerGuid(mRootLayerTreeId, presShellId, scrollId),
scrollOffset);
}
}
return NS_OK;
}

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

@ -46,7 +46,8 @@ class FrameworkView;
} } }
class MetroWidget : public nsWindowBase,
public mozilla::layers::GeckoContentController
public mozilla::layers::GeckoContentController,
public nsIObserver
{
typedef mozilla::widget::WindowHook WindowHook;
typedef mozilla::widget::TaskbarWindowPreview TaskbarWindowPreview;
@ -55,6 +56,7 @@ class MetroWidget : public nsWindowBase,
typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs;
typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs;
typedef mozilla::widget::winrt::FrameworkView FrameworkView;
typedef mozilla::layers::FrameMetrics FrameMetrics;
static LRESULT CALLBACK
StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam);
@ -65,6 +67,7 @@ public:
virtual ~MetroWidget();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIOBSERVER
static HWND GetICoreWindowHWND() { return sICoreHwnd; }
@ -194,11 +197,11 @@ public:
void RequestContentRepaintImplMainThread();
// GeckoContentController interface impl
virtual void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics);
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics);
virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint);
virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint);
virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint);
virtual void SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize);
virtual void PostDelayedTask(Task* aTask, int aDelayMs);
virtual void HandlePanBegin();
virtual void HandlePanEnd();
@ -243,6 +246,7 @@ protected:
bool mTempBasicLayerInUse;
Microsoft::WRL::ComPtr<mozilla::widget::winrt::MetroInput> mMetroInput;
mozilla::layers::FrameMetrics mFrameMetrics;
uint64_t mRootLayerTreeId;
public:
static nsRefPtr<mozilla::layers::APZCTreeManager> sAPZC;