diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index 54a0ec50e276..0e02528e77a1 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -227,6 +227,9 @@ public: void ActivateUpdateHitRegion(); void DeactivateUpdateHitRegion(); + // Properly retrieves documentSize of any subdocument type. + nsresult GetWindowDimensions(nsIntRect& aRect); + private: void SetOwnerContent(mozilla::dom::Element* aContent); @@ -282,9 +285,6 @@ private: nsresult MaybeCreateDocShell(); nsresult EnsureMessageManager(); - // Properly retrieves documentSize of any subdocument type. - nsresult GetWindowDimensions(nsIntRect& aRect); - // Updates the subdocument position and size. This gets called only // when we have our own in-process DocShell. void UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 094e2a3b7a10..15569ce23612 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -80,6 +80,7 @@ #include "nsICancelable.h" #include "gfxPrefs.h" #include "nsILoginManagerPrompter.h" +#include "nsPIWindowRoot.h" #include using namespace mozilla::dom; @@ -321,7 +322,27 @@ TabParent::RemoveTabParentFromTable(uint64_t aLayersId) void TabParent::SetOwnerElement(Element* aElement) { + // If we held previous content then unregister for its events. + if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) { + nsCOMPtr window = mFrameElement->OwnerDoc()->GetWindow(); + nsCOMPtr eventTarget = window->GetTopWindowRoot(); + if (eventTarget) { + eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"), + this, false); + } + } + + // Update to the new content, and register to listen for events from it. mFrameElement = aElement; + if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) { + nsCOMPtr window = mFrameElement->OwnerDoc()->GetWindow(); + nsCOMPtr eventTarget = window->GetTopWindowRoot(); + if (eventTarget) { + eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"), + this, false, false); + } + } + TryCacheDPIAndScale(); } @@ -357,6 +378,8 @@ TabParent::Destroy() return; } + SetOwnerElement(nullptr); + // If this fails, it's most likely due to a content-process crash, // and auto-cleanup will kick in. Otherwise, the child side will // destroy itself and send back __delete__(). @@ -900,8 +923,9 @@ TabParent::UpdateDimensions(const nsIntRect& rect, const nsIntSize& size, mRect = rect; mDimensions = size; mOrientation = orientation; + mChromeDisp = aChromeDisp; - unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, aChromeDisp); + unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, mChromeDisp); } } @@ -2668,6 +2692,27 @@ TabParent::DeallocPPluginWidgetParent(mozilla::plugins::PPluginWidgetParent* aAc return true; } +nsresult +TabParent::HandleEvent(nsIDOMEvent* aEvent) +{ + nsAutoString eventType; + aEvent->GetType(eventType); + + if (eventType.EqualsLiteral("MozUpdateWindowPos")) { + // This event is sent when the widget moved. Therefore we only update + // the position. + nsRefPtr frameLoader = GetFrameLoader(); + if (!frameLoader) { + return NS_OK; + } + nsIntRect windowDims; + NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE); + UpdateDimensions(windowDims, mDimensions, mChromeDisp); + return NS_OK; + } + return NS_OK; +} + class FakeChannel MOZ_FINAL : public nsIChannel, public nsIAuthPromptCallback, public nsIInterfaceRequestor, diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index f8c49232e8fb..63e2cc51aef9 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -22,6 +22,7 @@ #include "Units.h" #include "WritingModes.h" #include "js/TypeDecls.h" +#include "nsIDOMEventListener.h" class nsFrameLoader; class nsIFrameLoader; @@ -58,7 +59,8 @@ class nsIContentParent; class Element; struct StructuredCloneData; -class TabParent : public PBrowserParent +class TabParent : public PBrowserParent + , public nsIDOMEventListener , public nsITabParent , public nsIAuthPromptProvider , public nsISecureBrowserUI @@ -99,6 +101,9 @@ public: mBrowserDOMWindow = aBrowserDOMWindow; } + // nsIDOMEventListener interfaces + NS_DECL_NSIDOMEVENTLISTENER + already_AddRefed GetLoadContext(); nsIXULBrowserWindow* GetXULBrowserWindow(); @@ -440,6 +445,7 @@ protected: nsIntRect mRect; nsIntSize mDimensions; ScreenOrientation mOrientation; + nsIntPoint mChromeDisp; float mDPI; CSSToLayoutDeviceScale mDefaultScale; bool mShown; diff --git a/xpfe/appshell/nsWebShellWindow.cpp b/xpfe/appshell/nsWebShellWindow.cpp index 29dde6155d25..4c6632f680ea 100644 --- a/xpfe/appshell/nsWebShellWindow.cpp +++ b/xpfe/appshell/nsWebShellWindow.cpp @@ -71,6 +71,8 @@ #include "mozilla/DebugOnly.h" #include "mozilla/MouseEvents.h" +#include "nsPIWindowRoot.h" + #ifdef XP_MACOSX #include "nsINativeMenuService.h" #define USE_NATIVE_MENUS @@ -257,6 +259,15 @@ nsWebShellWindow::WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) pm->AdjustPopupsOnWindowChange(window); } + // Notify all tabs that the widget moved. + if (mDocShell && mDocShell->GetWindow()) { + nsCOMPtr eventTarget = mDocShell->GetWindow()->GetTopWindowRoot(); + nsContentUtils::DispatchChromeEvent(mDocShell->GetDocument(), + eventTarget, + NS_LITERAL_STRING("MozUpdateWindowPos"), + false, false, nullptr); + } + // Persist position, but not immediately, in case this OS is firing // repeated move events as the user drags the window SetPersistenceTimer(PAD_POSITION);