зеркало из https://github.com/mozilla/gecko-dev.git
Bug 898580 - Metro mechanism for content to inform APZC about scroll events. Handles multi-APZC. r=bbondy, r=kats
This commit is contained in:
Родитель
e2eae8dab7
Коммит
f4b3e0c923
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче