Browse Source

import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1178833 - Fix for unified builds when a new file is added to layout/base. r=mstange (bf961c00fd)
- Bug 1178847 - Add a MobileViewportManager to manage setting the CSS viewport on B2G. r=botond,tn (937ba486fa)
- Bug 1178847 - Don't use the MobileViewportManager code on Mulet or Fennec yet. r=botond (3061b2c617)
- Bug 1168950. Add the document to DoProcessRestyles profile label. r=dbaron (2347b76411)
- Bug 1187792 - Don't set the SPCSPS unless meta-viewport or zooming is enabled. r=botond (a8f5ed1006)
- Bug 1193062 - Don't double-send target APZC confirmations that might race each other. r=kats (de48467401)
- Bug 1186004 - Add a pref to enable/disable APZ zooming behaviour. r=botond (fc3653c979)
- Bug 1193062 - Add a PAN_MOMENTUM state. r=kats (10c8bb1a5e)
- Bug 1148350 - Have ConvertToGecko use a live screen-to-apzc transform to avoid transform mismatches. r=botond (9eee9ea6f2)
- Bug 1169844 - Remove incorrect assertion and properly untransform wheel events for overscroll situations. r=botond (9b101b53bb)
- Bug 1169690 - Accelerate flings correctly in the presence of overscroll handoff. r=kats (49d55c05f4)
- Bug 1158424 - Extract a BreadthFirstSearch() helper function. r=kats (6a49498185)
- Bug 1158424 - Add APZCTreeManager::FindRootContentApzcForLayersId(). r=kats (d6c7ecf781)
- Bug 1158424 - Fix APZCTreeManager::GetMultitouchTarget(). r=kats (bf8571a4ca)
- Bug 1174205 - Make sure to acquire the tree lock before finding the multitouch target. r=botond (bdbd98f2c7)
- Bug 1211660 - Remove dead obj argument from two functions. r=Waldo. (efba5a2f8d)
- Bug 1158424 - Undeprecate HasNoParentWithSameLayersId(). r=kats (d994ea28f8)
- Fix AsyncCompositionManager not comparing layer tree IDs when finding scrollbar targets. (bug 1151169, r=kats) (c7dbc4776a)
- Bug 1163259. Make sure we don't look at the parent ref layer when looking for a layer with the frame metrics for a scrollbar. r=kats (8b99d2c830)
- Bug 1164340. Convert the scrollbar thumb ratio to a unitless ratio properly for non-zoomable scrollframes. r=botond (27f56cab56)
- Bug 1164340. Fix up some scrollbar related comments in AsyncCompositionManager. r=botond (b9d540bea9)
- Bug 1164767. Modify async scrollbar positioning code to deal with containerless root scrollables. r=botond (501d07592e)
- Bug 1158424 - Remove FrameMetrics::IsRootScrollable() (it just duplicated IsRootContent()). r=kats (672fd034b3)
- Bug 1120683 - Properly handle unapplying 3D projective transforms throughout APZ code. r=botond (a46612811a)
- Bug 1148868 - Make APZ wheel handling handle pixel scrolling on OS X. r=dvander, r=kats (da3bd34135)
- Bug 1193062 - Add fields to PanGestureInput and ScrollWheelInput. r=kats (716ba34e18)
- Bug 1189565 - Send resize events when backing scale factor changes. r=mstange (4e81a7bbf7)
- Bug 1193062 - Add nsCocoaUtils::ModifiersForEvent. r=smichaud (da67b22ff7)
- Bug 1016035 - Remove the ability to swipe vertically. r=kats (fa315e0b97)
- Bug 1016035 - Refactor the code that decides whether we want to start a swipe. r=kats (3091961328)
- Bug 1016035 - Make the threshold in AxisPhysicsMSDModel::IsFinished controllable by the caller. r=kip (76df4d85a2)
- Bug 1016035 - More swipe refactoring. r=kats (2abcd05b33)
- Bug 1016035 - Implement the swipe animation ourselves instead of calling the NSEvent trackSwipe API. r=kats (4842b2a728)
- Bug 1016035 - Move swipe tracking code into DispatchAPZWheelInputEvent. r=kats (bb1052b87c)
- Bug 1016035 - Also mark widgetWheelEvents that are handled by APZ with mCanStartSwipe. r=kats (21809b902d)
- Bug 1016035 - Put PanGestureInput events into a queue if they can end up as a swipe. r=kats (2ebac59047)
- Bug 1016035 - Split up MaybeTrackScrollEventAsSwipe into SendMayStartSwipe and TrackScrollEventAsSwipe. r=kats (ced10d9671)
- Bug 1016035 - Send MayStartSwipe event before sending the wheel event. r=kats (b3346b81fb)
- Fix some fields missing in the widget event IPC glue. (bug 1139711, r=kats) (1298b25705)
- Bug 1016035 - Add mCanTriggerSwipe and TriggersSwipe(). r=masayuki (664a059972)
- Bug 1016035 - Make APZEventState report defaultPrevented=true when the event started a swipe. r=kats (128d627ac7)
- Bug 1016035 - Set scroll overflow information on potential swipe start events that have been processed by APZ. r=masayuki (b5931f6320)
- Bug 1206801 - fix broken CONFIG['DEBUG'] checks in moz.build files; r=mshal (292d5ac709)
- Bug 1186424: Refactor AsmJSValidate.cpp in preparation for parallelization; r=luke (4868bc66ca)
- Bug 1129267 - Fix by backing out patch for bug 1118615. r=mstange (ea8aaba04e)
- Bug 1182411 Part 1: Make plugin quirks available to the Parent as well as the Child. r=jimm (1f2551a6b7)
- Bug 1228462 - "PluginQuirks.* uses DOS CRLF". r=jmathies (b569a6c6c8)
- Bug 1152300 - When focus shifts from a native plugin window to content, content needs to forward the request for focus change to chrome. r=enn (5bd811fadd)
- Bug 1185529: On Windows, ensure that NPAPI child window has the correct parent before setwindow is called. r=jimm (9d94fdf2ff)
- Bug 1182411 Part 2: Change winless popup surrogate to have its parent set in the chrome process. r=jimm (adee9bb012)
pull/8/head
roytam1 5 months ago
parent
commit
e9ba40cf6b
  1. 9
      b2g/app/b2g.js
  2. 4
      dom/base/nsDocument.cpp
  3. 26
      dom/base/nsFocusManager.cpp
  4. 6
      dom/base/nsViewportInfo.h
  5. 23
      dom/events/EventStateManager.cpp
  6. 13
      dom/ipc/PBrowser.ipdl
  7. 454
      dom/ipc/TabChild.cpp
  8. 25
      dom/ipc/TabChild.h
  9. 50
      dom/ipc/TabParent.cpp
  10. 4
      dom/ipc/TabParent.h
  11. 13
      dom/plugins/base/nsNPAPIPlugin.cpp
  12. 106
      dom/plugins/base/nsPluginInstanceOwner.cpp
  13. 9
      dom/plugins/base/nsPluginInstanceOwner.h
  14. 17
      dom/plugins/ipc/PPluginInstance.ipdl
  15. 151
      dom/plugins/ipc/PluginInstanceChild.cpp
  16. 10
      dom/plugins/ipc/PluginInstanceChild.h
  17. 123
      dom/plugins/ipc/PluginInstanceParent.cpp
  18. 10
      dom/plugins/ipc/PluginInstanceParent.h
  19. 49
      dom/plugins/ipc/PluginModuleChild.cpp
  20. 56
      dom/plugins/ipc/PluginModuleChild.h
  21. 16
      dom/plugins/ipc/PluginModuleParent.cpp
  22. 9
      dom/plugins/ipc/PluginModuleParent.h
  23. 69
      dom/plugins/ipc/PluginQuirks.cpp
  24. 69
      dom/plugins/ipc/PluginQuirks.h
  25. 5
      dom/plugins/ipc/PluginWidgetParent.cpp
  26. 2
      dom/plugins/ipc/moz.build
  27. 25
      gfx/layers/AxisPhysicsMSDModel.cpp
  28. 2
      gfx/layers/AxisPhysicsMSDModel.h
  29. 5
      gfx/layers/FrameMetrics.h
  30. 170
      gfx/layers/apz/src/APZCTreeManager.cpp
  31. 2
      gfx/layers/apz/src/APZCTreeManager.h
  32. 73
      gfx/layers/apz/src/AsyncPanZoomController.cpp
  33. 13
      gfx/layers/apz/src/AsyncPanZoomController.h
  34. 4
      gfx/layers/apz/src/GestureEventListener.cpp
  35. 5
      gfx/layers/apz/src/HitTestingTreeNode.cpp
  36. 71
      gfx/layers/apz/util/APZCCallbackHelper.cpp
  37. 3
      gfx/layers/apz/util/APZCCallbackHelper.h
  38. 6
      gfx/layers/apz/util/APZEventState.cpp
  39. 122
      gfx/layers/composite/AsyncCompositionManager.cpp
  40. 1
      gfx/thebes/gfxPrefs.h
  41. 40
      js/src/asmjs/AsmJSModule.h
  42. 2411
      js/src/asmjs/AsmJSValidate.cpp
  43. 4
      js/src/builtin/TypedObject.cpp
  44. 3
      js/src/devtools/rootAnalysis/annotations.js
  45. 2
      js/src/vm/HelperThreads.h
  46. 20
      js/src/vm/NativeObject.cpp
  47. 4
      js/src/vm/NativeObject.h
  48. 4
      js/src/vm/UnboxedObject.cpp
  49. 284
      layout/base/MobileViewportManager.cpp
  50. 62
      layout/base/MobileViewportManager.h
  51. 14
      layout/base/RestyleTracker.cpp
  52. 39
      layout/base/UnitTransforms.h
  53. 4
      layout/base/ZoomConstraintsClient.cpp
  54. 1
      layout/base/moz.build
  55. 11
      layout/base/nsIPresShell.h
  56. 32
      layout/base/nsPresShell.cpp
  57. 10
      layout/base/nsPresShell.h
  58. 10
      layout/generic/nsGfxScrollFrame.cpp
  59. 1
      modules/libpref/init/all.js
  60. 123
      widget/InputData.cpp
  61. 54
      widget/InputData.h
  62. 16
      widget/MouseEvents.h
  63. 17
      widget/PuppetWidget.cpp
  64. 3
      widget/PuppetWidget.h
  65. 96
      widget/cocoa/SwipeTracker.h
  66. 219
      widget/cocoa/SwipeTracker.mm
  67. 7
      widget/cocoa/moz.build
  68. 29
      widget/cocoa/nsChildView.h
  69. 405
      widget/cocoa/nsChildView.mm
  70. 8
      widget/cocoa/nsCocoaUtils.h
  71. 41
      widget/cocoa/nsCocoaUtils.mm
  72. 3
      widget/cocoa/nsCocoaWindow.mm
  73. 8
      widget/nsGUIEventIPC.h
  74. 5
      widget/nsIWidget.h
  75. 33
      widget/windows/nsWindow.cpp
  76. 2
      xulrunner/app/moz.build

9
b2g/app/b2g.js

@ -4,6 +4,8 @@
#filter substitution
// For the all MOZ_MULET ifdef conditions in this file: see bug 1174234
#ifndef MOZ_MULET
pref("toolkit.defaultChromeURI", "chrome://b2g/content/shell.html");
pref("browser.chromeURL", "chrome://b2g/content/");
@ -385,7 +387,9 @@ pref("dom.ipc.processCount", 100000);
pref("dom.ipc.browser_frames.oop_by_default", false);
#ifndef MOZ_MULET
pref("dom.meta-viewport.enabled", true);
#endif
// SMS/MMS
pref("dom.sms.enabled", true);
@ -956,7 +960,10 @@ pref("security.exthelperapp.disable_background_handling", true);
pref("osfile.reset_worker_delay", 5000);
// APZC preferences.
//
#ifdef MOZ_WIDGET_GONK
pref("apz.allow_zooming", true);
#endif
// Gaia relies heavily on scroll events for now, so lets fire them
// more often than the default value (100).
pref("apz.asyncscroll.throttle", 40);

4
dom/base/nsDocument.cpp

@ -7895,14 +7895,14 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/false,
/*allowDoubleTapZoom*/ true);
/*allowDoubleTapZoom*/ false);
}
if (!gfxPrefs::MetaViewportEnabled()) {
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/ false,
/*allowDoubleTapZoom*/ true);
/*allowDoubleTapZoom*/ false);
}
// In cases where the width of the CSS viewport is less than or equal to the width

26
dom/base/nsFocusManager.cpp

@ -1641,14 +1641,24 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
nsIFrame* contentFrame = content->GetPrimaryFrame();
nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
if (aAdjustWidgets && objectFrame && !sTestMode) {
// note that the presshell's widget is being retrieved here, not the one
// for the object frame.
nsViewManager* vm = presShell->GetViewManager();
if (vm) {
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
if (widget)
widget->SetFocus(false);
if (XRE_IsContentProcess()) {
// set focus to the top level window via the chrome process.
nsCOMPtr<nsITabChild> tabChild = do_GetInterface(docShell);
if (tabChild) {
static_cast<TabChild*>(tabChild.get())->SendDispatchFocusToTopLevelWindow();
}
} else {
// note that the presshell's widget is being retrieved here, not the one
// for the object frame.
nsViewManager* vm = presShell->GetViewManager();
if (vm) {
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
if (widget) {
// set focus to the top level window but don't raise it.
widget->SetFocus(false);
}
}
}
}
}

6
dom/base/nsViewportInfo.h

@ -34,6 +34,9 @@ class MOZ_STACK_CLASS nsViewportInfo
mAllowZoom(aAllowZoom),
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
{
// Don't allow double-tap zooming unless zooming is also allowed
MOZ_ASSERT(mAllowZoom || !mAllowDoubleTapZoom);
mSize = mozilla::ScreenSize(aDisplaySize) / mDefaultZoom;
mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
mMinZoom = pixelRatio * kViewportMinScale;
@ -56,6 +59,9 @@ class MOZ_STACK_CLASS nsViewportInfo
mAllowZoom(aAllowZoom),
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
{
// Don't allow double-tap zooming unless zooming is also allowed
MOZ_ASSERT(mAllowZoom || !mAllowDoubleTapZoom);
ConstrainViewportValues();
}

23
dom/events/EventStateManager.cpp

@ -3143,12 +3143,31 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
case WheelPrefs::ACTION_NONE:
default:
// If we don't handle the wheel event, all of the delta values must
// be overflown delta values.
bool allDeltaOverflown = false;
if (wheelEvent->mFlags.mHandledByAPZ) {
if (wheelEvent->mCanTriggerSwipe) {
// For events that can trigger swipes, APZ needs to know whether
// scrolling is possible in the requested direction. It does this
// by looking at the scroll overflow values on mCanTriggerSwipe
// events after they have been processed.
allDeltaOverflown =
!ComputeScrollTarget(aTargetFrame, wheelEvent,
COMPUTE_DEFAULT_ACTION_TARGET);
}
} else {
// The event was processed neither by APZ nor by us, so all of the
// delta values must be overflown delta values.
allDeltaOverflown = true;
}
if (!allDeltaOverflown) {
break;
}
wheelEvent->overflowDeltaX = wheelEvent->deltaX;
wheelEvent->overflowDeltaY = wheelEvent->deltaY;
WheelPrefs::GetInstance()->
CancelApplyingUserPrefsFromOverflowDelta(wheelEvent);
wheelEvent->mViewPortIsOverscrolled = true;
break;
}
*aStatus = nsEventStatus_eConsumeNoDefault;

13
dom/ipc/PBrowser.ipdl

@ -141,6 +141,19 @@ parent:
*/
sync GetWidgetNativeData() returns (WindowsHandle value);
/**
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
* widget's shareable window on the chrome side. Only used on Windows.
*/
async SetNativeChildOfShareableWindow(uintptr_t childWindow);
/**
* When content moves focus from a native plugin window that's a child
* of the native browser window we need to move native focus to the
* browser. Otherwise the plugin window will never relinquish focus.
*/
sync DispatchFocusToTopLevelWindow();
parent:
/**
* When child sends this message, parent should move focus to

454
dom/ipc/TabChild.cpp

@ -165,8 +165,7 @@ NS_IMPL_ISUPPORTS(TabChild::DelayedFireContextMenuEvent,
nsITimerCallback)
TabChildBase::TabChildBase()
: mContentDocumentIsDisplayed(false)
, mTabChildGlobal(nullptr)
: mTabChildGlobal(nullptr)
{
mozilla::HoldJSObjects(this);
}
@ -206,280 +205,6 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(TabChildBase)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TabChildBase)
// For the root frame, Screen and ParentLayer pixels are interchangeable.
// nsViewportInfo stores zoom values as CSSToScreenScale (because it's a
// data structure specific to the root frame), while FrameMetrics and
// ZoomConstraints store zoom values as CSSToParentLayerScale (because they
// are not specific to the root frame). We define convenience functions for
// converting between the two. As the name suggests, they should only be used
// when dealing with the root frame!
CSSToScreenScale ConvertScaleForRoot(CSSToParentLayerScale aScale)
{
return ViewTargetAs<ScreenPixel>(aScale, PixelCastJustification::ScreenIsParentLayerForRoot);
}
CSSToParentLayerScale ConvertScaleForRoot(CSSToScreenScale aScale)
{
return ViewTargetAs<ParentLayerPixel>(aScale, PixelCastJustification::ScreenIsParentLayerForRoot);
}
// Calculate the scale needed to fit the given viewport into the given display.
CSSToScreenScale CalculateIntrinsicScale(const ScreenIntSize& aDisplaySize, const CSSSize& aViewportSize)
{
return MaxScaleRatio(ScreenSize(aDisplaySize), aViewportSize);
}
void
TabChildBase::InitializeRootMetrics()
{
// Calculate a really simple resolution that we probably won't
// be keeping, as well as putting the scroll offset back to
// the top-left of the page.
mLastRootMetrics.SetViewport(CSSRect(CSSPoint(), kDefaultViewportSize));
mLastRootMetrics.SetCompositionBounds(ParentLayerRect(
ParentLayerPoint(),
ParentLayerSize(
ViewAs<ParentLayerPixel>(GetInnerSize(),
PixelCastJustification::ScreenIsParentLayerForRoot))));
mLastRootMetrics.SetZoom(CSSToParentLayerScale2D(
ConvertScaleForRoot(CalculateIntrinsicScale(GetInnerSize(), kDefaultViewportSize))));
mLastRootMetrics.SetDevPixelsPerCSSPixel(WebWidget()->GetDefaultScale());
// We use ParentLayerToLayerScale(1) below in order to turn the
// async zoom amount into the gecko zoom amount.
mLastRootMetrics.SetCumulativeResolution(mLastRootMetrics.GetZoom() / mLastRootMetrics.GetDevPixelsPerCSSPixel() * ParentLayerToLayerScale(1));
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
mLastRootMetrics.SetPresShellResolution(mLastRootMetrics.GetCumulativeResolution().ToScaleFactor().scale);
nsCOMPtr<nsIPresShell> shell = GetPresShell();
if (shell && shell->GetRootScrollFrameAsScrollable()) {
// The session history code might restore a scroll position when navigating
// back or forward, and we don't want to clobber that.
nsPoint pos = shell->GetRootScrollFrameAsScrollable()->GetScrollPosition();
mLastRootMetrics.SetScrollOffset(CSSPoint::FromAppUnits(pos));
} else {
mLastRootMetrics.SetScrollOffset(CSSPoint(0, 0));
}
TABC_LOG("After InitializeRootMetrics, mLastRootMetrics is %s\n",
Stringify(mLastRootMetrics).c_str());
}
void
TabChildBase::SetCSSViewport(const CSSSize& aSize)
{
mOldViewportSize = aSize;
TABC_LOG("Setting CSS viewport to %s\n", Stringify(aSize).c_str());
if (mContentDocumentIsDisplayed) {
if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
nsLayoutUtils::SetCSSViewport(shell, aSize);
}
}
}
CSSSize
TabChildBase::GetPageSize(nsCOMPtr<nsIDocument> aDocument, const CSSSize& aViewport)
{
nsCOMPtr<Element> htmlDOMElement = aDocument->GetHtmlElement();
HTMLBodyElement* bodyDOMElement = aDocument->GetBodyElement();
if (!htmlDOMElement && !bodyDOMElement) {
// For non-HTML content (e.g. SVG), just assume page size == viewport size.
return aViewport;
}
int32_t htmlWidth = 0, htmlHeight = 0;
if (htmlDOMElement) {
htmlWidth = htmlDOMElement->ScrollWidth();
htmlHeight = htmlDOMElement->ScrollHeight();
}
int32_t bodyWidth = 0, bodyHeight = 0;
if (bodyDOMElement) {
bodyWidth = bodyDOMElement->ScrollWidth();
bodyHeight = bodyDOMElement->ScrollHeight();
}
return CSSSize(std::max(htmlWidth, bodyWidth),
std::max(htmlHeight, bodyHeight));
}
bool
TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
{
PuppetWidget* widget = WebWidget();
if (!widget || !widget->AsyncPanZoomEnabled()) {
return false;
}
TABC_LOG("HandlePossibleViewportChange aOldScreenSize=%s mInnerSize=%s\n",
Stringify(aOldScreenSize).c_str(), Stringify(GetInnerSize()).c_str());
nsCOMPtr<nsIDocument> document(GetDocument());
if (!document) {
return false;
}
nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, GetInnerSize());
uint32_t presShellId = 0;
mozilla::layers::FrameMetrics::ViewID viewId = FrameMetrics::NULL_SCROLL_ID;
APZCCallbackHelper::GetOrCreateScrollIdentifiers(
document->GetDocumentElement(), &presShellId, &viewId);
float screenW = GetInnerSize().width;
float screenH = GetInnerSize().height;
CSSSize viewport(viewportInfo.GetSize());
// We're not being displayed in any way; don't bother doing anything because
// that will just confuse future adjustments.
if (!screenW || !screenH) {
return false;
}
TABC_LOG("HandlePossibleViewportChange mOldViewportSize=%s viewport=%s\n",
Stringify(mOldViewportSize).c_str(), Stringify(viewport).c_str());
CSSSize oldBrowserSize = mOldViewportSize;
mLastRootMetrics.SetViewport(CSSRect(
mLastRootMetrics.GetViewport().TopLeft(), viewport));
if (oldBrowserSize == CSSSize()) {
oldBrowserSize = kDefaultViewportSize;
}
SetCSSViewport(viewport);
// If this page has not been painted yet, then this must be getting run
// because a meta-viewport element was added (via the DOMMetaAdded handler).
// in this case, we should not do anything that forces a reflow (see bug
// 759678) such as requesting the page size or sending a viewport update. this
// code will get run again in the before-first-paint handler and that point we
// will run though all of it. the reason we even bother executing up to this
// point on the DOMMetaAdded handler is so that scripts that use
// window.innerWidth before they are painted have a correct value (bug
// 771575).
if (!mContentDocumentIsDisplayed) {
return false;
}
ScreenIntSize oldScreenSize = aOldScreenSize;
if (oldScreenSize == ScreenIntSize()) {
oldScreenSize = GetInnerSize();
}
FrameMetrics metrics(mLastRootMetrics);
metrics.SetViewport(CSSRect(CSSPoint(), viewport));
// Calculate the composition bounds based on the inner size, excluding the sizes
// of the scrollbars if they are not overlay scrollbars.
ScreenSize compositionSize(GetInnerSize());
nsCOMPtr<nsIPresShell> shell = GetPresShell();
if (shell) {
nsMargin scrollbarsAppUnits =
nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(shell->GetRootScrollFrame());
// Scrollbars are not subject to scaling, so CSS pixels = screen pixels for them.
ScreenMargin scrollbars = CSSMargin::FromAppUnits(scrollbarsAppUnits)
* CSSToScreenScale(1.0f);
compositionSize.width -= scrollbars.LeftRight();
compositionSize.height -= scrollbars.TopBottom();
}
metrics.SetCompositionBounds(ParentLayerRect(
ParentLayerPoint(),
ParentLayerSize(
ViewAs<ParentLayerPixel>(GetInnerSize(),
PixelCastJustification::ScreenIsParentLayerForRoot))));
metrics.SetRootCompositionSize(
ScreenSize(compositionSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.GetDevPixelsPerCSSPixel());
// This change to the zoom accounts for all types of changes I can conceive:
// 1. screen size changes, CSS viewport does not (pages with no meta viewport
// or a fixed size viewport)
// 2. screen size changes, CSS viewport also does (pages with a device-width
// viewport)
// 3. screen size remains constant, but CSS viewport changes (meta viewport
// tag is added or removed)
// 4. neither screen size nor CSS viewport changes
//
// In all of these cases, we maintain how much actual content is visible
// within the screen width. Note that "actual content" may be different with
// respect to CSS pixels because of the CSS viewport size changing.
CSSToScreenScale oldIntrinsicScale = CalculateIntrinsicScale(oldScreenSize, oldBrowserSize);
CSSToScreenScale newIntrinsicScale = CalculateIntrinsicScale(GetInnerSize(), viewport);
metrics.ZoomBy(newIntrinsicScale.scale / oldIntrinsicScale.scale);
// Changing the zoom when we're not doing a first paint will get ignored
// by AsyncPanZoomController and causes a blurry flash.
bool isFirstPaint = true;
if (shell) {
isFirstPaint = shell->GetIsFirstPaint();
}
if (isFirstPaint) {
// FIXME/bug 799585(?): GetViewportInfo() returns a defaultZoom of
// 0.0 to mean "did not calculate a zoom". In that case, we default
// it to the intrinsic scale.
if (viewportInfo.GetDefaultZoom().scale < 0.01f) {
viewportInfo.SetDefaultZoom(newIntrinsicScale);
}
CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom();
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
defaultZoom <= viewportInfo.GetMaxZoom());
metrics.SetZoom(CSSToParentLayerScale2D(ConvertScaleForRoot(defaultZoom)));
metrics.SetPresShellId(presShellId);
metrics.SetScrollId(viewId);
}
if (shell) {
if (nsPresContext* context = shell->GetPresContext()) {
metrics.SetDevPixelsPerCSSPixel(CSSToLayoutDeviceScale(
(float)nsPresContext::AppUnitsPerCSSPixel() / context->AppUnitsPerDevPixel()));
}
}
metrics.SetCumulativeResolution(metrics.GetZoom()
/ metrics.GetDevPixelsPerCSSPixel()
* ParentLayerToLayerScale(1));
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
metrics.SetPresShellResolution(metrics.GetCumulativeResolution().ToScaleFactor().scale);
if (shell) {
nsLayoutUtils::SetResolutionAndScaleTo(shell, metrics.GetPresShellResolution());
nsLayoutUtils::SetScrollPositionClampingScrollPortSize(shell,
metrics.CalculateCompositedSizeInCssPixels());
}
// The call to GetPageSize forces a resize event to content, so we need to
// make sure that we have the right CSS viewport and
// scrollPositionClampingScrollPortSize set up before that happens.
CSSSize pageSize = GetPageSize(document, viewport);
if (!pageSize.width) {
// Return early rather than divide by 0.
return false;
}
metrics.SetScrollableRect(CSSRect(CSSPoint(), pageSize));
// Calculate a display port _after_ having a scrollable rect because the
// display port is clamped to the scrollable rect.
metrics.SetDisplayPortMargins(APZCTreeManager::CalculatePendingDisplayPort(
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, ParentLayerPoint(0.0f, 0.0f), 0.0));
metrics.SetUseDisplayPortMargins();
// Force a repaint with these metrics. This, among other things, sets the
// displayport, so we start with async painting.
mLastRootMetrics = ProcessUpdateFrame(metrics);
return true;
}
already_AddRefed<nsIDOMWindowUtils>
TabChildBase::GetDOMWindowUtils()
{
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation());
nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
return utils.forget();
}
already_AddRefed<nsIDocument>
TabChildBase::GetDocument() const
{
@ -535,7 +260,7 @@ TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
// Guard against stale updates (updates meant for a pres shell which
// has since been torn down and destroyed).
if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
mLastRootMetrics = ProcessUpdateFrame(aFrameMetrics);
ProcessUpdateFrame(aFrameMetrics);
return true;
}
}
@ -549,11 +274,11 @@ TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
return true;
}
FrameMetrics
void
TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
{
if (!mGlobal || !mTabChildGlobal) {
return aFrameMetrics;
return;
}
FrameMetrics newMetrics = aFrameMetrics;
@ -591,7 +316,6 @@ TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
data.AppendLiteral(" }");
DispatchMessageManagerMessage(NS_LITERAL_STRING("Viewport:Change"), data);
return newMetrics;
}
NS_IMETHODIMP
@ -909,22 +633,6 @@ TabChild::TabChild(nsIContentChild* aManager,
}
}
NS_IMETHODIMP
TabChild::HandleEvent(nsIDOMEvent* aEvent)
{
nsAutoString eventType;
aEvent->GetType(eventType);
if (eventType.EqualsLiteral("DOMMetaAdded")) {
// This meta data may or may not have been a meta viewport tag. If it was,
// we should handle it immediately.
HandlePossibleViewportChange(GetInnerSize());
} else if (eventType.EqualsLiteral("FullZoomChange")) {
HandlePossibleViewportChange(GetInnerSize());
}
return NS_OK;
}
NS_IMETHODIMP
TabChild::Observe(nsISupports *aSubject,
const char *aTopic,
@ -957,19 +665,7 @@ TabChild::Observe(nsISupports *aSubject,
shell->SetIsFirstPaint(true);
}
mContentDocumentIsDisplayed = true;
// In some cases before-first-paint gets called before
// RecvUpdateDimensions is called and therefore before we have an
// inner size value set. In such cases defer initializing the viewport
// until we we get an inner size.
if (HasValidInnerSize()) {
InitializeRootMetrics();
if (shell) {
nsLayoutUtils::SetResolutionAndScaleTo(shell, mLastRootMetrics.GetPresShellResolution());
}
HandlePossibleViewportChange(GetInnerSize());
}
APZCCallbackHelper::InitializeRootDisplayport(shell);
}
}
}
@ -1027,100 +723,6 @@ TabChild::Observe(nsISupports *aSubject,
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
uint32_t aStateFlags,
nsresult aStatus)
{
NS_NOTREACHED("not implemented in TabChild");
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnProgressChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
int32_t aCurSelfProgress,
int32_t aMaxSelfProgress,
int32_t aCurTotalProgress,
int32_t aMaxTotalProgress)
{
NS_NOTREACHED("not implemented in TabChild");
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI *aLocation,
uint32_t aFlags)
{
if (!AsyncPanZoomEnabled()) {
return NS_OK;
}
nsCOMPtr<nsIDOMWindow> window;
aWebProgress->GetDOMWindow(getter_AddRefs(window));
if (!window) {
return NS_OK;
}
nsCOMPtr<nsIDOMDocument> progressDoc;
window->GetDocument(getter_AddRefs(progressDoc));
if (!progressDoc) {
return NS_OK;
}
nsCOMPtr<nsIDOMDocument> domDoc;
WebNavigation()->GetDocument(getter_AddRefs(domDoc));
if (!domDoc || !SameCOMIdentity(domDoc, progressDoc)) {
return NS_OK;
}
nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID));
if (!urifixup) {
return NS_OK;
}
nsCOMPtr<nsIURI> exposableURI;
urifixup->CreateExposableURI(aLocation, getter_AddRefs(exposableURI));
if (!exposableURI) {
return NS_OK;
}
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
mContentDocumentIsDisplayed = false;
} else if (mLastURI != nullptr) {
bool exposableEqualsLast, exposableEqualsNew;
exposableURI->Equals(mLastURI.get(), &exposableEqualsLast);
exposableURI->Equals(aLocation, &exposableEqualsNew);
if (exposableEqualsLast && !exposableEqualsNew) {
mContentDocumentIsDisplayed = false;
}
}
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnStatusChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsresult aStatus,
const char16_t* aMessage)
{
NS_NOTREACHED("not implemented in TabChild");
return NS_OK;
}
NS_IMETHODIMP
TabChild::OnSecurityChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
uint32_t aState)
{
NS_NOTREACHED("not implemented in TabChild");
return NS_OK;
}
bool
TabChild::DoUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
@ -1201,10 +803,6 @@ TabChild::Init()
loadContext->SetRemoteTabs(
mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
NS_ENSURE_TRUE(webProgress, NS_ERROR_FAILURE);
webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_LOCATION);
// Few lines before, baseWindow->Create() will end up creating a new
// window root in nsGlobalWindow::SetDocShell.
// Then this chrome event handler, will be inherited to inner windows.
@ -1249,8 +847,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsITabChild)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@ -1651,12 +1247,6 @@ TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
return NS_OK;
}
bool
TabChild::HasValidInnerSize()
{
return mHasValidInnerSize;
}
void
TabChild::DestroyWindow()
{
@ -2112,40 +1702,25 @@ TabChild::RecvUpdateDimensions(const CSSRect& rect, const CSSSize& size,
mUnscaledOuterRect = rect;
mChromeDisp = chromeDisp;
bool initialSizing = !HasValidInnerSize()
&& (size.width != 0 && size.height != 0);
mOrientation = orientation;
ScreenIntSize oldScreenSize = GetInnerSize();
SetUnscaledInnerSize(size);
ScreenIntSize screenSize = GetInnerSize();
bool sizeChanged = true;
if (initialSizing) {
if (!mHasValidInnerSize && size.width != 0 && size.height != 0) {
mHasValidInnerSize = true;
} else if (screenSize == oldScreenSize) {
sizeChanged = false;
}
ScreenIntSize screenSize = GetInnerSize();
ScreenIntRect screenRect = GetOuterRect();
mPuppetWidget->Resize(screenRect.x + chromeDisp.x,
screenRect.y + chromeDisp.y,
screenSize.width, screenSize.height, true);
// Set the size on the document viewer before we update the widget and
// trigger a reflow. Otherwise the MobileViewportManager reads the stale
// size from the content viewer when it computes a new CSS viewport.
nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
true);
if (initialSizing && mContentDocumentIsDisplayed) {
// If this is the first time we're getting a valid inner size, and the
// before-first-paint event has already been handled, then we need to set
// up our default viewport here. See the corresponding call to
// InitializeRootMetrics in the before-first-paint handler.
InitializeRootMetrics();
}
if (sizeChanged) {
HandlePossibleViewportChange(oldScreenSize);
}
mPuppetWidget->Resize(screenRect.x + chromeDisp.x,
screenRect.y + chromeDisp.y,
screenSize.width, screenSize.height, true);
return true;
}
@ -3000,9 +2575,6 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
NS_ENSURE_TRUE(root, false);
root->SetParentTarget(scope);
chromeHandler->AddEventListener(NS_LITERAL_STRING("DOMMetaAdded"), this, false);
chromeHandler->AddEventListener(NS_LITERAL_STRING("FullZoomChange"), this, false);
}
if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) {

25
dom/ipc/TabChild.h

@ -21,7 +21,6 @@
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsFrameMessageManager.h"
#include "nsIWebProgressListener.h"
#include "nsIPresShell.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsWeakReference.h"
@ -183,12 +182,6 @@ public:
virtual nsIWebNavigation* WebNavigation() const = 0;
virtual PuppetWidget* WebWidget() = 0;
nsIPrincipal* GetPrincipal() { return mPrincipal; }
// Recalculates the display state, including the CSS
// viewport. This should be called whenever we believe the
// viewport data on a document may have changed. If it didn't
// change, this function doesn't do anything. However, it should
// not be called all the time as it is fairly expensive.
bool HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize);
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
const mozilla::layers::FrameMetrics::ViewID& aViewId,
const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
@ -197,19 +190,12 @@ public:
protected:
virtual ~TabChildBase();
CSSSize GetPageSize(nsCOMPtr<nsIDocument> aDocument, const CSSSize& aViewport);
// Get the DOMWindowUtils for the top-level window in this tab.
already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils();
// Get the Document for the top-level window in this tab.
already_AddRefed<nsIDocument> GetDocument() const;
// Get the pres-shell of the document for the top-level window in this tab.
already_AddRefed<nsIPresShell> GetPresShell() const;
// Wrapper for nsIDOMWindowUtils.setCSSViewport(). This updates some state
// variables local to this class before setting it.
void SetCSSViewport(const CSSSize& aSize);
// Wraps up a JSON object as a structured clone and sends it to the browser
// chrome script.
//
@ -218,17 +204,12 @@ protected:
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData);
void InitializeRootMetrics();
mozilla::layers::FrameMetrics ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
protected:
CSSSize mOldViewportSize;
bool mContentDocumentIsDisplayed;
nsRefPtr<TabChildGlobal> mTabChildGlobal;
mozilla::layers::FrameMetrics mLastRootMetrics;
nsCOMPtr<nsIWebBrowserChrome3> mWebBrowserChrome;
};
@ -239,8 +220,6 @@ class TabChild final : public TabChildBase,
public nsIWebBrowserChromeFocus,
public nsIInterfaceRequestor,
public nsIWindowProvider,
public nsIDOMEventListener,
public nsIWebProgressListener,
public nsSupportsWeakReference,
public nsITabChild,
public nsIObserver,
@ -288,8 +267,6 @@ public:
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWINDOWPROVIDER
NS_DECL_NSIDOMEVENTLISTENER
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSITABCHILD
NS_DECL_NSIOBSERVER
NS_DECL_NSITOOLTIPLISTENER

50
dom/ipc/TabParent.cpp

@ -2521,10 +2521,9 @@ TabParent::RecvGetMaxTouchPoints(uint32_t* aTouchPoints)
return true;
}
bool
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
already_AddRefed<nsIWidget>
TabParent::GetTopLevelWidget()
{
*aValue = 0;
nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
if (content) {
nsIPresShell* shell = content->OwnerDoc()->GetShell();
@ -2532,12 +2531,49 @@ TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
nsViewManager* vm = shell->GetViewManager();
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
if (widget) {
*aValue = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
}
return widget.forget();
}
}
return nullptr;
}
bool
TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
{
*aValue = 0;
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
*aValue = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
}
return true;
}
bool
TabParent::RecvSetNativeChildOfShareableWindow(const uintptr_t& aChildWindow)
{
#if defined(XP_WIN)
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
// Note that this call will probably cause a sync native message to the
// process that owns the child window.
widget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW, aChildWindow);
}
return true;
#else
NS_NOTREACHED(
"TabParent::RecvSetNativeChildOfShareableWindow not implemented!");
return false;
#endif
}
bool
TabParent::RecvDispatchFocusToTopLevelWindow()
{
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
widget->SetFocus(false);
}
return true;
}

4
dom/ipc/TabParent.h

@ -116,7 +116,7 @@ public:
}
already_AddRefed<nsILoadContext> GetLoadContext();
already_AddRefed<nsIWidget> GetTopLevelWidget();
nsIXULBrowserWindow* GetXULBrowserWindow();
void Destroy();
@ -218,6 +218,8 @@ public:
virtual bool RecvGetDefaultScale(double* aValue) override;
virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
virtual bool RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
virtual bool RecvDispatchFocusToTopLevelWindow() override;
virtual bool RecvZoomToRect(const uint32_t& aPresShellId,
const ViewID& aViewId,
const CSSRect& aRect) override;

13
dom/plugins/base/nsNPAPIPlugin.cpp

@ -2164,19 +2164,6 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
nsNPAPIPluginInstance *inst =
(nsNPAPIPluginInstance *) (npp ? npp->ndata : nullptr);
double scaleFactor = inst ? inst->GetContentsScaleFactor() : 1.0;
// Work around a Flash ActionScript bug that causes long hangs if
// Flash thinks HiDPI support is available. Adobe is tracking this as
// ADBE 3921114. If this turns out to be Adobe's fault and they fix it,
// we'll no longer need this quirk. See QUIRK_FLASH_HIDE_HIDPI_SUPPORT
// in PluginModuleChild.h, and also bug 1118615.
if (inst) {
const char *mimeType;
inst->GetMIMEType(&mimeType);
NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
if (!PL_strncasecmp(mimeType, flash.get(), flash.Length())) {
scaleFactor = 1.0;
}
}
*(double*)result = scaleFactor;
return NPERR_NO_ERROR;
}

106
dom/plugins/base/nsPluginInstanceOwner.cpp

@ -622,23 +622,17 @@ nsPluginInstanceOwner::RedrawPlugin()
return NS_OK;
}
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
#if defined(XP_WIN)
nsIWidget*
nsPluginInstanceOwner::GetContainingWidgetIfOffset()
{
if (!mPluginFrame) {
NS_WARNING("plugin owner has no owner in getting doc's window handle");
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(mPluginFrame, "Caller should have checked for null mPluginFrame.");
#if defined(XP_WIN)
void** pvalue = (void**)value;
nsViewManager* vm = mPluginFrame->PresContext()->GetPresShell()->GetViewManager();
if (!vm)
return NS_ERROR_FAILURE;
// This property is provided to allow a "windowless" plugin to determine the window it is drawing
// in, so it can translate mouse coordinates it receives directly from the operating system
// to coordinates relative to itself.
// The original code (outside this #if) returns the document's window, which is OK if the window the "windowless" plugin
// The original code returns the document's window, which is OK if the window the "windowless" plugin
// is drawing into has the same origin as the document's window, but this is not the case for "windowless" plugins inside of scrolling DIVs etc
// To make sure "windowless" plugins always get the right origin for translating mouse coordinates, this code
@ -672,17 +666,53 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
if (offset.x || offset.y) {
// in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
// so that mouse co-ordinates are not messed up.
*pvalue = (void*)win->GetNativeData(NS_NATIVE_WINDOW);
if (*pvalue)
return NS_OK;
return win;
}
}
}
return nullptr;
}
static already_AddRefed<nsIWidget>
GetRootWidgetForPluginFrame(const nsPluginFrame* aPluginFrame)
{
MOZ_ASSERT(aPluginFrame);
nsViewManager* vm =
aPluginFrame->PresContext()->GetPresShell()->GetViewManager();
if (!vm) {
NS_WARNING("Could not find view manager for plugin frame.");
return nullptr;
}
nsCOMPtr<nsIWidget> rootWidget;
vm->GetRootWidget(getter_AddRefs(rootWidget));
return rootWidget.forget();
}
#endif
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
{
if (!mPluginFrame) {
NS_WARNING("plugin owner has no owner in getting doc's window handle");
return NS_ERROR_FAILURE;
}
#if defined(XP_WIN)
void** pvalue = (void**)value;
nsIWidget* offsetContainingWidget = GetContainingWidgetIfOffset();
if (offsetContainingWidget) {
*pvalue = (void*)offsetContainingWidget->GetNativeData(NS_NATIVE_WINDOW);
if (*pvalue) {
return NS_OK;
}
}
// simply return the topmost document window
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
nsCOMPtr<nsIWidget> widget = GetRootWidgetForPluginFrame(mPluginFrame);
if (widget) {
*pvalue = (void*)widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
*pvalue = widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
} else {
NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
}
@ -700,6 +730,48 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
#endif
}
#if defined(XP_WIN)
void
nsPluginInstanceOwner::SetWidgetWindowAsParent(HWND aWindowToAdopt)
{
if (!mWidget) {
NS_ERROR("mWidget should exist before this gets called.");
return;
}
mWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
reinterpret_cast<uintptr_t>(aWindowToAdopt));
}
nsresult
nsPluginInstanceOwner::SetNetscapeWindowAsParent(HWND aWindowToAdopt)
{
if (!mPluginFrame) {
NS_WARNING("Plugin owner has no plugin frame.");
return NS_ERROR_FAILURE;
}
// If there is a containing window that is offset then ask that to adopt.
nsIWidget* offsetWidget = GetContainingWidgetIfOffset();
if (offsetWidget) {
offsetWidget->SetNativeData(NS_NATIVE_CHILD_WINDOW,
reinterpret_cast<uintptr_t>(aWindowToAdopt));
return NS_OK;
}
// Otherwise ask the topmost document window to adopt.
nsCOMPtr<nsIWidget> rootWidget = GetRootWidgetForPluginFrame(mPluginFrame);
if (!rootWidget) {
NS_ASSERTION(rootWidget, "Couldn't get topmost document's widget.");
return NS_ERROR_FAILURE;
}
rootWidget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW,
reinterpret_cast<uintptr_t>(aWindowToAdopt));
return NS_OK;
}
#endif
NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(int32_t eventModel)
{
#ifdef XP_MACOSX

9
dom/plugins/base/nsPluginInstanceOwner.h

@ -111,6 +111,11 @@ public:
void ReleasePluginPort(void* pluginPort);
nsEventStatus ProcessEvent(const mozilla::WidgetGUIEvent& anEvent);
#if defined(XP_WIN)
void SetWidgetWindowAsParent(HWND aWindowToAdopt);
nsresult SetNetscapeWindowAsParent(HWND aWindowToAdopt);
#endif
#ifdef XP_MACOSX
enum { ePluginPaintEnable, ePluginPaintDisable };
@ -272,6 +277,10 @@ private:
bool mFullScreen;
void* mJavaView;
#endif
#if defined(XP_WIN)
nsIWidget* GetContainingWidgetIfOffset();
#endif
nsPluginNativeWindow *mPluginWindow;
nsRefPtr<nsNPAPIPluginInstance> mInstance;

17
dom/plugins/ipc/PPluginInstance.ipdl

@ -68,10 +68,15 @@ intr protocol PPluginInstance
child:
intr __delete__();
// Return value is only used on Windows and only when the window needs its
// parent set to the chrome widget native window.
intr NPP_SetWindow(NPRemoteWindow window)
returns (NPRemoteWindow childWindowToBeAdopted);
// This is only used on Windows and, for windowed plugins, must be called
// before the first call to NPP_SetWindow.
intr CreateChildPluginWindow()
returns (NativeWindowHandle childPluginWindow);
// This is only used on Windows and, for windowless plugins.
async CreateChildPopupSurrogate(NativeWindowHandle netscapeWindow);
intr NPP_SetWindow(NPRemoteWindow window);
intr NPP_GetValue_NPPVpluginWantsAllNetworkStreams()
returns (bool value, NPError result);
@ -213,6 +218,10 @@ parent:
// Notifies the parent of its NPP_New result code.
async AsyncNPP_NewResult(NPError aResult);
// Sends a native window to be adopted by the native window that would be
// returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows.
async SetNetscapeWindowAsParent(NativeWindowHandle childWindow);
both:
async PPluginScriptableObject();

151
dom/plugins/ipc/PluginInstanceChild.cpp

@ -197,7 +197,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
#endif // OS_WIN
#if defined(OS_WIN)
InitPopupMenuHook();
if (GetQuirks() & PluginModuleChild::QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
SetUnityHooks();
}
#endif // OS_WIN
@ -207,7 +207,7 @@ PluginInstanceChild::~PluginInstanceChild()
{
#if defined(OS_WIN)
NS_ASSERTION(!mPluginWindowHWND, "Destroying PluginInstanceChild without NPP_Destroy?");
if (GetQuirks() & PluginModuleChild::QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
ClearUnityHooks();
}
#endif
@ -405,7 +405,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
}
if (result == NPERR_NO_ERROR ||
(GetQuirks() &
PluginModuleChild::QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN)) {
QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN)) {
*static_cast<char**>(aValue) = ToNewCString(v);
}
return result;
@ -494,11 +494,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
#endif /* NP_NO_QUICKDRAW */
case NPNVcontentsScaleFactor: {
double scaleFactor = mContentsScaleFactor;
if (GetQuirks() & PluginModuleChild::QUIRK_FLASH_HIDE_HIDPI_SUPPORT) {
scaleFactor = 1.0;
}
*static_cast<double*>(aValue) = scaleFactor;
*static_cast<double*>(aValue) = mContentsScaleFactor;
return NPERR_NO_ERROR;
}
#endif /* XP_MACOSX */
@ -1010,7 +1006,7 @@ PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
mCARenderer->SetupRenderer(caLayer, mWindow.width, mWindow.height,
mContentsScaleFactor,
GetQuirks() & PluginModuleChild::QUIRK_ALLOW_OFFLINE_RENDERER ?
GetQuirks() & QUIRK_ALLOW_OFFLINE_RENDERER ?
ALLOW_OFFLINE_RENDERER : DISALLOW_OFFLINE_RENDERER);
// Flash needs to have the window set again after this step
@ -1128,8 +1124,40 @@ void PluginInstanceChild::DeleteWindow()
#endif
bool
PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow,
NPRemoteWindow* aChildWindowToBeAdopted)
PluginInstanceChild::AnswerCreateChildPluginWindow(NativeWindowHandle* aChildPluginWindow)
{
#if defined(XP_WIN)
MOZ_ASSERT(!mPluginWindowHWND);
if (!CreatePluginWindow()) {
return false;
}
MOZ_ASSERT(mPluginWindowHWND);
*aChildPluginWindow = mPluginWindowHWND;
return true;
#else
NS_NOTREACHED("PluginInstanceChild::CreateChildPluginWindow not implemented!");
return false;
#endif
}
bool
PluginInstanceChild::RecvCreateChildPopupSurrogate(const NativeWindowHandle& aNetscapeWindow)
{
#if defined(XP_WIN)
mCachedWinlessPluginHWND = aNetscapeWindow;
CreateWinlessPopupSurrogate();
return true;
#else
NS_NOTREACHED("PluginInstanceChild::CreateChildPluginWindow not implemented!");
return false;
#endif
}
bool
PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
{
PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
FULLFUNCTION,
@ -1210,42 +1238,22 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow,
switch (aWindow.type) {
case NPWindowTypeWindow:
{
if ((GetQuirks() & PluginModuleChild::QUIRK_QUICKTIME_AVOID_SETWINDOW) &&
aWindow.width == 0 &&
aWindow.height == 0) {
// Skip SetWindow call for hidden QuickTime plugins
return true;
}
// This check is now done in PluginInstanceParent before this call, so
// we should never see it here.
MOZ_ASSERT(!(GetQuirks() & QUIRK_QUICKTIME_AVOID_SETWINDOW) ||
aWindow.width != 0 || aWindow.height != 0);
if (!CreatePluginWindow())
return false;
MOZ_ASSERT(mPluginWindowHWND,
"Child plugin window must exist before call to SetWindow");
SizePluginWindow(aWindow.width, aWindow.height);
// If the window is not our parent set the return child window so that
// it can be re-parented in the chrome process. Re-parenting now
// happens there as we might not have sufficient permission.
// Also, this needs to be after SizePluginWindow because SetWindowPos
// relies on things that it sets.
HWND parentWindow = reinterpret_cast<HWND>(aWindow.window);
if (mPluginParentHWND != parentWindow && IsWindow(parentWindow)) {
mPluginParentHWND = parentWindow;
aChildWindowToBeAdopted->window =
reinterpret_cast<uint64_t>(mPluginWindowHWND);
} else {
// Now we know that the window has the correct parent we can show
// it. The actual visibility is controlled by its parent.
// First time round, these calls are made by our caller after the
// parent is set.
HWND parentHWND = reinterpret_cast<HWND>(aWindow.window);
if (mPluginWindowHWND != parentHWND) {
mPluginParentHWND = parentHWND;
ShowWindow(mPluginWindowHWND, SW_SHOWNA);
// This used to be called in SizePluginWindow, but we need to make
// sure that mPluginWindowHWND has had it's parent set correctly,
// otherwise it can cause a focus issue.
SetWindowPos(mPluginWindowHWND, nullptr, 0, 0, aWindow.width,
aWindow.height, SWP_NOZORDER | SWP_NOREPOSITION);
}