Backed out 12 changesets (bug 1831649) for causing multiple failures.
Backed out changeset 501dc3134ae1 (bug1831649) Backed out changeset 21235ab42839 (bug1831649) Backed out changeset 279fdf36aac1 (bug1831649) Backed out changeset 17fb50534fae (bug1831649) Backed out changeset b2718b2f730d (bug1831649) Backed out changeset a05aa1c75ece (bug1831649) Backed out changeset becfb23cd6b4 (bug1831649) Backed out changeset 2d0e7e662530 (bug1831649) Backed out changeset 22538f7bdc88 (bug1831649) Backed out changeset 4ddecb37950f (bug1831649) Backed out changeset 1e6ed8b78e8f (bug1831649) Backed out changeset 6e96a1a01c24 (bug1831649)
This commit is contained in:
@@ -194,7 +194,6 @@
|
|||||||
#include "mozilla/dom/HTMLTextAreaElement.h"
|
#include "mozilla/dom/HTMLTextAreaElement.h"
|
||||||
#include "mozilla/dom/ImageTracker.h"
|
#include "mozilla/dom/ImageTracker.h"
|
||||||
#include "mozilla/dom/InspectorUtils.h"
|
#include "mozilla/dom/InspectorUtils.h"
|
||||||
#include "mozilla/dom/InteractiveWidget.h"
|
|
||||||
#include "mozilla/dom/Link.h"
|
#include "mozilla/dom/Link.h"
|
||||||
#include "mozilla/dom/MediaQueryList.h"
|
#include "mozilla/dom/MediaQueryList.h"
|
||||||
#include "mozilla/dom/MediaSource.h"
|
#include "mozilla/dom/MediaSource.h"
|
||||||
@@ -1433,7 +1432,6 @@ Document::Document(const char* aContentType)
|
|||||||
mHttpsOnlyStatus(nsILoadInfo::HTTPS_ONLY_UNINITIALIZED),
|
mHttpsOnlyStatus(nsILoadInfo::HTTPS_ONLY_UNINITIALIZED),
|
||||||
mViewportType(Unknown),
|
mViewportType(Unknown),
|
||||||
mViewportFit(ViewportFitType::Auto),
|
mViewportFit(ViewportFitType::Auto),
|
||||||
mInteractiveWidgetMode(InteractiveWidget::ResizesContent),
|
|
||||||
mHeaderData(nullptr),
|
mHeaderData(nullptr),
|
||||||
mServoRestyleRootDirtyBits(0),
|
mServoRestyleRootDirtyBits(0),
|
||||||
mThrowOnDynamicMarkupInsertionCounter(0),
|
mThrowOnDynamicMarkupInsertionCounter(0),
|
||||||
@@ -10952,47 +10950,11 @@ ViewportMetaData Document::GetViewportMetaData() const {
|
|||||||
: ViewportMetaData();
|
: ViewportMetaData();
|
||||||
}
|
}
|
||||||
|
|
||||||
static InteractiveWidget ParseInteractiveWidget(
|
|
||||||
const ViewportMetaData& aViewportMetaData) {
|
|
||||||
if (aViewportMetaData.mInteractiveWidgetMode.IsEmpty()) {
|
|
||||||
// The spec defines "use `resizes-visual` if no value specified", but here
|
|
||||||
// we use `resizes-content` for the backward compatibility now.
|
|
||||||
// We will change it in bug 1884807.
|
|
||||||
return InteractiveWidget::ResizesContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase(
|
|
||||||
"resizes-visual")) {
|
|
||||||
return InteractiveWidget::ResizesVisual;
|
|
||||||
}
|
|
||||||
if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase(
|
|
||||||
"resizes-content")) {
|
|
||||||
return InteractiveWidget::ResizesContent;
|
|
||||||
}
|
|
||||||
if (aViewportMetaData.mInteractiveWidgetMode.EqualsIgnoreCase(
|
|
||||||
"overlays-content")) {
|
|
||||||
return InteractiveWidget::OverlaysContent;
|
|
||||||
}
|
|
||||||
// For the same reason above empty case, we use `resizes-content` here.
|
|
||||||
return InteractiveWidget::ResizesContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Document::SetMetaViewportData(UniquePtr<ViewportMetaData> aData) {
|
void Document::SetMetaViewportData(UniquePtr<ViewportMetaData> aData) {
|
||||||
mLastModifiedViewportMetaData = std::move(aData);
|
mLastModifiedViewportMetaData = std::move(aData);
|
||||||
// Trigger recomputation of the nsViewportInfo the next time it's queried.
|
// Trigger recomputation of the nsViewportInfo the next time it's queried.
|
||||||
mViewportType = Unknown;
|
mViewportType = Unknown;
|
||||||
|
|
||||||
// Parse interactive-widget here anyway. Normally we parse any data in the
|
|
||||||
// meta viewport tag in GetViewportInfo(), but GetViewportInfo() depends on
|
|
||||||
// the document state (e.g. display size, fullscreen, desktop-mode etc.)
|
|
||||||
// whereas interactive-widget is independent from the document state, it's
|
|
||||||
// necessary whatever the document state is.
|
|
||||||
dom::InteractiveWidget interactiveWidget =
|
|
||||||
ParseInteractiveWidget(*mLastModifiedViewportMetaData);
|
|
||||||
if (mInteractiveWidgetMode != interactiveWidget) {
|
|
||||||
mInteractiveWidgetMode = interactiveWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncEventDispatcher::RunDOMEventWhenSafe(
|
AsyncEventDispatcher::RunDOMEventWhenSafe(
|
||||||
*this, u"DOMMetaViewportFitChanged"_ns, CanBubble::eYes,
|
*this, u"DOMMetaViewportFitChanged"_ns, CanBubble::eYes,
|
||||||
ChromeOnlyDispatch::eYes);
|
ChromeOnlyDispatch::eYes);
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ class FeaturePolicy;
|
|||||||
class FontFaceSet;
|
class FontFaceSet;
|
||||||
class FragmentDirective;
|
class FragmentDirective;
|
||||||
class FrameRequestCallback;
|
class FrameRequestCallback;
|
||||||
|
class ImageTracker;
|
||||||
class HighlightRegistry;
|
class HighlightRegistry;
|
||||||
class HTMLAllCollection;
|
class HTMLAllCollection;
|
||||||
class HTMLBodyElement;
|
class HTMLBodyElement;
|
||||||
@@ -254,8 +255,6 @@ class HTMLMetaElement;
|
|||||||
class HTMLDialogElement;
|
class HTMLDialogElement;
|
||||||
class HTMLSharedElement;
|
class HTMLSharedElement;
|
||||||
class HTMLImageElement;
|
class HTMLImageElement;
|
||||||
class ImageTracker;
|
|
||||||
enum class InteractiveWidget : uint8_t;
|
|
||||||
struct LifecycleCallbackArgs;
|
struct LifecycleCallbackArgs;
|
||||||
class Link;
|
class Link;
|
||||||
class Location;
|
class Location;
|
||||||
@@ -3939,10 +3938,6 @@ class Document : public nsINode,
|
|||||||
public:
|
public:
|
||||||
const OriginTrials& Trials() const { return mTrials; }
|
const OriginTrials& Trials() const { return mTrials; }
|
||||||
|
|
||||||
dom::InteractiveWidget InteractiveWidget() const {
|
|
||||||
return mInteractiveWidgetMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DoCacheAllKnownLangPrefs();
|
void DoCacheAllKnownLangPrefs();
|
||||||
void RecomputeLanguageFromCharset();
|
void RecomputeLanguageFromCharset();
|
||||||
@@ -5171,9 +5166,6 @@ class Document : public nsINode,
|
|||||||
// https://drafts.csswg.org/css-round-display/#viewport-fit-descriptor
|
// https://drafts.csswg.org/css-round-display/#viewport-fit-descriptor
|
||||||
ViewportFitType mViewportFit;
|
ViewportFitType mViewportFit;
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-viewport/#interactive-widget-section
|
|
||||||
dom::InteractiveWidget mInteractiveWidgetMode;
|
|
||||||
|
|
||||||
// XXXdholbert This should really be modernized to a nsTHashMap or similar,
|
// XXXdholbert This should really be modernized to a nsTHashMap or similar,
|
||||||
// though note that the modernization will need to take care to also convert
|
// though note that the modernization will need to take care to also convert
|
||||||
// the special hash_table_ops logic (e.g. how SubDocClearEntry clears the
|
// the special hash_table_ops logic (e.g. how SubDocClearEntry clears the
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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/. */
|
|
||||||
|
|
||||||
#ifndef DOM_INTERACTIVE_WIDGET_H_
|
|
||||||
#define DOM_INTERACTIVE_WIDGET_H_
|
|
||||||
|
|
||||||
namespace mozilla::dom {
|
|
||||||
// https://drafts.csswg.org/css-viewport/#interactive-widget-section
|
|
||||||
enum class InteractiveWidget : uint8_t {
|
|
||||||
OverlaysContent,
|
|
||||||
ResizesContent,
|
|
||||||
ResizesVisual,
|
|
||||||
};
|
|
||||||
} // namespace mozilla::dom
|
|
||||||
|
|
||||||
#endif // DOM_INTERACTIVE_WIDGET_H_
|
|
||||||
@@ -59,8 +59,6 @@ static void ProcessViewportToken(ViewportMetaData& aData,
|
|||||||
aData.mUserScalable.Assign(value);
|
aData.mUserScalable.Assign(value);
|
||||||
} else if (key_atom == nsGkAtoms::viewport_fit) {
|
} else if (key_atom == nsGkAtoms::viewport_fit) {
|
||||||
aData.mViewportFit.Assign(value);
|
aData.mViewportFit.Assign(value);
|
||||||
} else if (key_atom == nsGkAtoms::interactive_widget) {
|
|
||||||
aData.mInteractiveWidgetMode.Assign(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ struct ViewportMetaData {
|
|||||||
nsString mMaximumScale;
|
nsString mMaximumScale;
|
||||||
nsString mUserScalable;
|
nsString mUserScalable;
|
||||||
nsString mViewportFit;
|
nsString mViewportFit;
|
||||||
nsString mInteractiveWidgetMode;
|
|
||||||
|
|
||||||
bool operator==(const ViewportMetaData& aOther) const {
|
bool operator==(const ViewportMetaData& aOther) const {
|
||||||
return mWidth == aOther.mWidth && mHeight == aOther.mHeight &&
|
return mWidth == aOther.mWidth && mHeight == aOther.mHeight &&
|
||||||
@@ -28,8 +27,7 @@ struct ViewportMetaData {
|
|||||||
mMinimumScale == aOther.mMinimumScale &&
|
mMinimumScale == aOther.mMinimumScale &&
|
||||||
mMaximumScale == aOther.mMaximumScale &&
|
mMaximumScale == aOther.mMaximumScale &&
|
||||||
mUserScalable == aOther.mUserScalable &&
|
mUserScalable == aOther.mUserScalable &&
|
||||||
mViewportFit == aOther.mViewportFit &&
|
mViewportFit == aOther.mViewportFit;
|
||||||
mInteractiveWidgetMode == aOther.mInteractiveWidgetMode;
|
|
||||||
}
|
}
|
||||||
bool operator!=(const ViewportMetaData& aOther) const {
|
bool operator!=(const ViewportMetaData& aOther) const {
|
||||||
return !(*this == aOther);
|
return !(*this == aOther);
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ EXPORTS.mozilla.dom += [
|
|||||||
"IDTracker.h",
|
"IDTracker.h",
|
||||||
"ImageEncoder.h",
|
"ImageEncoder.h",
|
||||||
"ImageTracker.h",
|
"ImageTracker.h",
|
||||||
"InteractiveWidget.h",
|
|
||||||
"IntlUtils.h",
|
"IntlUtils.h",
|
||||||
"JSExecutionContext.h",
|
"JSExecutionContext.h",
|
||||||
"Link.h",
|
"Link.h",
|
||||||
|
|||||||
@@ -278,7 +278,6 @@ BrowserChild::BrowserChild(ContentChild* aManager, const TabId& aTabId,
|
|||||||
mLayersId{0},
|
mLayersId{0},
|
||||||
mEffectsInfo{EffectsInfo::FullyHidden()},
|
mEffectsInfo{EffectsInfo::FullyHidden()},
|
||||||
mDynamicToolbarMaxHeight(0),
|
mDynamicToolbarMaxHeight(0),
|
||||||
mKeyboardHeight(0),
|
|
||||||
mUniqueId(aTabId),
|
mUniqueId(aTabId),
|
||||||
mDidFakeShow(false),
|
mDidFakeShow(false),
|
||||||
mTriedBrowserInit(false),
|
mTriedBrowserInit(false),
|
||||||
@@ -1238,23 +1237,6 @@ mozilla::ipc::IPCResult BrowserChild::RecvDynamicToolbarOffsetChanged(
|
|||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult BrowserChild::RecvKeyboardHeightChanged(
|
|
||||||
const ScreenIntCoord& aHeight) {
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
|
||||||
mKeyboardHeight = aHeight;
|
|
||||||
|
|
||||||
RefPtr<Document> document = GetTopLevelDocument();
|
|
||||||
if (!document) {
|
|
||||||
return IPC_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nsPresContext* presContext = document->GetPresContext()) {
|
|
||||||
presContext->UpdateKeyboardHeight(aHeight);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return IPC_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::ipc::IPCResult BrowserChild::RecvSuppressDisplayport(
|
mozilla::ipc::IPCResult BrowserChild::RecvSuppressDisplayport(
|
||||||
const bool& aEnabled) {
|
const bool& aEnabled) {
|
||||||
if (RefPtr<PresShell> presShell = GetTopLevelPresShell()) {
|
if (RefPtr<PresShell> presShell = GetTopLevelPresShell()) {
|
||||||
|
|||||||
@@ -284,9 +284,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
mozilla::ipc::IPCResult RecvDynamicToolbarOffsetChanged(
|
mozilla::ipc::IPCResult RecvDynamicToolbarOffsetChanged(
|
||||||
const mozilla::ScreenIntCoord& aOffset);
|
const mozilla::ScreenIntCoord& aOffset);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvKeyboardHeightChanged(
|
|
||||||
const mozilla::ScreenIntCoord& aHeight);
|
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvActivate(uint64_t aActionId);
|
mozilla::ipc::IPCResult RecvActivate(uint64_t aActionId);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvDeactivate(uint64_t aActionId);
|
mozilla::ipc::IPCResult RecvDeactivate(uint64_t aActionId);
|
||||||
@@ -546,7 +543,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
ScreenIntCoord GetDynamicToolbarMaxHeight() const {
|
ScreenIntCoord GetDynamicToolbarMaxHeight() const {
|
||||||
return mDynamicToolbarMaxHeight;
|
return mDynamicToolbarMaxHeight;
|
||||||
};
|
};
|
||||||
mozilla::ScreenIntCoord GetKeyboardHeight() const { return mKeyboardHeight; }
|
|
||||||
|
|
||||||
bool IPCOpen() const { return mIPCOpen; }
|
bool IPCOpen() const { return mIPCOpen; }
|
||||||
|
|
||||||
@@ -808,8 +804,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
// NOTE: This value is valuable only for the top level browser.
|
// NOTE: This value is valuable only for the top level browser.
|
||||||
LayoutDeviceIntPoint mChromeOffset;
|
LayoutDeviceIntPoint mChromeOffset;
|
||||||
ScreenIntCoord mDynamicToolbarMaxHeight;
|
ScreenIntCoord mDynamicToolbarMaxHeight;
|
||||||
// The software keyboard height.
|
|
||||||
ScreenIntCoord mKeyboardHeight;
|
|
||||||
TabId mUniqueId;
|
TabId mUniqueId;
|
||||||
|
|
||||||
bool mDidFakeShow : 1;
|
bool mDidFakeShow : 1;
|
||||||
|
|||||||
@@ -1213,12 +1213,6 @@ void BrowserParent::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {
|
|||||||
Unused << SendDynamicToolbarOffsetChanged(aOffset);
|
Unused << SendDynamicToolbarOffsetChanged(aOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserParent::KeyboardHeightChanged(ScreenIntCoord aHeight) {
|
|
||||||
if (!mIsDestroyed) {
|
|
||||||
Unused << SendKeyboardHeightChanged(aHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void BrowserParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
|
void BrowserParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
|
||||||
|
|||||||
@@ -487,7 +487,6 @@ class BrowserParent final : public PBrowserParent,
|
|||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(MOZ_WIDGET_ANDROID)
|
||||||
void DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight);
|
void DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight);
|
||||||
void DynamicToolbarOffsetChanged(ScreenIntCoord aOffset);
|
void DynamicToolbarOffsetChanged(ScreenIntCoord aOffset);
|
||||||
void KeyboardHeightChanged(ScreenIntCoord aHeight);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Activate(uint64_t aActionId);
|
void Activate(uint64_t aActionId);
|
||||||
|
|||||||
@@ -697,9 +697,7 @@ child:
|
|||||||
|
|
||||||
async DynamicToolbarMaxHeightChanged(ScreenIntCoord height);
|
async DynamicToolbarMaxHeightChanged(ScreenIntCoord height);
|
||||||
|
|
||||||
async DynamicToolbarOffsetChanged(ScreenIntCoord offset);
|
async DynamicToolbarOffsetChanged(ScreenIntCoord height);
|
||||||
|
|
||||||
async KeyboardHeightChanged(ScreenIntCoord height);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StopIMEStateManagement() is called when the process loses focus and
|
* StopIMEStateManagement() is called when the process loses focus and
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include "MobileViewportManager.h"
|
#include "MobileViewportManager.h"
|
||||||
#include "mozilla/MVMContext.h"
|
#include "mozilla/MVMContext.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
#include "mozilla/dom/InteractiveWidget.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ class MockMVMContext : public MVMContext {
|
|||||||
MOCK_METHOD0(PostVisualViewportResizeEventByDynamicToolbar, void());
|
MOCK_METHOD0(PostVisualViewportResizeEventByDynamicToolbar, void());
|
||||||
MOCK_METHOD0(UpdateDisplayPortMargins, void());
|
MOCK_METHOD0(UpdateDisplayPortMargins, void());
|
||||||
MOCK_METHOD0(GetDynamicToolbarOffset, ScreenIntCoord());
|
MOCK_METHOD0(GetDynamicToolbarOffset, ScreenIntCoord());
|
||||||
MOCK_CONST_METHOD0(GetInteractiveWidgetMode, dom::InteractiveWidget());
|
|
||||||
|
|
||||||
void SetMVM(MobileViewportManager* aMVM) { mMVM = aMVM; }
|
void SetMVM(MobileViewportManager* aMVM) { mMVM = aMVM; }
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,4 @@ ScreenIntCoord GeckoMVMContext::GetDynamicToolbarOffset() {
|
|||||||
: ScreenIntCoord(0);
|
: ScreenIntCoord(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dom::InteractiveWidget GeckoMVMContext::GetInteractiveWidgetMode() const {
|
|
||||||
return mDocument->InteractiveWidget();
|
|
||||||
}
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class PresShell;
|
|||||||
namespace dom {
|
namespace dom {
|
||||||
class Document;
|
class Document;
|
||||||
class EventTarget;
|
class EventTarget;
|
||||||
enum class InteractiveWidget : uint8_t;
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +57,6 @@ class GeckoMVMContext final : public MVMContext {
|
|||||||
void UpdateDisplayPortMargins() override;
|
void UpdateDisplayPortMargins() override;
|
||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Reflow(const CSSSize& aNewSize) override;
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY void Reflow(const CSSSize& aNewSize) override;
|
||||||
ScreenIntCoord GetDynamicToolbarOffset() override;
|
ScreenIntCoord GetDynamicToolbarOffset() override;
|
||||||
dom::InteractiveWidget GetInteractiveWidgetMode() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<dom::Document> mDocument;
|
RefPtr<dom::Document> mDocument;
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ class nsIDOMEventListener;
|
|||||||
class nsIObserver;
|
class nsIObserver;
|
||||||
class nsISupports;
|
class nsISupports;
|
||||||
|
|
||||||
namespace mozilla::dom {
|
|
||||||
enum class InteractiveWidget : uint8_t;
|
|
||||||
} // namespace mozilla::dom
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +62,6 @@ class MVMContext {
|
|||||||
|
|
||||||
virtual void Reflow(const CSSSize& aNewSize) = 0;
|
virtual void Reflow(const CSSSize& aNewSize) = 0;
|
||||||
virtual ScreenIntCoord GetDynamicToolbarOffset() = 0;
|
virtual ScreenIntCoord GetDynamicToolbarOffset() = 0;
|
||||||
virtual dom::InteractiveWidget GetInteractiveWidgetMode() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
#include "mozilla/dom/EventTarget.h"
|
#include "mozilla/dom/EventTarget.h"
|
||||||
#include "mozilla/dom/InteractiveWidget.h"
|
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsViewManager.h"
|
#include "nsViewManager.h"
|
||||||
@@ -39,8 +38,7 @@ MobileViewportManager::MobileViewportManager(MVMContext* aContext,
|
|||||||
: mContext(aContext),
|
: mContext(aContext),
|
||||||
mManagerType(aType),
|
mManagerType(aType),
|
||||||
mIsFirstPaint(false),
|
mIsFirstPaint(false),
|
||||||
mPainted(false),
|
mPainted(false) {
|
||||||
mInvalidViewport(false) {
|
|
||||||
MOZ_ASSERT(mContext);
|
MOZ_ASSERT(mContext);
|
||||||
|
|
||||||
MVM_LOG("%p: creating with context %p\n", this, mContext.get());
|
MVM_LOG("%p: creating with context %p\n", this, mContext.get());
|
||||||
@@ -90,7 +88,8 @@ float MobileViewportManager::ComputeIntrinsicResolution() const {
|
|||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenIntSize displaySize = GetLayoutDisplaySize();
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
CSSToScreenScale intrinsicScale = ComputeIntrinsicScale(
|
CSSToScreenScale intrinsicScale = ComputeIntrinsicScale(
|
||||||
mContext->GetViewportInfo(displaySize), displaySize, mMobileViewportSize);
|
mContext->GetViewportInfo(displaySize), displaySize, mMobileViewportSize);
|
||||||
CSSToLayoutDeviceScale cssToDev = mContext->CSSToDevPixelScale();
|
CSSToLayoutDeviceScale cssToDev = mContext->CSSToDevPixelScale();
|
||||||
@@ -259,7 +258,8 @@ LayoutDeviceToLayerScale MobileViewportManager::ZoomToResolution(
|
|||||||
|
|
||||||
void MobileViewportManager::UpdateResolutionForFirstPaint(
|
void MobileViewportManager::UpdateResolutionForFirstPaint(
|
||||||
const CSSSize& aViewportSize) {
|
const CSSSize& aViewportSize) {
|
||||||
ScreenIntSize displaySize = GetLayoutDisplaySize();
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
||||||
ScreenIntSize compositionSize = GetCompositionSize(displaySize);
|
ScreenIntSize compositionSize = GetCompositionSize(displaySize);
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ void MobileViewportManager::UpdateResolutionForFirstPaint(
|
|||||||
MVM_LOG("%p: restored zoom is %f\n", this, restoreZoom.scale);
|
MVM_LOG("%p: restored zoom is %f\n", this, restoreZoom.scale);
|
||||||
restoreZoom = ClampZoom(restoreZoom, viewportInfo);
|
restoreZoom = ClampZoom(restoreZoom, viewportInfo);
|
||||||
|
|
||||||
ApplyNewZoom(restoreZoom);
|
ApplyNewZoom(displaySize, restoreZoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,13 +299,14 @@ void MobileViewportManager::UpdateResolutionForFirstPaint(
|
|||||||
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
|
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
|
||||||
defaultZoom <= viewportInfo.GetMaxZoom());
|
defaultZoom <= viewportInfo.GetMaxZoom());
|
||||||
|
|
||||||
ApplyNewZoom(defaultZoom);
|
ApplyNewZoom(displaySize, defaultZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::UpdateResolutionForViewportSizeChange(
|
void MobileViewportManager::UpdateResolutionForViewportSizeChange(
|
||||||
const CSSSize& aViewportSize,
|
const CSSSize& aViewportSize,
|
||||||
const Maybe<float>& aDisplayWidthChangeRatio) {
|
const Maybe<float>& aDisplayWidthChangeRatio) {
|
||||||
ScreenIntSize displaySize = GetLayoutDisplaySize();
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
||||||
|
|
||||||
CSSToScreenScale zoom = GetZoom();
|
CSSToScreenScale zoom = GetZoom();
|
||||||
@@ -344,7 +345,7 @@ void MobileViewportManager::UpdateResolutionForViewportSizeChange(
|
|||||||
// 4. neither screen size nor CSS viewport changes
|
// 4. neither screen size nor CSS viewport changes
|
||||||
|
|
||||||
if (!aDisplayWidthChangeRatio) {
|
if (!aDisplayWidthChangeRatio) {
|
||||||
UpdateVisualViewportSize(zoom);
|
UpdateVisualViewportSize(displaySize, zoom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,12 +412,13 @@ void MobileViewportManager::UpdateResolutionForViewportSizeChange(
|
|||||||
zoom, adjustedRatio, aViewportSize, mMobileViewportSize);
|
zoom, adjustedRatio, aViewportSize, mMobileViewportSize);
|
||||||
CSSToScreenScale newZoom = ClampZoom(adjustedZoom, viewportInfo);
|
CSSToScreenScale newZoom = ClampZoom(adjustedZoom, viewportInfo);
|
||||||
|
|
||||||
ApplyNewZoom(newZoom);
|
ApplyNewZoom(displaySize, newZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::UpdateResolutionForContentSizeChange(
|
void MobileViewportManager::UpdateResolutionForContentSizeChange(
|
||||||
const CSSSize& aContentSize) {
|
const CSSSize& aContentSize) {
|
||||||
ScreenIntSize displaySize = GetLayoutDisplaySize();
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
||||||
|
|
||||||
CSSToScreenScale zoom = GetZoom();
|
CSSToScreenScale zoom = GetZoom();
|
||||||
@@ -439,7 +441,7 @@ void MobileViewportManager::UpdateResolutionForContentSizeChange(
|
|||||||
if (!mRestoreResolution && !mContext->IsResolutionUpdatedByApz() &&
|
if (!mRestoreResolution && !mContext->IsResolutionUpdatedByApz() &&
|
||||||
!viewportInfo.IsDefaultZoomValid()) {
|
!viewportInfo.IsDefaultZoomValid()) {
|
||||||
if (zoom != intrinsicScale) {
|
if (zoom != intrinsicScale) {
|
||||||
ApplyNewZoom(intrinsicScale);
|
ApplyNewZoom(displaySize, intrinsicScale);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -457,11 +459,12 @@ void MobileViewportManager::UpdateResolutionForContentSizeChange(
|
|||||||
clampedZoom = ClampZoom(clampedZoom, viewportInfo);
|
clampedZoom = ClampZoom(clampedZoom, viewportInfo);
|
||||||
|
|
||||||
if (clampedZoom != zoom) {
|
if (clampedZoom != zoom) {
|
||||||
ApplyNewZoom(clampedZoom);
|
ApplyNewZoom(displaySize, clampedZoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::ApplyNewZoom(const CSSToScreenScale& aNewZoom) {
|
void MobileViewportManager::ApplyNewZoom(const ScreenIntSize& aDisplaySize,
|
||||||
|
const CSSToScreenScale& aNewZoom) {
|
||||||
// If the zoom has changed, update the pres shell resolution accordingly.
|
// If the zoom has changed, update the pres shell resolution accordingly.
|
||||||
// We characterize this as MainThreadAdjustment, because we don't want our
|
// We characterize this as MainThreadAdjustment, because we don't want our
|
||||||
// change here to be remembered as a restore resolution.
|
// change here to be remembered as a restore resolution.
|
||||||
@@ -477,7 +480,7 @@ void MobileViewportManager::ApplyNewZoom(const CSSToScreenScale& aNewZoom) {
|
|||||||
|
|
||||||
MVM_LOG("%p: New zoom is %f\n", this, aNewZoom.scale);
|
MVM_LOG("%p: New zoom is %f\n", this, aNewZoom.scale);
|
||||||
|
|
||||||
UpdateVisualViewportSize(aNewZoom);
|
UpdateVisualViewportSize(aDisplaySize, aNewZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenIntSize MobileViewportManager::GetCompositionSize(
|
ScreenIntSize MobileViewportManager::GetCompositionSize(
|
||||||
@@ -505,17 +508,13 @@ ScreenIntSize MobileViewportManager::GetCompositionSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::UpdateVisualViewportSize(
|
void MobileViewportManager::UpdateVisualViewportSize(
|
||||||
const CSSToScreenScale& aZoom) {
|
const ScreenIntSize& aDisplaySize, const CSSToScreenScale& aZoom) {
|
||||||
if (!mContext) {
|
if (!mContext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenIntSize displaySize = GetDisplaySizeForVisualViewport();
|
ScreenSize compositionSize = ScreenSize(GetCompositionSize(aDisplaySize));
|
||||||
if (displaySize.width == 0 || displaySize.height == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenSize compositionSize = ScreenSize(GetCompositionSize(displaySize));
|
|
||||||
CSSSize compSize = compositionSize / aZoom;
|
CSSSize compSize = compositionSize / aZoom;
|
||||||
MVM_LOG("%p: Setting VVPS %s\n", this, ToString(compSize).c_str());
|
MVM_LOG("%p: Setting VVPS %s\n", this, ToString(compSize).c_str());
|
||||||
mContext->SetVisualViewportSize(compSize);
|
mContext->SetVisualViewportSize(compSize);
|
||||||
@@ -534,7 +533,8 @@ void MobileViewportManager::UpdateVisualViewportSizeByDynamicToolbar(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenIntSize displaySize = GetDisplaySizeForVisualViewport();
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
displaySize.height += aToolbarHeight;
|
displaySize.height += aToolbarHeight;
|
||||||
nsSize compSize = CSSSize::ToAppUnits(
|
nsSize compSize = CSSSize::ToAppUnits(
|
||||||
ScreenSize(GetCompositionSize(displaySize)) / GetZoom());
|
ScreenSize(GetCompositionSize(displaySize)) / GetZoom());
|
||||||
@@ -563,11 +563,19 @@ void MobileViewportManager::UpdateDisplayPortMargins() {
|
|||||||
void MobileViewportManager::RefreshVisualViewportSize() {
|
void MobileViewportManager::RefreshVisualViewportSize() {
|
||||||
// This function is a subset of RefreshViewportSize, and only updates the
|
// This function is a subset of RefreshViewportSize, and only updates the
|
||||||
// visual viewport size.
|
// visual viewport size.
|
||||||
|
|
||||||
if (!mContext) {
|
if (!mContext) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateVisualViewportSize(GetZoom());
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
|
|
||||||
|
if (displaySize.width == 0 || displaySize.height == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVisualViewportSize(displaySize, GetZoom());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::UpdateSizesBeforeReflow() {
|
void MobileViewportManager::UpdateSizesBeforeReflow() {
|
||||||
@@ -581,8 +589,9 @@ void MobileViewportManager::UpdateSizesBeforeReflow() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsViewportInfo viewportInfo =
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
mContext->GetViewportInfo(GetLayoutDisplaySize());
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
|
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
||||||
mMobileViewportSize = viewportInfo.GetSize();
|
mMobileViewportSize = viewportInfo.GetSize();
|
||||||
MVM_LOG("%p: MVSize updated to %s\n", this,
|
MVM_LOG("%p: MVSize updated to %s\n", this,
|
||||||
ToString(mMobileViewportSize).c_str());
|
ToString(mMobileViewportSize).c_str());
|
||||||
@@ -636,8 +645,9 @@ void MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsViewportInfo viewportInfo =
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
mContext->GetViewportInfo(GetLayoutDisplaySize());
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
|
nsViewportInfo viewportInfo = mContext->GetViewportInfo(displaySize);
|
||||||
MVM_LOG("%p: viewport info has zooms min=%f max=%f default=%f,valid=%d\n",
|
MVM_LOG("%p: viewport info has zooms min=%f max=%f default=%f,valid=%d\n",
|
||||||
this, viewportInfo.GetMinZoom().scale,
|
this, viewportInfo.GetMinZoom().scale,
|
||||||
viewportInfo.GetMaxZoom().scale, viewportInfo.GetDefaultZoom().scale,
|
viewportInfo.GetMaxZoom().scale, viewportInfo.GetDefaultZoom().scale,
|
||||||
@@ -646,7 +656,7 @@ void MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution) {
|
|||||||
CSSSize viewport = viewportInfo.GetSize();
|
CSSSize viewport = viewportInfo.GetSize();
|
||||||
MVM_LOG("%p: Computed CSS viewport %s\n", this, ToString(viewport).c_str());
|
MVM_LOG("%p: Computed CSS viewport %s\n", this, ToString(viewport).c_str());
|
||||||
|
|
||||||
if (!mInvalidViewport && !mIsFirstPaint && mMobileViewportSize == viewport) {
|
if (!mIsFirstPaint && mMobileViewportSize == viewport) {
|
||||||
// Nothing changed, so no need to do a reflow
|
// Nothing changed, so no need to do a reflow
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -696,7 +706,6 @@ void MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution) {
|
|||||||
ShrinkToDisplaySizeIfNeeded();
|
ShrinkToDisplaySizeIfNeeded();
|
||||||
|
|
||||||
mIsFirstPaint = false;
|
mIsFirstPaint = false;
|
||||||
mInvalidViewport = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::ShrinkToDisplaySizeIfNeeded() {
|
void MobileViewportManager::ShrinkToDisplaySizeIfNeeded() {
|
||||||
@@ -728,9 +737,8 @@ void MobileViewportManager::ShrinkToDisplaySizeIfNeeded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CSSSize MobileViewportManager::GetIntrinsicCompositionSize() const {
|
CSSSize MobileViewportManager::GetIntrinsicCompositionSize() const {
|
||||||
// TODO: Should we use GetDisplaySizeForVisualViewport() for computing the
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
// intrinsic composition size?
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
ScreenIntSize displaySize = GetLayoutDisplaySize();
|
|
||||||
ScreenIntSize compositionSize = GetCompositionSize(displaySize);
|
ScreenIntSize compositionSize = GetCompositionSize(displaySize);
|
||||||
CSSToScreenScale intrinsicScale =
|
CSSToScreenScale intrinsicScale =
|
||||||
ComputeIntrinsicScale(mContext->GetViewportInfo(displaySize),
|
ComputeIntrinsicScale(mContext->GetViewportInfo(displaySize),
|
||||||
@@ -741,44 +749,9 @@ CSSSize MobileViewportManager::GetIntrinsicCompositionSize() const {
|
|||||||
|
|
||||||
ParentLayerSize MobileViewportManager::GetCompositionSizeWithoutDynamicToolbar()
|
ParentLayerSize MobileViewportManager::GetCompositionSizeWithoutDynamicToolbar()
|
||||||
const {
|
const {
|
||||||
|
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
||||||
|
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
||||||
return ViewAs<ParentLayerPixel>(
|
return ViewAs<ParentLayerPixel>(
|
||||||
ScreenSize(GetCompositionSize(GetDisplaySizeForVisualViewport())),
|
ScreenSize(GetCompositionSize(displaySize)),
|
||||||
PixelCastJustification::ScreenIsParentLayerForRoot);
|
PixelCastJustification::ScreenIsParentLayerForRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobileViewportManager::UpdateKeyboardHeight(
|
|
||||||
ScreenIntCoord aKeyboardHeight) {
|
|
||||||
if (aKeyboardHeight == mKeyboardHeight) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mKeyboardHeight = aKeyboardHeight;
|
|
||||||
mInvalidViewport = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenIntSize MobileViewportManager::GetLayoutDisplaySize() const {
|
|
||||||
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
|
||||||
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
|
||||||
switch (mContext->GetInteractiveWidgetMode()) {
|
|
||||||
case InteractiveWidget::ResizesContent:
|
|
||||||
break;
|
|
||||||
case InteractiveWidget::OverlaysContent:
|
|
||||||
case InteractiveWidget::ResizesVisual:
|
|
||||||
displaySize.height += mKeyboardHeight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return displaySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenIntSize MobileViewportManager::GetDisplaySizeForVisualViewport() const {
|
|
||||||
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
|
|
||||||
mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
|
||||||
switch (mContext->GetInteractiveWidgetMode()) {
|
|
||||||
case InteractiveWidget::ResizesContent:
|
|
||||||
case InteractiveWidget::ResizesVisual:
|
|
||||||
break;
|
|
||||||
case InteractiveWidget::OverlaysContent:
|
|
||||||
displaySize.height += mKeyboardHeight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return displaySize;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "nsIDOMEventListener.h"
|
#include "nsIDOMEventListener.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
#include "UnitTransforms.h"
|
|
||||||
|
|
||||||
class nsViewportInfo;
|
class nsViewportInfo;
|
||||||
|
|
||||||
@@ -97,10 +96,8 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||||||
* presShell is initialized. */
|
* presShell is initialized. */
|
||||||
void SetInitialViewport();
|
void SetInitialViewport();
|
||||||
|
|
||||||
mozilla::LayoutDeviceIntSize DisplaySize() const {
|
const mozilla::LayoutDeviceIntSize& DisplaySize() const {
|
||||||
return mozilla::ViewAs<mozilla::LayoutDevicePixel>(
|
return mDisplaySize;
|
||||||
GetLayoutDisplaySize(),
|
|
||||||
mozilla::PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -139,17 +136,15 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||||||
|
|
||||||
mozilla::ParentLayerSize GetCompositionSizeWithoutDynamicToolbar() const;
|
mozilla::ParentLayerSize GetCompositionSizeWithoutDynamicToolbar() const;
|
||||||
|
|
||||||
void UpdateKeyboardHeight(mozilla::ScreenIntCoord aKeyboardHeight);
|
|
||||||
|
|
||||||
static mozilla::LazyLogModule gLog;
|
static mozilla::LazyLogModule gLog;
|
||||||
|
|
||||||
|
private:
|
||||||
|
~MobileViewportManager();
|
||||||
|
|
||||||
/* Main helper method to update the CSS viewport and any other properties that
|
/* Main helper method to update the CSS viewport and any other properties that
|
||||||
* need updating. */
|
* need updating. */
|
||||||
void RefreshViewportSize(bool aForceAdjustResolution);
|
void RefreshViewportSize(bool aForceAdjustResolution);
|
||||||
|
|
||||||
private:
|
|
||||||
~MobileViewportManager();
|
|
||||||
|
|
||||||
/* Secondary main helper method to update just the visual viewport size. */
|
/* Secondary main helper method to update just the visual viewport size. */
|
||||||
void RefreshVisualViewportSize();
|
void RefreshVisualViewportSize();
|
||||||
|
|
||||||
@@ -180,9 +175,11 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||||||
void UpdateResolutionForContentSizeChange(
|
void UpdateResolutionForContentSizeChange(
|
||||||
const mozilla::CSSSize& aContentSize);
|
const mozilla::CSSSize& aContentSize);
|
||||||
|
|
||||||
void ApplyNewZoom(const mozilla::CSSToScreenScale& aNewZoom);
|
void ApplyNewZoom(const mozilla::ScreenIntSize& aDisplaySize,
|
||||||
|
const mozilla::CSSToScreenScale& aNewZoom);
|
||||||
|
|
||||||
void UpdateVisualViewportSize(const mozilla::CSSToScreenScale& aZoom);
|
void UpdateVisualViewportSize(const mozilla::ScreenIntSize& aDisplaySize,
|
||||||
|
const mozilla::CSSToScreenScale& aZoom);
|
||||||
|
|
||||||
/* Updates the displayport margins for the presShell's root scrollable frame
|
/* Updates the displayport margins for the presShell's root scrollable frame
|
||||||
*/
|
*/
|
||||||
@@ -200,23 +197,12 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||||||
mozilla::ScreenIntSize GetCompositionSize(
|
mozilla::ScreenIntSize GetCompositionSize(
|
||||||
const mozilla::ScreenIntSize& aDisplaySize) const;
|
const mozilla::ScreenIntSize& aDisplaySize) const;
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the display size for layout. It varies depending on the
|
|
||||||
* interactive-widget value.
|
|
||||||
*/
|
|
||||||
mozilla::ScreenIntSize GetLayoutDisplaySize() const;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the display size for visual viewport events. It varies depending on
|
|
||||||
* the interactive-widget value. The size doesn't match above
|
|
||||||
* GetLayoutDisplaySize() in the case of resizes-visual.
|
|
||||||
*/
|
|
||||||
mozilla::ScreenIntSize GetDisplaySizeForVisualViewport() const;
|
|
||||||
|
|
||||||
mozilla::CSSToScreenScale GetZoom() const;
|
mozilla::CSSToScreenScale GetZoom() const;
|
||||||
|
|
||||||
RefPtr<mozilla::MVMContext> mContext;
|
RefPtr<mozilla::MVMContext> mContext;
|
||||||
ManagerType mManagerType;
|
ManagerType mManagerType;
|
||||||
|
bool mIsFirstPaint;
|
||||||
|
bool mPainted;
|
||||||
mozilla::LayoutDeviceIntSize mDisplaySize;
|
mozilla::LayoutDeviceIntSize mDisplaySize;
|
||||||
mozilla::CSSSize mMobileViewportSize;
|
mozilla::CSSSize mMobileViewportSize;
|
||||||
mozilla::Maybe<float> mRestoreResolution;
|
mozilla::Maybe<float> mRestoreResolution;
|
||||||
@@ -229,17 +215,6 @@ class MobileViewportManager final : public nsIDOMEventListener,
|
|||||||
* FrameMetrics.mFixedLayerMargins to conform with this value.
|
* FrameMetrics.mFixedLayerMargins to conform with this value.
|
||||||
*/
|
*/
|
||||||
nsSize mVisualViewportSizeUpdatedByDynamicToolbar;
|
nsSize mVisualViewportSizeUpdatedByDynamicToolbar;
|
||||||
|
|
||||||
/*
|
|
||||||
* The software keyboard height.
|
|
||||||
*/
|
|
||||||
mozilla::ScreenIntCoord mKeyboardHeight;
|
|
||||||
|
|
||||||
bool mIsFirstPaint;
|
|
||||||
bool mPainted;
|
|
||||||
// True if this MobileViewportManager needs to update the visual viewport size
|
|
||||||
// even if the layout viewport size is unchanged.
|
|
||||||
bool mInvalidViewport;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11460,12 +11460,6 @@ bool PresShell::SetVisualViewportOffset(const nsPoint& aScrollOffset,
|
|||||||
|
|
||||||
void PresShell::ResetVisualViewportOffset() { mVisualViewportOffset.reset(); }
|
void PresShell::ResetVisualViewportOffset() { mVisualViewportOffset.reset(); }
|
||||||
|
|
||||||
void PresShell::RefreshViewportSize() {
|
|
||||||
if (mMobileViewportManager) {
|
|
||||||
mMobileViewportManager->RefreshViewportSize(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PresShell::ScrollToVisual(const nsPoint& aVisualViewportOffset,
|
void PresShell::ScrollToVisual(const nsPoint& aVisualViewportOffset,
|
||||||
FrameMetrics::ScrollOffsetUpdateType aUpdateType,
|
FrameMetrics::ScrollOffsetUpdateType aUpdateType,
|
||||||
ScrollMode aMode) {
|
ScrollMode aMode) {
|
||||||
|
|||||||
@@ -1521,9 +1521,6 @@ class PresShell final : public nsStubDocumentObserver,
|
|||||||
// shown/hidden.
|
// shown/hidden.
|
||||||
nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const;
|
nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const;
|
||||||
|
|
||||||
// Trigger refreshing the MobileViewportManager's size metrics.
|
|
||||||
void RefreshViewportSize();
|
|
||||||
|
|
||||||
/* Enable/disable author style level. Disabling author style disables the
|
/* Enable/disable author style level. Disabling author style disables the
|
||||||
* entire author level of the cascade, including the HTML preshint level.
|
* entire author level of the cascade, including the HTML preshint level.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1965,12 +1965,6 @@ nsDocumentViewer::SetBoundsWithFlags(const nsIntRect& aBounds,
|
|||||||
nsIFrame* f = rootView->GetFrame();
|
nsIFrame* f = rootView->GetFrame();
|
||||||
if (f) {
|
if (f) {
|
||||||
f->InvalidateFrame();
|
f->InvalidateFrame();
|
||||||
|
|
||||||
// Forcibly refresh the viewport sizes even if the view size is not
|
|
||||||
// changed since it is possible that the |mBounds| change means that
|
|
||||||
// the software keyboard appeared/disappered, in such cases we might
|
|
||||||
// need to fire visual viewport events.
|
|
||||||
mPresShell->RefreshViewportSize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@
|
|||||||
#include "mozilla/dom/HTMLVideoElement.h"
|
#include "mozilla/dom/HTMLVideoElement.h"
|
||||||
#include "mozilla/dom/InspectorFontFace.h"
|
#include "mozilla/dom/InspectorFontFace.h"
|
||||||
#include "mozilla/dom/ImageBitmap.h"
|
#include "mozilla/dom/ImageBitmap.h"
|
||||||
#include "mozilla/dom/InteractiveWidget.h"
|
|
||||||
#include "mozilla/dom/KeyframeEffect.h"
|
#include "mozilla/dom/KeyframeEffect.h"
|
||||||
#include "mozilla/dom/SVGViewportElement.h"
|
#include "mozilla/dom/SVGViewportElement.h"
|
||||||
#include "mozilla/dom/UIEvent.h"
|
#include "mozilla/dom/UIEvent.h"
|
||||||
@@ -8252,17 +8251,6 @@ bool nsLayoutUtils::UpdateCompositionBoundsForRCDRSF(
|
|||||||
shouldSubtractDynamicToolbar)) {
|
shouldSubtractDynamicToolbar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the keyboard height in the case of
|
|
||||||
// `interactive-widget=overlays-content` so that contents being overlaid by
|
|
||||||
// the keyboard can NOT be reachable by scrolling.
|
|
||||||
if (aPresContext->GetKeyboardHeight() &&
|
|
||||||
aPresContext->Document()->InteractiveWidget() ==
|
|
||||||
InteractiveWidget::OverlaysContent) {
|
|
||||||
contentSize.height += ViewAs<LayoutDevicePixel>(
|
|
||||||
aPresContext->GetKeyboardHeight(),
|
|
||||||
PixelCastJustification::LayoutDeviceIsScreenForBounds);
|
|
||||||
}
|
|
||||||
aCompBounds.SizeTo(ViewAs<ParentLayerPixel>(
|
aCompBounds.SizeTo(ViewAs<ParentLayerPixel>(
|
||||||
LayoutDeviceSize(contentSize),
|
LayoutDeviceSize(contentSize),
|
||||||
PixelCastJustification::LayoutDeviceIsParentLayerForRCDRSF));
|
PixelCastJustification::LayoutDeviceIsParentLayerForRCDRSF));
|
||||||
|
|||||||
@@ -96,7 +96,6 @@
|
|||||||
#include "mozilla/layers/APZThreadUtils.h"
|
#include "mozilla/layers/APZThreadUtils.h"
|
||||||
#include "MobileViewportManager.h"
|
#include "MobileViewportManager.h"
|
||||||
#include "mozilla/dom/ImageTracker.h"
|
#include "mozilla/dom/ImageTracker.h"
|
||||||
#include "mozilla/dom/InteractiveWidget.h"
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
# include "mozilla/a11y/DocAccessible.h"
|
# include "mozilla/a11y/DocAccessible.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -247,7 +246,6 @@ nsPresContext::nsPresContext(dom::Document* aDocument, nsPresContextType aType)
|
|||||||
mCurAppUnitsPerDevPixel(0),
|
mCurAppUnitsPerDevPixel(0),
|
||||||
mDynamicToolbarMaxHeight(0),
|
mDynamicToolbarMaxHeight(0),
|
||||||
mDynamicToolbarHeight(0),
|
mDynamicToolbarHeight(0),
|
||||||
mKeyboardHeight(0),
|
|
||||||
mPageSize(-1, -1),
|
mPageSize(-1, -1),
|
||||||
mPageScale(0.0),
|
mPageScale(0.0),
|
||||||
mPPScale(1.0f),
|
mPPScale(1.0f),
|
||||||
@@ -718,15 +716,13 @@ nsresult nsPresContext::Init(nsDeviceContext* aDeviceContext) {
|
|||||||
mEventManager->SetPresContext(this);
|
mEventManager->SetPresContext(this);
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(MOZ_WIDGET_ANDROID)
|
||||||
if (IsRootContentDocumentCrossProcess()) {
|
if (IsRootContentDocumentCrossProcess() &&
|
||||||
if (BrowserChild* browserChild = BrowserChild::GetFrom(GetDocShell())) {
|
MOZ_LIKELY(
|
||||||
mKeyboardHeight = browserChild->GetKeyboardHeight();
|
!Preferences::HasUserValue("layout.dynamic-toolbar-max-height"))) {
|
||||||
|
if (BrowserChild* browserChild =
|
||||||
if (MOZ_LIKELY(!Preferences::HasUserValue(
|
BrowserChild::GetFrom(mDocument->GetDocShell())) {
|
||||||
"layout.dynamic-toolbar-max-height"))) {
|
mDynamicToolbarMaxHeight = browserChild->GetDynamicToolbarMaxHeight();
|
||||||
mDynamicToolbarMaxHeight = browserChild->GetDynamicToolbarMaxHeight();
|
mDynamicToolbarHeight = mDynamicToolbarMaxHeight;
|
||||||
mDynamicToolbarHeight = mDynamicToolbarMaxHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2963,9 +2959,9 @@ gfx::PaletteCache& nsPresContext::FontPaletteCache() {
|
|||||||
return *mFontPaletteCache.get();
|
return *mFontPaletteCache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsPresContext::SetVisibleArea(const nsRect& aRect) {
|
void nsPresContext::SetVisibleArea(const nsRect& r) {
|
||||||
if (!aRect.IsEqualEdges(mVisibleArea)) {
|
if (!r.IsEqualEdges(mVisibleArea)) {
|
||||||
mVisibleArea = aRect;
|
mVisibleArea = r;
|
||||||
mSizeForViewportUnits = mVisibleArea.Size();
|
mSizeForViewportUnits = mVisibleArea.Size();
|
||||||
if (IsRootContentDocumentCrossProcess()) {
|
if (IsRootContentDocumentCrossProcess()) {
|
||||||
AdjustSizeForViewportUnits();
|
AdjustSizeForViewportUnits();
|
||||||
@@ -3038,27 +3034,13 @@ void nsPresContext::UpdateDynamicToolbarOffset(ScreenIntCoord aOffset) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dom::InteractiveWidget interactiveWidget = mDocument->InteractiveWidget();
|
// Forcibly flush position:fixed elements in the case where the dynamic
|
||||||
if (interactiveWidget == InteractiveWidget::OverlaysContent &&
|
// toolbar is going to be completely hidden or starts to be visible so that
|
||||||
mKeyboardHeight > 0) {
|
// %-based style values will be recomputed with the visual viewport size which
|
||||||
// On overlays-content mode, the toolbar offset change should NOT affect
|
// is including the area covered by the dynamic toolbar.
|
||||||
// the visual viewport while the software keyboard is being shown since
|
if (mDynamicToolbarHeight == 0 || aOffset == -mDynamicToolbarMaxHeight) {
|
||||||
// the toolbar will be positioned somewhere in the middle of the visual
|
mPresShell->MarkFixedFramesForReflow(IntrinsicDirty::None);
|
||||||
// viewport.
|
mPresShell->AddResizeEventFlushObserverIfNeeded();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactiveWidget == InteractiveWidget::ResizesContent ||
|
|
||||||
mKeyboardHeight == 0) {
|
|
||||||
// On resizes-content mode or the software keyboard is not visible, forcibly
|
|
||||||
// flush position:fixed elements in the case where the dynamic toolbar is
|
|
||||||
// going to be completely hidden or starts to be visible so that %-based
|
|
||||||
// style values will be recomputed with the visual viewport size which is
|
|
||||||
// including the area covered by the dynamic toolbar.
|
|
||||||
if (mDynamicToolbarHeight == 0 || aOffset == -mDynamicToolbarMaxHeight) {
|
|
||||||
mPresShell->MarkFixedFramesForReflow(IntrinsicDirty::None);
|
|
||||||
mPresShell->AddResizeEventFlushObserverIfNeeded();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mDynamicToolbarHeight = mDynamicToolbarMaxHeight + aOffset;
|
mDynamicToolbarHeight = mDynamicToolbarMaxHeight + aOffset;
|
||||||
@@ -3072,20 +3054,6 @@ void nsPresContext::UpdateDynamicToolbarOffset(ScreenIntCoord aOffset) {
|
|||||||
ServoStyleSet::OnlyDynamic::Yes);
|
ServoStyleSet::OnlyDynamic::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsPresContext::UpdateKeyboardHeight(ScreenIntCoord aHeight) {
|
|
||||||
MOZ_ASSERT(IsRootContentDocumentCrossProcess());
|
|
||||||
mKeyboardHeight = aHeight;
|
|
||||||
|
|
||||||
if (!mPresShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RefPtr<MobileViewportManager> mvm =
|
|
||||||
mPresShell->GetMobileViewportManager()) {
|
|
||||||
mvm->UpdateKeyboardHeight(aHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicToolbarState nsPresContext::GetDynamicToolbarState() const {
|
DynamicToolbarState nsPresContext::GetDynamicToolbarState() const {
|
||||||
if (!IsRootContentDocumentCrossProcess() || !HasDynamicToolbar()) {
|
if (!IsRootContentDocumentCrossProcess() || !HasDynamicToolbar()) {
|
||||||
return DynamicToolbarState::None;
|
return DynamicToolbarState::None;
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||||||
* Set the currently visible area. The units for r are standard
|
* Set the currently visible area. The units for r are standard
|
||||||
* nscoord units (as scaled by the device context).
|
* nscoord units (as scaled by the device context).
|
||||||
*/
|
*/
|
||||||
void SetVisibleArea(const nsRect& aRect);
|
void SetVisibleArea(const nsRect& r);
|
||||||
|
|
||||||
nsSize GetSizeForViewportUnits() const { return mSizeForViewportUnits; }
|
nsSize GetSizeForViewportUnits() const { return mSizeForViewportUnits; }
|
||||||
|
|
||||||
@@ -433,10 +433,6 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||||||
return mDynamicToolbarHeight;
|
return mDynamicToolbarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateKeyboardHeight(mozilla::ScreenIntCoord aHeight);
|
|
||||||
|
|
||||||
mozilla::ScreenIntCoord GetKeyboardHeight() const { return mKeyboardHeight; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the state of the dynamic toolbar.
|
* Returns the state of the dynamic toolbar.
|
||||||
*/
|
*/
|
||||||
@@ -1223,8 +1219,6 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||||||
// The maximum height of the dynamic toolbar on mobile.
|
// The maximum height of the dynamic toolbar on mobile.
|
||||||
mozilla::ScreenIntCoord mDynamicToolbarMaxHeight;
|
mozilla::ScreenIntCoord mDynamicToolbarMaxHeight;
|
||||||
mozilla::ScreenIntCoord mDynamicToolbarHeight;
|
mozilla::ScreenIntCoord mDynamicToolbarHeight;
|
||||||
// The software keyboard height.
|
|
||||||
mozilla::ScreenIntCoord mKeyboardHeight;
|
|
||||||
// Safe area insets support
|
// Safe area insets support
|
||||||
mozilla::ScreenIntMargin mSafeAreaInsets;
|
mozilla::ScreenIntMargin mSafeAreaInsets;
|
||||||
nsSize mPageSize;
|
nsSize mPageSize;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ support-files = [
|
|||||||
"file_bug842853.html",
|
"file_bug842853.html",
|
||||||
"file_bug842853.sjs",
|
"file_bug842853.sjs",
|
||||||
"selection-utils.js",
|
"selection-utils.js",
|
||||||
"!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js",
|
|
||||||
"!/gfx/layers/apz/test/mochitest/apz_test_utils.js",
|
"!/gfx/layers/apz/test/mochitest/apz_test_utils.js",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -271,9 +270,6 @@ support-files = [
|
|||||||
|
|
||||||
["test_getClientRects_emptytext.html"]
|
["test_getClientRects_emptytext.html"]
|
||||||
|
|
||||||
["test_interactive_widget.html"]
|
|
||||||
run-if = ["os == 'android'"]
|
|
||||||
|
|
||||||
["test_mozPaintCount.html"]
|
["test_mozPaintCount.html"]
|
||||||
skip-if = ["os == 'android'"] # android: Requires plugin support
|
skip-if = ["os == 'android'"] # android: Requires plugin support
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1733509
|
|||||||
|
|
||||||
<div class="target" id="t2" hidden></div>
|
<div class="target" id="t2" hidden></div>
|
||||||
|
|
||||||
<input class="target" id="t3_1" hidden inputMode="none"></input>
|
<input class="target" id="t3_1" hidden></input>
|
||||||
<a href="#" class="target" id="t3_2" hidden></a>
|
<a href="#" class="target" id="t3_2" hidden></a>
|
||||||
<label class="target" id="t3_3" hidden></label>
|
<label class="target" id="t3_3" hidden></label>
|
||||||
<button class="target" id="t3_4" hidden></button>
|
<button class="target" id="t3_4" hidden></button>
|
||||||
<select class="target" id="t3_5" hidden></select>
|
<select class="target" id="t3_5" hidden></select>
|
||||||
<textarea class="target" id="t3_6" hidden inputMode="none"></textarea>
|
<textarea class="target" id="t3_6" hidden></textarea>
|
||||||
<div role="button" class="target" id="t3_7" hidden></div>
|
<div role="button" class="target" id="t3_7" hidden></div>
|
||||||
<div role="key" class="target" id="t3_8" hidden></div>
|
<div role="key" class="target" id="t3_8" hidden></div>
|
||||||
<img class="target" id="t3_9" hidden></img>
|
<img class="target" id="t3_9" hidden></img>
|
||||||
@@ -53,7 +53,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1733509
|
|||||||
<div class="target" id="t7" onmousedown="x=1" hidden></div>
|
<div class="target" id="t7" onmousedown="x=1" hidden></div>
|
||||||
<div class="target" id="t7_over" hidden></div>
|
<div class="target" id="t7_over" hidden></div>
|
||||||
|
|
||||||
<div id="t8" contenteditable="true" class="target" hidden inputMode="none"></div>
|
<div id="t8" contenteditable="true" class="target" hidden></div>
|
||||||
|
|
||||||
<div id="t9" class="target" ontouchend="x=1" hidden></div>
|
<div id="t9" class="target" ontouchend="x=1" hidden></div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,273 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>interactive-widget tests</title>
|
|
||||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
|
|
||||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
|
||||||
<style>
|
|
||||||
textarea {
|
|
||||||
height: 100px;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<textarea></textarea>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none"></div>
|
|
||||||
<pre id="test"></pre>
|
|
||||||
<script>
|
|
||||||
async function getViewportMetrics() {
|
|
||||||
return SpecialPowers.spawn(parent, [], () => {
|
|
||||||
return [ content.window.innerHeight, content.window.visualViewport.height ];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let initial_window_height, initial_visual_viewport_height;
|
|
||||||
|
|
||||||
// setup a meta viewport tag in the top document.
|
|
||||||
add_task(async () => {
|
|
||||||
await SpecialPowers.spawn(parent, [], () => {
|
|
||||||
const meta = content.document.createElement("meta");
|
|
||||||
meta.setAttribute("id", "interactive-widget");
|
|
||||||
meta.setAttribute("name", "viewport");
|
|
||||||
meta.setAttribute("content", "width=device-width, initial-scale=1, user-scalable=no");
|
|
||||||
content.document.documentElement.appendChild(meta);
|
|
||||||
|
|
||||||
// Flush the viewport change.
|
|
||||||
content.document.documentElement.getBoundingClientRect();
|
|
||||||
});
|
|
||||||
|
|
||||||
SimpleTest.registerCleanupFunction(async () => {
|
|
||||||
await SpecialPowers.spawn(parent, [], () => {
|
|
||||||
const meta = content.document.querySelector("#interactive-widget");
|
|
||||||
meta.remove();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
[ initial_window_height, initial_visual_viewport_height ] = await getViewportMetrics();
|
|
||||||
});
|
|
||||||
|
|
||||||
async function setupInteractiveWidget(aValue) {
|
|
||||||
await SpecialPowers.spawn(parent, [aValue], async (value) => {
|
|
||||||
const meta = content.document.querySelector("#interactive-widget");
|
|
||||||
meta.setAttribute("content", `width=device-width, initial-scale=1, user-scalable=no, interactive-widget=${value}`);
|
|
||||||
|
|
||||||
// Flush the viewport change.
|
|
||||||
content.document.documentElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
// A dummy Promise to make sure that SpecialPowers.spawn's Promise will
|
|
||||||
// never be resolved until these script have run in the parent context.
|
|
||||||
await new Promise(resolve => resolve());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpecialPowers.spawn doesn't provide any reasonable way to make sure event
|
|
||||||
// listeners have been set in the given context (bug 1743857), so here we post
|
|
||||||
// a message just before setting up a resize event listener and return two
|
|
||||||
// Promises, one will be resolved when we received the message, the other will
|
|
||||||
// be resolved when we got a resize event.
|
|
||||||
function setupResizeEventListener(aInteractiveWidget) {
|
|
||||||
const ready = new Promise(resolve => {
|
|
||||||
window.addEventListener("message", msg => {
|
|
||||||
if (msg.data == "interactive-widget:ready") {
|
|
||||||
resolve(msg.data)
|
|
||||||
}
|
|
||||||
}, { once: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
const resizePromise = SpecialPowers.spawn(parent, [aInteractiveWidget], async (interactiveWidget) => {
|
|
||||||
// #testframe is the iframe id where our mochitest harness loads each test
|
|
||||||
// document, but if this test runs solely just like ./mach test TEST_PATH,
|
|
||||||
// the test document gets loaded in the top level content.
|
|
||||||
const target = content.document.querySelector("#testframe") ?
|
|
||||||
content.document.querySelector("#testframe").contentWindow : content.window;
|
|
||||||
|
|
||||||
let eventPromise;
|
|
||||||
if (interactiveWidget == "resizes-content") {
|
|
||||||
eventPromise = new Promise(resolve => content.window.addEventListener("resize", resolve));
|
|
||||||
} else if (interactiveWidget == "resizes-visual") {
|
|
||||||
eventPromise = new Promise(resolve => content.window.visualViewport.addEventListener("resize", resolve));
|
|
||||||
} else {
|
|
||||||
ok(false, `Unexpected interactive-widget=${interactiveWidget}`);
|
|
||||||
}
|
|
||||||
target.postMessage("interactive-widget:ready", "*");
|
|
||||||
await eventPromise;
|
|
||||||
});
|
|
||||||
|
|
||||||
return [ ready, resizePromise ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// A utility function to hide the software keyboard.
|
|
||||||
// This function needs to be called while the software keyboard is shown on
|
|
||||||
// `resizes-content' or `resizes-visual` mode.
|
|
||||||
async function hideKeyboard() {
|
|
||||||
const interactiveWidget = await SpecialPowers.spawn(parent, [], () => {
|
|
||||||
const meta = content.document.querySelector("#interactive-widget");
|
|
||||||
return meta.getAttribute("content").match(/interactive-widget=([\w-].+?)[,\s]*$/)[1];
|
|
||||||
});
|
|
||||||
|
|
||||||
let [ readyPromise, resizePromise ] = setupResizeEventListener(interactiveWidget);
|
|
||||||
await readyPromise;
|
|
||||||
|
|
||||||
// Tap outside the textarea to hide the software keyboard.
|
|
||||||
await synthesizeNativeTap(document.querySelector("textarea"), 150, 50);
|
|
||||||
await resizePromise;
|
|
||||||
|
|
||||||
await SimpleTest.promiseWaitForCondition(
|
|
||||||
async () => {
|
|
||||||
let [ current_window_height, current_visual_viewport_height ] = await getViewportMetrics();
|
|
||||||
return current_window_height == initial_window_height &&
|
|
||||||
current_visual_viewport_height == initial_visual_viewport_height;
|
|
||||||
},
|
|
||||||
"Waiting for restoring the initial state");
|
|
||||||
}
|
|
||||||
|
|
||||||
// `resizes-content` test
|
|
||||||
add_task(async () => {
|
|
||||||
await setupInteractiveWidget("resizes-content");
|
|
||||||
|
|
||||||
// Setup a resize event listener in the top level document.
|
|
||||||
let [ readyPromise, resizePromise ] = setupResizeEventListener("resizes-content");
|
|
||||||
// Make sure the event listener has been set.
|
|
||||||
await readyPromise;
|
|
||||||
|
|
||||||
// Tap the textarea to show the software keyboard.
|
|
||||||
await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);
|
|
||||||
|
|
||||||
await resizePromise;
|
|
||||||
|
|
||||||
// Now the software keyboard has appeared, before running the next test we
|
|
||||||
// need to hide the keyboard.
|
|
||||||
SimpleTest.registerCurrentTaskCleanupFunction(async () => await hideKeyboard());
|
|
||||||
|
|
||||||
await promiseAfterPaint();
|
|
||||||
|
|
||||||
await SimpleTest.promiseWaitForCondition(
|
|
||||||
() => document.activeElement == document.querySelector("textarea"),
|
|
||||||
"Waiting for focus");
|
|
||||||
|
|
||||||
let [ window_height, visual_viewport_height ] = await getViewportMetrics();
|
|
||||||
ok(window_height < initial_window_height,
|
|
||||||
`The layout viewport got resized to ${window_height} from ${initial_window_height}`);
|
|
||||||
ok(visual_viewport_height < initial_visual_viewport_height,
|
|
||||||
`The visual viewport got resized to ${visual_viewport_height} from ${initial_visual_viewport_height}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// `resizes-visual` test
|
|
||||||
add_task(async () => {
|
|
||||||
await setupInteractiveWidget("resizes-visual");
|
|
||||||
|
|
||||||
// Setup a resize event listener in the top level document.
|
|
||||||
let [ readyPromise, resizePromise ] = setupResizeEventListener("resizes-visual");
|
|
||||||
// Make sure the event listener has been set.
|
|
||||||
await readyPromise;
|
|
||||||
|
|
||||||
// Tap the textarea to show the software keyboard.
|
|
||||||
await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);
|
|
||||||
|
|
||||||
await resizePromise;
|
|
||||||
|
|
||||||
// Now the software keyboard has appeared, before running the next test we
|
|
||||||
// need to hide the keyboard.
|
|
||||||
SimpleTest.registerCurrentTaskCleanupFunction(async () => await hideKeyboard());
|
|
||||||
|
|
||||||
await promiseAfterPaint();
|
|
||||||
await SimpleTest.promiseWaitForCondition(
|
|
||||||
() => document.activeElement == document.querySelector("textarea"),
|
|
||||||
"Waiting for focus");
|
|
||||||
|
|
||||||
let [ window_height, visual_viewport_height ] = await getViewportMetrics();
|
|
||||||
is(window_height, initial_window_height,
|
|
||||||
"The layout viewport is not resized on resizes-visual");
|
|
||||||
ok(visual_viewport_height < initial_visual_viewport_height,
|
|
||||||
`The visual viewport got resized to ${visual_viewport_height} from ${initial_visual_viewport_height}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Append an element in the top level document that the element will be the
|
|
||||||
// underneath the software keyboard.
|
|
||||||
async function appendSpacer() {
|
|
||||||
await SpecialPowers.spawn(parent, [], async () => {
|
|
||||||
const div = content.document.createElement("div");
|
|
||||||
div.setAttribute("id", "interactive-widget-test-spacer");
|
|
||||||
div.style = "height: 200vh; position: absolute; top: 90vh;";
|
|
||||||
content.document.body.appendChild(div);
|
|
||||||
|
|
||||||
// Flush the change.
|
|
||||||
content.document.documentElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
// A dummy Promise to make sure that SpecialPowers.spawn's Promise will
|
|
||||||
// never be resolved until these script have run in the parent context.
|
|
||||||
await new Promise(resolve => resolve());
|
|
||||||
});
|
|
||||||
|
|
||||||
SimpleTest.registerCurrentTaskCleanupFunction(async () => {
|
|
||||||
await SpecialPowers.spawn(parent, [], async () => {
|
|
||||||
const div = content.document.querySelector("#interactive-widget-test-spacer");
|
|
||||||
div.remove();
|
|
||||||
// Flush the change.
|
|
||||||
content.document.documentElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
// A dummy Promise to make sure that SpecialPowers.spawn's Promise will
|
|
||||||
// never be resolved until these script have run in the parent context.
|
|
||||||
await new Promise(resolve => resolve());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// `overlays-content` test
|
|
||||||
add_task(async () => {
|
|
||||||
await setupInteractiveWidget("overlays-content");
|
|
||||||
|
|
||||||
await appendSpacer();
|
|
||||||
|
|
||||||
// Tap the textarea to show the software keyboard.
|
|
||||||
await synthesizeNativeTap(document.querySelector("textarea"), 50, 50);
|
|
||||||
|
|
||||||
// Now the software keyboard has appeared, before running the next test we
|
|
||||||
// need to hide the keyboard.
|
|
||||||
SimpleTest.registerCurrentTaskCleanupFunction(async () => {
|
|
||||||
// Switch back to `resizes-content` mode so that we can receive a resize
|
|
||||||
// event when the keyboard gets hidden.
|
|
||||||
await setupInteractiveWidget("resizes-content");
|
|
||||||
await hideKeyboard();
|
|
||||||
});
|
|
||||||
|
|
||||||
await promiseAfterPaint();
|
|
||||||
await SimpleTest.promiseWaitForCondition(
|
|
||||||
() => document.activeElement == document.querySelector("textarea"),
|
|
||||||
"Waiting for focus");
|
|
||||||
|
|
||||||
let [ window_height, visual_viewport_height ] = await getViewportMetrics();
|
|
||||||
is(window_height, initial_window_height,
|
|
||||||
"The layout viewport is not resized on overlays-content");
|
|
||||||
is(visual_viewport_height, initial_visual_viewport_height,
|
|
||||||
"The visual viewport is not resized on overlays-content");
|
|
||||||
|
|
||||||
// Call a scrollIntoView() on an element underneath the keyboard and see if
|
|
||||||
// the current scroll position changes.
|
|
||||||
const scrollPosition = await SpecialPowers.spawn(parent, [], () => {
|
|
||||||
return content.window.scrollY;
|
|
||||||
});
|
|
||||||
await SpecialPowers.spawn(parent, [], async () => {
|
|
||||||
const div = content.document.querySelector("#interactive-widget-test-spacer");
|
|
||||||
div.scrollIntoView({ behavior: "instant" });
|
|
||||||
|
|
||||||
// Though two rAFs ensure there's at least one scroll event if there is,
|
|
||||||
// we use two additional rAFs just in case.
|
|
||||||
await new Promise(resolve => content.window.requestAnimationFrame(resolve));
|
|
||||||
await new Promise(resolve => content.window.requestAnimationFrame(resolve));
|
|
||||||
await new Promise(resolve => content.window.requestAnimationFrame(resolve));
|
|
||||||
await new Promise(resolve => content.window.requestAnimationFrame(resolve));
|
|
||||||
});
|
|
||||||
|
|
||||||
const newScrollPosition = await SpecialPowers.spawn(parent, [], () => {
|
|
||||||
return content.window.scrollY;
|
|
||||||
});
|
|
||||||
is(scrollPosition, newScrollPosition, "The scrollIntoView() call has no effect");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -23,7 +23,6 @@ import org.mozilla.geckoview.BasicSelectionActionDelegate
|
|||||||
import org.mozilla.geckoview.GeckoResult
|
import org.mozilla.geckoview.GeckoResult
|
||||||
import org.mozilla.geckoview.GeckoSession
|
import org.mozilla.geckoview.GeckoSession
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener as AndroidxOnApplyWindowInsetsListener
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gecko-based EngineView implementation.
|
* Gecko-based EngineView implementation.
|
||||||
@@ -234,13 +233,6 @@ class GeckoEngineView @JvmOverloads constructor(
|
|||||||
super.setVisibility(visibility)
|
super.setVisibility(visibility)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addWindowInsetsListener(
|
|
||||||
key: String,
|
|
||||||
listener: AndroidxOnApplyWindowInsetsListener?,
|
|
||||||
) = geckoView.addWindowInsetsListener(key, listener)
|
|
||||||
|
|
||||||
override fun removeWindowInsetsListener(key: String) = geckoView.removeWindowInsetsListener(key)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal const val DARK_COVER = 0xFF2A2A2E.toInt()
|
internal const val DARK_COVER = 0xFF2A2A2E.toInt()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import android.widget.FrameLayout
|
|||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
|
import androidx.annotation.VisibleForTesting.Companion.PRIVATE
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import mozilla.components.browser.engine.system.matcher.UrlMatcher
|
import mozilla.components.browser.engine.system.matcher.UrlMatcher
|
||||||
import mozilla.components.browser.engine.system.permission.SystemPermissionRequest
|
import mozilla.components.browser.engine.system.permission.SystemPermissionRequest
|
||||||
@@ -706,18 +705,6 @@ class SystemEngineView @JvmOverloads constructor(
|
|||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addWindowInsetsListener(
|
|
||||||
key: String,
|
|
||||||
listener: androidx.core.view.OnApplyWindowInsetsListener?,
|
|
||||||
) {
|
|
||||||
val rootView = (context as Activity).window.decorView.rootView
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(rootView, listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeWindowInsetsListener(key: String) {
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(rootView, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canScrollVerticallyUp() = session?.webView?.canScrollVertically(-1) ?: false
|
override fun canScrollVerticallyUp() = session?.webView?.canScrollVertically(-1) ?: false
|
||||||
|
|
||||||
override fun canScrollVerticallyDown() = session?.webView?.canScrollVertically(1) ?: false
|
override fun canScrollVerticallyDown() = session?.webView?.canScrollVertically(1) ?: false
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package mozilla.components.concept.engine
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener
|
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
@@ -139,24 +138,6 @@ interface EngineView {
|
|||||||
*/
|
*/
|
||||||
fun setActivityContext(context: Context?)
|
fun setActivityContext(context: Context?)
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an OnApplyWindowInsetsListener to observe the root view WindowInsets changes through
|
|
||||||
* the listener set on GeckoView
|
|
||||||
*
|
|
||||||
* @param key The key associated to the listener.
|
|
||||||
* @param listener The OnApplyWindowInsetsListener to be invoked.
|
|
||||||
*/
|
|
||||||
fun addWindowInsetsListener(
|
|
||||||
key: String,
|
|
||||||
listener: OnApplyWindowInsetsListener?,
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the OnApplyWindowInsetsListener to stop observing WindowInsets changed.
|
|
||||||
* @param key The key associated to the listener to remove.
|
|
||||||
*/
|
|
||||||
fun removeWindowInsetsListener(key: String)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A delegate that will handle interactions with text selection context menus.
|
* A delegate that will handle interactions with text selection context menus.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,15 +9,12 @@ import android.os.Build.VERSION.SDK_INT
|
|||||||
import android.os.Build.VERSION_CODES
|
import android.os.Build.VERSION_CODES
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener
|
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.ViewCompat.onApplyWindowInsets
|
import androidx.core.view.ViewCompat.onApplyWindowInsets
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import mozilla.components.support.base.log.logger.Logger
|
import mozilla.components.support.base.log.logger.Logger
|
||||||
|
|
||||||
private const val IMMERSIVE_MODE_WINDOW_INSETS_LISTENER = "IMMERSIVE_MODE_WINDOW_INSETS_LISTENER"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to enter immersive mode - fullscreen with the status bar and navigation buttons hidden,
|
* Attempts to enter immersive mode - fullscreen with the status bar and navigation buttons hidden,
|
||||||
* expanding itself into the notch area for devices running API 28+.
|
* expanding itself into the notch area for devices running API 28+.
|
||||||
@@ -25,18 +22,13 @@ private const val IMMERSIVE_MODE_WINDOW_INSETS_LISTENER = "IMMERSIVE_MODE_WINDOW
|
|||||||
* This will automatically register and use an inset listener: [View.OnApplyWindowInsetsListener]
|
* This will automatically register and use an inset listener: [View.OnApplyWindowInsetsListener]
|
||||||
* to restore immersive mode if interactions with various other widgets like the keyboard or dialogs
|
* to restore immersive mode if interactions with various other widgets like the keyboard or dialogs
|
||||||
* got the activity out of immersive mode without [exitImmersiveMode] being called.
|
* got the activity out of immersive mode without [exitImmersiveMode] being called.
|
||||||
*
|
|
||||||
* @param setListenerFunction is an optional function to setup an WindowInsets listener:
|
|
||||||
* [View.OnApplyWindowInsetsListener] to allow having multiple listeners at the same time.
|
|
||||||
*/
|
*/
|
||||||
fun Activity.enterImmersiveMode(
|
fun Activity.enterImmersiveMode(
|
||||||
insetsController: WindowInsetsControllerCompat = window.createWindowInsetsController(),
|
insetsController: WindowInsetsControllerCompat = window.createWindowInsetsController(),
|
||||||
setOnApplyWindowInsetsListener: (String, OnApplyWindowInsetsListener) ->
|
|
||||||
Unit = { _, listener -> ViewCompat.setOnApplyWindowInsetsListener(window.decorView, listener) },
|
|
||||||
) {
|
) {
|
||||||
insetsController.hideInsets()
|
insetsController.hideInsets()
|
||||||
|
|
||||||
val insetsListener = OnApplyWindowInsetsListener { view, insetsCompat ->
|
ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { view, insetsCompat ->
|
||||||
if (insetsCompat.isVisible(WindowInsetsCompat.Type.statusBars())) {
|
if (insetsCompat.isVisible(WindowInsetsCompat.Type.statusBars())) {
|
||||||
insetsController.hideInsets()
|
insetsController.hideInsets()
|
||||||
}
|
}
|
||||||
@@ -44,8 +36,6 @@ fun Activity.enterImmersiveMode(
|
|||||||
onApplyWindowInsets(view, insetsCompat)
|
onApplyWindowInsets(view, insetsCompat)
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnApplyWindowInsetsListener(IMMERSIVE_MODE_WINDOW_INSETS_LISTENER, insetsListener)
|
|
||||||
|
|
||||||
if (SDK_INT >= VERSION_CODES.P) {
|
if (SDK_INT >= VERSION_CODES.P) {
|
||||||
window.setFlags(
|
window.setFlags(
|
||||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
|
||||||
@@ -70,16 +60,13 @@ private fun WindowInsetsControllerCompat.hideInsets() {
|
|||||||
*
|
*
|
||||||
* @param insetsController is an optional [WindowInsetsControllerCompat] object for controlling the
|
* @param insetsController is an optional [WindowInsetsControllerCompat] object for controlling the
|
||||||
* window insets.
|
* window insets.
|
||||||
* @param removeListenerFunction is an optional function which was used for [enterImmersiveMode].
|
|
||||||
*/
|
*/
|
||||||
fun Activity.exitImmersiveMode(
|
fun Activity.exitImmersiveMode(
|
||||||
insetsController: WindowInsetsControllerCompat = window.createWindowInsetsController(),
|
insetsController: WindowInsetsControllerCompat = window.createWindowInsetsController(),
|
||||||
unregisterOnApplyWindowInsetsListener: (String) ->
|
|
||||||
Unit = { ViewCompat.setOnApplyWindowInsetsListener(window.decorView, null) },
|
|
||||||
) {
|
) {
|
||||||
insetsController.show(WindowInsetsCompat.Type.systemBars())
|
insetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||||
|
|
||||||
unregisterOnApplyWindowInsetsListener(IMMERSIVE_MODE_WINDOW_INSETS_LISTENER)
|
ViewCompat.setOnApplyWindowInsetsListener(window.decorView, null)
|
||||||
|
|
||||||
if (SDK_INT >= VERSION_CODES.P) {
|
if (SDK_INT >= VERSION_CODES.P) {
|
||||||
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
|
||||||
|
|||||||
@@ -10,15 +10,11 @@ import android.view.View
|
|||||||
import mozilla.components.concept.engine.EngineSession
|
import mozilla.components.concept.engine.EngineSession
|
||||||
import mozilla.components.concept.engine.EngineView
|
import mozilla.components.concept.engine.EngineView
|
||||||
import mozilla.components.concept.engine.selection.SelectionActionDelegate
|
import mozilla.components.concept.engine.selection.SelectionActionDelegate
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener as AndroidxOnApplyWindowInsetsListener
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fake [EngineView] to be used in tests.
|
* A fake [EngineView] to be used in tests.
|
||||||
*/
|
*/
|
||||||
class FakeEngineView(
|
class FakeEngineView(context: Context) : View(context), EngineView {
|
||||||
context: Context,
|
|
||||||
) : View(context),
|
|
||||||
EngineView {
|
|
||||||
override fun render(session: EngineSession) = Unit
|
override fun render(session: EngineSession) = Unit
|
||||||
|
|
||||||
override fun captureThumbnail(onFinish: (Bitmap?) -> Unit) = Unit
|
override fun captureThumbnail(onFinish: (Bitmap?) -> Unit) = Unit
|
||||||
@@ -33,12 +29,5 @@ class FakeEngineView(
|
|||||||
|
|
||||||
override fun release() = Unit
|
override fun release() = Unit
|
||||||
|
|
||||||
override fun addWindowInsetsListener(
|
|
||||||
key: String,
|
|
||||||
listener: AndroidxOnApplyWindowInsetsListener?,
|
|
||||||
) = Unit
|
|
||||||
|
|
||||||
override fun removeWindowInsetsListener(key: String) = Unit
|
|
||||||
|
|
||||||
override var selectionActionDelegate: SelectionActionDelegate? = null
|
override var selectionActionDelegate: SelectionActionDelegate? = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,15 +109,6 @@ Initialize GeckoView in an Activity
|
|||||||
view.setSession(session);
|
view.setSession(session);
|
||||||
session.loadUri("about:buildconfig"); // Or any other URL...
|
session.loadUri("about:buildconfig"); // Or any other URL...
|
||||||
|
|
||||||
**4. Set the** `windowSoftInputMode <https://developer.android.com/guide/topics/manifest/activity-element#wsoft>`_ **to** ``adjustResize`` **for** `interactive-widget <https://drafts.csswg.org/css-viewport/#interactive-widget-section>`_ **:**
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<activity android:name=".YourActivity"
|
|
||||||
android:windowSoftInputMode="stateUnspecified|adjustResize" />
|
|
||||||
</manifest>
|
|
||||||
|
|
||||||
You're done!
|
You're done!
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.ContextCompat.getColor
|
import androidx.core.content.ContextCompat.getColor
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@@ -2077,11 +2076,7 @@ abstract class BaseBrowserFragment :
|
|||||||
GestureNavUtils,
|
GestureNavUtils,
|
||||||
).show()
|
).show()
|
||||||
|
|
||||||
activity.enterImmersiveMode(
|
activity.enterImmersiveMode()
|
||||||
setOnApplyWindowInsetsListener = { key: String, listener: OnApplyWindowInsetsListener ->
|
|
||||||
binding.engineView.addWindowInsetsListener(key, listener)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
(view as? SwipeGestureLayout)?.isSwipeEnabled = false
|
(view as? SwipeGestureLayout)?.isSwipeEnabled = false
|
||||||
browserToolbarView.collapse()
|
browserToolbarView.collapse()
|
||||||
browserToolbarView.gone()
|
browserToolbarView.gone()
|
||||||
@@ -2100,10 +2095,7 @@ abstract class BaseBrowserFragment :
|
|||||||
|
|
||||||
MediaState.fullscreen.record(NoExtras())
|
MediaState.fullscreen.record(NoExtras())
|
||||||
} else {
|
} else {
|
||||||
activity.exitImmersiveMode(
|
activity.exitImmersiveMode()
|
||||||
unregisterOnApplyWindowInsetsListener = binding.engineView::removeWindowInsetsListener,
|
|
||||||
)
|
|
||||||
|
|
||||||
(view as? SwipeGestureLayout)?.isSwipeEnabled = true
|
(view as? SwipeGestureLayout)?.isSwipeEnabled = true
|
||||||
(activity as? HomeActivity)?.let { homeActivity ->
|
(activity as? HomeActivity)?.let { homeActivity ->
|
||||||
// ExternalAppBrowserActivity exclusively handles it's own theming unless in private mode.
|
// ExternalAppBrowserActivity exclusively handles it's own theming unless in private mode.
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ import androidx.annotation.AnyThread;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.core.view.OnApplyWindowInsetsListener;
|
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
@@ -715,7 +713,6 @@ package org.mozilla.geckoview {
|
|||||||
method @UiThread public boolean shouldPinOnScreen();
|
method @UiThread public boolean shouldPinOnScreen();
|
||||||
method @UiThread public void surfaceChanged(@NonNull GeckoDisplay.SurfaceInfo);
|
method @UiThread public void surfaceChanged(@NonNull GeckoDisplay.SurfaceInfo);
|
||||||
method @UiThread public void surfaceDestroyed();
|
method @UiThread public void surfaceDestroyed();
|
||||||
method @UiThread public void windowInsetsChanged(@NonNull WindowInsetsCompat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface GeckoDisplay.NewSurfaceProvider {
|
public static interface GeckoDisplay.NewSurfaceProvider {
|
||||||
@@ -1947,7 +1944,6 @@ package org.mozilla.geckoview {
|
|||||||
@UiThread public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfaceProvider {
|
@UiThread public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfaceProvider {
|
||||||
ctor public GeckoView(Context);
|
ctor public GeckoView(Context);
|
||||||
ctor public GeckoView(Context, AttributeSet);
|
ctor public GeckoView(Context, AttributeSet);
|
||||||
method @UiThread public void addWindowInsetsListener(@NonNull String, @Nullable OnApplyWindowInsetsListener);
|
|
||||||
method @NonNull @UiThread public GeckoResult<Bitmap> capturePixels();
|
method @NonNull @UiThread public GeckoResult<Bitmap> capturePixels();
|
||||||
method public void coverUntilFirstPaint(int);
|
method public void coverUntilFirstPaint(int);
|
||||||
method public void dispatchDraw(@Nullable Canvas);
|
method public void dispatchDraw(@Nullable Canvas);
|
||||||
@@ -1961,7 +1957,6 @@ package org.mozilla.geckoview {
|
|||||||
method public void onDetachedFromWindow();
|
method public void onDetachedFromWindow();
|
||||||
method @NonNull public GeckoResult<PanZoomController.InputResultDetail> onTouchEventForDetailResult(@NonNull MotionEvent);
|
method @NonNull public GeckoResult<PanZoomController.InputResultDetail> onTouchEventForDetailResult(@NonNull MotionEvent);
|
||||||
method @Nullable @UiThread public GeckoSession releaseSession();
|
method @Nullable @UiThread public GeckoSession releaseSession();
|
||||||
method @UiThread public void removeWindowInsetsListener(@NonNull String);
|
|
||||||
method public void setActivityContextDelegate(@Nullable GeckoView.ActivityContextDelegate);
|
method public void setActivityContextDelegate(@Nullable GeckoView.ActivityContextDelegate);
|
||||||
method public void setAutofillEnabled(boolean);
|
method public void setAutofillEnabled(boolean);
|
||||||
method public void setDynamicToolbarMaxHeight(int);
|
method public void setDynamicToolbarMaxHeight(int);
|
||||||
|
|||||||
@@ -234,7 +234,6 @@ dependencies {
|
|||||||
|
|
||||||
implementation "com.google.android.gms:play-services-fido:21.1.0"
|
implementation "com.google.android.gms:play-services-fido:21.1.0"
|
||||||
implementation "org.yaml:snakeyaml:2.2"
|
implementation "org.yaml:snakeyaml:2.2"
|
||||||
implementation 'androidx.core:core:1.12.0'
|
|
||||||
|
|
||||||
implementation ComponentsDependencies.androidx_lifecycle_common
|
implementation ComponentsDependencies.androidx_lifecycle_common
|
||||||
implementation ComponentsDependencies.androidx_lifecycle_process
|
implementation ComponentsDependencies.androidx_lifecycle_process
|
||||||
|
|||||||
@@ -8,15 +8,12 @@ package org.mozilla.geckoview;
|
|||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.WindowInsets;
|
|
||||||
import androidx.annotation.AnyThread;
|
import androidx.annotation.AnyThread;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -530,46 +527,4 @@ public class GeckoDisplay {
|
|||||||
public @NonNull ScreenshotBuilder screenshot() {
|
public @NonNull ScreenshotBuilder screenshot() {
|
||||||
return new ScreenshotBuilder(mSession);
|
return new ScreenshotBuilder(mSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getKeyboardHeight(@NonNull final WindowInsetsCompat insetsCompat) {
|
|
||||||
if (Build.VERSION.SDK_INT >= 30) {
|
|
||||||
final WindowInsets insets = insetsCompat.toWindowInsets();
|
|
||||||
if (insets == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://developer.android.com/reference/android/view/WindowInsets.Type#ime()
|
|
||||||
final int imeHeight = insets.getInsets(WindowInsets.Type.ime()).bottom;
|
|
||||||
if (imeHeight == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return imeHeight - insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 29) {
|
|
||||||
final int imeHeight = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()).bottom;
|
|
||||||
if (imeHeight == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return imeHeight - insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
return insetsCompat.getSystemWindowInsets().bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the root window insets changed.
|
|
||||||
*
|
|
||||||
* @param insets the WindowInsetsCompat
|
|
||||||
*/
|
|
||||||
@UiThread
|
|
||||||
public void windowInsetsChanged(@NonNull final WindowInsetsCompat insets) {
|
|
||||||
ThreadUtils.assertOnUiThread();
|
|
||||||
|
|
||||||
final int keyboardHeight = getKeyboardHeight(insets);
|
|
||||||
|
|
||||||
if (mSession != null) {
|
|
||||||
mSession.onKeyboardHeight(keyboardHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,7 +284,6 @@ public class GeckoSession {
|
|||||||
private float mViewportLeft;
|
private float mViewportLeft;
|
||||||
private float mViewportTop;
|
private float mViewportTop;
|
||||||
private float mViewportZoom = 1.0f;
|
private float mViewportZoom = 1.0f;
|
||||||
private int mKeyboardHeight = 0; // The software keyboard height, 0 if it's hidden.
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// NOTE: These values are also defined in
|
// NOTE: These values are also defined in
|
||||||
@@ -411,9 +410,6 @@ public class GeckoSession {
|
|||||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
||||||
public native void onSafeAreaInsetsChanged(int top, int right, int bottom, int left);
|
public native void onSafeAreaInsetsChanged(int top, int right, int bottom, int left);
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
|
||||||
public native void onKeyboardHeightChanged(int height);
|
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "ui")
|
@WrapForJNI(calledFrom = "ui")
|
||||||
public void setPointerIcon(
|
public void setPointerIcon(
|
||||||
final int defaultCursor, final Bitmap customCursor, final float x, final float y) {
|
final int defaultCursor, final Bitmap customCursor, final float x, final float y) {
|
||||||
@@ -2642,10 +2638,6 @@ public class GeckoSession {
|
|||||||
} else {
|
} else {
|
||||||
// Delete any pending memory pressure events since we're active again.
|
// Delete any pending memory pressure events since we're active again.
|
||||||
ThreadUtils.removeUiThreadCallbacks(mNotifyMemoryPressure);
|
ThreadUtils.removeUiThreadCallbacks(mNotifyMemoryPressure);
|
||||||
|
|
||||||
if (mAttachedCompositor) {
|
|
||||||
mCompositor.onKeyboardHeightChanged(mKeyboardHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadUtils.runOnUiThread(() -> getAutofillSupport().onActiveChanged(active));
|
ThreadUtils.runOnUiThread(() -> getAutofillSupport().onActiveChanged(active));
|
||||||
@@ -7904,20 +7896,6 @@ public class GeckoSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void onKeyboardHeight(final int height) {
|
|
||||||
ThreadUtils.assertOnUiThread();
|
|
||||||
|
|
||||||
if (mKeyboardHeight == height) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mKeyboardHeight = height;
|
|
||||||
|
|
||||||
if (mAttachedCompositor) {
|
|
||||||
mCompositor.onKeyboardHeightChanged(mKeyboardHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package */ void setPointerIcon(
|
/* package */ void setPointerIcon(
|
||||||
final int defaultCursor, final @Nullable Bitmap customCursor, final float x, final float y) {
|
final int defaultCursor, final @Nullable Bitmap customCursor, final float x, final float y) {
|
||||||
ThreadUtils.assertOnUiThread();
|
ThreadUtils.assertOnUiThread();
|
||||||
|
|||||||
@@ -56,12 +56,10 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.mozilla.gecko.AndroidGamepadManager;
|
import org.mozilla.gecko.AndroidGamepadManager;
|
||||||
import org.mozilla.gecko.EventDispatcher;
|
import org.mozilla.gecko.EventDispatcher;
|
||||||
@@ -73,10 +71,6 @@ import org.mozilla.gecko.util.ThreadUtils;
|
|||||||
public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfaceProvider {
|
public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfaceProvider {
|
||||||
private static final String LOGTAG = "GeckoView";
|
private static final String LOGTAG = "GeckoView";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final String KEYBOARD_WINDOW_INSETS_LISTENER = "KEYBOARD_WINDOW_INSETS_LISTENER";
|
|
||||||
private final HashMap<String, androidx.core.view.OnApplyWindowInsetsListener>
|
|
||||||
mWindowInsetsListeners =
|
|
||||||
new HashMap<String, androidx.core.view.OnApplyWindowInsetsListener>();
|
|
||||||
|
|
||||||
protected final @NonNull Display mDisplay = new Display();
|
protected final @NonNull Display mDisplay = new Display();
|
||||||
|
|
||||||
@@ -101,8 +95,7 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
|
|||||||
private @Nullable ActivityContextDelegate mActivityDelegate;
|
private @Nullable ActivityContextDelegate mActivityDelegate;
|
||||||
private GeckoSession.PrintDelegate mPrintDelegate;
|
private GeckoSession.PrintDelegate mPrintDelegate;
|
||||||
|
|
||||||
private class Display
|
private class Display implements SurfaceViewWrapper.Listener {
|
||||||
implements SurfaceViewWrapper.Listener, androidx.core.view.OnApplyWindowInsetsListener {
|
|
||||||
private final int[] mOrigin = new int[2];
|
private final int[] mOrigin = new int[2];
|
||||||
|
|
||||||
private GeckoDisplay mDisplay;
|
private GeckoDisplay mDisplay;
|
||||||
@@ -201,24 +194,6 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // OnApplyWindowInsetsListener
|
|
||||||
public WindowInsetsCompat onApplyWindowInsets(
|
|
||||||
@NonNull final View view, @NonNull final WindowInsetsCompat insets) {
|
|
||||||
final WindowInsetsCompat updatedInsets =
|
|
||||||
WindowInsetsCompat.toWindowInsetsCompat(
|
|
||||||
view.onApplyWindowInsets(insets.toWindowInsets()));
|
|
||||||
if (mDisplay != null) {
|
|
||||||
mDisplay.windowInsetsChanged(updatedInsets);
|
|
||||||
}
|
|
||||||
return updatedInsets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void windowInsetsChanged(@NonNull final WindowInsetsCompat insets) {
|
|
||||||
if (mDisplay != null) {
|
|
||||||
mDisplay.windowInsetsChanged(insets);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldPinOnScreen() {
|
public boolean shouldPinOnScreen() {
|
||||||
return mDisplay != null && mDisplay.shouldPinOnScreen();
|
return mDisplay != null && mDisplay.shouldPinOnScreen();
|
||||||
}
|
}
|
||||||
@@ -637,75 +612,6 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
|
|||||||
return mSession.getPanZoomController();
|
return mSession.getPanZoomController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register an internal windowInsetsListener that will forward its calls to the listeners
|
|
||||||
* registered in {@link GeckoView#mWindowInsetsListeners}
|
|
||||||
*
|
|
||||||
* @param activity The target Activity to observe.
|
|
||||||
*/
|
|
||||||
private void attachWindowInsetsListener(final @NonNull Activity activity) {
|
|
||||||
try {
|
|
||||||
final View rootView = activity.getWindow().getDecorView().getRootView();
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(
|
|
||||||
rootView,
|
|
||||||
(view, insets) -> {
|
|
||||||
final WindowInsetsCompat updatedInsets =
|
|
||||||
WindowInsetsCompat.toWindowInsetsCompat(
|
|
||||||
view.onApplyWindowInsets(insets.toWindowInsets()));
|
|
||||||
|
|
||||||
for (final androidx.core.view.OnApplyWindowInsetsListener listener :
|
|
||||||
mWindowInsetsListeners.values()) {
|
|
||||||
listener.onApplyWindowInsets(view, updatedInsets);
|
|
||||||
}
|
|
||||||
return updatedInsets;
|
|
||||||
});
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.e(LOGTAG, "Failed to attach WindowInsetsListener: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister the internal WindowInsetsListener attached to the Activity's root view and clear the
|
|
||||||
* listeners that were attached through {@link GeckoView#addWindowInsetsListener(String,
|
|
||||||
* androidx.core.view.OnApplyWindowInsetsListener) }
|
|
||||||
*
|
|
||||||
* @param activity The target Activity to stop observing.
|
|
||||||
*/
|
|
||||||
private void detachWindowInsetsListener(final @NonNull Activity activity) {
|
|
||||||
try {
|
|
||||||
final View rootView = activity.getWindow().getDecorView().getRootView();
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(rootView, null);
|
|
||||||
mWindowInsetsListeners.clear();
|
|
||||||
} catch (final Exception e) {
|
|
||||||
Log.e(LOGTAG, "Failed to detach WindowInsetsListener: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an OnApplyWindowInsetsListener to observe the root view WindowInsets changes.
|
|
||||||
*
|
|
||||||
* @param key The key associated to the listener.
|
|
||||||
* @param listener The OnApplyWindowInsetsListener to be invoked.
|
|
||||||
*/
|
|
||||||
@UiThread
|
|
||||||
public void addWindowInsetsListener(
|
|
||||||
final @NonNull String key,
|
|
||||||
final @Nullable androidx.core.view.OnApplyWindowInsetsListener listener) {
|
|
||||||
ThreadUtils.assertOnUiThread();
|
|
||||||
mWindowInsetsListeners.put(key, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the OnApplyWindowInsetsListener to stop observing WindowInsets changed.
|
|
||||||
*
|
|
||||||
* @param key The key associated to the listener to remove.
|
|
||||||
*/
|
|
||||||
@UiThread
|
|
||||||
public void removeWindowInsetsListener(final @NonNull String key) {
|
|
||||||
ThreadUtils.assertOnUiThread();
|
|
||||||
mWindowInsetsListeners.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
if (mIsSessionPoisoned) {
|
if (mIsSessionPoisoned) {
|
||||||
@@ -723,18 +629,12 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
|
|
||||||
// This needs to be called after the `super.onAttachedToWindow()`.
|
|
||||||
attachWindowInsetsListener(getActivityFromContext(getContext()));
|
|
||||||
addWindowInsetsListener(KEYBOARD_WINDOW_INSETS_LISTENER, mDisplay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromWindow() {
|
public void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
|
|
||||||
detachWindowInsetsListener(getActivityFromContext(getContext()));
|
|
||||||
|
|
||||||
if (mSession == null) {
|
if (mSession == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,8 @@ exclude: true
|
|||||||
## v130
|
## v130
|
||||||
- ⚠️ Removed [`TranslationState`][127.4] constructor, please use the new [`TranslationState`][127.3] constructor with `hasVisibleChange`. ([bug 1895275]({{bugzilla}}1895275))
|
- ⚠️ Removed [`TranslationState`][127.4] constructor, please use the new [`TranslationState`][127.3] constructor with `hasVisibleChange`. ([bug 1895275]({{bugzilla}}1895275))
|
||||||
- Added support for controlling `privacy.fingerprintingProtection` and `privacy.fingerprintingProtection.pbmode` via [`GeckoRuntimeSettings.setFingerprintingProtection`][130.1]
|
- Added support for controlling `privacy.fingerprintingProtection` and `privacy.fingerprintingProtection.pbmode` via [`GeckoRuntimeSettings.setFingerprintingProtection`][130.1]
|
||||||
- Added [`GeckoDisplay.windowInsetsChanged`][130.2].
|
|
||||||
- Added [`GeckoView.addWindowInsetsListener`][130.3] and [`GeckoView.removeWindowInsetsListener`][130.4] to allow listening WindowInsets changes of Activity's root window with multiple listeners.
|
|
||||||
|
|
||||||
[130.1]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setFingerprintingProtection
|
[130.1]: {{javadoc_uri}}/GeckoRuntimeSettings.html#setFingerprintingProtection
|
||||||
[130.2]: {{javadoc_uri}}/GeckoDisplay.html#windowInsetsChanged
|
|
||||||
[130.3]: {{javadoc_uri}}/GeckoView.html#addWindowInsetsListener
|
|
||||||
[130.4]: {{javadoc_uri}}/GeckoView.html#removeWindowInsetsListener
|
|
||||||
|
|
||||||
## v129
|
## v129
|
||||||
- Added [`ERROR_ADMIN_INSTALL_ONLY`][129.1] to `WebExtension.InstallException.ErrorCodes`. ([bug 1902222]({{bugzilla}}1902222))
|
- Added [`ERROR_ADMIN_INSTALL_ONLY`][129.1] to `WebExtension.InstallException.ErrorCodes`. ([bug 1902222]({{bugzilla}}1902222))
|
||||||
@@ -1594,4 +1589,4 @@ to allow adding gecko profiler markers.
|
|||||||
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
|
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
|
||||||
[65.25]: {{javadoc_uri}}/GeckoResult.html
|
[65.25]: {{javadoc_uri}}/GeckoResult.html
|
||||||
|
|
||||||
[api-version]: f935b93b2a809fdf1fc8561189f3f14d3105ddce
|
[api-version]: 54de491a757351b552176a5686609f62afb23da6
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
<uses-library android:name="android.test.runner" android:required="false"/>
|
<uses-library android:name="android.test.runner" android:required="false"/>
|
||||||
<activity android:name=".TestRunnerActivity"
|
<activity android:name=".TestRunnerActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:windowSoftInputMode="stateUnspecified|adjustResize"
|
|
||||||
android:exported="true"/>
|
android:exported="true"/>
|
||||||
<activity-alias android:name=".App" android:targetActivity=".TestRunnerActivity"
|
<activity-alias android:name=".App" android:targetActivity=".TestRunnerActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -921,8 +921,23 @@ void nsView::DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight) {
|
|||||||
MOZ_ASSERT(this == mViewManager->GetRootView(),
|
MOZ_ASSERT(this == mViewManager->GetRootView(),
|
||||||
"Should be called for the root view");
|
"Should be called for the root view");
|
||||||
|
|
||||||
CallOnAllRemoteChildren(
|
PresShell* presShell = mViewManager->GetPresShell();
|
||||||
[aHeight](dom::BrowserParent* aBrowserParent) -> CallState {
|
if (!presShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dom::Document* document = presShell->GetDocument();
|
||||||
|
if (!document) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowOuter* window = document->GetWindow();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsContentUtils::CallOnAllRemoteChildren(
|
||||||
|
window, [&aHeight](dom::BrowserParent* aBrowserParent) -> CallState {
|
||||||
aBrowserParent->DynamicToolbarMaxHeightChanged(aHeight);
|
aBrowserParent->DynamicToolbarMaxHeightChanged(aHeight);
|
||||||
return CallState::Continue;
|
return CallState::Continue;
|
||||||
});
|
});
|
||||||
@@ -933,8 +948,24 @@ void nsView::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {
|
|||||||
"Should be only called for the browser parent process");
|
"Should be only called for the browser parent process");
|
||||||
MOZ_ASSERT(this == mViewManager->GetRootView(),
|
MOZ_ASSERT(this == mViewManager->GetRootView(),
|
||||||
"Should be called for the root view");
|
"Should be called for the root view");
|
||||||
CallOnAllRemoteChildren(
|
|
||||||
[aOffset](dom::BrowserParent* aBrowserParent) -> CallState {
|
PresShell* presShell = mViewManager->GetPresShell();
|
||||||
|
if (!presShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dom::Document* document = presShell->GetDocument();
|
||||||
|
if (!document) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowOuter* window = document->GetWindow();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsContentUtils::CallOnAllRemoteChildren(
|
||||||
|
window, [&aOffset](dom::BrowserParent* aBrowserParent) -> CallState {
|
||||||
// Skip background tabs.
|
// Skip background tabs.
|
||||||
if (!aBrowserParent->GetDocShellIsActive()) {
|
if (!aBrowserParent->GetDocShellIsActive()) {
|
||||||
return CallState::Continue;
|
return CallState::Continue;
|
||||||
@@ -944,23 +975,6 @@ void nsView::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {
|
|||||||
return CallState::Stop;
|
return CallState::Stop;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsView::KeyboardHeightChanged(ScreenIntCoord aHeight) {
|
|
||||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
|
||||||
"Should be only called for the browser parent process");
|
|
||||||
MOZ_ASSERT(this == mViewManager->GetRootView(),
|
|
||||||
"Should be called for the root view");
|
|
||||||
CallOnAllRemoteChildren(
|
|
||||||
[aHeight](dom::BrowserParent* aBrowserParent) -> CallState {
|
|
||||||
// Skip background tabs.
|
|
||||||
if (!aBrowserParent->GetDocShellIsActive()) {
|
|
||||||
return CallState::Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
aBrowserParent->KeyboardHeightChanged(aHeight);
|
|
||||||
return CallState::Stop;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool nsView::RequestWindowClose(nsIWidget* aWidget) {
|
bool nsView::RequestWindowClose(nsIWidget* aWidget) {
|
||||||
@@ -1078,24 +1092,6 @@ void nsView::SafeAreaInsetsChanged(const ScreenIntMargin& aSafeAreaInsets) {
|
|||||||
// https://github.com/w3c/csswg-drafts/issues/4670
|
// https://github.com/w3c/csswg-drafts/issues/4670
|
||||||
// Actually we don't set this value on sub document. This behaviour is
|
// Actually we don't set this value on sub document. This behaviour is
|
||||||
// same as Blink.
|
// same as Blink.
|
||||||
CallOnAllRemoteChildren([windowSafeAreaInsets](
|
|
||||||
dom::BrowserParent* aBrowserParent) -> CallState {
|
|
||||||
Unused << aBrowserParent->SendSafeAreaInsetsChanged(windowSafeAreaInsets);
|
|
||||||
return CallState::Continue;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsView::IsPrimaryFramePaintSuppressed() {
|
|
||||||
return StaticPrefs::layout_show_previous_page() && mFrame &&
|
|
||||||
mFrame->PresShell()->IsPaintingSuppressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsView::CallOnAllRemoteChildren(
|
|
||||||
const std::function<CallState(dom::BrowserParent*)>& aCallback) {
|
|
||||||
PresShell* presShell = mViewManager->GetPresShell();
|
|
||||||
if (!presShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dom::Document* document = presShell->GetDocument();
|
dom::Document* document = presShell->GetDocument();
|
||||||
if (!document) {
|
if (!document) {
|
||||||
@@ -1107,5 +1103,16 @@ void nsView::CallOnAllRemoteChildren(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsContentUtils::CallOnAllRemoteChildren(window, aCallback);
|
nsContentUtils::CallOnAllRemoteChildren(
|
||||||
|
window,
|
||||||
|
[windowSafeAreaInsets](dom::BrowserParent* aBrowserParent) -> CallState {
|
||||||
|
Unused << aBrowserParent->SendSafeAreaInsetsChanged(
|
||||||
|
windowSafeAreaInsets);
|
||||||
|
return CallState::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nsView::IsPrimaryFramePaintSuppressed() {
|
||||||
|
return StaticPrefs::layout_show_previous_page() && mFrame &&
|
||||||
|
mFrame->PresShell()->IsPaintingSuppressed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
#include "nsIWidgetListener.h"
|
#include "nsIWidgetListener.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/CallState.h"
|
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/UniquePtr.h"
|
||||||
|
|
||||||
@@ -25,9 +24,6 @@ class nsIFrame;
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class PresShell;
|
class PresShell;
|
||||||
namespace dom {
|
|
||||||
class BrowserParent;
|
|
||||||
} // namespace dom
|
|
||||||
namespace widget {
|
namespace widget {
|
||||||
struct InitData;
|
struct InitData;
|
||||||
enum class TransparencyMode : uint8_t;
|
enum class TransparencyMode : uint8_t;
|
||||||
@@ -433,7 +429,6 @@ class nsView final : public nsIWidgetListener {
|
|||||||
mozilla::ScreenIntCoord aHeight) override;
|
mozilla::ScreenIntCoord aHeight) override;
|
||||||
virtual void DynamicToolbarOffsetChanged(
|
virtual void DynamicToolbarOffsetChanged(
|
||||||
mozilla::ScreenIntCoord aOffset) override;
|
mozilla::ScreenIntCoord aOffset) override;
|
||||||
virtual void KeyboardHeightChanged(mozilla::ScreenIntCoord aHeight) override;
|
|
||||||
#endif
|
#endif
|
||||||
virtual bool RequestWindowClose(nsIWidget* aWidget) override;
|
virtual bool RequestWindowClose(nsIWidget* aWidget) override;
|
||||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||||
@@ -519,10 +514,6 @@ class nsView final : public nsIWidgetListener {
|
|||||||
// Update the cached RootViewManager for all view manager descendents.
|
// Update the cached RootViewManager for all view manager descendents.
|
||||||
void InvalidateHierarchy();
|
void InvalidateHierarchy();
|
||||||
|
|
||||||
void CallOnAllRemoteChildren(
|
|
||||||
const std::function<mozilla::CallState(mozilla::dom::BrowserParent*)>&
|
|
||||||
aCallback);
|
|
||||||
|
|
||||||
nsViewManager* mViewManager;
|
nsViewManager* mViewManager;
|
||||||
nsView* mParent;
|
nsView* mParent;
|
||||||
nsCOMPtr<nsIWidget> mWindow;
|
nsCOMPtr<nsIWidget> mWindow;
|
||||||
|
|||||||
@@ -1315,21 +1315,6 @@ class LayerViewSupport final
|
|||||||
gkWindow->UpdateDynamicToolbarMaxHeight(ScreenIntCoord(aHeight));
|
gkWindow->UpdateDynamicToolbarMaxHeight(ScreenIntCoord(aHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnKeyboardHeightChanged(int32_t aHeight) {
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
auto win(mWindow.Access());
|
|
||||||
if (!win) {
|
|
||||||
return; // Already shut down.
|
|
||||||
}
|
|
||||||
|
|
||||||
nsWindow* gkWindow = win->GetNsWindow();
|
|
||||||
if (!gkWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gkWindow->KeyboardHeightChanged(ScreenIntCoord(aHeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncPauseCompositor() {
|
void SyncPauseCompositor() {
|
||||||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||||
|
|
||||||
@@ -3274,16 +3259,6 @@ void nsWindow::UpdateDynamicToolbarOffset(ScreenIntCoord aOffset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::KeyboardHeightChanged(ScreenIntCoord aHeight) {
|
|
||||||
if (mWidgetListener) {
|
|
||||||
mWidgetListener->KeyboardHeightChanged(aHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAttachedWidgetListener) {
|
|
||||||
mAttachedWidgetListener->KeyboardHeightChanged(aHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenIntMargin nsWindow::GetSafeAreaInsets() const { return mSafeAreaInsets; }
|
ScreenIntMargin nsWindow::GetSafeAreaInsets() const { return mSafeAreaInsets; }
|
||||||
|
|
||||||
void nsWindow::UpdateSafeAreaInsets(const ScreenIntMargin& aSafeAreaInsets) {
|
void nsWindow::UpdateSafeAreaInsets(const ScreenIntMargin& aSafeAreaInsets) {
|
||||||
|
|||||||
@@ -245,8 +245,6 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
mozilla::ScreenIntMargin GetSafeAreaInsets() const override;
|
mozilla::ScreenIntMargin GetSafeAreaInsets() const override;
|
||||||
void UpdateSafeAreaInsets(const mozilla::ScreenIntMargin& aSafeAreaInsets);
|
void UpdateSafeAreaInsets(const mozilla::ScreenIntMargin& aSafeAreaInsets);
|
||||||
|
|
||||||
void KeyboardHeightChanged(mozilla::ScreenIntCoord aHeight);
|
|
||||||
|
|
||||||
mozilla::jni::NativeWeakPtr<mozilla::widget::NPZCSupport>
|
mozilla::jni::NativeWeakPtr<mozilla::widget::NPZCSupport>
|
||||||
GetNPZCSupportWeakPtr();
|
GetNPZCSupportWeakPtr();
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ void nsIWidgetListener::SafeAreaInsetsChanged(const mozilla::ScreenIntMargin&) {
|
|||||||
void nsIWidgetListener::DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight) {
|
void nsIWidgetListener::DynamicToolbarMaxHeightChanged(ScreenIntCoord aHeight) {
|
||||||
}
|
}
|
||||||
void nsIWidgetListener::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {}
|
void nsIWidgetListener::DynamicToolbarOffsetChanged(ScreenIntCoord aOffset) {}
|
||||||
void nsIWidgetListener::KeyboardHeightChanged(ScreenIntCoord aHeight) {}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void nsIWidgetListener::MacFullscreenMenubarOverlapChanged(
|
void nsIWidgetListener::MacFullscreenMenubarOverlapChanged(
|
||||||
|
|||||||
@@ -84,11 +84,6 @@ class nsIWidgetListener {
|
|||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(MOZ_WIDGET_ANDROID)
|
||||||
virtual void DynamicToolbarMaxHeightChanged(mozilla::ScreenIntCoord aHeight);
|
virtual void DynamicToolbarMaxHeightChanged(mozilla::ScreenIntCoord aHeight);
|
||||||
virtual void DynamicToolbarOffsetChanged(mozilla::ScreenIntCoord aOffset);
|
virtual void DynamicToolbarOffsetChanged(mozilla::ScreenIntCoord aOffset);
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the software keyboard appears/disappears.
|
|
||||||
*/
|
|
||||||
virtual void KeyboardHeightChanged(mozilla::ScreenIntCoord aHeight);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -568,7 +568,6 @@ STATIC_ATOMS = [
|
|||||||
Atom("insertion", "insertion"),
|
Atom("insertion", "insertion"),
|
||||||
Atom("integer", "integer"),
|
Atom("integer", "integer"),
|
||||||
Atom("integrity", "integrity"),
|
Atom("integrity", "integrity"),
|
||||||
Atom("interactive_widget", "interactive-widget"),
|
|
||||||
Atom("internal", "internal"),
|
Atom("internal", "internal"),
|
||||||
Atom("internals", "internals"),
|
Atom("internals", "internals"),
|
||||||
Atom("intersection", "intersection"),
|
Atom("intersection", "intersection"),
|
||||||
|
|||||||
Reference in New Issue
Block a user